From 96fc578f45eb44f83ca43850ac66d7b9e5e832f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Fri, 2 May 2025 18:03:27 +0200 Subject: [PATCH 01/49] simple dependency bumps --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index d435ec8..be1afa6 100644 --- a/build.gradle +++ b/build.gradle @@ -96,7 +96,7 @@ dependencies { //Keycloak // implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" - implementation "com.nimbusds:nimbus-jose-jwt:9.24.3" + implementation 'com.nimbusds:nimbus-jose-jwt:9.37.2' implementation "io.jsonwebtoken:jjwt-api:0.11.5" implementation "io.jsonwebtoken:jjwt-impl:0.11.5" implementation "io.jsonwebtoken:jjwt-jackson:0.11.5" @@ -115,9 +115,9 @@ dependencies { implementation "org.apache.commons:commons-collections4:4.1" // driver for postgres - implementation "org.postgresql:postgresql:42.5.0" + implementation 'org.postgresql:postgresql:42.7.2' //driver for h2 - implementation "com.h2database:h2:2.1.214" + implementation 'com.h2database:h2:2.2.220' testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:2.0.6.RELEASE" testImplementation "org.springframework.boot:spring-boot-starter-test" @@ -131,7 +131,7 @@ dependencies { testImplementation "io.rest-assured:rest-assured" testImplementation "io.rest-assured:spring-mock-mvc" testImplementation "io.rest-assured:rest-assured" - testImplementation ("io.specto:hoverfly-java-junit5:0.17.1") { + testImplementation ("io.specto:hoverfly-java-junit5:0.20.0") { exclude group: 'ch.qos.logback', module: 'logback-classic' } From 8b7af21e3d41ef0e91f2e2165ba96adf577d0a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Fri, 2 May 2025 21:50:28 +0200 Subject: [PATCH 02/49] upgrade spring boot + gradle + jena --- build.gradle | 35 ++-- gradle/profile-complete.gradle | 4 +- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 18 +- gradlew.bat | 15 +- .../kit/scc/dem/wapsrv/app/CorsFilter.java | 16 +- .../kit/scc/dem/wapsrv/app/FusekiRunner.java | 8 +- .../scc/dem/wapsrv/app/WapServerConfig.java | 2 +- .../controller/AnnotationController.java | 2 +- .../wapsrv/controller/BackupController.java | 2 +- .../wapsrv/controller/BasicController.java | 2 +- .../wapsrv/controller/CatchAllController.java | 2 +- .../controller/ContainerController.java | 2 +- .../wapsrv/controller/JavadocController.java | 2 +- .../dem/wapsrv/controller/PageController.java | 2 +- .../SimpleFolderServerController.java | 2 +- .../controller/WebClientController.java | 2 +- .../WapResponseEntityExceptionHandler.java | 2 +- .../dem/wapsrv/installer/JarUtilities.java | 6 +- .../wapsrv/model/ext/SequenceResource.java | 8 +- .../wapsrv/repository/jena/JenaDataBase.java | 2 +- .../repository/jena/JenaRdfBackend.java | 6 +- .../repository/jena/JenaRepository.java | 3 +- .../repository/jena/JenaRepository2.java | 2 +- .../controller/BasicControllerTest.java | 2 +- .../controller/HttpServletRequestAdapter.java | 189 +++++++++--------- .../controller/JavadocControllerTest.java | 14 +- ...WapResponseEntityExceptionHandlerTest.java | 2 +- .../wapsrv/testscommon/ApacheJenaTests.java | 2 +- .../wapsrv/testscommon/FusekiSparqlTests.java | 2 +- 31 files changed, 183 insertions(+), 176 deletions(-) mode change 100644 => 100755 gradlew diff --git a/build.gradle b/build.gradle index be1afa6..fa30e75 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { - id "org.springframework.boot" version "2.7.5" - id "io.spring.dependency-management" version "1.1.0" + id "org.springframework.boot" version "3.4.5" + id "io.spring.dependency-management" version "1.1.4" id "io.freefair.maven-publish-java" version "6.5.1" id "com.github.kt3k.coveralls" version "2.12.0" id "org.owasp.dependencycheck" version "7.3.0" @@ -31,11 +31,12 @@ configurations { ext { set('javersVersion', "6.8.0") - set('springBootVersion', "2.7.5") - set('springDocVersion', "1.6.9") + set('jenaVersion', "5.4.0") + set('springBootVersion', "3.4.5") + set('springDocVersion', "2.5.0") set('keycloakVersion', "19.0.0") - set('junitPlatformVersion', "1.2.0") - set('junitJupiterVersion', "5.2.0") + set('junitPlatformVersion', "1.11.4") + set('junitJupiterVersion', "5.11.4") // directory for generated code snippets during tests snippetsDir = file("build/generated-snippets") @@ -80,7 +81,7 @@ dependencies { //implementation "org.springframework.security:spring-security-web:5.7.5" //implementation "org.springframework.security:spring-security-config:5.7.5" - implementation "org.thymeleaf:thymeleaf-spring5" + implementation "org.thymeleaf:thymeleaf-spring6" // cloud support @@ -90,9 +91,7 @@ dependencies { //implementation 'de.codecentric:spring-boot-admin-starter-client:2.7.10' // springdoc - implementation "org.springdoc:springdoc-openapi-ui:${springDocVersion}" - implementation "org.springdoc:springdoc-openapi-data-rest:${springDocVersion}" - implementation "org.springdoc:springdoc-openapi-webmvc-core:${springDocVersion}" + implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springDocVersion}" //Keycloak // implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" @@ -102,11 +101,11 @@ dependencies { implementation "io.jsonwebtoken:jjwt-jackson:0.11.5" //Jena - implementation "org.apache.jena:apache-jena-libs:4.10.0" - implementation "org.apache.jena:jena-fuseki:4.10.0" - implementation "org.apache.jena:jena-fuseki-server:4.10.0" + implementation "org.apache.jena:apache-jena-libs:${jenaVersion}" + implementation "org.apache.jena:jena-fuseki:${jenaVersion}" + implementation "org.apache.jena:jena-fuseki-server:${jenaVersion}" - implementation "org.apache.jena:jena-commonsrdf:4.10.0" + implementation "org.apache.jena:jena-commonsrdf:${jenaVersion}" implementation "org.apache.thrift:libthrift:0.18.1" implementation "org.apache.commons:commons-rdf-jsonld-java:0.5.0" @@ -119,7 +118,7 @@ dependencies { //driver for h2 implementation 'com.h2database:h2:2.2.220' - testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:2.0.6.RELEASE" + testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:3.0.3" testImplementation "org.springframework.boot:spring-boot-starter-test" testImplementation "org.springframework:spring-test" // testImplementation "org.springframework.security:spring-security-test" @@ -168,7 +167,7 @@ test { environment "spring.config.location", "classpath:/test-config/" } -tasks.withType(Test) { +tasks.withType(Test).configureEach { testLogging { events 'started', 'passed' } @@ -183,13 +182,13 @@ bootJar { archiveFileName = "${archiveBaseName.get()}.${archiveExtension.get()}" duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { - attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher' + attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher' } launchScript() } // task for printing project name. -task printProjectName { +tasks.register('printProjectName') { doLast { println "${project.name}" } diff --git a/gradle/profile-complete.gradle b/gradle/profile-complete.gradle index 866be7c..eb45ecd 100644 --- a/gradle/profile-complete.gradle +++ b/gradle/profile-complete.gradle @@ -7,7 +7,7 @@ test { jacocoTestReport { dependsOn test reports { - xml.enabled true - html.enabled false + xml.required.set(true) + html.required.set(false) } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 36987 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 z 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 VBfu2+*qg&~f-ihLS3eum{s(|${^$Sz diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb70..3c44eb1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index 1b6c787..65dcd68 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # 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"' @@ -143,12 +143,16 @@ fi 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=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=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -205,6 +209,12 @@ set -- \ 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. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/CorsFilter.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/CorsFilter.java index a8ff9f2..f684314 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/CorsFilter.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/CorsFilter.java @@ -4,14 +4,14 @@ import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import org.eclipse.jetty.servlets.CrossOriginFilter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponseWrapper; +import org.apache.jena.fuseki.servlets.CrossOriginFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/FusekiRunner.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/FusekiRunner.java index 6f63454..c97a1e3 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/FusekiRunner.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/FusekiRunner.java @@ -3,10 +3,10 @@ import java.util.EnumSet; import java.util.List; import java.util.Vector; -import javax.servlet.DispatcherType; -import javax.servlet.FilterRegistration.Dynamic; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.FilterRegistration.Dynamic; import org.apache.jena.fuseki.main.FusekiServer; -import org.eclipse.jetty.servlets.CrossOriginFilter; +import org.apache.jena.fuseki.servlets.CrossOriginFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -149,7 +149,7 @@ private void addCorsFilter(FusekiServer fusekiServer, boolean writeable) { * @return A cross origin filter that enforces the given parameters */ private CrossOriginFilter createCrossOriginFilter(final int maxAge, final String allowedHeaders, - final String exposedHeaders) { + final String exposedHeaders) { // The jena/jetty implementation has some flaws we have to work around // Details are found within the CorsFilter class return new CorsFilter(maxAge, allowedHeaders, exposedHeaders); diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java index 055c96a..7d49cb9 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java @@ -7,7 +7,7 @@ import java.util.HashSet; import java.util.Properties; import java.util.Set; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/AnnotationController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/AnnotationController.java index 1967899..1c314b1 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/AnnotationController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/AnnotationController.java @@ -2,7 +2,7 @@ import java.net.URI; import java.net.URISyntaxException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/BackupController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/BackupController.java index c2cbae2..834a93a 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/BackupController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/BackupController.java @@ -2,7 +2,7 @@ import java.util.Arrays; import java.util.HashSet; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/BasicController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/BasicController.java index 7877bfe..cbeb75d 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/BasicController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/BasicController.java @@ -1,6 +1,6 @@ package edu.kit.scc.dem.wapsrv.controller; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpMethod; /** diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/CatchAllController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/CatchAllController.java index 4dfe93e..e0948de 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/CatchAllController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/CatchAllController.java @@ -2,7 +2,7 @@ import java.util.Hashtable; import java.util.Map; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.eclipse.jetty.http.HttpMethod; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/ContainerController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/ContainerController.java index f22e862..2a7c278 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/ContainerController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/ContainerController.java @@ -5,7 +5,7 @@ import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/JavadocController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/JavadocController.java index b68e126..633ffed 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/JavadocController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/JavadocController.java @@ -1,6 +1,6 @@ package edu.kit.scc.dem.wapsrv.controller; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/PageController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/PageController.java index 59fbb63..199dcb0 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/PageController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/PageController.java @@ -1,6 +1,6 @@ package edu.kit.scc.dem.wapsrv.controller; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/SimpleFolderServerController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/SimpleFolderServerController.java index b885b3b..cb21499 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/SimpleFolderServerController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/SimpleFolderServerController.java @@ -8,7 +8,7 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/controller/WebClientController.java b/src/main/java/edu/kit/scc/dem/wapsrv/controller/WebClientController.java index 9bdd01b..15e3c43 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/controller/WebClientController.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/controller/WebClientController.java @@ -1,6 +1,6 @@ package edu.kit.scc.dem.wapsrv.controller; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandler.java b/src/main/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandler.java index 5dbe6f3..f931729 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandler.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandler.java @@ -1,7 +1,7 @@ package edu.kit.scc.dem.wapsrv.exceptions; import java.util.Date; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/installer/JarUtilities.java b/src/main/java/edu/kit/scc/dem/wapsrv/installer/JarUtilities.java index bb46ed6..7452ff2 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/installer/JarUtilities.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/installer/JarUtilities.java @@ -83,11 +83,11 @@ public static File getCurrentlyRunningJarFile() { // jar:file:/C:/Users/andreas/Desktop/TestInstall/PSE-AA-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/ // linux : // mac : - String[] parts = uri.split(Pattern.quote("/")); + String[] parts = uri.split(Pattern.quote("!"))[0].split(Pattern.quote("/")); for (String part : parts) { - if (part.toLowerCase().endsWith(".jar!")) { + if (part.toLowerCase().endsWith(".jar")) { System.out.println("Part found : " + part); - return new File("./" + part.substring(0, part.length() - 1)); + return new File("./" + part); } } return guessJar(); diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/model/ext/SequenceResource.java b/src/main/java/edu/kit/scc/dem/wapsrv/model/ext/SequenceResource.java index 565d649..043d7bf 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/model/ext/SequenceResource.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/model/ext/SequenceResource.java @@ -17,10 +17,10 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.io.Serializable; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; /** * diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaDataBase.java b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaDataBase.java index ab38bf9..eb30c5a 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaDataBase.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaDataBase.java @@ -1,7 +1,7 @@ package edu.kit.scc.dem.wapsrv.repository.jena; import java.util.Calendar; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.apache.jena.query.Dataset; import org.apache.jena.query.ReadWrite; import org.apache.jena.rdf.model.Literal; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRdfBackend.java b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRdfBackend.java index 8da4243..fb1c27e 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRdfBackend.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRdfBackend.java @@ -72,7 +72,7 @@ public String getOutput(Dataset dataset, Format format) throws WapException { StringWriter writer = new StringWriter(); //Specifying format option to match behaviour of jsonld-java. Likely to break on dependency change / jena upgrade. See https://jena.apache.org/documentation/io/rdf-output.html#json-ld if(format == Format.JSON_LD) { - RDFDataMgr.write(writer, graph, RDFFormat.JSONLD_EXPAND_PRETTY); + RDFDataMgr.write(writer, graph, RDFFormat.JSONLD_PRETTY); return writer.toString(); } RDFDataMgr.write(writer, graph, lang); @@ -83,8 +83,8 @@ public String getOutput(Dataset dataset, Format format) throws WapException { @Override public Dataset readFromString(String serialization, final Format format) throws WapException { Lang lang = JenaFormatMapper.map(format); - //TODO: this solution is already deprecated. See https://github.com/apache/jena/issues/1765 - if(format == Format.JSON_LD) {lang = Lang.JSONLD10;} + //TODO: Does this still work as expected? See https://github.com/apache/jena/issues/1765 + if(format == Format.JSON_LD) {lang = Lang.JSONLD;} if (lang == null) { throw new FormatException("Format " + format + " not supported in jena RDF backend"); } diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository.java b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository.java index 5b96824..12e1e88 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository.java @@ -4,7 +4,8 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import javax.annotation.PostConstruct; + +import jakarta.annotation.PostConstruct; import org.apache.commons.rdf.api.RDF; import org.apache.jena.commonsrdf.JenaCommonsRDF; import org.apache.jena.commonsrdf.impl.JenaDataset; diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository2.java b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository2.java index 4075801..91fd3bf 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository2.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/repository/jena/JenaRepository2.java @@ -5,7 +5,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import org.apache.commons.rdf.api.RDF; import org.apache.jena.commonsrdf.JenaCommonsRDF; import org.apache.jena.commonsrdf.JenaRDF; diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/controller/BasicControllerTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/controller/BasicControllerTest.java index b5a13d1..080b871 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/controller/BasicControllerTest.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/controller/BasicControllerTest.java @@ -1,7 +1,7 @@ package edu.kit.scc.dem.wapsrv.controller; import static org.junit.jupiter.api.Assertions.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/controller/HttpServletRequestAdapter.java b/src/test/java/edu/kit/scc/dem/wapsrv/controller/HttpServletRequestAdapter.java index 3f0aab6..a2630c8 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/controller/HttpServletRequestAdapter.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/controller/HttpServletRequestAdapter.java @@ -8,20 +8,14 @@ import java.util.Enumeration; import java.util.Locale; import java.util.Map; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpUpgradeHandler; -import javax.servlet.http.Part; + +import jakarta.servlet.*; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpUpgradeHandler; +import jakarta.servlet.http.Part; /** * @author Matthias Dressel @@ -104,7 +98,7 @@ public HttpServletRequestAdapter(String url, String httpMethod, Map getAttributeNames() { @@ -122,7 +116,7 @@ public Enumeration getAttributeNames() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getCharacterEncoding() + * @see jakarta.servlet.ServletRequest#getCharacterEncoding() */ @Override public String getCharacterEncoding() { @@ -131,7 +125,7 @@ public String getCharacterEncoding() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) + * @see jakarta.servlet.ServletRequest#setCharacterEncoding(java.lang.String) */ @Override public void setCharacterEncoding(String env) throws UnsupportedEncodingException { @@ -139,7 +133,7 @@ public void setCharacterEncoding(String env) throws UnsupportedEncodingException /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getContentLength() + * @see jakarta.servlet.ServletRequest#getContentLength() */ @Override public int getContentLength() { @@ -148,7 +142,7 @@ public int getContentLength() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getContentLengthLong() + * @see jakarta.servlet.ServletRequest#getContentLengthLong() */ @Override public long getContentLengthLong() { @@ -157,7 +151,7 @@ public long getContentLengthLong() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getContentType() + * @see jakarta.servlet.ServletRequest#getContentType() */ @Override public String getContentType() { @@ -166,7 +160,7 @@ public String getContentType() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getInputStream() + * @see jakarta.servlet.ServletRequest#getInputStream() */ @Override public ServletInputStream getInputStream() throws IOException { @@ -175,7 +169,7 @@ public ServletInputStream getInputStream() throws IOException { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getParameter(java.lang.String) + * @see jakarta.servlet.ServletRequest#getParameter(java.lang.String) */ @Override public String getParameter(String name) { @@ -191,7 +185,7 @@ public String getParameter(String name) { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getParameterNames() + * @see jakarta.servlet.ServletRequest#getParameterNames() */ @Override public Enumeration getParameterNames() { @@ -200,7 +194,7 @@ public Enumeration getParameterNames() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) + * @see jakarta.servlet.ServletRequest#getParameterValues(java.lang.String) */ @Override public String[] getParameterValues(String name) { @@ -209,7 +203,7 @@ public String[] getParameterValues(String name) { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getParameterMap() + * @see jakarta.servlet.ServletRequest#getParameterMap() */ @Override public Map getParameterMap() { @@ -218,7 +212,7 @@ public Map getParameterMap() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getProtocol() + * @see jakarta.servlet.ServletRequest#getProtocol() */ @Override public String getProtocol() { @@ -227,7 +221,7 @@ public String getProtocol() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getScheme() + * @see jakarta.servlet.ServletRequest#getScheme() */ @Override public String getScheme() { @@ -236,7 +230,7 @@ public String getScheme() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getServerName() + * @see jakarta.servlet.ServletRequest#getServerName() */ @Override public String getServerName() { @@ -245,7 +239,7 @@ public String getServerName() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getServerPort() + * @see jakarta.servlet.ServletRequest#getServerPort() */ @Override public int getServerPort() { @@ -254,7 +248,7 @@ public int getServerPort() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getReader() + * @see jakarta.servlet.ServletRequest#getReader() */ @Override public BufferedReader getReader() throws IOException { @@ -263,7 +257,7 @@ public BufferedReader getReader() throws IOException { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getRemoteAddr() + * @see jakarta.servlet.ServletRequest#getRemoteAddr() */ @Override public String getRemoteAddr() { @@ -272,7 +266,7 @@ public String getRemoteAddr() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getRemoteHost() + * @see jakarta.servlet.ServletRequest#getRemoteHost() */ @Override public String getRemoteHost() { @@ -281,7 +275,7 @@ public String getRemoteHost() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) + * @see jakarta.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) */ @Override public void setAttribute(String name, Object o) { @@ -289,7 +283,7 @@ public void setAttribute(String name, Object o) { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String) + * @see jakarta.servlet.ServletRequest#removeAttribute(java.lang.String) */ @Override public void removeAttribute(String name) { @@ -297,7 +291,7 @@ public void removeAttribute(String name) { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getLocale() + * @see jakarta.servlet.ServletRequest#getLocale() */ @Override public Locale getLocale() { @@ -306,7 +300,7 @@ public Locale getLocale() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getLocales() + * @see jakarta.servlet.ServletRequest#getLocales() */ @Override public Enumeration getLocales() { @@ -315,7 +309,7 @@ public Enumeration getLocales() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#isSecure() + * @see jakarta.servlet.ServletRequest#isSecure() */ @Override public boolean isSecure() { @@ -324,7 +318,7 @@ public boolean isSecure() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String) + * @see jakarta.servlet.ServletRequest#getRequestDispatcher(java.lang.String) */ @Override public RequestDispatcher getRequestDispatcher(String path) { @@ -333,16 +327,7 @@ public RequestDispatcher getRequestDispatcher(String path) { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getRealPath(java.lang.String) - */ - @Override - public String getRealPath(String path) { - return null; - } - - /* - * (non-Javadoc) - * @see javax.servlet.ServletRequest#getRemotePort() + * @see jakarta.servlet.ServletRequest#getRemotePort() */ @Override public int getRemotePort() { @@ -351,7 +336,7 @@ public int getRemotePort() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getLocalName() + * @see jakarta.servlet.ServletRequest#getLocalName() */ @Override public String getLocalName() { @@ -360,7 +345,7 @@ public String getLocalName() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getLocalAddr() + * @see jakarta.servlet.ServletRequest#getLocalAddr() */ @Override public String getLocalAddr() { @@ -369,7 +354,7 @@ public String getLocalAddr() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getLocalPort() + * @see jakarta.servlet.ServletRequest#getLocalPort() */ @Override public int getLocalPort() { @@ -378,7 +363,7 @@ public int getLocalPort() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getServletContext() + * @see jakarta.servlet.ServletRequest#getServletContext() */ @Override public ServletContext getServletContext() { @@ -387,7 +372,7 @@ public ServletContext getServletContext() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#startAsync() + * @see jakarta.servlet.ServletRequest#startAsync() */ @Override public AsyncContext startAsync() throws IllegalStateException { @@ -396,7 +381,7 @@ public AsyncContext startAsync() throws IllegalStateException { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#startAsync(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + * @see jakarta.servlet.ServletRequest#startAsync(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ @Override public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) @@ -406,7 +391,7 @@ public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse se /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#isAsyncStarted() + * @see jakarta.servlet.ServletRequest#isAsyncStarted() */ @Override public boolean isAsyncStarted() { @@ -415,7 +400,7 @@ public boolean isAsyncStarted() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#isAsyncSupported() + * @see jakarta.servlet.ServletRequest#isAsyncSupported() */ @Override public boolean isAsyncSupported() { @@ -424,7 +409,7 @@ public boolean isAsyncSupported() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getAsyncContext() + * @see jakarta.servlet.ServletRequest#getAsyncContext() */ @Override public AsyncContext getAsyncContext() { @@ -433,16 +418,31 @@ public AsyncContext getAsyncContext() { /* * (non-Javadoc) - * @see javax.servlet.ServletRequest#getDispatcherType() + * @see jakarta.servlet.ServletRequest#getDispatcherType() */ @Override public DispatcherType getDispatcherType() { return null; } + @Override + public String getRequestId() { + return ""; + } + + @Override + public String getProtocolRequestId() { + return ""; + } + + @Override + public ServletConnection getServletConnection() { + return null; + } + /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getAuthType() + * @see jakarta.servlet.http.HttpServletRequest#getAuthType() */ @Override public String getAuthType() { @@ -451,7 +451,7 @@ public String getAuthType() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getCookies() + * @see jakarta.servlet.http.HttpServletRequest#getCookies() */ @Override public Cookie[] getCookies() { @@ -460,7 +460,7 @@ public Cookie[] getCookies() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) */ @Override public long getDateHeader(String name) { @@ -469,7 +469,7 @@ public long getDateHeader(String name) { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#getHeader(java.lang.String) */ @Override public String getHeader(String name) { @@ -480,7 +480,7 @@ public String getHeader(String name) { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#getHeaders(java.lang.String) */ @Override public Enumeration getHeaders(String name) { @@ -489,7 +489,7 @@ public Enumeration getHeaders(String name) { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getHeaderNames() + * @see jakarta.servlet.http.HttpServletRequest#getHeaderNames() */ @Override public Enumeration getHeaderNames() { @@ -498,7 +498,7 @@ public Enumeration getHeaderNames() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) */ @Override public int getIntHeader(String name) { @@ -507,7 +507,7 @@ public int getIntHeader(String name) { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getMethod() + * @see jakarta.servlet.http.HttpServletRequest#getMethod() */ @Override public String getMethod() { @@ -516,7 +516,7 @@ public String getMethod() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getPathInfo() + * @see jakarta.servlet.http.HttpServletRequest#getPathInfo() */ @Override public String getPathInfo() { @@ -525,7 +525,7 @@ public String getPathInfo() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getPathTranslated() + * @see jakarta.servlet.http.HttpServletRequest#getPathTranslated() */ @Override public String getPathTranslated() { @@ -534,7 +534,7 @@ public String getPathTranslated() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getContextPath() + * @see jakarta.servlet.http.HttpServletRequest#getContextPath() */ @Override public String getContextPath() { @@ -543,7 +543,7 @@ public String getContextPath() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getQueryString() + * @see jakarta.servlet.http.HttpServletRequest#getQueryString() */ @Override public String getQueryString() { @@ -552,7 +552,7 @@ public String getQueryString() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getRemoteUser() + * @see jakarta.servlet.http.HttpServletRequest#getRemoteUser() */ @Override public String getRemoteUser() { @@ -561,7 +561,7 @@ public String getRemoteUser() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) */ @Override public boolean isUserInRole(String role) { @@ -570,7 +570,7 @@ public boolean isUserInRole(String role) { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() + * @see jakarta.servlet.http.HttpServletRequest#getUserPrincipal() */ @Override public Principal getUserPrincipal() { @@ -579,7 +579,7 @@ public Principal getUserPrincipal() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() + * @see jakarta.servlet.http.HttpServletRequest#getRequestedSessionId() */ @Override public String getRequestedSessionId() { @@ -588,7 +588,7 @@ public String getRequestedSessionId() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getRequestURI() + * @see jakarta.servlet.http.HttpServletRequest#getRequestURI() */ @Override public String getRequestURI() { @@ -597,7 +597,7 @@ public String getRequestURI() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getRequestURL() + * @see jakarta.servlet.http.HttpServletRequest#getRequestURL() */ @Override public StringBuffer getRequestURL() { @@ -609,7 +609,7 @@ public StringBuffer getRequestURL() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getServletPath() + * @see jakarta.servlet.http.HttpServletRequest#getServletPath() */ @Override public String getServletPath() { @@ -618,7 +618,7 @@ public String getServletPath() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getSession(boolean) + * @see jakarta.servlet.http.HttpServletRequest#getSession(boolean) */ @Override public HttpSession getSession(boolean create) { @@ -627,7 +627,7 @@ public HttpSession getSession(boolean create) { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getSession() + * @see jakarta.servlet.http.HttpServletRequest#getSession() */ @Override public HttpSession getSession() { @@ -636,7 +636,7 @@ public HttpSession getSession() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#changeSessionId() + * @see jakarta.servlet.http.HttpServletRequest#changeSessionId() */ @Override public String changeSessionId() { @@ -645,7 +645,7 @@ public String changeSessionId() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() + * @see jakarta.servlet.http.HttpServletRequest#isRequestedSessionIdValid() */ @Override public boolean isRequestedSessionIdValid() { @@ -654,7 +654,7 @@ public boolean isRequestedSessionIdValid() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() + * @see jakarta.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() */ @Override public boolean isRequestedSessionIdFromCookie() { @@ -663,7 +663,7 @@ public boolean isRequestedSessionIdFromCookie() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() + * @see jakarta.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() */ @Override public boolean isRequestedSessionIdFromURL() { @@ -672,16 +672,7 @@ public boolean isRequestedSessionIdFromURL() { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() - */ - @Override - public boolean isRequestedSessionIdFromUrl() { - return false; - } - - /* - * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#authenticate(javax.servlet.http.HttpServletResponse) + * @see jakarta.servlet.http.HttpServletRequest#authenticate(javax.servlet.http.HttpServletResponse) */ @Override public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { @@ -690,7 +681,7 @@ public boolean authenticate(HttpServletResponse response) throws IOException, Se /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#login(java.lang.String, java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#login(java.lang.String, java.lang.String) */ @Override public void login(String username, String password) throws ServletException { @@ -698,7 +689,7 @@ public void login(String username, String password) throws ServletException { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#logout() + * @see jakarta.servlet.http.HttpServletRequest#logout() */ @Override public void logout() throws ServletException { @@ -706,7 +697,7 @@ public void logout() throws ServletException { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getParts() + * @see jakarta.servlet.http.HttpServletRequest#getParts() */ @Override public Collection getParts() throws IOException, ServletException { @@ -715,7 +706,7 @@ public Collection getParts() throws IOException, ServletException { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getPart(java.lang.String) + * @see jakarta.servlet.http.HttpServletRequest#getPart(java.lang.String) */ @Override public Part getPart(String name) throws IOException, ServletException { @@ -724,7 +715,7 @@ public Part getPart(String name) throws IOException, ServletException { /* * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#upgrade(java.lang.Class) + * @see jakarta.servlet.http.HttpServletRequest#upgrade(java.lang.Class) */ @Override public T upgrade(Class handlerClass) throws IOException, ServletException { diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/controller/JavadocControllerTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/controller/JavadocControllerTest.java index c71d9aa..188d1ba 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/controller/JavadocControllerTest.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/controller/JavadocControllerTest.java @@ -3,10 +3,13 @@ import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit.jupiter.SpringExtension; import edu.kit.scc.dem.wapsrv.app.WapServerConfig; +import jakarta.servlet.http.HttpServletRequest; + /** * Tests the class JavadocController. This test is quite simple, as no own functionality beside @@ -41,12 +44,11 @@ final void testJavadocController() { final void testGetFileResponse() { WapServerConfig paramWapServerConfig = WapServerConfig.getInstance(); JavadocController actual = new JavadocController(paramWapServerConfig); - actual.getFileResponse(new HttpServletRequestAdapter() { - @Override - public StringBuffer getRequestURL() { - return new StringBuffer(paramWapServerConfig.getBaseUrl() + JavadocController.PATH); - } - }, null); // headers not used + HttpServletRequest mockRequest = Mockito.mock(HttpServletRequest.class); + Mockito.when(mockRequest.getRequestURL()).thenReturn( + new StringBuffer(paramWapServerConfig.getBaseUrl() + JavadocController.PATH) + ); + actual.getFileResponse(mockRequest, null); // headers not used } /** diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandlerTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandlerTest.java index 95745c3..0ae884f 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandlerTest.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/exceptions/WapResponseEntityExceptionHandlerTest.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; import java.util.Properties; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.http.ResponseEntity; diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/ApacheJenaTests.java b/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/ApacheJenaTests.java index f52c2d1..5d2c365 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/ApacheJenaTests.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/ApacheJenaTests.java @@ -115,7 +115,7 @@ public void jenaOutput() throws FileNotFoundException { res.addLiteral(DCTerms.created, "2018-06-5T00:23:00Z"); res = ResourceUtils.renameResource(res, "http://wapserver.dem.scc.kit.edu/tristrant/anno1"); } - RDFDataMgr.write(System.out, readModel, RDFFormat.JSONLD_COMPACT_PRETTY); + RDFDataMgr.write(System.out, readModel, RDFFormat.JSONLD_PRETTY); } /** diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/FusekiSparqlTests.java b/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/FusekiSparqlTests.java index 6ba0e86..5087f44 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/FusekiSparqlTests.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/testscommon/FusekiSparqlTests.java @@ -91,7 +91,7 @@ public void datasetReads() throws FileNotFoundException { Dataset ds = this.createDataset(); ds.begin(ReadWrite.READ); Resource model2 = ds.getDefaultModel().getResource("http://data.dem.scc.kit.edu/wap/persons/person1"); - RDFDataMgr.write(System.out, model2.getModel(), RDFFormat.JSONLD_COMPACT_PRETTY); + RDFDataMgr.write(System.out, model2.getModel(), RDFFormat.JSONLD_PRETTY); ds.end(); } From 4f321f6fbff219a666ad59dd1d31ae5741ebe91c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Mon, 5 May 2025 13:41:44 +0200 Subject: [PATCH 03/49] add jdk 21 to workflows --- .github/workflows/bootjar_testing.yml | 2 +- .github/workflows/gradle.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bootjar_testing.yml b/.github/workflows/bootjar_testing.yml index 380ac6a..5bec2ce 100644 --- a/.github/workflows/bootjar_testing.yml +++ b/.github/workflows/bootjar_testing.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - java: [17] + java: [17, 21] steps: - name: Checkout code diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 4c5c789..efa3943 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -19,7 +19,7 @@ jobs: matrix: operating-system: [ubuntu-latest, macOS-latest] # Use both LTS releases and latest one for tests - jdk: [ 17 ] + jdk: [ 17, 21 ] steps: - name: Checkout repo uses: actions/checkout@v4 From 33cf71016e5bf1736248382df3229212017e8933 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 12:19:31 +0000 Subject: [PATCH 04/49] Bump net.researchgate.release from 3.0.2 to 3.1.0 Bumps net.researchgate.release from 3.0.2 to 3.1.0. --- updated-dependencies: - dependency-name: net.researchgate.release dependency-version: 3.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ef1aad6..2f08530 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { id "com.github.kt3k.coveralls" version "2.12.0" id "org.owasp.dependencycheck" version "7.3.0" id 'org.asciidoctor.jvm.convert' version '3.3.2' - id "net.researchgate.release" version "3.0.2" + id "net.researchgate.release" version "3.1.0" id "com.gorylenko.gradle-git-properties" version "2.4.1" id 'java' id 'jacoco' From 786b20b8f3c9c0ff0129638c05cd7fcc26af86a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 12:19:37 +0000 Subject: [PATCH 05/49] Bump com.github.java-json-tools:json-schema-validator Bumps [com.github.java-json-tools:json-schema-validator](https://github.com/java-json-tools/json-schema-validator) from 2.2.8 to 2.2.14. - [Release notes](https://github.com/java-json-tools/json-schema-validator/releases) - [Changelog](https://github.com/java-json-tools/json-schema-validator/blob/master/RELEASE-NOTES.md) - [Commits](https://github.com/java-json-tools/json-schema-validator/compare/2.2.8...v2.2.14) --- updated-dependencies: - dependency-name: com.github.java-json-tools:json-schema-validator dependency-version: 2.2.14 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ef1aad6..66ef362 100644 --- a/build.gradle +++ b/build.gradle @@ -115,7 +115,7 @@ dependencies { implementation "org.apache.thrift:libthrift:0.18.1" implementation "org.apache.commons:commons-rdf-jsonld-java:0.5.0" - implementation "com.github.java-json-tools:json-schema-validator:2.2.8" + implementation "com.github.java-json-tools:json-schema-validator:2.2.14" implementation "org.apache.commons:commons-collections4:4.1" From 64716cd4b2e37c366b4e66cf269fd3b2f4742831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Fri, 13 Jun 2025 15:23:38 +0200 Subject: [PATCH 06/49] initialize next snapshot version --- gradle.properties | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8a4c5f4..57190bd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ systemProp.jdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" -version=1.1.0 +version=1.2.0-SNAPSHOT action.custom-1=allTests action.custom-1.args=--configure-on-demand -w -x check action.custom-2=release diff --git a/pom.xml b/pom.xml index a6ba7a3..82f51bf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ edu.kit.scc.dem.wapsrv wap-server - 1.1.0 + 1.2.0-SNAPSHOT jar WAP Server From d059efb6f4ff0d1a98a1de9fbb5ceced9c8f05e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 13:27:01 +0000 Subject: [PATCH 07/49] Bump io.spring.dependency-management from 1.1.0 to 1.1.7 Bumps [io.spring.dependency-management](https://github.com/spring-gradle-plugins/dependency-management-plugin) from 1.1.0 to 1.1.7. - [Release notes](https://github.com/spring-gradle-plugins/dependency-management-plugin/releases) - [Commits](https://github.com/spring-gradle-plugins/dependency-management-plugin/compare/v1.1.0...v1.1.7) --- updated-dependencies: - dependency-name: io.spring.dependency-management dependency-version: 1.1.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7b85458..8c3938d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "org.springframework.boot" version "3.4.5" - id "io.spring.dependency-management" version "1.1.4" + id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "6.5.1" id "com.github.kt3k.coveralls" version "2.12.0" id "org.owasp.dependencycheck" version "7.3.0" From f7d8092fd4ef1ac28ef343c2f185056aa39b7b08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 13:27:03 +0000 Subject: [PATCH 08/49] Bump com.nimbusds:nimbus-jose-jwt from 9.24.3 to 10.3 Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 9.24.3 to 10.3. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/10.3..9.24.3) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-version: '10.3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7b85458..99da1f5 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,7 @@ dependencies { //Keycloak // implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" - implementation 'com.nimbusds:nimbus-jose-jwt:9.37.2' + implementation 'com.nimbusds:nimbus-jose-jwt:10.3' implementation "io.jsonwebtoken:jjwt-api:0.11.5" implementation "io.jsonwebtoken:jjwt-impl:0.11.5" implementation "io.jsonwebtoken:jjwt-jackson:0.11.5" From 5276e6cd861d6897fb777089feb31c1599960674 Mon Sep 17 00:00:00 2001 From: GGoetzelmann <31686246+GGoetzelmann@users.noreply.github.com> Date: Fri, 13 Jun 2025 15:52:30 +0200 Subject: [PATCH 09/49] Minor workflow update Bump hurl action version might fix an issue using hurl on windows latest runner --- .github/workflows/bootjar_testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bootjar_testing.yml b/.github/workflows/bootjar_testing.yml index 9791bdf..e15d738 100644 --- a/.github/workflows/bootjar_testing.yml +++ b/.github/workflows/bootjar_testing.yml @@ -38,7 +38,7 @@ jobs: sleep 20 # Give the server time to start - name: hurl install - uses: gacts/install-hurl@v1 + uses: gacts/install-hurl@v1.3.0 - name: hurl CRUD tests (windows) if: runner.os == 'Windows' From 51685d49adbd345ad0bf9f98afc258feec5f6d78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:10:20 +0000 Subject: [PATCH 10/49] Bump io.specto:hoverfly-java-junit5 from 0.20.0 to 0.20.2 Bumps [io.specto:hoverfly-java-junit5](https://github.com/SpectoLabs/hoverfly-java) from 0.20.0 to 0.20.2. - [Commits](https://github.com/SpectoLabs/hoverfly-java/compare/0.20.0...0.20.2) --- updated-dependencies: - dependency-name: io.specto:hoverfly-java-junit5 dependency-version: 0.20.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f82e39b..db2b170 100644 --- a/build.gradle +++ b/build.gradle @@ -135,7 +135,7 @@ dependencies { testImplementation "io.rest-assured:rest-assured" testImplementation "io.rest-assured:spring-mock-mvc" testImplementation "io.rest-assured:rest-assured" - testImplementation ("io.specto:hoverfly-java-junit5:0.20.0") { + testImplementation ("io.specto:hoverfly-java-junit5:0.20.2") { exclude group: 'ch.qos.logback', module: 'logback-classic' } From a3b5e19fd8ad1e5989f351ff29469cdcf300d87c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:14:47 +0000 Subject: [PATCH 11/49] Bump org.springframework.boot from 3.4.5 to 3.5.0 Bumps [org.springframework.boot](https://github.com/spring-projects/spring-boot) from 3.4.5 to 3.5.0. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.5...v3.5.0) --- updated-dependencies: - dependency-name: org.springframework.boot dependency-version: 3.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f82e39b..23f2698 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.springframework.boot" version "3.4.5" + id "org.springframework.boot" version "3.5.0" id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "6.5.1" id "com.github.kt3k.coveralls" version "2.12.0" From 110a99f5485a2e38b4b31781d4dcac704c3d06ee Mon Sep 17 00:00:00 2001 From: GGoetzelmann <31686246+GGoetzelmann@users.noreply.github.com> Date: Mon, 23 Jun 2025 18:07:46 +0200 Subject: [PATCH 12/49] Workaround for hurl issue in github action --- .github/workflows/bootjar_testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bootjar_testing.yml b/.github/workflows/bootjar_testing.yml index e15d738..2c44cc9 100644 --- a/.github/workflows/bootjar_testing.yml +++ b/.github/workflows/bootjar_testing.yml @@ -39,7 +39,7 @@ jobs: - name: hurl install uses: gacts/install-hurl@v1.3.0 - + with: {disable-cache: true} # hurl installation sometimes fails on cache restore, trying to disable it as a workaround https://github.com/gacts/install-hurl/issues/93 - name: hurl CRUD tests (windows) if: runner.os == 'Windows' shell: bash From 029cdee7e5bb96493ffc8ccdef972c9f242f6512 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:15:35 +0000 Subject: [PATCH 13/49] Bump com.h2database:h2 from 2.2.220 to 2.3.232 Bumps [com.h2database:h2](https://github.com/h2database/h2database) from 2.2.220 to 2.3.232. - [Release notes](https://github.com/h2database/h2database/releases) - [Commits](https://github.com/h2database/h2database/compare/version-2.2.220...version-2.3.232) --- updated-dependencies: - dependency-name: com.h2database:h2 dependency-version: 2.3.232 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a2d0dd2..f835441 100644 --- a/build.gradle +++ b/build.gradle @@ -121,7 +121,7 @@ dependencies { // driver for postgres implementation 'org.postgresql:postgresql:42.7.2' //driver for h2 - implementation 'com.h2database:h2:2.2.220' + implementation 'com.h2database:h2:2.3.232' testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:3.0.3" testImplementation "org.springframework.boot:spring-boot-starter-test" From ce3a70ff26df952627ebb62fb854cf619466111e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:18:52 +0000 Subject: [PATCH 14/49] Bump io.freefair.maven-publish-java from 6.5.1 to 8.14 Bumps [io.freefair.maven-publish-java](https://github.com/freefair/gradle-plugins) from 6.5.1 to 8.14. - [Release notes](https://github.com/freefair/gradle-plugins/releases) - [Commits](https://github.com/freefair/gradle-plugins/compare/6.5.1...8.14) --- updated-dependencies: - dependency-name: io.freefair.maven-publish-java dependency-version: '8.14' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a2d0dd2..245fffc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id "org.springframework.boot" version "3.5.0" id "io.spring.dependency-management" version "1.1.7" - id "io.freefair.maven-publish-java" version "6.5.1" + id "io.freefair.maven-publish-java" version "8.14" id "com.github.kt3k.coveralls" version "2.12.0" id "org.owasp.dependencycheck" version "7.3.0" id 'org.asciidoctor.jvm.convert' version '3.3.2' From f4d4d769ad563192aae50216477103efaffec9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Tue, 24 Jun 2025 10:19:23 +0200 Subject: [PATCH 15/49] gradle linting --- build.gradle | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index f835441..fed7b56 100644 --- a/build.gradle +++ b/build.gradle @@ -7,12 +7,15 @@ plugins { id 'org.asciidoctor.jvm.convert' version '3.3.2' id "net.researchgate.release" version "3.1.0" id "com.gorylenko.gradle-git-properties" version "2.4.1" + id 'nebula.lint' version "20.6.2" id 'java' id 'jacoco' } apply plugin: 'project-report' +gradleLint.rules = ['all-dependency', 'unused-dependency'] + //make sure that git properties plugin does not fail on build without access to the git repo information (zip download etc.) gitProperties { failOnNoGitDirectory = false @@ -51,8 +54,10 @@ println "Running gradle version: $gradle.gradleVersion" println "Building ${name} version: ${version}" println "JDK version: ${JavaVersion.current()}" -sourceCompatibility = '17' -targetCompatibility = '17' +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} if (System.getProperty('profile') == 'minimal') { println 'Using minimal profile for building ' + project.getName() @@ -135,9 +140,7 @@ dependencies { testImplementation "io.rest-assured:rest-assured" testImplementation "io.rest-assured:spring-mock-mvc" testImplementation "io.rest-assured:rest-assured" - testImplementation ("io.specto:hoverfly-java-junit5:0.20.2") { - exclude group: 'ch.qos.logback', module: 'logback-classic' - } + testImplementation "io.specto:hoverfly-java-junit5:0.20.2" //Java 11 Support testImplementation "org.mockito:mockito-inline:4.10.0" From c07a52d93735a1800ca98cebfc66a9a389b49445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Tue, 24 Jun 2025 10:42:34 +0200 Subject: [PATCH 16/49] gradle linting --- build.gradle | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index fed7b56..7b0e1f9 100644 --- a/build.gradle +++ b/build.gradle @@ -38,13 +38,9 @@ configurations { } ext { - set('javersVersion', "6.8.0") set('jenaVersion', "5.4.0") - set('springBootVersion', "3.4.5") set('springDocVersion', "2.5.0") - set('keycloakVersion', "19.0.0") - set('junitPlatformVersion', "1.11.4") - set('junitJupiterVersion', "5.11.4") + //set('keycloakVersion', "19.0.0") // directory for generated code snippets during tests snippetsDir = file("build/generated-snippets") @@ -89,34 +85,31 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-mail" //implementation "org.springframework.boot:spring-boot-starter-actuator" - //implementation "org.springframework.security:spring-security-web:5.7.5" - //implementation "org.springframework.security:spring-security-config:5.7.5" - implementation "org.thymeleaf:thymeleaf-spring6" + //implementation "org.springframework.security:spring-security-web" + //implementation "org.springframework.security:spring-security-config" // cloud support - //implementation "org.springframework.cloud:spring-cloud-starter-config:3.1.5" - //implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:3.1.4" - // implementation "org.springframework.cloud:spring-cloud-gateway-mvc:3.1.4" - //implementation 'de.codecentric:spring-boot-admin-starter-client:2.7.10' + //implementation "org.springframework.cloud:spring-cloud-starter-config" + //implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client" + // implementation "org.springframework.cloud:spring-cloud-gateway-mvc" + //implementation 'de.codecentric:spring-boot-admin-starter-client' // springdoc implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springDocVersion}" //Keycloak // implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" - implementation 'com.nimbusds:nimbus-jose-jwt:10.3' - implementation "io.jsonwebtoken:jjwt-api:0.11.5" - implementation "io.jsonwebtoken:jjwt-impl:0.11.5" - implementation "io.jsonwebtoken:jjwt-jackson:0.11.5" + //implementation 'com.nimbusds:nimbus-jose-jwt:10.3' + //implementation "io.jsonwebtoken:jjwt-api:0.11.5" + //implementation "io.jsonwebtoken:jjwt-impl:0.11.5" + //implementation "io.jsonwebtoken:jjwt-jackson:0.11.5" //Jena implementation "org.apache.jena:apache-jena-libs:${jenaVersion}" implementation "org.apache.jena:jena-fuseki:${jenaVersion}" implementation "org.apache.jena:jena-fuseki-server:${jenaVersion}" - implementation "org.apache.jena:jena-commonsrdf:${jenaVersion}" - implementation "org.apache.thrift:libthrift:0.18.1" implementation "org.apache.commons:commons-rdf-jsonld-java:0.5.0" implementation "com.github.java-json-tools:json-schema-validator:2.2.14" @@ -124,21 +117,15 @@ dependencies { implementation "org.apache.commons:commons-collections4:4.1" // driver for postgres - implementation 'org.postgresql:postgresql:42.7.2' + runtimeOnly 'org.postgresql:postgresql:42.7.2' //driver for h2 - implementation 'com.h2database:h2:2.3.232' + runtimeOnly 'com.h2database:h2:2.3.232' - testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:3.0.3" testImplementation "org.springframework.boot:spring-boot-starter-test" testImplementation "org.springframework:spring-test" // testImplementation "org.springframework.security:spring-security-test" - testImplementation "org.junit.platform:junit-platform-launcher:${junitPlatformVersion}" - testImplementation "org.junit.platform:junit-platform-engine:${junitPlatformVersion}" - testImplementation "org.junit.jupiter:junit-jupiter-api:${junitJupiterVersion}" - testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}" testImplementation "io.rest-assured:rest-assured" - testImplementation "io.rest-assured:spring-mock-mvc" testImplementation "io.rest-assured:rest-assured" testImplementation "io.specto:hoverfly-java-junit5:0.20.2" From 58833f1ecf9c6ccd17005021389bab1343261e71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 08:43:57 +0000 Subject: [PATCH 17/49] Bump org.asciidoctor.jvm.convert from 3.3.2 to 4.0.4 Bumps org.asciidoctor.jvm.convert from 3.3.2 to 4.0.4. --- updated-dependencies: - dependency-name: org.asciidoctor.jvm.convert dependency-version: 4.0.4 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7b0e1f9..4dbe241 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { id "io.freefair.maven-publish-java" version "6.5.1" id "com.github.kt3k.coveralls" version "2.12.0" id "org.owasp.dependencycheck" version "7.3.0" - id 'org.asciidoctor.jvm.convert' version '3.3.2' + id 'org.asciidoctor.jvm.convert' version '4.0.4' id "net.researchgate.release" version "3.1.0" id "com.gorylenko.gradle-git-properties" version "2.4.1" id 'nebula.lint' version "20.6.2" From b866aa9a41417e15cdbb21d5b32e2c39ab72a1b4 Mon Sep 17 00:00:00 2001 From: GGoetzelmann <31686246+GGoetzelmann@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:56:08 +0200 Subject: [PATCH 18/49] github action: fail fast on gradle task --- .github/workflows/gradle.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 0ec9f7d..12ea00f 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -32,11 +32,11 @@ jobs: - name: Build with Gradle run: | if [ "$RUNNER_OS" == "Linux" ]; then - ./gradlew clean build + ./gradlew clean build test --fail-fast elif [ "$RUNNER_OS" == "macOS" ]; then - ./gradlew clean build + ./gradlew clean build test --fail-fast elif [ "$RUNNER_OS" == "Windows" ]; then - ./gradlew.bat clean build + ./gradlew.bat clean build test --fail-fast else echo "$RUNNER_OS not supported" exit 1 @@ -51,12 +51,12 @@ jobs: - name: Set up OpenJDK version ... uses: actions/setup-java@v2 with: - distribution: 'zulu' + distribution: 'temurin' java-version: ${{ env.currentBuildVersion }} - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle (JDK ${{ env.currentBuildVersion }}) - run: ./gradlew clean check jacocoTestReport + run: ./gradlew clean check jacocoTestReport test --fail-fast - name: Codecov uses: codecov/codecov-action@v1 with: From 05d7f8ae4e4357242bb49a29d1d1ac11eb2b234c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:00:51 +0000 Subject: [PATCH 19/49] Bump com.github.kt3k.coveralls from 2.12.0 to 2.12.2 Bumps com.github.kt3k.coveralls from 2.12.0 to 2.12.2. --- updated-dependencies: - dependency-name: com.github.kt3k.coveralls dependency-version: 2.12.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 905de0e..b9f817f 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id "org.springframework.boot" version "3.5.0" id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "8.14" - id "com.github.kt3k.coveralls" version "2.12.0" + id "com.github.kt3k.coveralls" version "2.12.2" id "org.owasp.dependencycheck" version "7.3.0" id 'org.asciidoctor.jvm.convert' version '4.0.4' id "net.researchgate.release" version "3.1.0" From ef6d014e160327d1473ebee1b45ca9ce83140aa3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:33:29 +0000 Subject: [PATCH 20/49] Bump org.owasp.dependencycheck from 7.3.0 to 12.1.3 Bumps org.owasp.dependencycheck from 7.3.0 to 12.1.3. --- updated-dependencies: - dependency-name: org.owasp.dependencycheck dependency-version: 12.1.3 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b9f817f..9e662ea 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "8.14" id "com.github.kt3k.coveralls" version "2.12.2" - id "org.owasp.dependencycheck" version "7.3.0" + id "org.owasp.dependencycheck" version "12.1.3" id 'org.asciidoctor.jvm.convert' version '4.0.4' id "net.researchgate.release" version "3.1.0" id "com.gorylenko.gradle-git-properties" version "2.4.1" From 2fde0981f4ae83c2bf1830730c7fc09629866f6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Aug 2025 06:49:36 +0000 Subject: [PATCH 21/49] Bump com.gorylenko.gradle-git-properties from 2.4.1 to 2.5.2 Bumps com.gorylenko.gradle-git-properties from 2.4.1 to 2.5.2. --- updated-dependencies: - dependency-name: com.gorylenko.gradle-git-properties dependency-version: 2.5.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9e662ea..0ff885c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id "org.owasp.dependencycheck" version "12.1.3" id 'org.asciidoctor.jvm.convert' version '4.0.4' id "net.researchgate.release" version "3.1.0" - id "com.gorylenko.gradle-git-properties" version "2.4.1" + id "com.gorylenko.gradle-git-properties" version "2.5.2" id 'nebula.lint' version "20.6.2" id 'java' id 'jacoco' From 9565a654354a36b9310011d8664ff6f886e8fad8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 21:38:53 +0000 Subject: [PATCH 22/49] Bump org.apache.commons:commons-collections4 from 4.1 to 4.5.0 Bumps org.apache.commons:commons-collections4 from 4.1 to 4.5.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-collections4 dependency-version: 4.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0ff885c..688fa85 100644 --- a/build.gradle +++ b/build.gradle @@ -114,7 +114,7 @@ dependencies { implementation "org.apache.commons:commons-rdf-jsonld-java:0.5.0" implementation "com.github.java-json-tools:json-schema-validator:2.2.14" - implementation "org.apache.commons:commons-collections4:4.1" + implementation "org.apache.commons:commons-collections4:4.5.0" // driver for postgres runtimeOnly 'org.postgresql:postgresql:42.7.2' From d51485b63873a5026262dff649c86f938444ad9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Thu, 21 Aug 2025 07:59:57 +0200 Subject: [PATCH 23/49] Adding repo metadata (now maintained via somesy) --- CITATION.cff | 43 +++ codemeta.json | 96 +++++++ pom.xml | 771 +++++++++++++++++++++++++++----------------------- somesy.toml | 68 +++++ 4 files changed, 621 insertions(+), 357 deletions(-) create mode 100644 CITATION.cff create mode 100644 codemeta.json create mode 100644 somesy.toml diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..6ea8eae --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,43 @@ +cff-version: 1.2.0 +message: If you use this software, please cite it using these metadata. +type: software +title: kitdatamanager/wap-server +abstract: This project contains a server for creating and managing annotations + based on the Web Annotation Data Model (WADM) implementing the complete Web + Annotation Protocol (WAP). The service is realized as microservice using + Spring Boot and can be operated standalone. +version: v1.2.0-SNAPSHOT +keywords: + - kit-data-manager + - metadata + - SPARQL + - RDF + - WADM + - Web Annotation + - jena-fuseki + - restful +authors: + - given-names: Germaine + orcid: https://orcid.org/0000-0003-3974-3728 + affiliation: Karlsruhe Institute of Technology (KIT) + family-names: Götzelmann + - given-names: Thomas + orcid: https://orcid.org/0000-0003-2804-688X + affiliation: Karlsruhe Institute of Technology (KIT) + family-names: Jejkal + - given-names: Danah + orcid: https://orcid.org/0000-0001-6296-7282 + affiliation: Karlsruhe Institute of Technology (KIT) + family-names: Tonne +contact: + - given-names: Germaine + orcid: https://orcid.org/0000-0003-3974-3728 + affiliation: Karlsruhe Institute of Technology (KIT) + family-names: Götzelmann + - given-names: Thomas + orcid: https://orcid.org/0000-0003-2804-688X + affiliation: Karlsruhe Institute of Technology (KIT) + family-names: Jejkal +license: Apache-2.0 +url: https://kit-data-manager.github.io/webpage/wap-server/ +repository-code: https://github.com/kit-data-manager/wap-server diff --git a/codemeta.json b/codemeta.json new file mode 100644 index 0000000..72c1d82 --- /dev/null +++ b/codemeta.json @@ -0,0 +1,96 @@ +{ + "@context": [ + "https://doi.org/10.5063/schema/codemeta-2.0", + "https://w3id.org/software-iodata", + "https://raw.githubusercontent.com/jantman/repostatus.org/master/badges/latest/ontology.jsonld", + "https://schema.org", + "https://w3id.org/software-types" + ], + "@type": "SoftwareSourceCode", + "author": [ + { + "@type": "Person", + "givenName": "Germaine", + "familyName": "Götzelmann", + "@id": "https://orcid.org/0000-0003-3974-3728", + "identifier": "https://orcid.org/0000-0003-3974-3728", + "affiliation": "Karlsruhe Institute of Technology (KIT)" + }, + { + "@type": "Person", + "givenName": "Thomas", + "familyName": "Jejkal", + "@id": "https://orcid.org/0000-0003-2804-688X", + "identifier": "https://orcid.org/0000-0003-2804-688X", + "affiliation": "Karlsruhe Institute of Technology (KIT)" + }, + { + "@type": "Person", + "givenName": "Danah", + "familyName": "Tonne", + "@id": "https://orcid.org/0000-0001-6296-7282", + "identifier": "https://orcid.org/0000-0001-6296-7282", + "affiliation": "Karlsruhe Institute of Technology (KIT)" + } + ], + "name": "kitdatamanager/wap-server", + "description": "This project contains a server for creating and managing annotations based on the Web Annotation Data Model (WADM) implementing the complete Web Annotation Protocol (WAP). The service is realized as microservice using Spring Boot and can be operated standalone.", + "version": "v1.2.0-SNAPSHOT", + "keywords": [ + "kit-data-manager", + "metadata", + "SPARQL", + "RDF", + "WADM", + "Web Annotation", + "jena-fuseki", + "restful" + ], + "maintainer": [ + { + "@type": "Person", + "givenName": "Germaine", + "familyName": "Götzelmann", + "@id": "https://orcid.org/0000-0003-3974-3728", + "identifier": "https://orcid.org/0000-0003-3974-3728", + "affiliation": "Karlsruhe Institute of Technology (KIT)" + }, + { + "@type": "Person", + "givenName": "Thomas", + "familyName": "Jejkal", + "@id": "https://orcid.org/0000-0003-2804-688X", + "identifier": "https://orcid.org/0000-0003-2804-688X", + "affiliation": "Karlsruhe Institute of Technology (KIT)" + } + ], + "license": [ + "https://spdx.org/licenses/Apache-2.0" + ], + "softwareHelp": "https://kit-data-manager.github.io/webpage/wap-server/", + "codeRepository": "https://github.com/kit-data-manager/wap-server", + "buildInstructions": "https://kit-data-manager.github.io/webpage/wap-server/", + "contributor": [ + { + "@type": "Person", + "givenName": "Andreas", + "familyName": "Löffler" + }, + { + "@type": "Person", + "givenName": "Michael", + "familyName": "Hitzker" + }, + { + "@type": "Person", + "givenName": "Markus", + "familyName": "Höfler" + }, + { + "@type": "Person", + "givenName": "Timo", + "familyName": "Schmidt" + } + ], + "url": "https://kit-data-manager.github.io/webpage/wap-server/" +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 82f51bf..1585d2f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,300 +1,291 @@ - - - 4.0.0 - - edu.kit.scc.dem.wapsrv - wap-server - 1.2.0-SNAPSHOT - jar - - WAP Server - Web Annotation Protocol Server - - - org.springframework.boot - spring-boot-starter-parent - 2.7.5 - - - - - UTF-8 - UTF-8 - 17 - - 1.2.0 - 5.2.0 - - - - - - central - https://repo1.maven.org/maven2 - - - jcenter-snapshots - jcenter - https://oss.jfrog.org/artifactory/oss-snapshot-local/ - - - - - - org.springframework.boot - spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-tomcat - - - - junit - junit - - - - - org.springframework - spring-aspects - - - org.springframework.boot - spring-boot-devtools - true - - - org.springframework.boot - spring-boot-starter-test - test - - - junit - junit - - - org.assertj - assertj-core - - - - org.mockito - mockito-core - - - - - org.springframework.boot - spring-boot-starter-jetty - - - org.springframework.boot - spring-boot-starter-data-rest - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - - org.apache.jena - apache-jena-libs - pom - 4.10.0 - - - org.thymeleaf - thymeleaf-spring5 - - - org.apache.jena - jena-commonsrdf - 4.10.0 - - - org.apache.commons - commons-rdf-jsonld-java - 0.5.0 - - - org.apache.jena - jena-fuseki-main - 4.10.0 - - - com.github.java-json-tools - json-schema-validator - 2.2.8 - - - - - - org.junit.platform - junit-platform-launcher - test - ${junit-platform.version} - - - org.junit.platform - junit-platform-engine - test - ${junit-platform.version} - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - io.rest-assured - rest-assured - test - - - io.rest-assured - spring-mock-mvc - test - - - - io.specto - hoverfly-java-junit5 - 0.17.1 - test - - - org.apache.commons - commons-collections4 - 4.1 - + + + 4.0.0 + edu.kit.scc.dem.wapsrv + wap-server + v1.2.0-SNAPSHOT + jar + kitdatamanager/wap-server + This project contains a server for creating and managing annotations based on the Web Annotation Data Model (WADM) implementing the complete Web Annotation Protocol (WAP). The service is realized as microservice using Spring Boot and can be operated standalone. + + org.springframework.boot + spring-boot-starter-parent + 2.7.5 + + + + + UTF-8 + UTF-8 + 17 + 1.2.0 + 5.2.0 + + + + central + https://repo1.maven.org/maven2 + + + jcenter-snapshots + jcenter + https://oss.jfrog.org/artifactory/oss-snapshot-local/ + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + junit + junit + + + + + org.springframework + spring-aspects + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + org.assertj + assertj-core + - - org.mockito - mockito-core - 2.23.4 - - - com.sun.xml.bind - jaxb-core - 2.3.0.1 - - - com.sun.xml.bind - jaxb-impl - 2.3.0.1 - - - javax.activation - activation - 1.1.1 - - - org.javassist - javassist - 3.23.1-GA - - - javax.xml.bind - jaxb-api - 2.3.1 - - - - com.h2database - h2 - 2.1.214 - - - - org.postgresql - postgresql - 42.5.0 - - - - - - + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.apache.jena + apache-jena-libs + pom + 4.10.0 + + + org.thymeleaf + thymeleaf-spring5 + + + org.apache.jena + jena-commonsrdf + 4.10.0 + + + org.apache.commons + commons-rdf-jsonld-java + 0.5.0 + + + org.apache.jena + jena-fuseki-main + 4.10.0 + + + com.github.java-json-tools + json-schema-validator + 2.2.8 + + + + org.junit.platform + junit-platform-launcher + test + ${junit-platform.version} + + + org.junit.platform + junit-platform-engine + test + ${junit-platform.version} + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + io.rest-assured + rest-assured + test + + + io.rest-assured + spring-mock-mvc + test + + + + io.specto + hoverfly-java-junit5 + 0.17.1 + test + + + org.apache.commons + commons-collections4 + 4.1 + + + + org.mockito + mockito-core + 2.23.4 + + + com.sun.xml.bind + jaxb-core + 2.3.0.1 + + + com.sun.xml.bind + jaxb-impl + 2.3.0.1 + + + javax.activation + activation + 1.1.1 + + + org.javassist + javassist + 3.23.1-GA + + + javax.xml.bind + jaxb-api + 2.3.1 + + + + com.h2database + h2 + 2.1.214 + + + + org.postgresql + postgresql + 42.5.0 + + + + + - - maven-surefire-plugin - 2.22.0 - - - org.junit.platform - junit-platform-surefire-provider - 1.3.2 - - - - - 1 - - optional:classpath:/test-config/ - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - generate-sources - - add-source - - - - src/installer/java - - - - - - - pl.project13.maven - git-commit-id-plugin - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - true - - - + 1 + + optional:classpath:/test-config/ + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-sources + + add-source + + + + src/installer/java + + + + + + + + pl.project13.maven + git-commit-id-plugin + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + true + + + - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - prepare-agent - - prepare-agent - - - - report - prepare-package - - report - - - - post-unit-test - test - - report - - - - **/**/*WapServerInstaller.java - - - target/jacoco.exec - - target/jacoco-ut - - - - - - - - . - - doc/**/*.* - webcontent/**/*.* - schemas/**/*.* - profiles/**/FRAME_*.* - - - - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - - - report - - - - - - + + org.jacoco + jacoco-maven-plugin + 0.8.7 + + + prepare-agent + + prepare-agent + + + + report + prepare-package + + report + + + + post-unit-test + test + + report + + + + **/**/*WapServerInstaller.java + + + target/jacoco.exec + + target/jacoco-ut + + + + + + + + . + + doc/**/*.* + webcontent/**/*.* + schemas/**/*.* + profiles/**/FRAME_*.* + + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.7 + + + + + report + + + + + + + + + https://orcid.org/0000-0003-3974-3728 + https://orcid.org/0000-0003-3974-3728 + Germaine Götzelmann + + + https://orcid.org/0000-0003-2804-688X + https://orcid.org/0000-0003-2804-688X + Thomas Jejkal + + + https://orcid.org/0000-0001-6296-7282 + https://orcid.org/0000-0001-6296-7282 + Danah Tonne + + + + + Apache-2.0 + repo + + + https://kit-data-manager.github.io/webpage/wap-server/ + + git repository + https://github.com/kit-data-manager/wap-server + + + + documentation site + https://kit-data-manager.github.io/webpage/wap-server/ + + + + + https://orcid.org/0000-0003-3974-3728 + https://orcid.org/0000-0003-3974-3728 + Germaine Götzelmann + + + https://orcid.org/0000-0003-2804-688X + https://orcid.org/0000-0003-2804-688X + Thomas Jejkal + + + https://orcid.org/0000-0001-6296-7282 + https://orcid.org/0000-0001-6296-7282 + Danah Tonne + + + Andreas Löffler + Andreas Löffler + + + Michael Hitzker + Michael Hitzker + + + Markus Höfler + Markus Höfler + + + Timo Schmidt + Timo Schmidt + + diff --git a/somesy.toml b/somesy.toml new file mode 100644 index 0000000..d034396 --- /dev/null +++ b/somesy.toml @@ -0,0 +1,68 @@ +# Change these settings according to your project +[project] +name = "kit-data-manager/wap-server" +version = "v1.2.0-SNAPSHOT" +description = "This project contains a server for creating and managing annotations based on the Web Annotation Data Model (WADM) implementing the complete Web Annotation Protocol (WAP). The service is realized as microservice using Spring Boot and can be operated standalone." + +license = "Apache-2.0" +keywords = [ + "kit-data-manager", + "metadata", + "SPARQL", + "RDF", + "WADM", + "Web Annotation", + "jena-fuseki", + "restful" +] +repository = "https://github.com/kit-data-manager/wap-server" +homepage = "https://kit-data-manager.github.io/webpage/wap-server/" +documentation = "https://kit-data-manager.github.io/webpage/wap-server/" + +[config] +verbose = true + +[[project.people]] +given-names = "Germaine" +family-names = "Götzelmann" +orcid = "https://orcid.org/0000-0003-3974-3728" +affiliation = "Karlsruhe Institute of Technology (KIT)" +author = true +maintainer = true +publication_author = true + +[[project.people]] +given-names = "Thomas" +family-names = "Jejkal" +orcid = "https://orcid.org/0000-0003-2804-688X" +affiliation = "Karlsruhe Institute of Technology (KIT)" +author = true +maintainer = true + +[[project.people]] +given-names = "Danah" +family-names = "Tonne" +orcid = "https://orcid.org/0000-0001-6296-7282" +affiliation = "Karlsruhe Institute of Technology (KIT)" +author = true +publication_author = true + +[[project.people]] +given-names = "Andreas" +family-names = "Löffler" +author = true + +[[project.people]] +given-names = "Michael" +family-names = "Hitzker" +author = true + +[[project.people]] +given-names = "Markus" +family-names = "Höfler" +author = true + +[[project.people]] +given-names = "Timo" +family-names = "Schmidt" +author = true From 344cb5f259c5571005b5ba78d46166ac0b6c309b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 02:31:06 +0000 Subject: [PATCH 24/49] Bump org.springframework.boot from 3.5.0 to 3.5.5 Bumps [org.springframework.boot](https://github.com/spring-projects/spring-boot) from 3.5.0 to 3.5.5. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.5.0...v3.5.5) --- updated-dependencies: - dependency-name: org.springframework.boot dependency-version: 3.5.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0ff885c..e0acb1c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.springframework.boot" version "3.5.0" + id "org.springframework.boot" version "3.5.5" id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "8.14" id "com.github.kt3k.coveralls" version "2.12.2" From 35bd8095d4c7f545d41aafc27162bf027da66db3 Mon Sep 17 00:00:00 2001 From: GGoetzelmann <31686246+GGoetzelmann@users.noreply.github.com> Date: Mon, 22 Sep 2025 14:40:45 +0200 Subject: [PATCH 25/49] Dependabot: set minimal package age to 3 days --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9dfac4e..76e97ac 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,5 @@ updates: target-branch: "development" schedule: interval: "weekly" + cooldown: + default-days: 3 From 4ebfa490e45106c34c310034f145f16c20e0e814 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 13:33:00 +0000 Subject: [PATCH 26/49] Bump org.owasp.dependencycheck from 12.1.3 to 12.1.5 Bumps org.owasp.dependencycheck from 12.1.3 to 12.1.5. --- updated-dependencies: - dependency-name: org.owasp.dependencycheck dependency-version: 12.1.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e0acb1c..ab5d7bb 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "8.14" id "com.github.kt3k.coveralls" version "2.12.2" - id "org.owasp.dependencycheck" version "12.1.3" + id "org.owasp.dependencycheck" version "12.1.5" id 'org.asciidoctor.jvm.convert' version '4.0.4' id "net.researchgate.release" version "3.1.0" id "com.gorylenko.gradle-git-properties" version "2.5.2" From 6be61cc8d0cbc40d7741ea7967b2c1a134199234 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:27:52 +0000 Subject: [PATCH 27/49] Bump org.postgresql:postgresql from 42.7.2 to 42.7.8 Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.7.2 to 42.7.8. - [Release notes](https://github.com/pgjdbc/pgjdbc/releases) - [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md) - [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.7.2...REL42.7.8) --- updated-dependencies: - dependency-name: org.postgresql:postgresql dependency-version: 42.7.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 801c92c..74c8005 100644 --- a/build.gradle +++ b/build.gradle @@ -117,7 +117,7 @@ dependencies { implementation "org.apache.commons:commons-collections4:4.5.0" // driver for postgres - runtimeOnly 'org.postgresql:postgresql:42.7.2' + runtimeOnly 'org.postgresql:postgresql:42.7.8' //driver for h2 runtimeOnly 'com.h2database:h2:2.3.232' From a4a753605a8ca50e927ed8b33192ea52773e9834 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:24:34 +0000 Subject: [PATCH 28/49] Bump org.springframework.boot from 3.5.5 to 3.5.7 Bumps [org.springframework.boot](https://github.com/spring-projects/spring-boot) from 3.5.5 to 3.5.7. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.5.5...v3.5.7) --- updated-dependencies: - dependency-name: org.springframework.boot dependency-version: 3.5.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 801c92c..b5675f1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.springframework.boot" version "3.5.5" + id "org.springframework.boot" version "3.5.7" id "io.spring.dependency-management" version "1.1.7" id "io.freefair.maven-publish-java" version "8.14" id "com.github.kt3k.coveralls" version "2.12.2" From 37743a1f0ed27b3448ea88a9c32fed91e5cb3489 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:32:45 +0000 Subject: [PATCH 29/49] Bump org.mockito:mockito-inline from 4.10.0 to 5.2.0 Bumps [org.mockito:mockito-inline](https://github.com/mockito/mockito) from 4.10.0 to 5.2.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.10.0...v5.2.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-inline dependency-version: 5.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b5675f1..5e2921e 100644 --- a/build.gradle +++ b/build.gradle @@ -130,7 +130,7 @@ dependencies { testImplementation "io.specto:hoverfly-java-junit5:0.20.2" //Java 11 Support - testImplementation "org.mockito:mockito-inline:4.10.0" + testImplementation "org.mockito:mockito-inline:5.2.0" //testImplementation "org.mockito:mockito-core:2.23.4" testImplementation "com.sun.xml.bind:jaxb-core:2.3.0.1" testImplementation "com.sun.xml.bind:jaxb-impl:2.3.0.1" From 0f199b56b2cea5afdd8bbcaca88ceaa204d6200c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:40:25 +0000 Subject: [PATCH 30/49] Create PR for #65 From f38302ef36b8602c0226425997cbb2f50ae70fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Mon, 3 Nov 2025 15:17:03 +0100 Subject: [PATCH 31/49] Test added for put with new via field --- .../testdata/annotations/example0.jsonld | 6 +++ .../wapsrv/testsrest/AnnotationRestTest.java | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/main/resources/testdata/annotations/example0.jsonld diff --git a/src/main/resources/testdata/annotations/example0.jsonld b/src/main/resources/testdata/annotations/example0.jsonld new file mode 100644 index 0000000..8dc51cd --- /dev/null +++ b/src/main/resources/testdata/annotations/example0.jsonld @@ -0,0 +1,6 @@ +{ + "@context": "http://www.w3.org/ns/anno.jsonld", + "type": "Annotation", + "body": "http://example.org/post1", + "target": "http://example.com/page1" +} diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/testsrest/AnnotationRestTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/testsrest/AnnotationRestTest.java index 29b7a2d..19b280d 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/testsrest/AnnotationRestTest.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/testsrest/AnnotationRestTest.java @@ -1127,6 +1127,58 @@ public void testPutAnnotationWithUnallowedChanges() { checkException(UnallowedPropertyChangeException.class, putResponse); } + /** + * Test put annotation with allowed changes. + * Via field and canonical field are not changeable but are allowed on PUT if they did not exist before + */ + @Test + public void testPutAnnotationWitAllowedChanges() { + String annotation = getAnnotation(0); // The one holds a canonical and a via value + assertNotNull(annotation, "Could not load example annotation"); + RequestSpecification request = RestAssured.given(); + request.contentType("application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\""); + request.accept("application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\""); + request.body(annotation); + Response response = postAnnotation(request); + assertNotNull(response, "Could not get response"); + assertEquals(AnnotationConstants.POST_ANNOTATION_SUCCESS_CODE, response.getStatusCode(), + "Annotation could not be created"); + final String annoInDb = response.getBody().asString(); + String etag = getEtag(response); + final String realId = getAnnotationId(response); + Response response2 = postAnnotation(request); + assertNotNull(response2, "Could not get response"); + assertEquals(AnnotationConstants.POST_ANNOTATION_SUCCESS_CODE, response2.getStatusCode(), + "Annotation could not be created"); + final String annoInDb2 = response2.getBody().asString(); + String etag2 = getEtag(response2); + final String realId2 = getAnnotationId(response2); + // post with a new via + String annoWithVia = annoInDb.replaceAll(Pattern.quote("\n}"), ",\n\"via\": \"http://newvia\"\n}"); + request = RestAssured.given(); + request.contentType("application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\""); + request.accept("application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\""); + request.header("If-Match", etag); + request.body(annoWithVia); + logger.trace("from : \n" + annoInDb + "\nto :\n" + annoWithVia); + Response putResponse = putAnnotation(request, realId); + assertNotNull(putResponse, "Could not get put response"); + assertEquals(AnnotationConstants.PUT_ANNOTATION_SUCCESS_CODE, putResponse.getStatusCode(), + "Annotation could not be updated."); + // post with a new canonical + String annoWithCanonical = annoInDb2.replaceAll(Pattern.quote("\n}"), ",\n\"canonical\": \"http://newcanon\"\n}"); + request = RestAssured.given(); + request.contentType("application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\""); + request.accept("application/ld+json;profile=\"http://www.w3.org/ns/anno.jsonld\""); + request.header("If-Match", etag2); + request.body(annoWithCanonical); + logger.trace("from : \n" + annoInDb2 + "\nto :\n" + annoWithCanonical); + putResponse = putAnnotation(request, realId2); + assertNotNull(putResponse, "Could not get put response"); + assertEquals(AnnotationConstants.PUT_ANNOTATION_SUCCESS_CODE, putResponse.getStatusCode(), + "Annotation could not be updated."); + } + /** * Test posting annotation with a series of multiple escaped characters. * @throws JSONException From 1c18d0d1430243c3792d5cebb94e7806712c9d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Mon, 3 Nov 2025 17:41:53 +0100 Subject: [PATCH 32/49] Put for annotations now checks existance of canonical and via field before comparing with new values Fixes #65 --- .../wapsrv/service/AnnotationServiceImpl.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/service/AnnotationServiceImpl.java b/src/main/java/edu/kit/scc/dem/wapsrv/service/AnnotationServiceImpl.java index db64153..5c85a62 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/service/AnnotationServiceImpl.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/service/AnnotationServiceImpl.java @@ -57,6 +57,20 @@ public class AnnotationServiceImpl extends AbstractWapService implements Annotat @Autowired private EtagFactory etagFactory; + /** + * Spec: WAP 5.3 Update an Existing Annotation + * + * @param iri + * The IRI of the annotation + * @param etag + * The ETag associated with the annotation state known to the client + * @param rawAnnotation + * A String representation of the Annotation + * @param format + * The data format used + * @return the updated annotation + * @throws WapException on error encountered during update + */ @Override public Annotation putAnnotation(final String iri, final String etag, String rawAnnotation, Format format) throws WapException{ @@ -82,12 +96,16 @@ public Annotation putAnnotation(final String iri, final String etag, String rawA if(!iri.equals(newAnnotation.getIriString())){ throw new UnallowedPropertyChangeException("The IRI cannot change with a PUT requests"); } + /** + * Servers SHOULD reject update requests that modify the values of the canonical or via properties, + * if they have been already set + */ // Check if no forbidden field has been changed canonical (there is only one) - if(!existingAnnotation.isPropertyEqual(newAnnotation, AnnoVocab.canonical)){ + if(existingAnnotation.hasProperty(AnnoVocab.canonical) && !existingAnnotation.isPropertyEqual(newAnnotation, AnnoVocab.canonical)){ throw new UnallowedPropertyChangeException("canonical property cannot change"); } // Check via (there may be more) - if(!existingAnnotation.isPropertyWithMultipleValuesEqual(newAnnotation, AnnoVocab.via)){ + if(existingAnnotation.hasProperty(AnnoVocab.via) && !existingAnnotation.isPropertyWithMultipleValuesEqual(newAnnotation, AnnoVocab.via)){ throw new UnallowedPropertyChangeException("via properties cannot change"); } String oldEtag = etag; From 2de2d39473ddc242b336633d4f7fe3ecd1135de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 20:12:57 +0100 Subject: [PATCH 33/49] allow for context path config --- .../edu/kit/scc/dem/wapsrv/app/WapServerConfig.java | 11 +++++++---- webcontent/ExampleData.js | 3 ++- webcontent/Main.js | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java index 7d49cb9..5760ee1 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java @@ -245,6 +245,9 @@ public class WapServerConfig extends WebMvcConfigurationSupport{ @Value("${RdfBackendImplementation:" + RDF_BACKEND_IMPLEMENTATION_DEFAULT + "}") private String rdfBackendImplementation; + @Value("${server.servlet.context-path:}") + private String contextPath; + /** * The cors configuration to use */ @@ -815,15 +818,15 @@ public boolean isRootWapUrl(String url){ public String getBaseUrl(){ if(enableHttps){ if(wapPort == 443){ - return "https://" + hostname; + return "https://" + hostname + contextPath; } else{ - return "https://" + hostname + ":" + wapPort; + return "https://" + hostname + ":" + wapPort + contextPath; } } else{ if(wapPort == 80){ - return "http://" + hostname; + return "http://" + hostname + contextPath; } else{ - return "http://" + hostname + ":" + wapPort; + return "http://" + hostname + ":" + wapPort + contextPath; } } } diff --git a/webcontent/ExampleData.js b/webcontent/ExampleData.js index be45f37..5445c5b 100644 --- a/webcontent/ExampleData.js +++ b/webcontent/ExampleData.js @@ -50,7 +50,8 @@ class ExampleData { } if (window.location.origin !== "null") { - callback.settings["url"] = window.location.origin + "/webapp/" + "resources/examples/" + filename; + let contextpath = !window.location.pathname.startsWith("/webapp") ? window.location.pathname.split("/webapp").at(0) : "" + callback.settings["url"] = window.location.origin + contextpath + "/webapp/" + "resources/examples/" + filename; } else { return false; } diff --git a/webcontent/Main.js b/webcontent/Main.js index 338fa10..4f820a5 100644 --- a/webcontent/Main.js +++ b/webcontent/Main.js @@ -55,7 +55,8 @@ class Main { this.initEventHandler(); //init value for targetUrl if (window.location.origin !== "null") { - $("#targetUrl").val(window.location.origin + "/wap/"); + let contextpath = !window.location.pathname.startsWith("/webapp") ? window.location.pathname.split("/webapp").at(0) : "" + $("#targetUrl").val(window.location.origin + contextpath + "/wap/"); } } From ea71cac07f0311118882e9291e206130a4673357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 20:13:41 +0100 Subject: [PATCH 34/49] allow setting WapBasePath (for proxy / docker) --- src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java index 5760ee1..02f573b 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java @@ -248,6 +248,9 @@ public class WapServerConfig extends WebMvcConfigurationSupport{ @Value("${server.servlet.context-path:}") private String contextPath; + @Value("${WapBasePath:#{null}}") + private String proxiedBasePath; + /** * The cors configuration to use */ @@ -816,6 +819,7 @@ public boolean isRootWapUrl(String url){ * @return The base url */ public String getBaseUrl(){ + if(proxiedBasePath != null) return proxiedBasePath; if(enableHttps){ if(wapPort == 443){ return "https://" + hostname + contextPath; From 3c649bc8268d6e9230d69c807f6a6ec641bca2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 20:14:04 +0100 Subject: [PATCH 35/49] config cleanup --- .../kit/scc/dem/wapsrv/app/ConfigurationKeys.java | 10 +++++++++- .../kit/scc/dem/wapsrv/app/WapServerConfig.java | 14 ++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/ConfigurationKeys.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/ConfigurationKeys.java index 224a37c..bcadab1 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/ConfigurationKeys.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/ConfigurationKeys.java @@ -111,5 +111,13 @@ public enum ConfigurationKeys { /** * @see WapServerConfig#fallbackValidation */ - FallbackValidation + FallbackValidation, + /** + * @see WapServerConfig#contextPath + */ + ContextPath, + /** + * @see WapServerConfig#proxiedBasePath + */ + ProxiedBasePath } diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java index 02f573b..bce3359 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java @@ -90,6 +90,8 @@ public class WapServerConfig extends WebMvcConfigurationSupport{ private static final String CORS_ALLOWED_ORIGINS_PATH_DEFAULT = "./cors_allowed_origins.conf"; private static final boolean FALLBACK_VALIDATION_DEFAULT = true; private static final String RDF_BACKEND_IMPLEMENTATION_DEFAULT = "jena"; + private static final String CONTEXT_PATH_DEFAULT = ""; + private static final String PROXYBASEPATH_DEFAULT = ""; /** * The single instance of the configuration @@ -245,10 +247,10 @@ public class WapServerConfig extends WebMvcConfigurationSupport{ @Value("${RdfBackendImplementation:" + RDF_BACKEND_IMPLEMENTATION_DEFAULT + "}") private String rdfBackendImplementation; - @Value("${server.servlet.context-path:}") - private String contextPath; + @Value("${server.servlet.context-path:" + CONTEXT_PATH_DEFAULT + "}") + private String contextPath = CONTEXT_PATH_DEFAULT; - @Value("${WapBasePath:#{null}}") + @Value("${WapBasePath:" + PROXYBASEPATH_DEFAULT + "}") private String proxiedBasePath; /** @@ -368,6 +370,8 @@ public static Properties getDefaultProperties(){ props.put(ConfigurationKeys.SimpleFormatters.toString(), SIMPLE_FORMATTERS_DEFAULT); props.put(ConfigurationKeys.CorsAllowedOriginsPath.toString(), CORS_ALLOWED_ORIGINS_PATH_DEFAULT); props.put(ConfigurationKeys.FallbackValidation.toString(), FALLBACK_VALIDATION_DEFAULT + ""); + props.put(ConfigurationKeys.ContextPath.toString(), CONTEXT_PATH_DEFAULT); + props.put(ConfigurationKeys.ProxiedBasePath.toString(), PROXYBASEPATH_DEFAULT); if(ConfigurationKeys.values().length != props.size()){ throw new RuntimeException("Default properties and the ConfigurationKeys enum not in sync"); } @@ -721,6 +725,8 @@ public void updateConfig(Properties props){ corsAllowedOriginsPath = getProperty(props, ConfigurationKeys.CorsAllowedOriginsPath, CORS_ALLOWED_ORIGINS_PATH_DEFAULT); fallbackValidation = getProperty(props, ConfigurationKeys.FallbackValidation, FALLBACK_VALIDATION_DEFAULT); + contextPath = getProperty(props, ConfigurationKeys.ContextPath, CONTEXT_PATH_DEFAULT); + proxiedBasePath = getProperty(props, ConfigurationKeys.ProxiedBasePath, PROXYBASEPATH_DEFAULT); } private String getProperty(Properties newProps, ConfigurationKeys key, String defaultValue){ @@ -819,7 +825,7 @@ public boolean isRootWapUrl(String url){ * @return The base url */ public String getBaseUrl(){ - if(proxiedBasePath != null) return proxiedBasePath; + if(proxiedBasePath != null && proxiedBasePath != "") return proxiedBasePath; if(enableHttps){ if(wapPort == 443){ return "https://" + hostname + contextPath; From bf3399cc23e5226627905ad032456e490f69ed5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 20:34:58 +0100 Subject: [PATCH 36/49] Test extended for context path and proxied path --- .../dem/wapsrv/app/WapServerConfigTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java index b546e84..251aa63 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java @@ -453,6 +453,24 @@ final void testGetBaseUrl() { assertNotNull(actual, "Could not get base url from WapServerConfig after setting wapPort == 443."); expected = "https://localhost"; assertEquals(expected, actual); + // test context path == context + paramProperties.setProperty(ConfigurationKeys.ContextPath.toString(), "/context"); + objWapServerConfig.updateConfig(paramProperties); + + actual = null; + actual = objWapServerConfig.getBaseUrl(); + assertNotNull(actual, "Could not get base url from WapServerConfig after setting context path."); + expected = "https://localhost/context"; + assertEquals(expected, actual); + // test WapBasePath = http://example.com + paramProperties.setProperty(ConfigurationKeys.ProxiedBasePath.toString(), "http://example.com"); + objWapServerConfig.updateConfig(paramProperties); + + actual = null; + actual = objWapServerConfig.getBaseUrl(); + assertNotNull(actual, "Could not get base url from WapServerConfig after setting WapBasePath."); + expected = "http://example.com"; + assertEquals(expected, actual); } /** From f63b115b44c5034ff1e752e9850c5c707d6cdeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 20:42:27 +0100 Subject: [PATCH 37/49] Documentation update for WapBasePath --- howtos/configuration.md | 2 ++ howtos/root_container.md | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/howtos/configuration.md b/howtos/configuration.md index 0ebb8dc..75009f0 100644 --- a/howtos/configuration.md +++ b/howtos/configuration.md @@ -30,3 +30,5 @@ absorb: true | MultipleAnnotationPost | Is posting multiple annotations in one request possible. | true | | WapPort | The port under which the WAP service is reachable. This port is used for HTTP and HTTPS service. When 80 is set and a http service is used, the port is omitted. The same applies to HTTPS and port 443. This setting has influence on the root IRI and cannot be changed after a database has been created. For details refer to the Root Container section. | 80 | | RdfBackendImplementation | The qualifier of the used RDF backend implementation. The default backend is 'jena'. | jena | +| WapBasePath | An override for the base URL. Only use to run behind proxy or in a container. | | + diff --git a/howtos/root_container.md b/howtos/root_container.md index db18484..72fbc3e 100644 --- a/howtos/root_container.md +++ b/howtos/root_container.md @@ -29,6 +29,10 @@ Example 4: Hostname=host1.example.org, EnableHttps=true, WapPort=443 When using the installer (via --install or by starting the jar in an empty folder) it asks for this base configuration and shows its consequences on the root container IRI. +All of the above can be overwritten by using the `WapBasePath` property. +This property is intended to be used only in scenarios where the server is reachable from a different URL +and if this should or must be reflected in the database (reverse proxy, docker container). + If changing any of those parameters with an already running server is necessary, a deletion of the database is needed. It gets recreated on first startup after the configuration has been changed. @@ -38,6 +42,6 @@ It gets recreated on first startup after the configuration has been changed. Using manual database manipulation, a conversion of the database to fit the new root container IRI can be achieved, but this is not implemented in the application. The easiest way to achieve this would be to have the database been backed up to NQUADS (which retains the named graphs) and then run a simple text replacement of old IRI ==> new IRI. -This has never been tested and should be regarded as a good starting point at best. +Also see [data migration guide](https://github.com/kit-data-manager/wap-server/wiki/Migrating-a-Server-Instance-and-its-Data) for details. --- \ No newline at end of file From 6e0a45719cac2ed04a7b7e231700ed9974557146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 20:45:08 +0100 Subject: [PATCH 38/49] WapBasePath renamed to WapBaseUrl --- howtos/configuration.md | 2 +- howtos/root_container.md | 2 +- src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java | 2 +- .../java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/howtos/configuration.md b/howtos/configuration.md index 75009f0..f58bc29 100644 --- a/howtos/configuration.md +++ b/howtos/configuration.md @@ -30,5 +30,5 @@ absorb: true | MultipleAnnotationPost | Is posting multiple annotations in one request possible. | true | | WapPort | The port under which the WAP service is reachable. This port is used for HTTP and HTTPS service. When 80 is set and a http service is used, the port is omitted. The same applies to HTTPS and port 443. This setting has influence on the root IRI and cannot be changed after a database has been created. For details refer to the Root Container section. | 80 | | RdfBackendImplementation | The qualifier of the used RDF backend implementation. The default backend is 'jena'. | jena | -| WapBasePath | An override for the base URL. Only use to run behind proxy or in a container. | | +| WapBaseUrl | An override for the base URL. Only use to run behind proxy or in a container. | | diff --git a/howtos/root_container.md b/howtos/root_container.md index 72fbc3e..75effa0 100644 --- a/howtos/root_container.md +++ b/howtos/root_container.md @@ -29,7 +29,7 @@ Example 4: Hostname=host1.example.org, EnableHttps=true, WapPort=443 When using the installer (via --install or by starting the jar in an empty folder) it asks for this base configuration and shows its consequences on the root container IRI. -All of the above can be overwritten by using the `WapBasePath` property. +All of the above can be overwritten by using the `WapBaseUrl` property. This property is intended to be used only in scenarios where the server is reachable from a different URL and if this should or must be reflected in the database (reverse proxy, docker container). diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java index bce3359..fd64016 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java @@ -250,7 +250,7 @@ public class WapServerConfig extends WebMvcConfigurationSupport{ @Value("${server.servlet.context-path:" + CONTEXT_PATH_DEFAULT + "}") private String contextPath = CONTEXT_PATH_DEFAULT; - @Value("${WapBasePath:" + PROXYBASEPATH_DEFAULT + "}") + @Value("${WapBaseUrl:" + PROXYBASEPATH_DEFAULT + "}") private String proxiedBasePath; /** diff --git a/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java index 251aa63..78f2c08 100644 --- a/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java +++ b/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java @@ -462,13 +462,13 @@ final void testGetBaseUrl() { assertNotNull(actual, "Could not get base url from WapServerConfig after setting context path."); expected = "https://localhost/context"; assertEquals(expected, actual); - // test WapBasePath = http://example.com + // test WapBaseUrl = http://example.com paramProperties.setProperty(ConfigurationKeys.ProxiedBasePath.toString(), "http://example.com"); objWapServerConfig.updateConfig(paramProperties); actual = null; actual = objWapServerConfig.getBaseUrl(); - assertNotNull(actual, "Could not get base url from WapServerConfig after setting WapBasePath."); + assertNotNull(actual, "Could not get base url from WapServerConfig after setting WapBaseUrl."); expected = "http://example.com"; assertEquals(expected, actual); } From 9f41b3aca218ba08e8b6377b015e9eba05c8dcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 21:03:09 +0100 Subject: [PATCH 39/49] make proxy base path check more robust --- src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java index fd64016..9cc002a 100644 --- a/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java +++ b/src/main/java/edu/kit/scc/dem/wapsrv/app/WapServerConfig.java @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.util.PathMatcher; +import org.springframework.util.StringUtils; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; @@ -825,7 +826,7 @@ public boolean isRootWapUrl(String url){ * @return The base url */ public String getBaseUrl(){ - if(proxiedBasePath != null && proxiedBasePath != "") return proxiedBasePath; + if(StringUtils.hasText(proxiedBasePath))return proxiedBasePath; if(enableHttps){ if(wapPort == 443){ return "https://" + hostname + contextPath; From 9af9eb4182be2219e4ade09afc3564d7d231b947 Mon Sep 17 00:00:00 2001 From: germaine Date: Fri, 17 Nov 2023 23:59:37 +0100 Subject: [PATCH 40/49] Starting dockerization. --- Dockerfile | 34 +++++++++++++++++++++++++++ build.sh | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Dockerfile create mode 100644 build.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b0343cd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM openjdk:17-bullseye + +ARG SERVER_NAME_DEFAULT=wapserver + +#This is the post that you want to use on the HOST machine, not in the container itself +ARG PORT_DEFAULT=8090 +ARG HOST_DEFAULT=localhost +ARG ROOT_DIRECTORY_DEFAULT=/spring + +# Install git as additional requirement +RUN apt-get -y update && \ + apt-get -y upgrade && \ + apt-get install -y --no-install-recommends git bash && \ + apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +ENV SERVICE_DIRECTORY=${ROOT_DIRECTORY_DEFAULT}/${SERVER_NAME_DEFAULT} +RUN mkdir -p /git +WORKDIR /git +COPY . . +# Build service in given directory +RUN echo $SERVICE_DIRECTORY +RUN bash ./build.sh $SERVICE_DIRECTORY + +#You can use this to set config variables or mount in an application.properties file +ENV SPRING_APPLICATION_JSON "{\"WapPort\": ${PORT_DEFAULT}, \"Hostname\": ${HOST_DEFAULT}}" + +EXPOSE ${PORT_DEFAULT} +WORKDIR $SERVICE_DIRECTORY +COPY ./profiles ./profiles/ +COPY ./schemas ./schemas/ +COPY ./webcontent ./webcontent/ +COPY ./doc ./doc/ +ENTRYPOINT ["/spring/wapserver/run.sh"] \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..bc180c2 --- /dev/null +++ b/build.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# Check no of parameters. +if [ "$#" -ne 1 ]; then + echo "Illegal number of parameters!" + usage +fi + +INSTALLATION_DIRECTORY=$1 +ACTUAL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +# Check if directory exists + if [ ! -d "$INSTALLATION_DIRECTORY" ]; then + # Create directory if it doesn't exists. + mkdir -p "$INSTALLATION_DIRECTORY" + if [ $? -ne 0 ]; then + echo "Error creating directory '$INSTALLATION_DIRECTORY'!" + echo "Please make sure that you have the correct access permissions for the specified directory." + exit 1 + fi + fi + # Check if directory is empty + if [ ! -z "$(ls -A "$INSTALLATION_DIRECTORY")" ]; then + echo "Directory '$INSTALLATION_DIRECTORY' is not empty!" + echo "Please enter an empty or a new directory!" + exit 1 + fi + # Convert variable of installation directory to an absolute path + cd "$INSTALLATION_DIRECTORY" + INSTALLATION_DIRECTORY=`pwd` + cd "$ACTUAL_DIR" + +APP_NAME=`./gradlew -q printProjectName` +APP_NAME=${APP_NAME##*$'\n'} +echo "$APP_NAME" + +echo Build service... +./gradlew -Dprofile=minimal clean build + +echo "Copy jar file to '$INSTALLATION_DIRECTORY'..." +find . -name "$APP_NAME.jar" -exec cp '{}' "$INSTALLATION_DIRECTORY" \; + +# Create run script +echo "$INSTALLATION_DIRECTORY" +cd "$INSTALLATION_DIRECTORY" + +# Determine name of jar file. +jarFile=(`ls $APP_NAME.jar`) + +java -jar $jarFile "--create-config" + +echo '#!/bin/sh' >> run.sh +echo 'pwd' >> run.sh +echo 'ls' >> run.sh +echo 'cat run.sh' >> run.sh +echo "################################################################################" >> run.sh +echo "# Define jar file" >> run.sh +echo "################################################################################" >> run.sh +echo jarFile=$jarFile >> run.sh +echo " " >> run.sh +echo "################################################################################" >> run.sh +echo "# Start micro service" >> run.sh +echo "################################################################################" >> run.sh +echo 'java -jar $jarFile' >> run.sh + +# make script executable +chmod 755 run.sh \ No newline at end of file From ccd83108040e2d9283f31fee69b4aef41fa96d54 Mon Sep 17 00:00:00 2001 From: germaine Date: Sat, 18 Nov 2023 01:34:46 +0100 Subject: [PATCH 41/49] Fixes on dockerfile --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b0343cd..ef1ece9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ ARG SERVER_NAME_DEFAULT=wapserver #This is the post that you want to use on the HOST machine, not in the container itself ARG PORT_DEFAULT=8090 +ARG SPARQ_DEFAULT=3330 ARG HOST_DEFAULT=localhost ARG ROOT_DIRECTORY_DEFAULT=/spring @@ -23,9 +24,10 @@ RUN echo $SERVICE_DIRECTORY RUN bash ./build.sh $SERVICE_DIRECTORY #You can use this to set config variables or mount in an application.properties file -ENV SPRING_APPLICATION_JSON "{\"WapPort\": ${PORT_DEFAULT}, \"Hostname\": ${HOST_DEFAULT}}" +ENV SPRING_APPLICATION_JSON "{\"WapPort\": ${PORT_DEFAULT}, \"Hostname\": \"${HOST_DEFAULT}\"}" EXPOSE ${PORT_DEFAULT} +EXPOSE ${SPARQL_DEFAULT} WORKDIR $SERVICE_DIRECTORY COPY ./profiles ./profiles/ COPY ./schemas ./schemas/ From 6a29c63af6264a18b2d8e35b7122ea5ba02b94b5 Mon Sep 17 00:00:00 2001 From: germaine Date: Tue, 19 Mar 2024 18:25:06 +0100 Subject: [PATCH 42/49] Moved Dockerfile to subfolder Updated base image added dockerignore file [skip ci] --- .dockerignore | 17 +++++++++++++++++ Dockerfile => docker/Dockerfile | 13 ++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 .dockerignore rename Dockerfile => docker/Dockerfile (86%) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2aceab5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +#git +.git +.gitattributes +.gitignore +.github/ +#IDE +.idea +#build +.gradle/ +build +#data +production_db +#misc +CHANGELOG +LICENSE +temp +docker diff --git a/Dockerfile b/docker/Dockerfile similarity index 86% rename from Dockerfile rename to docker/Dockerfile index ef1ece9..b2c0497 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,4 @@ -FROM openjdk:17-bullseye - +FROM eclipse-temurin:17-jdk ARG SERVER_NAME_DEFAULT=wapserver #This is the post that you want to use on the HOST machine, not in the container itself @@ -18,7 +17,7 @@ RUN apt-get -y update && \ ENV SERVICE_DIRECTORY=${ROOT_DIRECTORY_DEFAULT}/${SERVER_NAME_DEFAULT} RUN mkdir -p /git WORKDIR /git -COPY . . +COPY .. . # Build service in given directory RUN echo $SERVICE_DIRECTORY RUN bash ./build.sh $SERVICE_DIRECTORY @@ -29,8 +28,8 @@ ENV SPRING_APPLICATION_JSON "{\"WapPort\": ${PORT_DEFAULT}, \"Hostname\": \"${HO EXPOSE ${PORT_DEFAULT} EXPOSE ${SPARQL_DEFAULT} WORKDIR $SERVICE_DIRECTORY -COPY ./profiles ./profiles/ -COPY ./schemas ./schemas/ -COPY ./webcontent ./webcontent/ -COPY ./doc ./doc/ +COPY ../profiles ./profiles/ +COPY ../schemas ./schemas/ +COPY ../webcontent ./webcontent/ +COPY ../doc ./doc/ ENTRYPOINT ["/spring/wapserver/run.sh"] \ No newline at end of file From 8fe78d3c9840a58a139489f357e6ca48b7d67afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 19:20:10 +0100 Subject: [PATCH 43/49] align docker default port with application default port --- docker/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index b2c0497..84b0c56 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,8 +1,7 @@ FROM eclipse-temurin:17-jdk ARG SERVER_NAME_DEFAULT=wapserver -#This is the post that you want to use on the HOST machine, not in the container itself -ARG PORT_DEFAULT=8090 +ARG PORT_DEFAULT=8080 ARG SPARQ_DEFAULT=3330 ARG HOST_DEFAULT=localhost ARG ROOT_DIRECTORY_DEFAULT=/spring From a5e64a3915488dd5524ed0e71885a1ce4c893b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 21:26:24 +0100 Subject: [PATCH 44/49] Readme updated for docker usage --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3fa2585..29fb166 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,21 @@ This project contains a server for creating and managing annotations based on th the complete Web Annotation Protocol (WAP). The service is realized as microservice using Spring Boot and can be operated standalone. -## How to build +## How to build and use + +### Docker + +``` +docker build -f docker/Dockerfile -t wap-server . +``` + +To run the application at `http://localhost:`, use: + +``` +docker run -d -p :8080 -e WAPBASEPATH=http://localhost: wap-server +``` + +### From source To install the application from source, see [howtos](howtos/summary.md). From 7abc2fa41d3a17c7ef6bce9366ae482a28d946a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 21:33:04 +0100 Subject: [PATCH 45/49] Workflow for docker test (same as bootjar test) --- .github/workflows/docker_testing.yml | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/docker_testing.yml diff --git a/.github/workflows/docker_testing.yml b/.github/workflows/docker_testing.yml new file mode 100644 index 0000000..7bc9095 --- /dev/null +++ b/.github/workflows/docker_testing.yml @@ -0,0 +1,72 @@ +name: Build and Test Dockerized App + +on: + push: + pull_request: + branches: [ main, development ] + +jobs: + build-and-test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + java: [17, 21] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: ${{ matrix.java }} + + - name: Grant execute permission for Gradle wrapper (Unix) + if: runner.os != 'Windows' + run: chmod +x gradlew + + # Build Docker image instead of bootable JAR + - name: Build Docker image + run: | + docker build -f docker/Dockerfile -t wap-server:${{ matrix.os }}-${{ matrix.java }} . + + # Run Docker container (detached, expose port 8080) + - name: Run Docker container + run: | + docker run -d -p 8080:8080 --name wap-server \ + wap-server:${{ matrix.os }}-${{ matrix.java }} + sleep 100 # Give the server time to start + + - name: hurl install + uses: gacts/install-hurl@v1.3.0 + with: {disable-cache: true} + + - name: hurl CRUD tests (windows) + if: runner.os == 'Windows' + shell: bash + run: | + for file in ./integration_tests/CRUD/*.hurl; do + hurl --variable host=http://localhost:8080 --test "$file" --verbose --error-format=long --continue-on-error --report-html hurlreports + done + + - name: hurl tests (other) + if: runner.os != 'Windows' + run: hurl --variable host=http://localhost:8080 --test ./integration_tests/CRUD/*.hurl --verbose --error-format=long --continue-on-error --report-html hurlreports + + # Stop and clean up container + - name: Stop Docker container + if: always() + run: | + docker logs wap-server + docker stop wap-server + docker rm wap-server + + # Upload artifacts (optional: you may want to upload Docker logs instead of JARs) + - name: Upload Docker logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: docker_logs_jdk${{ matrix.java }}_${{ matrix.os }} + path: ./hurlreports From ae19dd9c58aaa39129b264759bfe812365de558c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 21:45:45 +0100 Subject: [PATCH 46/49] Workflow: check docker startup more transparently --- .github/workflows/docker_testing.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker_testing.yml b/.github/workflows/docker_testing.yml index 7bc9095..776904a 100644 --- a/.github/workflows/docker_testing.yml +++ b/.github/workflows/docker_testing.yml @@ -37,7 +37,21 @@ jobs: run: | docker run -d -p 8080:8080 --name wap-server \ wap-server:${{ matrix.os }}-${{ matrix.java }} - sleep 100 # Give the server time to start + echo "Wait for wap server to be healthy before proceeding to tests" + while true; do + docker ps -a + if ! docker ps | grep -q wap-server; then + echo "Docker container stopped unexpectedly. Aborting." + exit 1 + fi + if curl -f http://localhost:8080; then + echo "Service is running." + break + fi + echo "Waiting for the service to be ready..." + docker logs --tail 20 wap-server + sleep 5 + done - name: hurl install uses: gacts/install-hurl@v1.3.0 From e223141aa2960fdf9a0957f12145c30014d1c927 Mon Sep 17 00:00:00 2001 From: germaine Date: Fri, 5 Apr 2024 11:41:07 +0200 Subject: [PATCH 47/49] exclude linter from printProjectName task --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 8e45f92..66dbd63 100644 --- a/build.gradle +++ b/build.gradle @@ -188,3 +188,7 @@ tasks.register('printProjectName') { println "${project.name}" } } + +gradleLint { + skipForTask('printProjectName') +} From 724edc2d29c3dc1f0fa0c8fa49bb17f710c8e6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 22:43:05 +0100 Subject: [PATCH 48/49] workflow for docker publish --- .github/workflows/docker_publish.yml | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/docker_publish.yml diff --git a/.github/workflows/docker_publish.yml b/.github/workflows/docker_publish.yml new file mode 100644 index 0000000..5e6d616 --- /dev/null +++ b/.github/workflows/docker_publish.yml @@ -0,0 +1,54 @@ +name: Create and publish a Docker image + +# Configures this workflow to run every time a change is pushed to the branch called `release`. +on: + push: + branches: ['main'] + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./docker + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + + # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v3 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true \ No newline at end of file From 168a1c4e9dd2daed502c5b15b0faa8e5afd96807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germaine=20G=C3=B6tzelmann?= Date: Wed, 10 Dec 2025 23:03:38 +0100 Subject: [PATCH 49/49] changelog and version update --- CHANGELOG | 44 +++++++++++++++++++++++++++++++++++++++++++- gradle.properties | 2 +- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 464d835..ec05fc1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,7 +4,49 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [1.2.0] - 2025-12-11 +### Added +- Docker version +- configurable context path +- configurable proxy URL + +### Changed + +### Removed + +### Deprecated + +### Fixed +- PUT Annotation with added via field results in erronous HTTP 409 + +### Security + +### Full changelog + +* Bump dependencies by @GGoetzelmann in https://github.com/kit-data-manager/wap-server/pull/17 +* Bump com.github.java-json-tools:json-schema-validator from 2.2.8 to 2.2.14 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/29 +* Bump io.spring.dependency-management from 1.1.0 to 1.1.7 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/28 +* Bump net.researchgate.release from 3.0.2 to 3.1.0 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/26 +* Bump com.nimbusds:nimbus-jose-jwt from 9.24.3 to 10.3 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/25 +* Bump io.specto:hoverfly-java-junit5 from 0.20.0 to 0.20.2 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/30 +* Bump org.springframework.boot from 3.4.5 to 3.5.0 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/31 +* Bump com.h2database:h2 from 2.2.220 to 2.3.232 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/36 +* Bump org.asciidoctor.jvm.convert from 3.3.2 to 4.0.4 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/37 +* Bump io.freefair.maven-publish-java from 6.5.1 to 8.14 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/38 +* Bump com.github.kt3k.coveralls from 2.12.0 to 2.12.2 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/39 +* Bump org.owasp.dependencycheck from 7.3.0 to 12.1.3 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/44 +* Bump com.gorylenko.gradle-git-properties from 2.4.1 to 2.5.2 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/45 +* Bump org.springframework.boot from 3.5.0 to 3.5.5 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/51 +* Bump org.owasp.dependencycheck from 12.1.3 to 12.1.5 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/54 +* Bump org.apache.commons:commons-collections4 from 4.1 to 4.5.0 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/48 +* Bump org.springframework.boot from 3.5.5 to 3.5.7 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/63 +* PUT Annotation with added via field results in erronous HTTP 409 by @github-actions[bot] in https://github.com/kit-data-manager/wap-server/pull/66 +* Bump org.mockito:mockito-inline from 4.10.0 to 5.2.0 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/64 +* Bump org.postgresql:postgresql from 42.7.2 to 42.7.8 by @dependabot[bot] in https://github.com/kit-data-manager/wap-server/pull/58 +* Extend URL configuration options by @GGoetzelmann in https://github.com/kit-data-manager/wap-server/pull/69 +* Dockerization by @GGoetzelmann in https://github.com/kit-data-manager/wap-server/pull/70 + +**Full Changelog**: https://github.com/kit-data-manager/wap-server/compare/v1.1.0...v1.2.0 ## [1.1.0] - 2025-06-13 ### Added diff --git a/gradle.properties b/gradle.properties index 57190bd..bedd8ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ systemProp.jdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" -version=1.2.0-SNAPSHOT +version=1.2.0 action.custom-1=allTests action.custom-1.args=--configure-on-demand -w -x check action.custom-2=release