From be52740c5312f5c6e5de0d97e7a9382c02e07488 Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 12:51:01 +0200
Subject: [PATCH 1/8] Implement create project route
---
config/checkstyle/checkstyle-ignore.xml | 18 +-
config/checkstyle/checkstyle.xml | 46 +-
gradle/wrapper/gradle-wrapper.properties | 14 +-
gradlew | 504 +++++++++---------
.../config/OpenAPIConfiguration.java | 120 ++---
.../lf8_starter/project/GetProjectDto.java | 43 ++
.../project/dto/CreateProjectAction.java | 42 ++
.../security/KeycloakLogoutHandler.java | 98 ++--
.../resources/application-test.properties | 8 +-
.../Lf8StarterApplicationTests.java | 28 +-
10 files changed, 503 insertions(+), 418 deletions(-)
create mode 100644 src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
create mode 100644 src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
diff --git a/config/checkstyle/checkstyle-ignore.xml b/config/checkstyle/checkstyle-ignore.xml
index fe3b2fe..5ec61a5 100644
--- a/config/checkstyle/checkstyle-ignore.xml
+++ b/config/checkstyle/checkstyle-ignore.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index d8f0701..3c18de8 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index df97d72..b9ddd88 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
-networkTimeout=10000
-validateDistributionUrl=true
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index f5feea6..ec19934 100755
--- a/gradlew
+++ b/gradlew
@@ -1,252 +1,252 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 the original 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.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-# This is normally unused
-# shellcheck disable=SC2034
-APP_BASE_NAME=${0##*/}
-# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- if ! command -v java >/dev/null 2>&1
- then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if "$cygwin" || "$msys" ; then
- APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
-
- JAVACMD=$( cygpath --unix "$JAVACMD" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
-# and any embedded shellness will be escaped.
-# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
-# treated as '${Hostname}' itself on the command line.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
index 1b2282b..76a6f58 100644
--- a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
+++ b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
@@ -1,60 +1,60 @@
-package de.szut.lf8_starter.config;
-
-
-
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.info.Info;
-import io.swagger.v3.oas.models.security.SecurityRequirement;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import io.swagger.v3.oas.models.servers.Server;
-import jakarta.servlet.ServletContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-
-@Configuration
-public class OpenAPIConfiguration {
-
- private ServletContext context;
-
- public OpenAPIConfiguration(ServletContext context) {
- this.context = context;
- }
-
-
- @Bean
- public OpenAPI springShopOpenAPI(
- // @Value("${info.app.version}") String appVersion,
- ) {
- final String securitySchemeName = "bearerAuth";
-
- return new OpenAPI()
- .addServersItem(new Server().url(this.context.getContextPath()))
- .info(new Info()
- .title("LF8 project starter")
- .description("\n## Auth\n" +
- "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
- "\n" +
- "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
- "\n" +
- "\nor by CURL\n" +
- "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
- "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
-
- .version("0.1"))
- .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
- .components(
- new Components()
- .addSecuritySchemes(securitySchemeName,
- new SecurityScheme()
- .name(securitySchemeName)
- .type(SecurityScheme.Type.HTTP)
- .scheme("bearer")
- .bearerFormat("JWT")
- )
- );
- }
-
-
-}
+package de.szut.lf8_starter.config;
+
+
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.servers.Server;
+import jakarta.servlet.ServletContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class OpenAPIConfiguration {
+
+ private ServletContext context;
+
+ public OpenAPIConfiguration(ServletContext context) {
+ this.context = context;
+ }
+
+
+ @Bean
+ public OpenAPI springShopOpenAPI(
+ // @Value("${info.app.version}") String appVersion,
+ ) {
+ final String securitySchemeName = "bearerAuth";
+
+ return new OpenAPI()
+ .addServersItem(new Server().url(this.context.getContextPath()))
+ .info(new Info()
+ .title("LF8 project starter")
+ .description("\n## Auth\n" +
+ "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
+ "\n" +
+ "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
+ "\n" +
+ "\nor by CURL\n" +
+ "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
+ "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
+
+ .version("0.1"))
+ .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
+ .components(
+ new Components()
+ .addSecuritySchemes(securitySchemeName,
+ new SecurityScheme()
+ .name(securitySchemeName)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")
+ )
+ );
+ }
+
+
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
new file mode 100644
index 0000000..86ce087
--- /dev/null
+++ b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
@@ -0,0 +1,43 @@
+package de.szut.lf8_starter.project;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+public class GetProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate startDate;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate plannedEndDate;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
new file mode 100644
index 0000000..f1c6cdc
--- /dev/null
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
@@ -0,0 +1,42 @@
+package de.szut.lf8_starter.project.dto;
+
+import de.szut.lf8_starter.project.GetProjectDto;
+import de.szut.lf8_starter.project.ProjectEntity;
+import de.szut.lf8_starter.project.ProjectMapper;
+import de.szut.lf8_starter.project.ProjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.Valid;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/projects")
+public class CreateProjectAction {
+ private final ProjectService projectService;
+ private final ProjectMapper projectMapper;
+
+ public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
+ this.projectService = projectService;
+ this.projectMapper = mappingService;
+ }
+
+ @Operation(summary = "Creates a new Project")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
+ @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
+ @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
+ @PostMapping
+ public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
+ ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
+
+ projectEntity = this.projectService.create(projectEntity);
+
+ return this.projectMapper.mapToGetDto(projectEntity);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
index 8555ef9..e06f2f7 100644
--- a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
+++ b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
@@ -1,49 +1,49 @@
-package de.szut.lf8_starter.security;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.core.oidc.user.OidcUser;
-import org.springframework.security.web.authentication.logout.LogoutHandler;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-@Slf4j
-@Component
-public class KeycloakLogoutHandler implements LogoutHandler {
-
-
- private final RestTemplate restTemplate;
-
- public KeycloakLogoutHandler(RestTemplate restTemplate) {
- this.restTemplate = restTemplate;
- }
-
- @Override
- public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
- logout(request, auth);
- }
-
- public void logout(HttpServletRequest request, Authentication auth) {
- logoutFromKeycloak((OidcUser) auth.getPrincipal());
- }
-
- private void logoutFromKeycloak(OidcUser user) {
- String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromUriString(endSessionEndpoint)
- .queryParam("id_token_hint", user.getIdToken().getTokenValue());
-
- ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
- if (logoutResponse.getStatusCode().is2xxSuccessful()) {
- log.info("Successfulley logged out from Keycloak");
- } else {
- log.error("Could not propagate logout to Keycloak");
- }
- }
-
-}
+package de.szut.lf8_starter.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.oidc.user.OidcUser;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+@Slf4j
+@Component
+public class KeycloakLogoutHandler implements LogoutHandler {
+
+
+ private final RestTemplate restTemplate;
+
+ public KeycloakLogoutHandler(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ @Override
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
+ logout(request, auth);
+ }
+
+ public void logout(HttpServletRequest request, Authentication auth) {
+ logoutFromKeycloak((OidcUser) auth.getPrincipal());
+ }
+
+ private void logoutFromKeycloak(OidcUser user) {
+ String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
+ UriComponentsBuilder builder = UriComponentsBuilder
+ .fromUriString(endSessionEndpoint)
+ .queryParam("id_token_hint", user.getIdToken().getTokenValue());
+
+ ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
+ if (logoutResponse.getStatusCode().is2xxSuccessful()) {
+ log.info("Successfulley logged out from Keycloak");
+ } else {
+ log.error("Could not propagate logout to Keycloak");
+ }
+ }
+
+}
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index af21e0e..259f612 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,5 +1,5 @@
-spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
-spring.datasource.driver-class-name=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
+spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
\ No newline at end of file
diff --git a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
index b5c7f7b..d418f1a 100644
--- a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
+++ b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
@@ -1,14 +1,14 @@
-package de.szut.lf8_starter;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.TestPropertySource;
-
-@SpringBootTest
-class Lf8StarterApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
+package de.szut.lf8_starter;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest
+class Lf8StarterApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
--
2.45.2
From 2f92dd3faabcf37f5637169794e87b5ea5c16d3e Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 12:52:05 +0200
Subject: [PATCH 2/8] Rebase
---
GetBearerToken.http | 10 +-
requests/createProject.http | 28 ++---
.../GlobalExceptionHandler.java | 102 +++++++++---------
.../lf8_starter/project/GetProjectDto.java | 86 +++++++--------
.../lf8_starter/project/ProjectEntity.java | 86 +++++++--------
.../project/dto/CreateProjectAction.java | 84 +++++++--------
.../project/dto/CreateProjectDto.java | 84 +++++++--------
7 files changed, 240 insertions(+), 240 deletions(-)
diff --git a/GetBearerToken.http b/GetBearerToken.http
index f5209ca..abf7e94 100644
--- a/GetBearerToken.http
+++ b/GetBearerToken.http
@@ -1,6 +1,6 @@
-POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
-Content-Type: application/x-www-form-urlencoded
-
-grant_type=password&client_id=employee-management-service&username=user&password=test
-
+POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=password&client_id=employee-management-service&username=user&password=test
+
> {% client.global.set("auth_token", response.body.access_token); %}
\ No newline at end of file
diff --git a/requests/createProject.http b/requests/createProject.http
index add2394..6854828 100644
--- a/requests/createProject.http
+++ b/requests/createProject.http
@@ -1,15 +1,15 @@
-### GET request to example server
-POST http://localhost:8080/projects
-Authorization: Bearer {{auth_token}}
-Content-Type: application/json
-
-{
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractorName": "Peter File",
- "comment": "goal of project",
- "startDate": "01.01.2000",
- "plannedEndDate": "01.01.2001"
+### GET request to example server
+POST http://localhost:8080/projects
+Authorization: Bearer {{auth_token}}
+Content-Type: application/json
+
+{
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractorName": "Peter File",
+ "comment": "goal of project",
+ "startDate": "01.01.2000",
+ "plannedEndDate": "01.01.2001"
}
\ No newline at end of file
diff --git a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
index 68a15a7..92ba734 100644
--- a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
+++ b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
@@ -1,51 +1,51 @@
-package de.szut.lf8_starter.exceptionHandling;
-
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.ConstraintViolationException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.Date;
-
-@ControllerAdvice
-@ApiResponses(value = {
- @ApiResponse(responseCode = "500", description = "invalid JSON posted",
- content = @Content)
-})
-public class GlobalExceptionHandler {
-
- @ExceptionHandler(ResourceNotFoundException.class)
- public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
- }
-
- @ExceptionHandler(Exception.class)
- public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- @ExceptionHandler(MethodArgumentNotValidException.class)
- public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-
- @ExceptionHandler(ConstraintViolationException.class)
- public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
- String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
-
- ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-}
+package de.szut.lf8_starter.exceptionHandling;
+
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.ConstraintViolationException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+
+import java.util.Date;
+
+@ControllerAdvice
+@ApiResponses(value = {
+ @ApiResponse(responseCode = "500", description = "invalid JSON posted",
+ content = @Content)
+})
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
+ String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
+
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
index 86ce087..75b8c60 100644
--- a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
@@ -1,43 +1,43 @@
-package de.szut.lf8_starter.project;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-public class GetProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate startDate;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate plannedEndDate;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+public class GetProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate startDate;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate plannedEndDate;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
index d9c35a1..82563fe 100644
--- a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
+++ b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
@@ -1,43 +1,43 @@
-package de.szut.lf8_starter.project;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import org.springframework.data.annotation.CreatedDate;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@NoArgsConstructor
-@AllArgsConstructor
-@Getter
-@Setter
-@Entity
-@Table(name = "projects")
-public class ProjectEntity {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
-
- private String name;
-
- private long leadingEmployee;
-
- @ElementCollection
- private List employees;
-
- private long contractor;
-
- private String contractorName;
-
- private String comment;
-
- @CreatedDate
- private LocalDate startDate;
-
- private LocalDate plannedEndDate;
-
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.data.annotation.CreatedDate;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@Entity
+@Table(name = "projects")
+public class ProjectEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ private long leadingEmployee;
+
+ @ElementCollection
+ private List employees;
+
+ private long contractor;
+
+ private String contractorName;
+
+ private String comment;
+
+ @CreatedDate
+ private LocalDate startDate;
+
+ private LocalDate plannedEndDate;
+
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
index f1c6cdc..511c5ee 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
@@ -1,42 +1,42 @@
-package de.szut.lf8_starter.project.dto;
-
-import de.szut.lf8_starter.project.GetProjectDto;
-import de.szut.lf8_starter.project.ProjectEntity;
-import de.szut.lf8_starter.project.ProjectMapper;
-import de.szut.lf8_starter.project.ProjectService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.Valid;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping(value = "/projects")
-public class CreateProjectAction {
- private final ProjectService projectService;
- private final ProjectMapper projectMapper;
-
- public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
- this.projectService = projectService;
- this.projectMapper = mappingService;
- }
-
- @Operation(summary = "Creates a new Project")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
- @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
- @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
- @PostMapping
- public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
- ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
-
- projectEntity = this.projectService.create(projectEntity);
-
- return this.projectMapper.mapToGetDto(projectEntity);
- }
-}
+package de.szut.lf8_starter.project.dto;
+
+import de.szut.lf8_starter.project.GetProjectDto;
+import de.szut.lf8_starter.project.ProjectEntity;
+import de.szut.lf8_starter.project.ProjectMapper;
+import de.szut.lf8_starter.project.ProjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.Valid;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/projects")
+public class CreateProjectAction {
+ private final ProjectService projectService;
+ private final ProjectMapper projectMapper;
+
+ public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
+ this.projectService = projectService;
+ this.projectMapper = mappingService;
+ }
+
+ @Operation(summary = "Creates a new Project")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
+ @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
+ @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
+ @PostMapping
+ public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
+ ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
+
+ projectEntity = this.projectService.create(projectEntity);
+
+ return this.projectMapper.mapToGetDto(projectEntity);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
index 4c6ab0d..f27e7f4 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
@@ -1,42 +1,42 @@
-package de.szut.lf8_starter.project.dto;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-public class CreateProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate startDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate plannedEndDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+public class CreateProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate startDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate plannedEndDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
--
2.45.2
From a5c627ccaa2181a99d6f84099514f24e7b3313fb Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 12:56:18 +0200
Subject: [PATCH 3/8] Line ending
---
GetBearerToken.http | 10 +-
config/checkstyle/checkstyle-ignore.xml | 18 +-
config/checkstyle/checkstyle.xml | 46 +-
gradle/wrapper/gradle-wrapper.properties | 14 +-
gradlew | 504 +++++++++---------
requests/createProject.http | 28 +-
.../config/OpenAPIConfiguration.java | 120 ++---
.../GlobalExceptionHandler.java | 102 ++--
.../lf8_starter/project/GetProjectDto.java | 86 +--
.../lf8_starter/project/ProjectEntity.java | 86 +--
.../project/dto/CreateProjectAction.java | 84 +--
.../project/dto/CreateProjectDto.java | 84 +--
.../security/KeycloakLogoutHandler.java | 98 ++--
.../resources/application-test.properties | 8 +-
.../Lf8StarterApplicationTests.java | 28 +-
15 files changed, 658 insertions(+), 658 deletions(-)
diff --git a/GetBearerToken.http b/GetBearerToken.http
index abf7e94..f5209ca 100644
--- a/GetBearerToken.http
+++ b/GetBearerToken.http
@@ -1,6 +1,6 @@
-POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
-Content-Type: application/x-www-form-urlencoded
-
-grant_type=password&client_id=employee-management-service&username=user&password=test
-
+POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=password&client_id=employee-management-service&username=user&password=test
+
> {% client.global.set("auth_token", response.body.access_token); %}
\ No newline at end of file
diff --git a/config/checkstyle/checkstyle-ignore.xml b/config/checkstyle/checkstyle-ignore.xml
index 5ec61a5..fe3b2fe 100644
--- a/config/checkstyle/checkstyle-ignore.xml
+++ b/config/checkstyle/checkstyle-ignore.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 3c18de8..d8f0701 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b9ddd88..df97d72 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
-networkTimeout=10000
-validateDistributionUrl=true
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index ec19934..f5feea6 100755
--- a/gradlew
+++ b/gradlew
@@ -1,252 +1,252 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 the original 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.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-# This is normally unused
-# shellcheck disable=SC2034
-APP_BASE_NAME=${0##*/}
-# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- if ! command -v java >/dev/null 2>&1
- then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if "$cygwin" || "$msys" ; then
- APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
-
- JAVACMD=$( cygpath --unix "$JAVACMD" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
-# and any embedded shellness will be escaped.
-# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
-# treated as '${Hostname}' itself on the command line.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/requests/createProject.http b/requests/createProject.http
index 6854828..add2394 100644
--- a/requests/createProject.http
+++ b/requests/createProject.http
@@ -1,15 +1,15 @@
-### GET request to example server
-POST http://localhost:8080/projects
-Authorization: Bearer {{auth_token}}
-Content-Type: application/json
-
-{
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractorName": "Peter File",
- "comment": "goal of project",
- "startDate": "01.01.2000",
- "plannedEndDate": "01.01.2001"
+### GET request to example server
+POST http://localhost:8080/projects
+Authorization: Bearer {{auth_token}}
+Content-Type: application/json
+
+{
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractorName": "Peter File",
+ "comment": "goal of project",
+ "startDate": "01.01.2000",
+ "plannedEndDate": "01.01.2001"
}
\ No newline at end of file
diff --git a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
index 76a6f58..1b2282b 100644
--- a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
+++ b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
@@ -1,60 +1,60 @@
-package de.szut.lf8_starter.config;
-
-
-
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.info.Info;
-import io.swagger.v3.oas.models.security.SecurityRequirement;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import io.swagger.v3.oas.models.servers.Server;
-import jakarta.servlet.ServletContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-
-@Configuration
-public class OpenAPIConfiguration {
-
- private ServletContext context;
-
- public OpenAPIConfiguration(ServletContext context) {
- this.context = context;
- }
-
-
- @Bean
- public OpenAPI springShopOpenAPI(
- // @Value("${info.app.version}") String appVersion,
- ) {
- final String securitySchemeName = "bearerAuth";
-
- return new OpenAPI()
- .addServersItem(new Server().url(this.context.getContextPath()))
- .info(new Info()
- .title("LF8 project starter")
- .description("\n## Auth\n" +
- "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
- "\n" +
- "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
- "\n" +
- "\nor by CURL\n" +
- "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
- "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
-
- .version("0.1"))
- .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
- .components(
- new Components()
- .addSecuritySchemes(securitySchemeName,
- new SecurityScheme()
- .name(securitySchemeName)
- .type(SecurityScheme.Type.HTTP)
- .scheme("bearer")
- .bearerFormat("JWT")
- )
- );
- }
-
-
-}
+package de.szut.lf8_starter.config;
+
+
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.servers.Server;
+import jakarta.servlet.ServletContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class OpenAPIConfiguration {
+
+ private ServletContext context;
+
+ public OpenAPIConfiguration(ServletContext context) {
+ this.context = context;
+ }
+
+
+ @Bean
+ public OpenAPI springShopOpenAPI(
+ // @Value("${info.app.version}") String appVersion,
+ ) {
+ final String securitySchemeName = "bearerAuth";
+
+ return new OpenAPI()
+ .addServersItem(new Server().url(this.context.getContextPath()))
+ .info(new Info()
+ .title("LF8 project starter")
+ .description("\n## Auth\n" +
+ "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
+ "\n" +
+ "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
+ "\n" +
+ "\nor by CURL\n" +
+ "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
+ "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
+
+ .version("0.1"))
+ .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
+ .components(
+ new Components()
+ .addSecuritySchemes(securitySchemeName,
+ new SecurityScheme()
+ .name(securitySchemeName)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")
+ )
+ );
+ }
+
+
+}
diff --git a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
index 92ba734..68a15a7 100644
--- a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
+++ b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
@@ -1,51 +1,51 @@
-package de.szut.lf8_starter.exceptionHandling;
-
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.ConstraintViolationException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.Date;
-
-@ControllerAdvice
-@ApiResponses(value = {
- @ApiResponse(responseCode = "500", description = "invalid JSON posted",
- content = @Content)
-})
-public class GlobalExceptionHandler {
-
- @ExceptionHandler(ResourceNotFoundException.class)
- public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
- }
-
- @ExceptionHandler(Exception.class)
- public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- @ExceptionHandler(MethodArgumentNotValidException.class)
- public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-
- @ExceptionHandler(ConstraintViolationException.class)
- public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
- String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
-
- ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-}
+package de.szut.lf8_starter.exceptionHandling;
+
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.ConstraintViolationException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+
+import java.util.Date;
+
+@ControllerAdvice
+@ApiResponses(value = {
+ @ApiResponse(responseCode = "500", description = "invalid JSON posted",
+ content = @Content)
+})
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
+ String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
+
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
index 75b8c60..86ce087 100644
--- a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
@@ -1,43 +1,43 @@
-package de.szut.lf8_starter.project;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-public class GetProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate startDate;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate plannedEndDate;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+public class GetProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate startDate;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate plannedEndDate;
+
+ @NotNull
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
index 82563fe..d9c35a1 100644
--- a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
+++ b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
@@ -1,43 +1,43 @@
-package de.szut.lf8_starter.project;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import org.springframework.data.annotation.CreatedDate;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@NoArgsConstructor
-@AllArgsConstructor
-@Getter
-@Setter
-@Entity
-@Table(name = "projects")
-public class ProjectEntity {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
-
- private String name;
-
- private long leadingEmployee;
-
- @ElementCollection
- private List employees;
-
- private long contractor;
-
- private String contractorName;
-
- private String comment;
-
- @CreatedDate
- private LocalDate startDate;
-
- private LocalDate plannedEndDate;
-
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.data.annotation.CreatedDate;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@Entity
+@Table(name = "projects")
+public class ProjectEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ private long leadingEmployee;
+
+ @ElementCollection
+ private List employees;
+
+ private long contractor;
+
+ private String contractorName;
+
+ private String comment;
+
+ @CreatedDate
+ private LocalDate startDate;
+
+ private LocalDate plannedEndDate;
+
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
index 511c5ee..f1c6cdc 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
@@ -1,42 +1,42 @@
-package de.szut.lf8_starter.project.dto;
-
-import de.szut.lf8_starter.project.GetProjectDto;
-import de.szut.lf8_starter.project.ProjectEntity;
-import de.szut.lf8_starter.project.ProjectMapper;
-import de.szut.lf8_starter.project.ProjectService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.Valid;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping(value = "/projects")
-public class CreateProjectAction {
- private final ProjectService projectService;
- private final ProjectMapper projectMapper;
-
- public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
- this.projectService = projectService;
- this.projectMapper = mappingService;
- }
-
- @Operation(summary = "Creates a new Project")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
- @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
- @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
- @PostMapping
- public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
- ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
-
- projectEntity = this.projectService.create(projectEntity);
-
- return this.projectMapper.mapToGetDto(projectEntity);
- }
-}
+package de.szut.lf8_starter.project.dto;
+
+import de.szut.lf8_starter.project.GetProjectDto;
+import de.szut.lf8_starter.project.ProjectEntity;
+import de.szut.lf8_starter.project.ProjectMapper;
+import de.szut.lf8_starter.project.ProjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.Valid;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/projects")
+public class CreateProjectAction {
+ private final ProjectService projectService;
+ private final ProjectMapper projectMapper;
+
+ public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
+ this.projectService = projectService;
+ this.projectMapper = mappingService;
+ }
+
+ @Operation(summary = "Creates a new Project")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
+ @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
+ @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
+ @PostMapping
+ public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
+ ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
+
+ projectEntity = this.projectService.create(projectEntity);
+
+ return this.projectMapper.mapToGetDto(projectEntity);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
index f27e7f4..4c6ab0d 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
@@ -1,42 +1,42 @@
-package de.szut.lf8_starter.project.dto;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-public class CreateProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate startDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate plannedEndDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+public class CreateProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate startDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate plannedEndDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
index e06f2f7..8555ef9 100644
--- a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
+++ b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
@@ -1,49 +1,49 @@
-package de.szut.lf8_starter.security;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.core.oidc.user.OidcUser;
-import org.springframework.security.web.authentication.logout.LogoutHandler;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-@Slf4j
-@Component
-public class KeycloakLogoutHandler implements LogoutHandler {
-
-
- private final RestTemplate restTemplate;
-
- public KeycloakLogoutHandler(RestTemplate restTemplate) {
- this.restTemplate = restTemplate;
- }
-
- @Override
- public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
- logout(request, auth);
- }
-
- public void logout(HttpServletRequest request, Authentication auth) {
- logoutFromKeycloak((OidcUser) auth.getPrincipal());
- }
-
- private void logoutFromKeycloak(OidcUser user) {
- String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromUriString(endSessionEndpoint)
- .queryParam("id_token_hint", user.getIdToken().getTokenValue());
-
- ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
- if (logoutResponse.getStatusCode().is2xxSuccessful()) {
- log.info("Successfulley logged out from Keycloak");
- } else {
- log.error("Could not propagate logout to Keycloak");
- }
- }
-
-}
+package de.szut.lf8_starter.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.oidc.user.OidcUser;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+@Slf4j
+@Component
+public class KeycloakLogoutHandler implements LogoutHandler {
+
+
+ private final RestTemplate restTemplate;
+
+ public KeycloakLogoutHandler(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ @Override
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
+ logout(request, auth);
+ }
+
+ public void logout(HttpServletRequest request, Authentication auth) {
+ logoutFromKeycloak((OidcUser) auth.getPrincipal());
+ }
+
+ private void logoutFromKeycloak(OidcUser user) {
+ String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
+ UriComponentsBuilder builder = UriComponentsBuilder
+ .fromUriString(endSessionEndpoint)
+ .queryParam("id_token_hint", user.getIdToken().getTokenValue());
+
+ ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
+ if (logoutResponse.getStatusCode().is2xxSuccessful()) {
+ log.info("Successfulley logged out from Keycloak");
+ } else {
+ log.error("Could not propagate logout to Keycloak");
+ }
+ }
+
+}
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 259f612..af21e0e 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,5 +1,5 @@
-spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
-spring.datasource.driver-class-name=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
+spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
\ No newline at end of file
diff --git a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
index d418f1a..b5c7f7b 100644
--- a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
+++ b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
@@ -1,14 +1,14 @@
-package de.szut.lf8_starter;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.TestPropertySource;
-
-@SpringBootTest
-class Lf8StarterApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
+package de.szut.lf8_starter;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest
+class Lf8StarterApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
--
2.45.2
From e209379f41d3d26ab958d379d3b7404f770c4026 Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 12:58:28 +0200
Subject: [PATCH 4/8] Order files
---
.../lf8_starter/project/GetProjectDto.java | 43 -------------------
.../project/dto/CreateProjectAction.java | 42 ------------------
2 files changed, 85 deletions(-)
delete mode 100644 src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
delete mode 100644 src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
diff --git a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
deleted file mode 100644
index 86ce087..0000000
--- a/src/main/java/de/szut/lf8_starter/project/GetProjectDto.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.szut.lf8_starter.project;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-public class GetProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate startDate;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate plannedEndDate;
-
- @NotNull
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
deleted file mode 100644
index f1c6cdc..0000000
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package de.szut.lf8_starter.project.dto;
-
-import de.szut.lf8_starter.project.GetProjectDto;
-import de.szut.lf8_starter.project.ProjectEntity;
-import de.szut.lf8_starter.project.ProjectMapper;
-import de.szut.lf8_starter.project.ProjectService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.Valid;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping(value = "/projects")
-public class CreateProjectAction {
- private final ProjectService projectService;
- private final ProjectMapper projectMapper;
-
- public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
- this.projectService = projectService;
- this.projectMapper = mappingService;
- }
-
- @Operation(summary = "Creates a new Project")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
- @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
- @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
- @PostMapping
- public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
- ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
-
- projectEntity = this.projectService.create(projectEntity);
-
- return this.projectMapper.mapToGetDto(projectEntity);
- }
-}
--
2.45.2
From 6723b49f7dcedeba69b958c0eb66e3f6d1f00cbd Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 14:05:31 +0200
Subject: [PATCH 5/8] Write integration test
---
.../project/CreateProjectAction.java | 7 +-
.../project/CreateProjectActionTest.java | 70 +++++++++++++++++++
2 files changed, 73 insertions(+), 4 deletions(-)
create mode 100644 src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java
diff --git a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
index c41b134..d54318b 100644
--- a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
+++ b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
@@ -8,10 +8,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.Valid;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/projects")
@@ -30,6 +28,7 @@ public class CreateProjectAction {
@ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
@ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
@PostMapping
+ @ResponseStatus(code = HttpStatus.CREATED)
public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
diff --git a/src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java b/src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java
new file mode 100644
index 0000000..b510ac7
--- /dev/null
+++ b/src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java
@@ -0,0 +1,70 @@
+package de.szut.lf8_starter.project;
+
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.time.LocalDate;
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.hamcrest.Matchers.is;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc(addFilters = false)
+public class CreateProjectActionTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ProjectRepository projectRepository;
+
+ @Test
+ void test() throws Exception {
+ String content = """
+ {
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractorName": "Peter File",
+ "comment": "goal of project",
+ "startDate": "01.01.2000",
+ "plannedEndDate": "01.01.2001"
+ }
+ """;
+
+ final var contentAsString = this.mockMvc.perform(
+ post("/projects").content(content).contentType(MediaType.APPLICATION_JSON)
+ )
+ .andExpect(status().isCreated())
+ .andExpect(jsonPath("name", is("name")))
+ .andExpect(jsonPath("leadingEmployee", is(0)))
+ .andExpect(jsonPath("employees", is(Arrays.asList(2, 3))))
+ .andExpect(jsonPath("contractor", is(4)))
+ .andExpect(jsonPath("contractorName", is("Peter File")))
+ .andExpect(jsonPath("comment", is("goal of project")))
+ .andExpect(jsonPath("startDate", is("01.01.2000")))
+ .andExpect(jsonPath("plannedEndDate", is("01.01.2001")))
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ final var id = Long.parseLong(new JSONObject(contentAsString).get("id").toString());
+
+ final var project = this.projectRepository.findById(id);
+ assertThat(project.get().getName()).isEqualTo("name");
+ assertThat(project.get().getLeadingEmployee()).isEqualTo(0);
+ assertThat(project.get().getContractor()).isEqualTo(4);
+ assertThat(project.get().getContractorName()).isEqualTo("Peter File");
+ assertThat(project.get().getComment()).isEqualTo("goal of project");
+ assertThat(project.get().getStartDate()).isEqualTo(LocalDate.of(2000, 1, 1));
+ assertThat(project.get().getPlannedEndDate()).isEqualTo(LocalDate.of(2001, 1, 1));
+ }
+}
--
2.45.2
From ffb1a1586a8e04f131e79321ea782249cc6783e7 Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 14:16:27 +0200
Subject: [PATCH 6/8] Ensure Snake Case in JSON
---
requests/createProject.http | 6 ++--
.../project/dto/CreateProjectDto.java | 3 ++
.../project/dto/GetProjectDto.java | 17 ++--------
.../project/CreateProjectActionTest.java | 31 ++++++++++---------
4 files changed, 25 insertions(+), 32 deletions(-)
rename src/test/java/de/szut/lf8_starter/{ => integration}/project/CreateProjectActionTest.java (75%)
diff --git a/requests/createProject.http b/requests/createProject.http
index add2394..7b08e28 100644
--- a/requests/createProject.http
+++ b/requests/createProject.http
@@ -8,8 +8,8 @@ Content-Type: application/json
"leading_employee": 1,
"employees": [2, 3],
"contractor": 4,
- "contractorName": "Peter File",
+ "contractor_name": "Peter File",
"comment": "goal of project",
- "startDate": "01.01.2000",
- "plannedEndDate": "01.01.2001"
+ "start_date": "01.01.2000",
+ "planned_end_date": "01.01.2001"
}
\ No newline at end of file
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
index 4c6ab0d..ebf4393 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
@@ -1,6 +1,8 @@
package de.szut.lf8_starter.project.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
@@ -11,6 +13,7 @@ import java.util.List;
@Getter
@Setter
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class CreateProjectDto {
@NotBlank
private String name;
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
index c90cd50..614ece1 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
@@ -1,6 +1,8 @@
package de.szut.lf8_starter.project.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
@@ -11,35 +13,22 @@ import java.util.List;
@Getter
@Setter
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class GetProjectDto {
private long id;
-
- @NotBlank
private String name;
-
- @NotNull
private long leadingEmployee;
-
private List employees;
-
- @NotNull
private long contractor;
-
- @NotBlank
private String contractorName;
-
- @NotBlank
private String comment;
- @NotNull
@JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate startDate;
- @NotNull
@JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate plannedEndDate;
- @NotNull
@JsonFormat(pattern = "dd.MM.yyyy")
private LocalDate endDate;
}
diff --git a/src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
similarity index 75%
rename from src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java
rename to src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
index b510ac7..22e40f8 100644
--- a/src/test/java/de/szut/lf8_starter/project/CreateProjectActionTest.java
+++ b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
@@ -1,5 +1,6 @@
-package de.szut.lf8_starter.project;
+package de.szut.lf8_starter.integration.project;
+import de.szut.lf8_starter.project.ProjectRepository;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -29,15 +30,15 @@ public class CreateProjectActionTest {
void test() throws Exception {
String content = """
{
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractorName": "Peter File",
- "comment": "goal of project",
- "startDate": "01.01.2000",
- "plannedEndDate": "01.01.2001"
- }
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractor_name": "Peter File",
+ "comment": "goal of project",
+ "start_date": "01.01.2000",
+ "planned_end_date": "01.01.2001"
+ }
""";
final var contentAsString = this.mockMvc.perform(
@@ -45,13 +46,13 @@ public class CreateProjectActionTest {
)
.andExpect(status().isCreated())
.andExpect(jsonPath("name", is("name")))
- .andExpect(jsonPath("leadingEmployee", is(0)))
+ .andExpect(jsonPath("leading_employee", is(1)))
.andExpect(jsonPath("employees", is(Arrays.asList(2, 3))))
.andExpect(jsonPath("contractor", is(4)))
- .andExpect(jsonPath("contractorName", is("Peter File")))
+ .andExpect(jsonPath("contractor_name", is("Peter File")))
.andExpect(jsonPath("comment", is("goal of project")))
- .andExpect(jsonPath("startDate", is("01.01.2000")))
- .andExpect(jsonPath("plannedEndDate", is("01.01.2001")))
+ .andExpect(jsonPath("start_date", is("01.01.2000")))
+ .andExpect(jsonPath("planned_end_date", is("01.01.2001")))
.andReturn()
.getResponse()
.getContentAsString();
@@ -60,7 +61,7 @@ public class CreateProjectActionTest {
final var project = this.projectRepository.findById(id);
assertThat(project.get().getName()).isEqualTo("name");
- assertThat(project.get().getLeadingEmployee()).isEqualTo(0);
+ assertThat(project.get().getLeadingEmployee()).isEqualTo(1);
assertThat(project.get().getContractor()).isEqualTo(4);
assertThat(project.get().getContractorName()).isEqualTo("Peter File");
assertThat(project.get().getComment()).isEqualTo("goal of project");
--
2.45.2
From a365c7aee32dfd08fb1c5066d55e641235d60e99 Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 14:22:26 +0200
Subject: [PATCH 7/8] Fix tests
---
.gitea/workflows/release.yml | 62 +--
GetBearerToken.http | 10 +-
config/checkstyle/checkstyle-ignore.xml | 18 +-
config/checkstyle/checkstyle.xml | 46 +-
gradle/wrapper/gradle-wrapper.properties | 14 +-
gradlew | 504 +++++++++---------
release.config.cjs | 24 +-
requests/createProject.http | 28 +-
.../config/OpenAPIConfiguration.java | 120 ++---
.../GlobalExceptionHandler.java | 102 ++--
.../project/CreateProjectAction.java | 78 +--
.../lf8_starter/project/ProjectEntity.java | 86 +--
.../project/dto/CreateProjectDto.java | 90 ++--
.../project/dto/GetProjectDto.java | 68 +--
.../security/KeycloakLogoutHandler.java | 98 ++--
.../resources/application-test.properties | 8 +-
.../Lf8StarterApplicationTests.java | 28 +-
.../project/CreateProjectActionTest.java | 142 ++---
...ss.java => ProjectFindAllSuccessTest.java} | 16 +-
19 files changed, 769 insertions(+), 773 deletions(-)
rename src/test/java/de/szut/lf8_starter/integration/project/{ProjectFindAllSuccess.java => ProjectFindAllSuccessTest.java} (80%)
diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml
index 1c29ae9..a04d812 100644
--- a/.gitea/workflows/release.yml
+++ b/.gitea/workflows/release.yml
@@ -1,31 +1,31 @@
-name: Release
-on:
- push:
- branches:
- - main
-
-env:
- GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
-
-permissions:
- contents: read # for checkout
-
-concurrency:
- group: ${{ github.ref }} # Ensure each branch has its own group
- cancel-in-progress: false # Prevent new runs from canceling in-progress runs
-
-jobs:
- release:
- name: Release
- runs-on: ubuntu-latest
- permissions:
- contents: write # to be able to publish a GitHub release
- issues: write # to be able to comment on released issues
- pull-requests: write # to be able to comment on released pull requests
- id-token: write # to enable use of OIDC for npm provenance
- steps:
- - name: Create Release
- uses: https://git.kjan.de/actions/semantic-release@main
- with:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
+name: Release
+on:
+ push:
+ branches:
+ - main
+
+env:
+ GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
+
+permissions:
+ contents: read # for checkout
+
+concurrency:
+ group: ${{ github.ref }} # Ensure each branch has its own group
+ cancel-in-progress: false # Prevent new runs from canceling in-progress runs
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write # to be able to publish a GitHub release
+ issues: write # to be able to comment on released issues
+ pull-requests: write # to be able to comment on released pull requests
+ id-token: write # to enable use of OIDC for npm provenance
+ steps:
+ - name: Create Release
+ uses: https://git.kjan.de/actions/semantic-release@main
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
diff --git a/GetBearerToken.http b/GetBearerToken.http
index f5209ca..abf7e94 100644
--- a/GetBearerToken.http
+++ b/GetBearerToken.http
@@ -1,6 +1,6 @@
-POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
-Content-Type: application/x-www-form-urlencoded
-
-grant_type=password&client_id=employee-management-service&username=user&password=test
-
+POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=password&client_id=employee-management-service&username=user&password=test
+
> {% client.global.set("auth_token", response.body.access_token); %}
\ No newline at end of file
diff --git a/config/checkstyle/checkstyle-ignore.xml b/config/checkstyle/checkstyle-ignore.xml
index fe3b2fe..5ec61a5 100644
--- a/config/checkstyle/checkstyle-ignore.xml
+++ b/config/checkstyle/checkstyle-ignore.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index d8f0701..3c18de8 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index df97d72..b9ddd88 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
-networkTimeout=10000
-validateDistributionUrl=true
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index f5feea6..ec19934 100755
--- a/gradlew
+++ b/gradlew
@@ -1,252 +1,252 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 the original 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.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-# This is normally unused
-# shellcheck disable=SC2034
-APP_BASE_NAME=${0##*/}
-# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- if ! command -v java >/dev/null 2>&1
- then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if "$cygwin" || "$msys" ; then
- APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
-
- JAVACMD=$( cygpath --unix "$JAVACMD" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
-# and any embedded shellness will be escaped.
-# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
-# treated as '${Hostname}' itself on the command line.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/release.config.cjs b/release.config.cjs
index 375ccd5..1b62d04 100644
--- a/release.config.cjs
+++ b/release.config.cjs
@@ -1,12 +1,12 @@
-module.exports = {
-
- branches: ['main'],
- plugins: [
- '@semantic-release/commit-analyzer',
- '@semantic-release/release-notes-generator',
- '@semantic-release/changelog',
- ["@saithodev/semantic-release-gitea", {
- "giteaUrl": "https://git.kjan.de"
- }],
- ],
-};
+module.exports = {
+
+ branches: ['main'],
+ plugins: [
+ '@semantic-release/commit-analyzer',
+ '@semantic-release/release-notes-generator',
+ '@semantic-release/changelog',
+ ["@saithodev/semantic-release-gitea", {
+ "giteaUrl": "https://git.kjan.de"
+ }],
+ ],
+};
diff --git a/requests/createProject.http b/requests/createProject.http
index 7b08e28..885c49e 100644
--- a/requests/createProject.http
+++ b/requests/createProject.http
@@ -1,15 +1,15 @@
-### GET request to example server
-POST http://localhost:8080/projects
-Authorization: Bearer {{auth_token}}
-Content-Type: application/json
-
-{
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractor_name": "Peter File",
- "comment": "goal of project",
- "start_date": "01.01.2000",
- "planned_end_date": "01.01.2001"
+### GET request to example server
+POST http://localhost:8080/projects
+Authorization: Bearer {{auth_token}}
+Content-Type: application/json
+
+{
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractor_name": "Peter File",
+ "comment": "goal of project",
+ "start_date": "01.01.2000",
+ "planned_end_date": "01.01.2001"
}
\ No newline at end of file
diff --git a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
index 1b2282b..76a6f58 100644
--- a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
+++ b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
@@ -1,60 +1,60 @@
-package de.szut.lf8_starter.config;
-
-
-
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.info.Info;
-import io.swagger.v3.oas.models.security.SecurityRequirement;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import io.swagger.v3.oas.models.servers.Server;
-import jakarta.servlet.ServletContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-
-@Configuration
-public class OpenAPIConfiguration {
-
- private ServletContext context;
-
- public OpenAPIConfiguration(ServletContext context) {
- this.context = context;
- }
-
-
- @Bean
- public OpenAPI springShopOpenAPI(
- // @Value("${info.app.version}") String appVersion,
- ) {
- final String securitySchemeName = "bearerAuth";
-
- return new OpenAPI()
- .addServersItem(new Server().url(this.context.getContextPath()))
- .info(new Info()
- .title("LF8 project starter")
- .description("\n## Auth\n" +
- "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
- "\n" +
- "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
- "\n" +
- "\nor by CURL\n" +
- "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
- "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
-
- .version("0.1"))
- .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
- .components(
- new Components()
- .addSecuritySchemes(securitySchemeName,
- new SecurityScheme()
- .name(securitySchemeName)
- .type(SecurityScheme.Type.HTTP)
- .scheme("bearer")
- .bearerFormat("JWT")
- )
- );
- }
-
-
-}
+package de.szut.lf8_starter.config;
+
+
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.servers.Server;
+import jakarta.servlet.ServletContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class OpenAPIConfiguration {
+
+ private ServletContext context;
+
+ public OpenAPIConfiguration(ServletContext context) {
+ this.context = context;
+ }
+
+
+ @Bean
+ public OpenAPI springShopOpenAPI(
+ // @Value("${info.app.version}") String appVersion,
+ ) {
+ final String securitySchemeName = "bearerAuth";
+
+ return new OpenAPI()
+ .addServersItem(new Server().url(this.context.getContextPath()))
+ .info(new Info()
+ .title("LF8 project starter")
+ .description("\n## Auth\n" +
+ "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
+ "\n" +
+ "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
+ "\n" +
+ "\nor by CURL\n" +
+ "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
+ "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
+
+ .version("0.1"))
+ .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
+ .components(
+ new Components()
+ .addSecuritySchemes(securitySchemeName,
+ new SecurityScheme()
+ .name(securitySchemeName)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")
+ )
+ );
+ }
+
+
+}
diff --git a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
index 68a15a7..92ba734 100644
--- a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
+++ b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
@@ -1,51 +1,51 @@
-package de.szut.lf8_starter.exceptionHandling;
-
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.ConstraintViolationException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.Date;
-
-@ControllerAdvice
-@ApiResponses(value = {
- @ApiResponse(responseCode = "500", description = "invalid JSON posted",
- content = @Content)
-})
-public class GlobalExceptionHandler {
-
- @ExceptionHandler(ResourceNotFoundException.class)
- public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
- }
-
- @ExceptionHandler(Exception.class)
- public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- @ExceptionHandler(MethodArgumentNotValidException.class)
- public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-
- @ExceptionHandler(ConstraintViolationException.class)
- public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
- String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
-
- ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-}
+package de.szut.lf8_starter.exceptionHandling;
+
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.ConstraintViolationException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+
+import java.util.Date;
+
+@ControllerAdvice
+@ApiResponses(value = {
+ @ApiResponse(responseCode = "500", description = "invalid JSON posted",
+ content = @Content)
+})
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
+ String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
+
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
index d54318b..4158fee 100644
--- a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
+++ b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
@@ -1,39 +1,39 @@
-package de.szut.lf8_starter.project;
-
-import de.szut.lf8_starter.project.dto.CreateProjectDto;
-import de.szut.lf8_starter.project.dto.GetProjectDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping(value = "/projects")
-public class CreateProjectAction {
- private final ProjectService projectService;
- private final ProjectMapper projectMapper;
-
- public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
- this.projectService = projectService;
- this.projectMapper = mappingService;
- }
-
- @Operation(summary = "Creates a new Project")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
- @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
- @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
- @PostMapping
- @ResponseStatus(code = HttpStatus.CREATED)
- public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
- ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
-
- projectEntity = this.projectService.create(projectEntity);
-
- return this.projectMapper.mapToGetDto(projectEntity);
- }
-}
+package de.szut.lf8_starter.project;
+
+import de.szut.lf8_starter.project.dto.CreateProjectDto;
+import de.szut.lf8_starter.project.dto.GetProjectDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.Valid;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "/projects")
+public class CreateProjectAction {
+ private final ProjectService projectService;
+ private final ProjectMapper projectMapper;
+
+ public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
+ this.projectService = projectService;
+ this.projectMapper = mappingService;
+ }
+
+ @Operation(summary = "Creates a new Project")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
+ @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
+ @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
+ @PostMapping
+ @ResponseStatus(code = HttpStatus.CREATED)
+ public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
+ ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
+
+ projectEntity = this.projectService.create(projectEntity);
+
+ return this.projectMapper.mapToGetDto(projectEntity);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
index d9c35a1..82563fe 100644
--- a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
+++ b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
@@ -1,43 +1,43 @@
-package de.szut.lf8_starter.project;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import org.springframework.data.annotation.CreatedDate;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@NoArgsConstructor
-@AllArgsConstructor
-@Getter
-@Setter
-@Entity
-@Table(name = "projects")
-public class ProjectEntity {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
-
- private String name;
-
- private long leadingEmployee;
-
- @ElementCollection
- private List employees;
-
- private long contractor;
-
- private String contractorName;
-
- private String comment;
-
- @CreatedDate
- private LocalDate startDate;
-
- private LocalDate plannedEndDate;
-
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.data.annotation.CreatedDate;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@Entity
+@Table(name = "projects")
+public class ProjectEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ private long leadingEmployee;
+
+ @ElementCollection
+ private List employees;
+
+ private long contractor;
+
+ private String contractorName;
+
+ private String comment;
+
+ @CreatedDate
+ private LocalDate startDate;
+
+ private LocalDate plannedEndDate;
+
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
index ebf4393..64d22b7 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
@@ -1,45 +1,45 @@
-package de.szut.lf8_starter.project.dto;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.PropertyNamingStrategies;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
-public class CreateProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate startDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate plannedEndDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class CreateProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate startDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate plannedEndDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
index 614ece1..250a6a0 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
@@ -1,34 +1,34 @@
-package de.szut.lf8_starter.project.dto;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.PropertyNamingStrategies;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
-public class GetProjectDto {
- private long id;
- private String name;
- private long leadingEmployee;
- private List employees;
- private long contractor;
- private String contractorName;
- private String comment;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate startDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate plannedEndDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class GetProjectDto {
+ private long id;
+ private String name;
+ private long leadingEmployee;
+ private List employees;
+ private long contractor;
+ private String contractorName;
+ private String comment;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate startDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate plannedEndDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
index 8555ef9..e06f2f7 100644
--- a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
+++ b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
@@ -1,49 +1,49 @@
-package de.szut.lf8_starter.security;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.core.oidc.user.OidcUser;
-import org.springframework.security.web.authentication.logout.LogoutHandler;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-@Slf4j
-@Component
-public class KeycloakLogoutHandler implements LogoutHandler {
-
-
- private final RestTemplate restTemplate;
-
- public KeycloakLogoutHandler(RestTemplate restTemplate) {
- this.restTemplate = restTemplate;
- }
-
- @Override
- public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
- logout(request, auth);
- }
-
- public void logout(HttpServletRequest request, Authentication auth) {
- logoutFromKeycloak((OidcUser) auth.getPrincipal());
- }
-
- private void logoutFromKeycloak(OidcUser user) {
- String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromUriString(endSessionEndpoint)
- .queryParam("id_token_hint", user.getIdToken().getTokenValue());
-
- ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
- if (logoutResponse.getStatusCode().is2xxSuccessful()) {
- log.info("Successfulley logged out from Keycloak");
- } else {
- log.error("Could not propagate logout to Keycloak");
- }
- }
-
-}
+package de.szut.lf8_starter.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.oidc.user.OidcUser;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+@Slf4j
+@Component
+public class KeycloakLogoutHandler implements LogoutHandler {
+
+
+ private final RestTemplate restTemplate;
+
+ public KeycloakLogoutHandler(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ @Override
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
+ logout(request, auth);
+ }
+
+ public void logout(HttpServletRequest request, Authentication auth) {
+ logoutFromKeycloak((OidcUser) auth.getPrincipal());
+ }
+
+ private void logoutFromKeycloak(OidcUser user) {
+ String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
+ UriComponentsBuilder builder = UriComponentsBuilder
+ .fromUriString(endSessionEndpoint)
+ .queryParam("id_token_hint", user.getIdToken().getTokenValue());
+
+ ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
+ if (logoutResponse.getStatusCode().is2xxSuccessful()) {
+ log.info("Successfulley logged out from Keycloak");
+ } else {
+ log.error("Could not propagate logout to Keycloak");
+ }
+ }
+
+}
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index af21e0e..259f612 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,5 +1,5 @@
-spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
-spring.datasource.driver-class-name=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
+spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
\ No newline at end of file
diff --git a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
index b5c7f7b..d418f1a 100644
--- a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
+++ b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
@@ -1,14 +1,14 @@
-package de.szut.lf8_starter;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.TestPropertySource;
-
-@SpringBootTest
-class Lf8StarterApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
+package de.szut.lf8_starter;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest
+class Lf8StarterApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
index 22e40f8..06d02b6 100644
--- a/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
+++ b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
@@ -1,71 +1,71 @@
-package de.szut.lf8_starter.integration.project;
-
-import de.szut.lf8_starter.project.ProjectRepository;
-import org.json.JSONObject;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-
-import java.time.LocalDate;
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.hamcrest.Matchers.is;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@SpringBootTest
-@AutoConfigureMockMvc(addFilters = false)
-public class CreateProjectActionTest {
- @Autowired
- private MockMvc mockMvc;
- @Autowired
- private ProjectRepository projectRepository;
-
- @Test
- void test() throws Exception {
- String content = """
- {
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractor_name": "Peter File",
- "comment": "goal of project",
- "start_date": "01.01.2000",
- "planned_end_date": "01.01.2001"
- }
- """;
-
- final var contentAsString = this.mockMvc.perform(
- post("/projects").content(content).contentType(MediaType.APPLICATION_JSON)
- )
- .andExpect(status().isCreated())
- .andExpect(jsonPath("name", is("name")))
- .andExpect(jsonPath("leading_employee", is(1)))
- .andExpect(jsonPath("employees", is(Arrays.asList(2, 3))))
- .andExpect(jsonPath("contractor", is(4)))
- .andExpect(jsonPath("contractor_name", is("Peter File")))
- .andExpect(jsonPath("comment", is("goal of project")))
- .andExpect(jsonPath("start_date", is("01.01.2000")))
- .andExpect(jsonPath("planned_end_date", is("01.01.2001")))
- .andReturn()
- .getResponse()
- .getContentAsString();
-
- final var id = Long.parseLong(new JSONObject(contentAsString).get("id").toString());
-
- final var project = this.projectRepository.findById(id);
- assertThat(project.get().getName()).isEqualTo("name");
- assertThat(project.get().getLeadingEmployee()).isEqualTo(1);
- assertThat(project.get().getContractor()).isEqualTo(4);
- assertThat(project.get().getContractorName()).isEqualTo("Peter File");
- assertThat(project.get().getComment()).isEqualTo("goal of project");
- assertThat(project.get().getStartDate()).isEqualTo(LocalDate.of(2000, 1, 1));
- assertThat(project.get().getPlannedEndDate()).isEqualTo(LocalDate.of(2001, 1, 1));
- }
-}
+package de.szut.lf8_starter.integration.project;
+
+import de.szut.lf8_starter.project.ProjectRepository;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.time.LocalDate;
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.hamcrest.Matchers.is;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc(addFilters = false)
+public class CreateProjectActionTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ProjectRepository projectRepository;
+
+ @Test
+ void createProjectTest() throws Exception {
+ String content = """
+ {
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractor_name": "Peter File",
+ "comment": "goal of project",
+ "start_date": "01.01.2000",
+ "planned_end_date": "01.01.2001"
+ }
+ """;
+
+ final var contentAsString = this.mockMvc.perform(
+ post("/projects").content(content).contentType(MediaType.APPLICATION_JSON)
+ )
+ .andExpect(status().isCreated())
+ .andExpect(jsonPath("name", is("name")))
+ .andExpect(jsonPath("leading_employee", is(1)))
+ .andExpect(jsonPath("employees", is(Arrays.asList(2, 3))))
+ .andExpect(jsonPath("contractor", is(4)))
+ .andExpect(jsonPath("contractor_name", is("Peter File")))
+ .andExpect(jsonPath("comment", is("goal of project")))
+ .andExpect(jsonPath("start_date", is("01.01.2000")))
+ .andExpect(jsonPath("planned_end_date", is("01.01.2001")))
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ final var id = Long.parseLong(new JSONObject(contentAsString).get("id").toString());
+
+ final var project = this.projectRepository.findById(id);
+ assertThat(project.get().getName()).isEqualTo("name");
+ assertThat(project.get().getLeadingEmployee()).isEqualTo(1);
+ assertThat(project.get().getContractor()).isEqualTo(4);
+ assertThat(project.get().getContractorName()).isEqualTo("Peter File");
+ assertThat(project.get().getComment()).isEqualTo("goal of project");
+ assertThat(project.get().getStartDate()).isEqualTo(LocalDate.of(2000, 1, 1));
+ assertThat(project.get().getPlannedEndDate()).isEqualTo(LocalDate.of(2001, 1, 1));
+ }
+}
diff --git a/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccess.java b/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccessTest.java
similarity index 80%
rename from src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccess.java
rename to src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccessTest.java
index 906b63f..8f1974a 100644
--- a/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccess.java
+++ b/src/test/java/de/szut/lf8_starter/integration/project/ProjectFindAllSuccessTest.java
@@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDate;
@@ -19,18 +18,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc(addFilters = false)
-public class ProjectFindAllSuccess {
+public class ProjectFindAllSuccessTest {
@Autowired
private ProjectRepository projectRepository;
@Autowired
private MockMvc mockMvc;
- @Autowired
- private TestRestTemplate restTemplate;
-
@Test
- void findAllProjects() throws Exception {
+ void findAllProjectsTest() throws Exception {
var project = new ProjectEntity();
project.setId(1);
project.setComment("comment");
@@ -49,11 +45,11 @@ public class ProjectFindAllSuccess {
.andExpect(jsonPath("$[0].id").value(1))
.andExpect(jsonPath("$[0].comment").value("comment"))
.andExpect(jsonPath("$[0].contractor").value(1))
- .andExpect(jsonPath("$[0].contractorName").value("contractorName"))
- .andExpect(jsonPath("$[0].endDate").value("01.01.2024"))
- .andExpect(jsonPath("$[0].leadingEmployee").value(1))
+ .andExpect(jsonPath("$[0].contractor_name").value("contractorName"))
+ .andExpect(jsonPath("$[0].end_date").value("01.01.2024"))
+ .andExpect(jsonPath("$[0].leading_employee").value(1))
.andExpect(jsonPath("$[0].name").value("name"))
- .andExpect(jsonPath("$[0].startDate").value("01.01.2021"))
+ .andExpect(jsonPath("$[0].start_date").value("01.01.2021"))
.andExpect(jsonPath("$[0].employees").isArray())
.andExpect(jsonPath("$[0].employees", hasSize(3)));
}
--
2.45.2
From 79300c77ee17017b3b370a0dc71ca4272e1b3fde Mon Sep 17 00:00:00 2001
From: Phan Huy Tran
Date: Wed, 25 Sep 2024 14:25:55 +0200
Subject: [PATCH 8/8] Fix line endings
---
.gitea/workflows/release.yml | 62 +--
GetBearerToken.http | 10 +-
config/checkstyle/checkstyle-ignore.xml | 18 +-
config/checkstyle/checkstyle.xml | 46 +-
gradle/wrapper/gradle-wrapper.properties | 14 +-
gradlew | 504 +++++++++---------
release.config.cjs | 24 +-
requests/createProject.http | 28 +-
.../config/OpenAPIConfiguration.java | 120 ++---
.../GlobalExceptionHandler.java | 102 ++--
.../project/CreateProjectAction.java | 78 +--
.../lf8_starter/project/ProjectEntity.java | 86 +--
.../project/dto/CreateProjectDto.java | 90 ++--
.../project/dto/GetProjectDto.java | 68 +--
.../security/KeycloakLogoutHandler.java | 98 ++--
.../resources/application-test.properties | 8 +-
.../Lf8StarterApplicationTests.java | 28 +-
.../project/CreateProjectActionTest.java | 142 ++---
18 files changed, 763 insertions(+), 763 deletions(-)
diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml
index a04d812..1c29ae9 100644
--- a/.gitea/workflows/release.yml
+++ b/.gitea/workflows/release.yml
@@ -1,31 +1,31 @@
-name: Release
-on:
- push:
- branches:
- - main
-
-env:
- GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
-
-permissions:
- contents: read # for checkout
-
-concurrency:
- group: ${{ github.ref }} # Ensure each branch has its own group
- cancel-in-progress: false # Prevent new runs from canceling in-progress runs
-
-jobs:
- release:
- name: Release
- runs-on: ubuntu-latest
- permissions:
- contents: write # to be able to publish a GitHub release
- issues: write # to be able to comment on released issues
- pull-requests: write # to be able to comment on released pull requests
- id-token: write # to enable use of OIDC for npm provenance
- steps:
- - name: Create Release
- uses: https://git.kjan.de/actions/semantic-release@main
- with:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
+name: Release
+on:
+ push:
+ branches:
+ - main
+
+env:
+ GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
+
+permissions:
+ contents: read # for checkout
+
+concurrency:
+ group: ${{ github.ref }} # Ensure each branch has its own group
+ cancel-in-progress: false # Prevent new runs from canceling in-progress runs
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write # to be able to publish a GitHub release
+ issues: write # to be able to comment on released issues
+ pull-requests: write # to be able to comment on released pull requests
+ id-token: write # to enable use of OIDC for npm provenance
+ steps:
+ - name: Create Release
+ uses: https://git.kjan.de/actions/semantic-release@main
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
diff --git a/GetBearerToken.http b/GetBearerToken.http
index abf7e94..f5209ca 100644
--- a/GetBearerToken.http
+++ b/GetBearerToken.http
@@ -1,6 +1,6 @@
-POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
-Content-Type: application/x-www-form-urlencoded
-
-grant_type=password&client_id=employee-management-service&username=user&password=test
-
+POST https://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=password&client_id=employee-management-service&username=user&password=test
+
> {% client.global.set("auth_token", response.body.access_token); %}
\ No newline at end of file
diff --git a/config/checkstyle/checkstyle-ignore.xml b/config/checkstyle/checkstyle-ignore.xml
index 5ec61a5..fe3b2fe 100644
--- a/config/checkstyle/checkstyle-ignore.xml
+++ b/config/checkstyle/checkstyle-ignore.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 3c18de8..d8f0701 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b9ddd88..df97d72 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
-networkTimeout=10000
-validateDistributionUrl=true
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index ec19934..f5feea6 100755
--- a/gradlew
+++ b/gradlew
@@ -1,252 +1,252 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 the original 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.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-# This is normally unused
-# shellcheck disable=SC2034
-APP_BASE_NAME=${0##*/}
-# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- if ! command -v java >/dev/null 2>&1
- then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if "$cygwin" || "$msys" ; then
- APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
-
- JAVACMD=$( cygpath --unix "$JAVACMD" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
-# and any embedded shellness will be escaped.
-# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
-# treated as '${Hostname}' itself on the command line.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/release.config.cjs b/release.config.cjs
index 1b62d04..375ccd5 100644
--- a/release.config.cjs
+++ b/release.config.cjs
@@ -1,12 +1,12 @@
-module.exports = {
-
- branches: ['main'],
- plugins: [
- '@semantic-release/commit-analyzer',
- '@semantic-release/release-notes-generator',
- '@semantic-release/changelog',
- ["@saithodev/semantic-release-gitea", {
- "giteaUrl": "https://git.kjan.de"
- }],
- ],
-};
+module.exports = {
+
+ branches: ['main'],
+ plugins: [
+ '@semantic-release/commit-analyzer',
+ '@semantic-release/release-notes-generator',
+ '@semantic-release/changelog',
+ ["@saithodev/semantic-release-gitea", {
+ "giteaUrl": "https://git.kjan.de"
+ }],
+ ],
+};
diff --git a/requests/createProject.http b/requests/createProject.http
index 885c49e..7b08e28 100644
--- a/requests/createProject.http
+++ b/requests/createProject.http
@@ -1,15 +1,15 @@
-### GET request to example server
-POST http://localhost:8080/projects
-Authorization: Bearer {{auth_token}}
-Content-Type: application/json
-
-{
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractor_name": "Peter File",
- "comment": "goal of project",
- "start_date": "01.01.2000",
- "planned_end_date": "01.01.2001"
+### GET request to example server
+POST http://localhost:8080/projects
+Authorization: Bearer {{auth_token}}
+Content-Type: application/json
+
+{
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractor_name": "Peter File",
+ "comment": "goal of project",
+ "start_date": "01.01.2000",
+ "planned_end_date": "01.01.2001"
}
\ No newline at end of file
diff --git a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
index 76a6f58..1b2282b 100644
--- a/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
+++ b/src/main/java/de/szut/lf8_starter/config/OpenAPIConfiguration.java
@@ -1,60 +1,60 @@
-package de.szut.lf8_starter.config;
-
-
-
-import io.swagger.v3.oas.models.Components;
-import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.info.Info;
-import io.swagger.v3.oas.models.security.SecurityRequirement;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import io.swagger.v3.oas.models.servers.Server;
-import jakarta.servlet.ServletContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-
-@Configuration
-public class OpenAPIConfiguration {
-
- private ServletContext context;
-
- public OpenAPIConfiguration(ServletContext context) {
- this.context = context;
- }
-
-
- @Bean
- public OpenAPI springShopOpenAPI(
- // @Value("${info.app.version}") String appVersion,
- ) {
- final String securitySchemeName = "bearerAuth";
-
- return new OpenAPI()
- .addServersItem(new Server().url(this.context.getContextPath()))
- .info(new Info()
- .title("LF8 project starter")
- .description("\n## Auth\n" +
- "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
- "\n" +
- "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
- "\n" +
- "\nor by CURL\n" +
- "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
- "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
-
- .version("0.1"))
- .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
- .components(
- new Components()
- .addSecuritySchemes(securitySchemeName,
- new SecurityScheme()
- .name(securitySchemeName)
- .type(SecurityScheme.Type.HTTP)
- .scheme("bearer")
- .bearerFormat("JWT")
- )
- );
- }
-
-
-}
+package de.szut.lf8_starter.config;
+
+
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import io.swagger.v3.oas.models.servers.Server;
+import jakarta.servlet.ServletContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class OpenAPIConfiguration {
+
+ private ServletContext context;
+
+ public OpenAPIConfiguration(ServletContext context) {
+ this.context = context;
+ }
+
+
+ @Bean
+ public OpenAPI springShopOpenAPI(
+ // @Value("${info.app.version}") String appVersion,
+ ) {
+ final String securitySchemeName = "bearerAuth";
+
+ return new OpenAPI()
+ .addServersItem(new Server().url(this.context.getContextPath()))
+ .info(new Info()
+ .title("LF8 project starter")
+ .description("\n## Auth\n" +
+ "\n## Authentication\n" + "\nThis Hello service uses JWTs to authenticate requests. You will receive a bearer token by making a POST-Request in IntelliJ on:\n\n" +
+ "\n" +
+ "```\nPOST http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token\nContent-Type: application/x-www-form-urlencoded\ngrant_type=password&client_id=employee-management-service&username=user&password=test\n```\n" +
+ "\n" +
+ "\nor by CURL\n" +
+ "```\ncurl -X POST 'http://keycloak.szut.dev/auth/realms/szut/protocol/openid-connect/token'\n--header 'Content-Type: application/x-www-form-urlencoded'\n--data-urlencode 'grant_type=password'\n--data-urlencode 'client_id=employee-management-service'\n--data-urlencode 'username=user'\n--data-urlencode 'password=test'\n```\n" +
+ "\nTo get a bearer-token in Postman, you have to follow the instructions in \n [Postman-Documentation](https://documenter.getpostman.com/view/7294517/SzmfZHnd).")
+
+ .version("0.1"))
+ .addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
+ .components(
+ new Components()
+ .addSecuritySchemes(securitySchemeName,
+ new SecurityScheme()
+ .name(securitySchemeName)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")
+ )
+ );
+ }
+
+
+}
diff --git a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
index 92ba734..68a15a7 100644
--- a/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
+++ b/src/main/java/de/szut/lf8_starter/exceptionHandling/GlobalExceptionHandler.java
@@ -1,51 +1,51 @@
-package de.szut.lf8_starter.exceptionHandling;
-
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.ConstraintViolationException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.context.request.WebRequest;
-
-import java.util.Date;
-
-@ControllerAdvice
-@ApiResponses(value = {
- @ApiResponse(responseCode = "500", description = "invalid JSON posted",
- content = @Content)
-})
-public class GlobalExceptionHandler {
-
- @ExceptionHandler(ResourceNotFoundException.class)
- public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
- }
-
- @ExceptionHandler(Exception.class)
- public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- @ExceptionHandler(MethodArgumentNotValidException.class)
- public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
- ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-
- @ExceptionHandler(ConstraintViolationException.class)
- public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
- String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
-
- ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
-
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
- }
-}
+package de.szut.lf8_starter.exceptionHandling;
+
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.ConstraintViolationException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+
+import java.util.Date;
+
+@ControllerAdvice
+@ApiResponses(value = {
+ @ApiResponse(responseCode = "500", description = "invalid JSON posted",
+ content = @Content)
+})
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity> handleHelloEntityNotFoundException(ResourceNotFoundException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+ return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
+ }
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity handleAllOtherExceptions(Exception ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getClass() + " " + ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) {
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
+ String errorMessage = ex.getConstraintViolations().stream().findFirst().get().getMessage();
+
+ ErrorDetails errorDetails = new ErrorDetails(new Date(), errorMessage, request.getDescription(false));
+
+ return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
index 4158fee..d54318b 100644
--- a/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
+++ b/src/main/java/de/szut/lf8_starter/project/CreateProjectAction.java
@@ -1,39 +1,39 @@
-package de.szut.lf8_starter.project;
-
-import de.szut.lf8_starter.project.dto.CreateProjectDto;
-import de.szut.lf8_starter.project.dto.GetProjectDto;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping(value = "/projects")
-public class CreateProjectAction {
- private final ProjectService projectService;
- private final ProjectMapper projectMapper;
-
- public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
- this.projectService = projectService;
- this.projectMapper = mappingService;
- }
-
- @Operation(summary = "Creates a new Project")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
- @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
- @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
- @PostMapping
- @ResponseStatus(code = HttpStatus.CREATED)
- public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
- ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
-
- projectEntity = this.projectService.create(projectEntity);
-
- return this.projectMapper.mapToGetDto(projectEntity);
- }
-}
+package de.szut.lf8_starter.project;
+
+import de.szut.lf8_starter.project.dto.CreateProjectDto;
+import de.szut.lf8_starter.project.dto.GetProjectDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.validation.Valid;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "/projects")
+public class CreateProjectAction {
+ private final ProjectService projectService;
+ private final ProjectMapper projectMapper;
+
+ public CreateProjectAction(ProjectService projectService, ProjectMapper mappingService) {
+ this.projectService = projectService;
+ this.projectMapper = mappingService;
+ }
+
+ @Operation(summary = "Creates a new Project")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201", description = "created project", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = GetProjectDto.class))}),
+ @ApiResponse(responseCode = "400", description = "invalid JSON posted", content = @Content),
+ @ApiResponse(responseCode = "401", description = "not authorized", content = @Content)})
+ @PostMapping
+ @ResponseStatus(code = HttpStatus.CREATED)
+ public GetProjectDto create(@RequestBody @Valid CreateProjectDto createProjectDto) {
+ ProjectEntity projectEntity = this.projectMapper.mapCreateDtoToEntity(createProjectDto);
+
+ projectEntity = this.projectService.create(projectEntity);
+
+ return this.projectMapper.mapToGetDto(projectEntity);
+ }
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
index 82563fe..d9c35a1 100644
--- a/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
+++ b/src/main/java/de/szut/lf8_starter/project/ProjectEntity.java
@@ -1,43 +1,43 @@
-package de.szut.lf8_starter.project;
-
-import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import org.springframework.data.annotation.CreatedDate;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@NoArgsConstructor
-@AllArgsConstructor
-@Getter
-@Setter
-@Entity
-@Table(name = "projects")
-public class ProjectEntity {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
-
- private String name;
-
- private long leadingEmployee;
-
- @ElementCollection
- private List employees;
-
- private long contractor;
-
- private String contractorName;
-
- private String comment;
-
- @CreatedDate
- private LocalDate startDate;
-
- private LocalDate plannedEndDate;
-
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.data.annotation.CreatedDate;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@Entity
+@Table(name = "projects")
+public class ProjectEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ private long leadingEmployee;
+
+ @ElementCollection
+ private List employees;
+
+ private long contractor;
+
+ private String contractorName;
+
+ private String comment;
+
+ @CreatedDate
+ private LocalDate startDate;
+
+ private LocalDate plannedEndDate;
+
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
index 64d22b7..ebf4393 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/CreateProjectDto.java
@@ -1,45 +1,45 @@
-package de.szut.lf8_starter.project.dto;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.PropertyNamingStrategies;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
-public class CreateProjectDto {
- @NotBlank
- private String name;
-
- @NotNull
- private long leadingEmployee;
-
- private List employees;
-
- @NotNull
- private long contractor;
-
- @NotBlank
- private String contractorName;
-
- @NotBlank
- private String comment;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate startDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- @NotNull
- private LocalDate plannedEndDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class CreateProjectDto {
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private long leadingEmployee;
+
+ private List employees;
+
+ @NotNull
+ private long contractor;
+
+ @NotBlank
+ private String contractorName;
+
+ @NotBlank
+ private String comment;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate startDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ @NotNull
+ private LocalDate plannedEndDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
index 250a6a0..614ece1 100644
--- a/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
+++ b/src/main/java/de/szut/lf8_starter/project/dto/GetProjectDto.java
@@ -1,34 +1,34 @@
-package de.szut.lf8_starter.project.dto;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.PropertyNamingStrategies;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Getter
-@Setter
-@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
-public class GetProjectDto {
- private long id;
- private String name;
- private long leadingEmployee;
- private List employees;
- private long contractor;
- private String contractorName;
- private String comment;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate startDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate plannedEndDate;
-
- @JsonFormat(pattern = "dd.MM.yyyy")
- private LocalDate endDate;
-}
+package de.szut.lf8_starter.project.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Getter
+@Setter
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class GetProjectDto {
+ private long id;
+ private String name;
+ private long leadingEmployee;
+ private List employees;
+ private long contractor;
+ private String contractorName;
+ private String comment;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate startDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate plannedEndDate;
+
+ @JsonFormat(pattern = "dd.MM.yyyy")
+ private LocalDate endDate;
+}
diff --git a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
index e06f2f7..8555ef9 100644
--- a/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
+++ b/src/main/java/de/szut/lf8_starter/security/KeycloakLogoutHandler.java
@@ -1,49 +1,49 @@
-package de.szut.lf8_starter.security;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.core.oidc.user.OidcUser;
-import org.springframework.security.web.authentication.logout.LogoutHandler;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-@Slf4j
-@Component
-public class KeycloakLogoutHandler implements LogoutHandler {
-
-
- private final RestTemplate restTemplate;
-
- public KeycloakLogoutHandler(RestTemplate restTemplate) {
- this.restTemplate = restTemplate;
- }
-
- @Override
- public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
- logout(request, auth);
- }
-
- public void logout(HttpServletRequest request, Authentication auth) {
- logoutFromKeycloak((OidcUser) auth.getPrincipal());
- }
-
- private void logoutFromKeycloak(OidcUser user) {
- String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromUriString(endSessionEndpoint)
- .queryParam("id_token_hint", user.getIdToken().getTokenValue());
-
- ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
- if (logoutResponse.getStatusCode().is2xxSuccessful()) {
- log.info("Successfulley logged out from Keycloak");
- } else {
- log.error("Could not propagate logout to Keycloak");
- }
- }
-
-}
+package de.szut.lf8_starter.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.core.oidc.user.OidcUser;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+@Slf4j
+@Component
+public class KeycloakLogoutHandler implements LogoutHandler {
+
+
+ private final RestTemplate restTemplate;
+
+ public KeycloakLogoutHandler(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ @Override
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) {
+ logout(request, auth);
+ }
+
+ public void logout(HttpServletRequest request, Authentication auth) {
+ logoutFromKeycloak((OidcUser) auth.getPrincipal());
+ }
+
+ private void logoutFromKeycloak(OidcUser user) {
+ String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
+ UriComponentsBuilder builder = UriComponentsBuilder
+ .fromUriString(endSessionEndpoint)
+ .queryParam("id_token_hint", user.getIdToken().getTokenValue());
+
+ ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
+ if (logoutResponse.getStatusCode().is2xxSuccessful()) {
+ log.info("Successfulley logged out from Keycloak");
+ } else {
+ log.error("Could not propagate logout to Keycloak");
+ }
+ }
+
+}
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 259f612..af21e0e 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,5 +1,5 @@
-spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
-spring.datasource.driver-class-name=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
+spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
\ No newline at end of file
diff --git a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
index d418f1a..b5c7f7b 100644
--- a/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
+++ b/src/test/java/de/szut/lf8_starter/Lf8StarterApplicationTests.java
@@ -1,14 +1,14 @@
-package de.szut.lf8_starter;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.TestPropertySource;
-
-@SpringBootTest
-class Lf8StarterApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
+package de.szut.lf8_starter;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+
+@SpringBootTest
+class Lf8StarterApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
index 06d02b6..36eee54 100644
--- a/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
+++ b/src/test/java/de/szut/lf8_starter/integration/project/CreateProjectActionTest.java
@@ -1,71 +1,71 @@
-package de.szut.lf8_starter.integration.project;
-
-import de.szut.lf8_starter.project.ProjectRepository;
-import org.json.JSONObject;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-
-import java.time.LocalDate;
-import java.util.Arrays;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.hamcrest.Matchers.is;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@SpringBootTest
-@AutoConfigureMockMvc(addFilters = false)
-public class CreateProjectActionTest {
- @Autowired
- private MockMvc mockMvc;
- @Autowired
- private ProjectRepository projectRepository;
-
- @Test
- void createProjectTest() throws Exception {
- String content = """
- {
- "name": "name",
- "leading_employee": 1,
- "employees": [2, 3],
- "contractor": 4,
- "contractor_name": "Peter File",
- "comment": "goal of project",
- "start_date": "01.01.2000",
- "planned_end_date": "01.01.2001"
- }
- """;
-
- final var contentAsString = this.mockMvc.perform(
- post("/projects").content(content).contentType(MediaType.APPLICATION_JSON)
- )
- .andExpect(status().isCreated())
- .andExpect(jsonPath("name", is("name")))
- .andExpect(jsonPath("leading_employee", is(1)))
- .andExpect(jsonPath("employees", is(Arrays.asList(2, 3))))
- .andExpect(jsonPath("contractor", is(4)))
- .andExpect(jsonPath("contractor_name", is("Peter File")))
- .andExpect(jsonPath("comment", is("goal of project")))
- .andExpect(jsonPath("start_date", is("01.01.2000")))
- .andExpect(jsonPath("planned_end_date", is("01.01.2001")))
- .andReturn()
- .getResponse()
- .getContentAsString();
-
- final var id = Long.parseLong(new JSONObject(contentAsString).get("id").toString());
-
- final var project = this.projectRepository.findById(id);
- assertThat(project.get().getName()).isEqualTo("name");
- assertThat(project.get().getLeadingEmployee()).isEqualTo(1);
- assertThat(project.get().getContractor()).isEqualTo(4);
- assertThat(project.get().getContractorName()).isEqualTo("Peter File");
- assertThat(project.get().getComment()).isEqualTo("goal of project");
- assertThat(project.get().getStartDate()).isEqualTo(LocalDate.of(2000, 1, 1));
- assertThat(project.get().getPlannedEndDate()).isEqualTo(LocalDate.of(2001, 1, 1));
- }
-}
+package de.szut.lf8_starter.integration.project;
+
+import de.szut.lf8_starter.project.ProjectRepository;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.time.LocalDate;
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.hamcrest.Matchers.is;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc(addFilters = false)
+public class CreateProjectActionTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ProjectRepository projectRepository;
+
+ @Test
+ void createProjectTest() throws Exception {
+ String content = """
+ {
+ "name": "name",
+ "leading_employee": 1,
+ "employees": [2, 3],
+ "contractor": 4,
+ "contractor_name": "Peter File",
+ "comment": "goal of project",
+ "start_date": "01.01.2000",
+ "planned_end_date": "01.01.2001"
+ }
+ """;
+
+ final var contentAsString = this.mockMvc.perform(
+ post("/projects").content(content).contentType(MediaType.APPLICATION_JSON)
+ )
+ .andExpect(status().isCreated())
+ .andExpect(jsonPath("name", is("name")))
+ .andExpect(jsonPath("leading_employee", is(1)))
+ .andExpect(jsonPath("employees", is(Arrays.asList(2, 3))))
+ .andExpect(jsonPath("contractor", is(4)))
+ .andExpect(jsonPath("contractor_name", is("Peter File")))
+ .andExpect(jsonPath("comment", is("goal of project")))
+ .andExpect(jsonPath("start_date", is("01.01.2000")))
+ .andExpect(jsonPath("planned_end_date", is("01.01.2001")))
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ final var id = Long.parseLong(new JSONObject(contentAsString).get("id").toString());
+
+ final var project = this.projectRepository.findById(id);
+ assertThat(project.get().getName()).isEqualTo("name");
+ assertThat(project.get().getLeadingEmployee()).isEqualTo(1);
+ assertThat(project.get().getContractor()).isEqualTo(4);
+ assertThat(project.get().getContractorName()).isEqualTo("Peter File");
+ assertThat(project.get().getComment()).isEqualTo("goal of project");
+ assertThat(project.get().getStartDate()).isEqualTo(LocalDate.of(2000, 1, 1));
+ assertThat(project.get().getPlannedEndDate()).isEqualTo(LocalDate.of(2001, 1, 1));
+ }
+}
--
2.45.2