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/.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 diff --git a/.github/workflows/bootjar_testing.yml b/.github/workflows/bootjar_testing.yml index 2e99560..2c44cc9 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 @@ -38,8 +38,8 @@ jobs: sleep 20 # Give the server time to start - name: hurl install - uses: gacts/install-hurl@v1 - + 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 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 diff --git a/.github/workflows/docker_testing.yml b/.github/workflows/docker_testing.yml new file mode 100644 index 0000000..776904a --- /dev/null +++ b/.github/workflows/docker_testing.yml @@ -0,0 +1,86 @@ +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 }} + 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 + 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 diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 0b9acea..12ea00f 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -18,7 +18,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 @@ -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: 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/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/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). diff --git a/build.gradle b/build.gradle index ef1aad6..66dbd63 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,21 @@ plugins { - id "org.springframework.boot" version "2.7.5" - id "io.spring.dependency-management" version "1.1.0" - 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 "net.researchgate.release" version "3.0.2" - id "com.gorylenko.gradle-git-properties" version "2.4.1" + 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" + 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" + 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 @@ -35,12 +38,9 @@ configurations { } ext { - set('javersVersion', "6.8.0") - set('springBootVersion', "2.7.5") - set('springDocVersion', "1.6.9") - set('keycloakVersion', "19.0.0") - set('junitPlatformVersion', "1.2.0") - set('junitJupiterVersion', "5.2.0") + set('jenaVersion', "5.4.0") + set('springDocVersion', "2.5.0") + //set('keycloakVersion', "19.0.0") // directory for generated code snippets during tests snippetsDir = file("build/generated-snippets") @@ -50,8 +50,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() @@ -83,65 +85,52 @@ 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-spring5" + //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-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}" - implementation "com.nimbusds:nimbus-jose-jwt:9.24.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: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:jena-commonsrdf:4.10.0" - implementation "org.apache.thrift:libthrift:0.18.1" + 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.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" + implementation "org.apache.commons:commons-collections4:4.5.0" // driver for postgres - implementation "org.postgresql:postgresql:42.5.0" + runtimeOnly 'org.postgresql:postgresql:42.7.8' //driver for h2 - implementation "com.h2database:h2:2.1.214" + runtimeOnly 'com.h2database:h2:2.3.232' - testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:2.0.6.RELEASE" 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.17.1") { - 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" + 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" @@ -173,7 +162,7 @@ test { environment "spring.config.location", "classpath:/test-config/" } -tasks.withType(Test) { +tasks.withType(Test).configureEach { testLogging { events 'started', 'passed' } @@ -188,14 +177,18 @@ 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}" } } + +gradleLint { + skipForTask('printProjectName') +} 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 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/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..84b0c56 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,34 @@ +FROM eclipse-temurin:17-jdk +ARG SERVER_NAME_DEFAULT=wapserver + +ARG PORT_DEFAULT=8080 +ARG SPARQ_DEFAULT=3330 +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} +EXPOSE ${SPARQL_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/gradle.properties b/gradle.properties index 8a4c5f4..bedd8ee 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 action.custom-1=allTests action.custom-1.args=--configure-on-demand -w -x check action.custom-2=release 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 41d9927..943f0cb 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ 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/howtos/configuration.md b/howtos/configuration.md index 0ebb8dc..f58bc29 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 | +| 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 db18484..75effa0 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 `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). + 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 diff --git a/pom.xml b/pom.xml index a6ba7a3..1585d2f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,300 +1,291 @@ - - - 4.0.0 - - edu.kit.scc.dem.wapsrv - wap-server - 1.1.0 - 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 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/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 f1a64c0..09a3261 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.apache.jena.tdb2.TDB2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -151,7 +151,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..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 @@ -7,12 +7,13 @@ 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; 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; @@ -90,6 +91,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,6 +248,12 @@ public class WapServerConfig extends WebMvcConfigurationSupport{ @Value("${RdfBackendImplementation:" + RDF_BACKEND_IMPLEMENTATION_DEFAULT + "}") private String rdfBackendImplementation; + @Value("${server.servlet.context-path:" + CONTEXT_PATH_DEFAULT + "}") + private String contextPath = CONTEXT_PATH_DEFAULT; + + @Value("${WapBaseUrl:" + PROXYBASEPATH_DEFAULT + "}") + private String proxiedBasePath; + /** * The cors configuration to use */ @@ -362,6 +371,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"); } @@ -715,6 +726,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){ @@ -813,17 +826,18 @@ public boolean isRootWapUrl(String url){ * @return The base url */ public String getBaseUrl(){ + if(StringUtils.hasText(proxiedBasePath))return proxiedBasePath; 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/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/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; 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/app/WapServerConfigTest.java b/src/test/java/edu/kit/scc/dem/wapsrv/app/WapServerConfigTest.java index b546e84..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 @@ -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 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 WapBaseUrl."); + expected = "http://example.com"; + assertEquals(expected, actual); } /** 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(); } 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 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/"); } }