From e1044c68b26a10ac71b092dd15883dce305d32a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 22:52:41 +0000 Subject: [PATCH 01/80] Update plugin com.gradle.enterprise to v3.19.1 --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 8b2ea627..9d5114dd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ plugins { - id "com.gradle.enterprise" version "3.19" + id "com.gradle.enterprise" version "3.19.1" } //gradleEnterprise { From ada458e74d54fbc3c52ea37f1bb00f6720998f7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 22:52:45 +0000 Subject: [PATCH 02/80] Update plugin org.springframework.boot to v3.4.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5c1cfeae..49791283 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.boot' version '3.4.1' + id 'org.springframework.boot' version '3.4.2' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' id 'io.freefair.maven-publish-java' version '8.11' From 4e51b3a3cd2481ab63a53a7ac253cb0d0ebfee49 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:11:41 +0000 Subject: [PATCH 03/80] Update plugin io.freefair.lombok to v8.12 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5c1cfeae..5009dc1c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id "org.owasp.dependencycheck" version "12.0.1" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.4.2" - id 'io.freefair.lombok' version '8.11' + id 'io.freefair.lombok' version '8.12' id 'java' id 'jacoco' } From 0d5d600daca08fdc521ea296826fb4d0876a170e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:11:45 +0000 Subject: [PATCH 04/80] Update plugin io.freefair.maven-publish-java to v8.12 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5c1cfeae..c6e5d440 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'org.springframework.boot' version '3.4.1' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' - id 'io.freefair.maven-publish-java' version '8.11' + id 'io.freefair.maven-publish-java' version '8.12' id "org.owasp.dependencycheck" version "12.0.1" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.4.2" From f843b62d9f85f8e4bc73d2de09cfa415f30066fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 17:25:35 +0000 Subject: [PATCH 05/80] Update dependency gradle to v8.12.1 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cea7a793..e18bc253 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 1defea29436ac5b990f2896d3d7ff1f933e2055d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 Jan 2025 20:27:19 +0000 Subject: [PATCH 06/80] Update springDocVersion to v2.8.4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5c1cfeae..f74cc65a 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ ext { pythonExecutable = System.getProperty('pythonExecutable', 'file:///usr/bin/python') userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") - set('springDocVersion', "2.8.3") + set('springDocVersion', "2.8.4") set('javersVersion', "7.7.0") set('keycloakVersion', "19.0.0") } From b82eea69319f508f7ae1dca182aa8d7258edfce5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:50:37 +0000 Subject: [PATCH 07/80] Update plugin io.freefair.lombok to v8.12.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ce0f2ea..be484692 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id "org.owasp.dependencycheck" version "12.0.1" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.4.2" - id 'io.freefair.lombok' version '8.12' + id 'io.freefair.lombok' version '8.12.1' id 'java' id 'jacoco' } From 39c2e29a8c2bf6e7cb042e7ea6fa6ead6fa9c6d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:50:42 +0000 Subject: [PATCH 08/80] Update plugin io.freefair.maven-publish-java to v8.12.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ce0f2ea..43084c03 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'org.springframework.boot' version '3.4.2' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' - id 'io.freefair.maven-publish-java' version '8.12' + id 'io.freefair.maven-publish-java' version '8.12.1' id "org.owasp.dependencycheck" version "12.0.1" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.4.2" From 9c6209fbe7265bd050afdcc9f2e677444a1aca1b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 01:19:54 +0000 Subject: [PATCH 09/80] Update dependency org.apache.tika:tika-core to v2.9.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ce0f2ea..f3272f64 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ dependencies { implementation 'javax.validation:validation-api:2.0.1.Final' implementation 'edu.kit.datamanager:service-base:1.3.3' // apache - implementation "org.apache.tika:tika-core:2.9.2" + implementation "org.apache.tika:tika-core:2.9.3" testImplementation platform('org.junit:junit-bom') testImplementation 'org.junit.jupiter:junit-jupiter' From 54561417c3f76263b09d912dbc5678ddda6d1450 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 11:06:40 +0000 Subject: [PATCH 10/80] Update dependency net.bytebuddy:byte-buddy to v1.17.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ce0f2ea..ab89e0f2 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { testImplementation 'org.mockito:mockito-core:5.15.2' testImplementation 'org.powermock:powermock-module-junit4:2.0.9' testImplementation 'org.powermock:powermock-api-mockito2:2.0.9' - testImplementation 'net.bytebuddy:byte-buddy:1.16.1' + testImplementation 'net.bytebuddy:byte-buddy:1.17.1' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' From 01e3d8fdf206276fc8b76fd29eb1d80c9bd808c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 16 Feb 2025 18:36:05 +0000 Subject: [PATCH 11/80] Update dependency org.javers:javers-spring-boot-starter-sql to v7.8.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2ce0f2ea..ce5e4686 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ ext { userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") set('springDocVersion', "2.8.4") - set('javersVersion', "7.7.0") + set('javersVersion', "7.8.0") set('keycloakVersion', "19.0.0") } From 1b06abbb80eab05b3f3a42596dc359e63939641b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:52:17 +0000 Subject: [PATCH 12/80] Update plugin com.gradle.enterprise to v3.19.2 --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 9d5114dd..cfb1341a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ plugins { - id "com.gradle.enterprise" version "3.19.1" + id "com.gradle.enterprise" version "3.19.2" } //gradleEnterprise { From 77b15f197a88d8264c3fa0074ce3b8781b95c672 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:20:42 +0000 Subject: [PATCH 13/80] Update springDocVersion to v2.8.5 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ce5e4686..b1cf2dbf 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ ext { pythonExecutable = System.getProperty('pythonExecutable', 'file:///usr/bin/python') userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") - set('springDocVersion', "2.8.4") + set('springDocVersion', "2.8.5") set('javersVersion', "7.8.0") set('keycloakVersion', "19.0.0") } From ba1610869524dc393e10517778ba3789d8ed02d6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:21:11 +0000 Subject: [PATCH 14/80] Update plugin org.owasp.dependencycheck to v12.1.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a1bd8f7d..406d0f23 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' id 'io.freefair.maven-publish-java' version '8.12.1' - id "org.owasp.dependencycheck" version "12.0.1" + id "org.owasp.dependencycheck" version "12.1.0" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.4.2" id 'io.freefair.lombok' version '8.12' From 5f99a1409b551e2a5cefcf645e8c84df09282e89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:46:44 +0000 Subject: [PATCH 15/80] Update plugin org.springframework.boot to v3.4.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b694adc5..741b60c6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.boot' version '3.4.2' + id 'org.springframework.boot' version '3.4.3' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' id 'io.freefair.maven-publish-java' version '8.12.1' From c79a719f2131390681580eb28a54bdca75576bb1 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Tue, 25 Feb 2025 12:25:55 +0100 Subject: [PATCH 16/80] Leaving plugins out of boot jar, removed duplicated gradle task, removed generated docs --- build.gradle | 14 ++++---- custom/map-valid-document/curl-request.adoc | 7 ---- custom/map-valid-document/http-request.adoc | 34 ------------------ custom/map-valid-document/http-response.adoc | 8 ----- custom/map-valid-document/httpie-request.adoc | 6 ---- custom/map-valid-document/request-body.adoc | 4 --- custom/map-valid-document/response-body.adoc | 4 --- custom/map-with-invalid-id/curl-request.adoc | 7 ---- custom/map-with-invalid-id/http-request.adoc | 34 ------------------ custom/map-with-invalid-id/http-response.adoc | 8 ----- .../map-with-invalid-id/httpie-request.adoc | 6 ---- custom/map-with-invalid-id/request-body.adoc | 4 --- custom/map-with-invalid-id/response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 8 ----- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- custom/map-without-document/curl-request.adoc | 7 ---- custom/map-without-document/http-request.adoc | 34 ------------------ .../map-without-document/http-response.adoc | 8 ----- .../map-without-document/httpie-request.adoc | 6 ---- custom/map-without-document/request-body.adoc | 4 --- .../map-without-document/response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 6 ---- .../http-request.adoc | 13 ------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 6 ---- .../http-request.adoc | 29 --------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- .../curl-request.adoc | 7 ---- .../http-request.adoc | 18 ---------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- custom/test-create-mapping/curl-request.adoc | 7 ---- custom/test-create-mapping/http-request.adoc | 34 ------------------ custom/test-create-mapping/http-response.adoc | 29 --------------- .../test-create-mapping/httpie-request.adoc | 6 ---- custom/test-create-mapping/request-body.adoc | 4 --- custom/test-create-mapping/response-body.adoc | 24 ------------- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- custom/test-delete-mapping/curl-request.adoc | 5 --- custom/test-delete-mapping/http-request.adoc | 7 ---- custom/test-delete-mapping/http-response.adoc | 5 --- .../test-delete-mapping/httpie-request.adoc | 5 --- custom/test-delete-mapping/request-body.adoc | 4 --- custom/test-delete-mapping/response-body.adoc | 4 --- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../test-get-mapping-by-id/curl-request.adoc | 5 --- .../test-get-mapping-by-id/http-request.adoc | 7 ---- .../test-get-mapping-by-id/http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../test-get-mapping-by-id/request-body.adoc | 4 --- .../test-get-mapping-by-id/response-body.adoc | 24 ------------- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 5 --- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 26 -------------- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 20 ----------- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 26 -------------- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 20 ----------- .../curl-request.adoc | 8 ----- .../http-request.adoc | 36 ------------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 7 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 8 ----- .../http-request.adoc | 36 ------------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 7 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 26 -------------- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 20 ----------- .../curl-request.adoc | 7 ---- .../http-request.adoc | 35 ------------------ .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 31 ---------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- custom/test-update-mapping/curl-request.adoc | 4 --- custom/test-update-mapping/http-request.adoc | 6 ---- custom/test-update-mapping/http-response.adoc | 26 -------------- .../test-update-mapping/httpie-request.adoc | 4 --- custom/test-update-mapping/request-body.adoc | 4 --- custom/test-update-mapping/response-body.adoc | 20 ----------- .../plugins/impl/IdentifyPlugin.java | 4 +-- .../{TestPlugin.java => InOutPlugin.java} | 14 ++++---- 165 files changed, 15 insertions(+), 1646 deletions(-) delete mode 100644 custom/map-valid-document/curl-request.adoc delete mode 100644 custom/map-valid-document/http-request.adoc delete mode 100644 custom/map-valid-document/http-response.adoc delete mode 100644 custom/map-valid-document/httpie-request.adoc delete mode 100644 custom/map-valid-document/request-body.adoc delete mode 100644 custom/map-valid-document/response-body.adoc delete mode 100644 custom/map-with-invalid-id/curl-request.adoc delete mode 100644 custom/map-with-invalid-id/http-request.adoc delete mode 100644 custom/map-with-invalid-id/http-response.adoc delete mode 100644 custom/map-with-invalid-id/httpie-request.adoc delete mode 100644 custom/map-with-invalid-id/request-body.adoc delete mode 100644 custom/map-with-invalid-id/response-body.adoc delete mode 100644 custom/map-with-missing-parameters/curl-request.adoc delete mode 100644 custom/map-with-missing-parameters/http-request.adoc delete mode 100644 custom/map-with-missing-parameters/http-response.adoc delete mode 100644 custom/map-with-missing-parameters/httpie-request.adoc delete mode 100644 custom/map-with-missing-parameters/request-body.adoc delete mode 100644 custom/map-with-missing-parameters/response-body.adoc delete mode 100644 custom/map-without-document/curl-request.adoc delete mode 100644 custom/map-without-document/http-request.adoc delete mode 100644 custom/map-without-document/http-response.adoc delete mode 100644 custom/map-without-document/httpie-request.adoc delete mode 100644 custom/map-without-document/request-body.adoc delete mode 100644 custom/map-without-document/response-body.adoc delete mode 100644 custom/test-create-mapping-empty-record/curl-request.adoc delete mode 100644 custom/test-create-mapping-empty-record/http-request.adoc delete mode 100644 custom/test-create-mapping-empty-record/http-response.adoc delete mode 100644 custom/test-create-mapping-empty-record/httpie-request.adoc delete mode 100644 custom/test-create-mapping-empty-record/request-body.adoc delete mode 100644 custom/test-create-mapping-empty-record/response-body.adoc delete mode 100644 custom/test-create-mapping-no-mapping/curl-request.adoc delete mode 100644 custom/test-create-mapping-no-mapping/http-request.adoc delete mode 100644 custom/test-create-mapping-no-mapping/http-response.adoc delete mode 100644 custom/test-create-mapping-no-mapping/httpie-request.adoc delete mode 100644 custom/test-create-mapping-no-mapping/request-body.adoc delete mode 100644 custom/test-create-mapping-no-mapping/response-body.adoc delete mode 100644 custom/test-create-mapping-no-record/curl-request.adoc delete mode 100644 custom/test-create-mapping-no-record/http-request.adoc delete mode 100644 custom/test-create-mapping-no-record/http-response.adoc delete mode 100644 custom/test-create-mapping-no-record/httpie-request.adoc delete mode 100644 custom/test-create-mapping-no-record/request-body.adoc delete mode 100644 custom/test-create-mapping-no-record/response-body.adoc delete mode 100644 custom/test-create-mapping-twice/curl-request.adoc delete mode 100644 custom/test-create-mapping-twice/http-request.adoc delete mode 100644 custom/test-create-mapping-twice/http-response.adoc delete mode 100644 custom/test-create-mapping-twice/httpie-request.adoc delete mode 100644 custom/test-create-mapping-twice/request-body.adoc delete mode 100644 custom/test-create-mapping-twice/response-body.adoc delete mode 100644 custom/test-create-mapping-with-acl/curl-request.adoc delete mode 100644 custom/test-create-mapping-with-acl/http-request.adoc delete mode 100644 custom/test-create-mapping-with-acl/http-response.adoc delete mode 100644 custom/test-create-mapping-with-acl/httpie-request.adoc delete mode 100644 custom/test-create-mapping-with-acl/request-body.adoc delete mode 100644 custom/test-create-mapping-with-acl/response-body.adoc delete mode 100644 custom/test-create-mapping-wrong-record/curl-request.adoc delete mode 100644 custom/test-create-mapping-wrong-record/http-request.adoc delete mode 100644 custom/test-create-mapping-wrong-record/http-response.adoc delete mode 100644 custom/test-create-mapping-wrong-record/httpie-request.adoc delete mode 100644 custom/test-create-mapping-wrong-record/request-body.adoc delete mode 100644 custom/test-create-mapping-wrong-record/response-body.adoc delete mode 100644 custom/test-create-mapping/curl-request.adoc delete mode 100644 custom/test-create-mapping/http-request.adoc delete mode 100644 custom/test-create-mapping/http-response.adoc delete mode 100644 custom/test-create-mapping/httpie-request.adoc delete mode 100644 custom/test-create-mapping/request-body.adoc delete mode 100644 custom/test-create-mapping/response-body.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/curl-request.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/http-request.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/http-response.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/httpie-request.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/request-body.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/response-body.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/http-request.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/http-response.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/request-body.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/response-body.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/curl-request.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/http-request.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/http-response.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/httpie-request.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/request-body.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/response-body.adoc delete mode 100644 custom/test-delete-mapping/curl-request.adoc delete mode 100644 custom/test-delete-mapping/http-request.adoc delete mode 100644 custom/test-delete-mapping/http-response.adoc delete mode 100644 custom/test-delete-mapping/httpie-request.adoc delete mode 100644 custom/test-delete-mapping/request-body.adoc delete mode 100644 custom/test-delete-mapping/response-body.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc delete mode 100644 custom/test-get-mapping-by-id/curl-request.adoc delete mode 100644 custom/test-get-mapping-by-id/http-request.adoc delete mode 100644 custom/test-get-mapping-by-id/http-response.adoc delete mode 100644 custom/test-get-mapping-by-id/httpie-request.adoc delete mode 100644 custom/test-get-mapping-by-id/request-body.adoc delete mode 100644 custom/test-get-mapping-by-id/response-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id/curl-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id/http-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id/http-response.adoc delete mode 100644 custom/test-get-mapping-document-by-id/httpie-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id/request-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id/response-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/http-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/http-response.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/request-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/response-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/http-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/http-response.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/request-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/response-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/http-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/http-response.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/request-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/response-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/http-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/http-response.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/request-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/response-body.adoc delete mode 100644 custom/test-update-mapping-without-document/curl-request.adoc delete mode 100644 custom/test-update-mapping-without-document/http-request.adoc delete mode 100644 custom/test-update-mapping-without-document/http-response.adoc delete mode 100644 custom/test-update-mapping-without-document/httpie-request.adoc delete mode 100644 custom/test-update-mapping-without-document/request-body.adoc delete mode 100644 custom/test-update-mapping-without-document/response-body.adoc delete mode 100644 custom/test-update-mapping-without-etag/curl-request.adoc delete mode 100644 custom/test-update-mapping-without-etag/http-request.adoc delete mode 100644 custom/test-update-mapping-without-etag/http-response.adoc delete mode 100644 custom/test-update-mapping-without-etag/httpie-request.adoc delete mode 100644 custom/test-update-mapping-without-etag/request-body.adoc delete mode 100644 custom/test-update-mapping-without-etag/response-body.adoc delete mode 100644 custom/test-update-mapping-without-record/curl-request.adoc delete mode 100644 custom/test-update-mapping-without-record/http-request.adoc delete mode 100644 custom/test-update-mapping-without-record/http-response.adoc delete mode 100644 custom/test-update-mapping-without-record/httpie-request.adoc delete mode 100644 custom/test-update-mapping-without-record/request-body.adoc delete mode 100644 custom/test-update-mapping-without-record/response-body.adoc delete mode 100644 custom/test-update-mapping/curl-request.adoc delete mode 100644 custom/test-update-mapping/http-request.adoc delete mode 100644 custom/test-update-mapping/http-response.adoc delete mode 100644 custom/test-update-mapping/httpie-request.adoc delete mode 100644 custom/test-update-mapping/request-body.adoc delete mode 100644 custom/test-update-mapping/response-body.adoc rename src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/{TestPlugin.java => InOutPlugin.java} (85%) diff --git a/build.gradle b/build.gradle index b694adc5..08abb1a8 100644 --- a/build.gradle +++ b/build.gradle @@ -154,12 +154,18 @@ asciidoctor { }*/ bootJar { + dependsOn asciidoctor println 'Create bootable jar...' + from ("${asciidoctor.outputDir}/html5") { + into 'static/docs' + } archiveFileName = "${archiveBaseName.get()}.${archiveExtension.get()}" duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher' } + exclude '**/plugins/impl/**' + launchScript() } @@ -172,14 +178,6 @@ bootRun { systemProperty "pythonLocation", pythonExecutable } -bootJar { - dependsOn asciidoctor - from ("${asciidoctor.outputDir}/html5") { - into 'static/docs' - } - launchScript() -} - release { tagTemplate = 'v${version}' } diff --git a/custom/map-valid-document/curl-request.adoc b/custom/map-valid-document/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/map-valid-document/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/map-valid-document/http-request.adoc b/custom/map-valid-document/http-request.adoc deleted file mode 100644 index c236e043..00000000 --- a/custom/map-valid-document/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"TEST_0.0.0","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/map-valid-document/http-response.adoc b/custom/map-valid-document/http-response.adoc deleted file mode 100644 index b32b4a1b..00000000 --- a/custom/map-valid-document/http-response.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found -Vary: Origin -Vary: Access-Control-Request-Method -Vary: Access-Control-Request-Headers - ----- \ No newline at end of file diff --git a/custom/map-valid-document/httpie-request.adoc b/custom/map-valid-document/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/map-valid-document/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/map-valid-document/request-body.adoc b/custom/map-valid-document/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/map-valid-document/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-valid-document/response-body.adoc b/custom/map-valid-document/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/map-valid-document/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-with-invalid-id/curl-request.adoc b/custom/map-with-invalid-id/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/map-with-invalid-id/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/map-with-invalid-id/http-request.adoc b/custom/map-with-invalid-id/http-request.adoc deleted file mode 100644 index c236e043..00000000 --- a/custom/map-with-invalid-id/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"TEST_0.0.0","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/map-with-invalid-id/http-response.adoc b/custom/map-with-invalid-id/http-response.adoc deleted file mode 100644 index b32b4a1b..00000000 --- a/custom/map-with-invalid-id/http-response.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found -Vary: Origin -Vary: Access-Control-Request-Method -Vary: Access-Control-Request-Headers - ----- \ No newline at end of file diff --git a/custom/map-with-invalid-id/httpie-request.adoc b/custom/map-with-invalid-id/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/map-with-invalid-id/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/map-with-invalid-id/request-body.adoc b/custom/map-with-invalid-id/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/map-with-invalid-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-with-invalid-id/response-body.adoc b/custom/map-with-invalid-id/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/map-with-invalid-id/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-with-missing-parameters/curl-request.adoc b/custom/map-with-missing-parameters/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/map-with-missing-parameters/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/map-with-missing-parameters/http-request.adoc b/custom/map-with-missing-parameters/http-request.adoc deleted file mode 100644 index c236e043..00000000 --- a/custom/map-with-missing-parameters/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"TEST_0.0.0","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/map-with-missing-parameters/http-response.adoc b/custom/map-with-missing-parameters/http-response.adoc deleted file mode 100644 index b32b4a1b..00000000 --- a/custom/map-with-missing-parameters/http-response.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found -Vary: Origin -Vary: Access-Control-Request-Method -Vary: Access-Control-Request-Headers - ----- \ No newline at end of file diff --git a/custom/map-with-missing-parameters/httpie-request.adoc b/custom/map-with-missing-parameters/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/map-with-missing-parameters/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/map-with-missing-parameters/request-body.adoc b/custom/map-with-missing-parameters/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/map-with-missing-parameters/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-with-missing-parameters/response-body.adoc b/custom/map-with-missing-parameters/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/map-with-missing-parameters/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-without-document/curl-request.adoc b/custom/map-without-document/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/map-without-document/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/map-without-document/http-request.adoc b/custom/map-without-document/http-request.adoc deleted file mode 100644 index c236e043..00000000 --- a/custom/map-without-document/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"TEST_0.0.0","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/map-without-document/http-response.adoc b/custom/map-without-document/http-response.adoc deleted file mode 100644 index b32b4a1b..00000000 --- a/custom/map-without-document/http-response.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found -Vary: Origin -Vary: Access-Control-Request-Method -Vary: Access-Control-Request-Headers - ----- \ No newline at end of file diff --git a/custom/map-without-document/httpie-request.adoc b/custom/map-without-document/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/map-without-document/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/map-without-document/request-body.adoc b/custom/map-without-document/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/map-without-document/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/map-without-document/response-body.adoc b/custom/map-without-document/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/map-without-document/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/curl-request.adoc b/custom/test-create-mapping-empty-record/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-empty-record/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/http-request.adoc b/custom/test-create-mapping-empty-record/http-request.adoc deleted file mode 100644 index 07fb3580..00000000 --- a/custom/test-create-mapping-empty-record/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/http-response.adoc b/custom/test-create-mapping-empty-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-empty-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/httpie-request.adoc b/custom/test-create-mapping-empty-record/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-empty-record/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/request-body.adoc b/custom/test-create-mapping-empty-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-empty-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/response-body.adoc b/custom/test-create-mapping-empty-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-empty-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/curl-request.adoc b/custom/test-create-mapping-no-mapping/curl-request.adoc deleted file mode 100644 index 78b426e8..00000000 --- a/custom/test-create-mapping-no-mapping/curl-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/http-request.adoc b/custom/test-create-mapping-no-mapping/http-request.adoc deleted file mode 100644 index e5ae37bd..00000000 --- a/custom/test-create-mapping-no-mapping/http-request.adoc +++ /dev/null @@ -1,13 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/http-response.adoc b/custom/test-create-mapping-no-mapping/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-no-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/httpie-request.adoc b/custom/test-create-mapping-no-mapping/httpie-request.adoc deleted file mode 100644 index 12eca7ef..00000000 --- a/custom/test-create-mapping-no-mapping/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/request-body.adoc b/custom/test-create-mapping-no-mapping/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-no-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/response-body.adoc b/custom/test-create-mapping-no-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-no-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/curl-request.adoc b/custom/test-create-mapping-no-record/curl-request.adoc deleted file mode 100644 index 886f0f75..00000000 --- a/custom/test-create-mapping-no-record/curl-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/http-request.adoc b/custom/test-create-mapping-no-record/http-request.adoc deleted file mode 100644 index d99bd7d0..00000000 --- a/custom/test-create-mapping-no-record/http-request.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/http-response.adoc b/custom/test-create-mapping-no-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-no-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/httpie-request.adoc b/custom/test-create-mapping-no-record/httpie-request.adoc deleted file mode 100644 index 61e90bbe..00000000 --- a/custom/test-create-mapping-no-record/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/request-body.adoc b/custom/test-create-mapping-no-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-no-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/response-body.adoc b/custom/test-create-mapping-no-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-no-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/curl-request.adoc b/custom/test-create-mapping-twice/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-twice/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/http-request.adoc b/custom/test-create-mapping-twice/http-request.adoc deleted file mode 100644 index 39da1244..00000000 --- a/custom/test-create-mapping-twice/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/http-response.adoc b/custom/test-create-mapping-twice/http-response.adoc deleted file mode 100644 index d863daa7..00000000 --- a/custom/test-create-mapping-twice/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 409 Conflict - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/httpie-request.adoc b/custom/test-create-mapping-twice/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-twice/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/request-body.adoc b/custom/test-create-mapping-twice/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-twice/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/response-body.adoc b/custom/test-create-mapping-twice/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-twice/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/curl-request.adoc b/custom/test-create-mapping-with-acl/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-with-acl/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/http-request.adoc b/custom/test-create-mapping-with-acl/http-request.adoc deleted file mode 100644 index 36c8215d..00000000 --- a/custom/test-create-mapping-with-acl/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/http-response.adoc b/custom/test-create-mapping-with-acl/http-response.adoc deleted file mode 100644 index eaedcd55..00000000 --- a/custom/test-create-mapping-with-acl/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 201 Created -Location: http://localhost:8095/api/v1/mappingAdministration/my_dc -Content-Type: application/json -Content-Length: 566 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/httpie-request.adoc b/custom/test-create-mapping-with-acl/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-with-acl/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/request-body.adoc b/custom/test-create-mapping-with-acl/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-with-acl/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/response-body.adoc b/custom/test-create-mapping-with-acl/response-body.adoc deleted file mode 100644 index 6b7f6fa8..00000000 --- a/custom/test-create-mapping-with-acl/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/curl-request.adoc b/custom/test-create-mapping-wrong-record/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-wrong-record/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/http-request.adoc b/custom/test-create-mapping-wrong-record/http-request.adoc deleted file mode 100644 index 3f563e82..00000000 --- a/custom/test-create-mapping-wrong-record/http-request.adoc +++ /dev/null @@ -1,18 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":null,"title":null,"description":null,"acl":[],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/http-response.adoc b/custom/test-create-mapping-wrong-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-wrong-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/httpie-request.adoc b/custom/test-create-mapping-wrong-record/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-wrong-record/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/request-body.adoc b/custom/test-create-mapping-wrong-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-wrong-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/response-body.adoc b/custom/test-create-mapping-wrong-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-wrong-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping/curl-request.adoc b/custom/test-create-mapping/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping/http-request.adoc b/custom/test-create-mapping/http-request.adoc deleted file mode 100644 index 36c8215d..00000000 --- a/custom/test-create-mapping/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping/http-response.adoc b/custom/test-create-mapping/http-response.adoc deleted file mode 100644 index eaedcd55..00000000 --- a/custom/test-create-mapping/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 201 Created -Location: http://localhost:8095/api/v1/mappingAdministration/my_dc -Content-Type: application/json -Content-Length: 566 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-create-mapping/httpie-request.adoc b/custom/test-create-mapping/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping/request-body.adoc b/custom/test-create-mapping/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping/response-body.adoc b/custom/test-create-mapping/response-body.adoc deleted file mode 100644 index 6b7f6fa8..00000000 --- a/custom/test-create-mapping/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/curl-request.adoc b/custom/test-delete-mapping-missing-etag/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-delete-mapping-missing-etag/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/http-request.adoc b/custom/test-delete-mapping-missing-etag/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-delete-mapping-missing-etag/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/http-response.adoc b/custom/test-delete-mapping-missing-etag/http-response.adoc deleted file mode 100644 index 0dc4f320..00000000 --- a/custom/test-delete-mapping-missing-etag/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 560 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 40, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 41, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 42, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/httpie-request.adoc b/custom/test-delete-mapping-missing-etag/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-delete-mapping-missing-etag/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/request-body.adoc b/custom/test-delete-mapping-missing-etag/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-missing-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/response-body.adoc b/custom/test-delete-mapping-missing-etag/response-body.adoc deleted file mode 100644 index 3129c6d5..00000000 --- a/custom/test-delete-mapping-missing-etag/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 40, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 41, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 42, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc deleted file mode 100644 index 890ac553..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/unknownMappingId' -i -X DELETE \ - -H 'If-Match: "104363025"' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc deleted file mode 100644 index 8113df33..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -DELETE /api/v1/mappingAdministration/unknownMappingId HTTP/1.1 -If-Match: "104363025" -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc b/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc deleted file mode 100644 index b2e108f3..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 204 No Content - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc deleted file mode 100644 index a0cc74a7..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http DELETE 'http://localhost:8095/api/v1/mappingAdministration/unknownMappingId' \ - 'If-Match:"104363025"' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc b/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc b/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/curl-request.adoc b/custom/test-delete-mapping-wrong-etag/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-delete-mapping-wrong-etag/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/http-request.adoc b/custom/test-delete-mapping-wrong-etag/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-delete-mapping-wrong-etag/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/http-response.adoc b/custom/test-delete-mapping-wrong-etag/http-response.adoc deleted file mode 100644 index 86dd8ecb..00000000 --- a/custom/test-delete-mapping-wrong-etag/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 560 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 38, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 39, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 37, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/httpie-request.adoc b/custom/test-delete-mapping-wrong-etag/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-delete-mapping-wrong-etag/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/request-body.adoc b/custom/test-delete-mapping-wrong-etag/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-wrong-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/response-body.adoc b/custom/test-delete-mapping-wrong-etag/response-body.adoc deleted file mode 100644 index afe6b1da..00000000 --- a/custom/test-delete-mapping-wrong-etag/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 38, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 39, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 37, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/curl-request.adoc b/custom/test-delete-mapping/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-delete-mapping/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/http-request.adoc b/custom/test-delete-mapping/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-delete-mapping/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/http-response.adoc b/custom/test-delete-mapping/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-delete-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/httpie-request.adoc b/custom/test-delete-mapping/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-delete-mapping/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/request-body.adoc b/custom/test-delete-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/response-body.adoc b/custom/test-delete-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc deleted file mode 100644 index 36fb7cb1..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc deleted file mode 100644 index 07b9f8c0..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/invalidMappingId HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc deleted file mode 100644 index f0ed9abb..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/curl-request.adoc b/custom/test-get-mapping-by-id/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-get-mapping-by-id/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/http-request.adoc b/custom/test-get-mapping-by-id/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-get-mapping-by-id/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/http-response.adoc b/custom/test-get-mapping-by-id/http-response.adoc deleted file mode 100644 index b568d34f..00000000 --- a/custom/test-get-mapping-by-id/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 560 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 51, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 49, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 50, - "sid" : "SELF", - "permission" : "READ" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/httpie-request.adoc b/custom/test-get-mapping-by-id/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-get-mapping-by-id/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/request-body.adoc b/custom/test-get-mapping-by-id/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-by-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/response-body.adoc b/custom/test-get-mapping-by-id/response-body.adoc deleted file mode 100644 index 0f3b9c01..00000000 --- a/custom/test-get-mapping-by-id/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 51, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 49, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 50, - "sid" : "SELF", - "permission" : "READ" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc deleted file mode 100644 index 443c291b..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc deleted file mode 100644 index a2d8037e..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/invalidMappingId HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc deleted file mode 100644 index 844f1b2c..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/curl-request.adoc b/custom/test-get-mapping-document-by-id/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-get-mapping-document-by-id/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/http-request.adoc b/custom/test-get-mapping-document-by-id/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-get-mapping-document-by-id/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/http-response.adoc b/custom/test-get-mapping-document-by-id/http-response.adoc deleted file mode 100644 index 528f6003..00000000 --- a/custom/test-get-mapping-document-by-id/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 425 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/httpie-request.adoc b/custom/test-get-mapping-document-by-id/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-get-mapping-document-by-id/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/request-body.adoc b/custom/test-get-mapping-document-by-id/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-document-by-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/response-body.adoc b/custom/test-get-mapping-document-by-id/response-body.adoc deleted file mode 100644 index bd0e4ace..00000000 --- a/custom/test-get-mapping-document-by-id/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/curl-request.adoc b/custom/test-update-mapping-with-invalid-record/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-update-mapping-with-invalid-record/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/http-request.adoc b/custom/test-update-mapping-with-invalid-record/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-update-mapping-with-invalid-record/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/http-response.adoc b/custom/test-update-mapping-with-invalid-record/http-response.adoc deleted file mode 100644 index e04ca78b..00000000 --- a/custom/test-update-mapping-with-invalid-record/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 560 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 44, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 43, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 45, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/httpie-request.adoc b/custom/test-update-mapping-with-invalid-record/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-update-mapping-with-invalid-record/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/request-body.adoc b/custom/test-update-mapping-with-invalid-record/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-invalid-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/response-body.adoc b/custom/test-update-mapping-with-invalid-record/response-body.adoc deleted file mode 100644 index 979c0422..00000000 --- a/custom/test-update-mapping-with-invalid-record/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 44, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 43, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 45, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f" -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/curl-request.adoc b/custom/test-update-mapping-with-invalid-record2/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-update-mapping-with-invalid-record2/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/http-request.adoc b/custom/test-update-mapping-with-invalid-record2/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-update-mapping-with-invalid-record2/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/http-response.adoc b/custom/test-update-mapping-with-invalid-record2/http-response.adoc deleted file mode 100644 index 9909624a..00000000 --- a/custom/test-update-mapping-with-invalid-record2/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 434 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc b/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/request-body.adoc b/custom/test-update-mapping-with-invalid-record2/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-invalid-record2/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/response-body.adoc b/custom/test-update-mapping-with-invalid-record2/response-body.adoc deleted file mode 100644 index 139a1028..00000000 --- a/custom/test-update-mapping-with-invalid-record2/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/curl-request.adoc b/custom/test-update-mapping-with-wrong-etag/curl-request.adoc deleted file mode 100644 index 51612ec4..00000000 --- a/custom/test-update-mapping-with-wrong-etag/curl-request.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -H 'If-Match: wrongEtag' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/http-request.adoc b/custom/test-update-mapping-with-wrong-etag/http-request.adoc deleted file mode 100644 index 7b7a9a49..00000000 --- a/custom/test-update-mapping-with-wrong-etag/http-request.adoc +++ /dev/null @@ -1,36 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -If-Match: wrongEtag -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"someoneelse","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f"} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/http-response.adoc b/custom/test-update-mapping-with-wrong-etag/http-response.adoc deleted file mode 100644 index 5549e3fe..00000000 --- a/custom/test-update-mapping-with-wrong-etag/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 412 Precondition Failed - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc b/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc deleted file mode 100644 index 51122c72..00000000 --- a/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'If-Match:wrongEtag' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/request-body.adoc b/custom/test-update-mapping-with-wrong-etag/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-with-wrong-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/response-body.adoc b/custom/test-update-mapping-with-wrong-etag/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-wrong-etag/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/curl-request.adoc b/custom/test-update-mapping-with-wrong-record3/curl-request.adoc deleted file mode 100644 index f6ea3824..00000000 --- a/custom/test-update-mapping-with-wrong-record3/curl-request.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/unknownMaping' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -H 'If-Match: "104363025"' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/http-request.adoc b/custom/test-update-mapping-with-wrong-record3/http-request.adoc deleted file mode 100644 index d7f53e6e..00000000 --- a/custom/test-update-mapping-with-wrong-record3/http-request.adoc +++ /dev/null @@ -1,36 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/unknownMaping HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -If-Match: "104363025" -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":36,"sid":"test2","permission":"ADMINISTRATE"},{"id":35,"sid":"SELF","permission":"READ"},{"id":34,"sid":"anonymousUser","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f"} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/http-response.adoc b/custom/test-update-mapping-with-wrong-record3/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-update-mapping-with-wrong-record3/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc b/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc deleted file mode 100644 index 0a2f8d2b..00000000 --- a/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/unknownMaping' \ - 'If-Match:"104363025"' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/request-body.adoc b/custom/test-update-mapping-with-wrong-record3/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-with-wrong-record3/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/response-body.adoc b/custom/test-update-mapping-with-wrong-record3/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-wrong-record3/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/curl-request.adoc b/custom/test-update-mapping-without-document/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-update-mapping-without-document/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/http-request.adoc b/custom/test-update-mapping-without-document/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-update-mapping-without-document/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/http-response.adoc b/custom/test-update-mapping-without-document/http-response.adoc deleted file mode 100644 index 528f6003..00000000 --- a/custom/test-update-mapping-without-document/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 425 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/httpie-request.adoc b/custom/test-update-mapping-without-document/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-update-mapping-without-document/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/request-body.adoc b/custom/test-update-mapping-without-document/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-without-document/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/response-body.adoc b/custom/test-update-mapping-without-document/response-body.adoc deleted file mode 100644 index bd0e4ace..00000000 --- a/custom/test-update-mapping-without-document/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/curl-request.adoc b/custom/test-update-mapping-without-etag/curl-request.adoc deleted file mode 100644 index ea30de0b..00000000 --- a/custom/test-update-mapping-without-etag/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/http-request.adoc b/custom/test-update-mapping-without-etag/http-request.adoc deleted file mode 100644 index b47ef2d2..00000000 --- a/custom/test-update-mapping-without-etag/http-request.adoc +++ /dev/null @@ -1,35 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"someoneelse","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:0b415cfd8c084ea65ec2c9200a85a95402184011d442e5ab343021660420127f"} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/http-response.adoc b/custom/test-update-mapping-without-etag/http-response.adoc deleted file mode 100644 index 7448deeb..00000000 --- a/custom/test-update-mapping-without-etag/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 428 Precondition Required - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/httpie-request.adoc b/custom/test-update-mapping-without-etag/httpie-request.adoc deleted file mode 100644 index 3b932a63..00000000 --- a/custom/test-update-mapping-without-etag/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/request-body.adoc b/custom/test-update-mapping-without-etag/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-without-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/response-body.adoc b/custom/test-update-mapping-without-etag/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-without-etag/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/curl-request.adoc b/custom/test-update-mapping-without-record/curl-request.adoc deleted file mode 100644 index baee036f..00000000 --- a/custom/test-update-mapping-without-record/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -H 'If-Match: "104363025"' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/http-request.adoc b/custom/test-update-mapping-without-record/http-request.adoc deleted file mode 100644 index 2fab7976..00000000 --- a/custom/test-update-mapping-without-record/http-request.adoc +++ /dev/null @@ -1,31 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -If-Match: "104363025" -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/http-response.adoc b/custom/test-update-mapping-without-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-update-mapping-without-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/httpie-request.adoc b/custom/test-update-mapping-without-record/httpie-request.adoc deleted file mode 100644 index 29510d9f..00000000 --- a/custom/test-update-mapping-without-record/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'If-Match:"104363025"' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/request-body.adoc b/custom/test-update-mapping-without-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-without-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/response-body.adoc b/custom/test-update-mapping-without-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-without-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping/curl-request.adoc b/custom/test-update-mapping/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-update-mapping/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-update-mapping/http-request.adoc b/custom/test-update-mapping/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-update-mapping/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping/http-response.adoc b/custom/test-update-mapping/http-response.adoc deleted file mode 100644 index 9909624a..00000000 --- a/custom/test-update-mapping/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 434 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping/httpie-request.adoc b/custom/test-update-mapping/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-update-mapping/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-update-mapping/request-body.adoc b/custom/test-update-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping/response-body.adoc b/custom/test-update-mapping/response-body.adoc deleted file mode 100644 index 139a1028..00000000 --- a/custom/test-update-mapping/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java index 204acff9..073f391c 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java @@ -61,12 +61,12 @@ public String uri() { @Override public MimeType[] inputTypes() { - return new MimeType[]{MimeType.valueOf("application/octet-stream")}; + return new MimeType[]{MimeType.valueOf("image/*")}; } @Override public MimeType[] outputTypes() { - return new MimeType[]{MimeType.valueOf("application/octet-stream")}; + return new MimeType[]{MimeType.valueOf("application/*")}; } @Override diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/TestPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java similarity index 85% rename from src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/TestPlugin.java rename to src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java index 609d1038..56a554fe 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/TestPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java @@ -31,23 +31,23 @@ * * @author jejkal */ -public class TestPlugin implements IMappingPlugin { +public class InOutPlugin implements IMappingPlugin { - static Logger LOG = LoggerFactory.getLogger(TestPlugin.class); + static Logger LOG = LoggerFactory.getLogger(InOutPlugin.class); @Override public String name() { - return "TestPlugin"; + return "InOutPlugin"; } @Override public String description() { - return "Simple plugin for testing."; + return "Simple plugin for testing just returning the input file."; } @Override public String version() { - return "1.0.0"; + return "1.1.2"; } @Override @@ -57,12 +57,12 @@ public String uri() { @Override public MimeType[] inputTypes() { - return new MimeType[]{MimeType.valueOf("application/octet-stream")}; + return new MimeType[]{MimeType.valueOf("application/*")}; } @Override public MimeType[] outputTypes() { - return new MimeType[]{MimeType.valueOf("application/octet-stream")}; + return new MimeType[]{MimeType.valueOf("application/*")}; } @Override From 18036d592488a89ab5bf9197de0ae68a832ea7fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:28:24 +0000 Subject: [PATCH 17/80] Update dependency gradle to v8.13 --- gradle/wrapper/gradle-wrapper.jar | Bin 43583 -> 43705 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b9530d66f5e68d973ea569d8e19de379189..9bbc975c742b298b441bfb90dbc124400a3751b9 100644 GIT binary patch delta 34744 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 delta 34727 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�{ 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 a%EQ2*fnt2> Date: Thu, 27 Feb 2025 22:31:59 +0100 Subject: [PATCH 18/80] Started reorganization of status propagation --- .../exception/BadExitCodeException.java | 27 +++++ .../exception/DuplicateMappingException.java | 2 +- .../exception/JobNotFoundException.java | 2 +- .../mappingservice/impl/MappingService.java | 2 +- .../plugins/MappingPluginState.java | 112 +++++++++++++----- .../mappingservice/plugins/PluginManager.java | 2 + .../mappingservice/util/PythonRunnerUtil.java | 25 ++-- .../mappingservice/util/ShellRunnerUtil.java | 88 ++++++++------ 8 files changed, 181 insertions(+), 79 deletions(-) create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java new file mode 100644 index 00000000..8577d1e9 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java @@ -0,0 +1,27 @@ +/* + * Copyright 2025 Karlsruhe Institute of Technology. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.kit.datamanager.mappingservice.exception; + +/** + * + * @author jejkal + */ +public class BadExitCodeException extends Exception { + + + public BadExitCodeException(int exitCode) { + super(Integer.toString(exitCode)); + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/DuplicateMappingException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/DuplicateMappingException.java index 757c7baf..dc34757b 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/exception/DuplicateMappingException.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/DuplicateMappingException.java @@ -21,7 +21,7 @@ /** * Invalid json format of data. */ -@ResponseStatus(value = HttpStatus.CONFLICT) +@ResponseStatus(value = HttpStatus.CONFLICT, reason = "Duplicate mapping id.") public class DuplicateMappingException extends RuntimeException { /** diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/JobNotFoundException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/JobNotFoundException.java index 9859e7f4..b99ec8de 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/exception/JobNotFoundException.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/JobNotFoundException.java @@ -21,7 +21,7 @@ /** * Job not found. */ -@ResponseStatus(value = HttpStatus.NOT_FOUND) +@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "No job with provided id found.") public class JobNotFoundException extends RuntimeException { /** diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index c6b83611..f0f87903 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -194,7 +194,7 @@ public Optional executeMapping(URI contentUrl, String mappingId) throws Ma LOGGER.trace("Searching for mapping with id {}.", mappingId); Optional optionalMappingRecord = mappingRepo.findByMappingId(mappingId); if (optionalMappingRecord.isPresent()) { - LOGGER.trace("Mapping for id {} found. Creating temporary output file."); + LOGGER.trace("Mapping for id {} found. Creating temporary output file.", mappingId); mappingRecord = optionalMappingRecord.get(); Path mappingFile = Paths.get(mappingRecord.getMappingDocumentUri()); // execute mapping diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java index c622098f..8a55bc90 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java @@ -5,46 +5,98 @@ import java.io.Serializable; /** - * State of a mapping plugin. - * This class is used to store the state of a mapping plugin and return an HTTP status code. + * State of a mapping plugin. This class is used to store the state of a mapping + * plugin and return an HTTP status code. * * @author maximilianiKIT */ -public enum MappingPluginState implements Serializable { - SUCCESS(HttpStatus.OK), - NOT_FOUND(HttpStatus.NOT_FOUND), - TIMEOUT, - EXECUTION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), - INVALID_INPUT, - INCORRECT_MIME_TYPE, - INSUFFICIENT_PRIVILEGES(HttpStatus.INTERNAL_SERVER_ERROR), - UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR); - - private final HttpStatus httpStatus; +public class MappingPluginState implements Serializable { - /** - * This method returns the HTTP status code for the given state. - * - * @return The HTTP status code for the given state. - */ - public HttpStatus getHttpStatus() { - return httpStatus; - } + public enum StateEnum { + SUCCESS(HttpStatus.OK), + NOT_FOUND(HttpStatus.NOT_FOUND), + TIMEOUT, + EXECUTION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), + INVALID_INPUT, + BAD_EXIT_CODE, + INCORRECT_MIME_TYPE, + INSUFFICIENT_PRIVILEGES(HttpStatus.INTERNAL_SERVER_ERROR), + UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR); + + private final HttpStatus httpStatus; + + StateEnum() { + this.httpStatus = HttpStatus.BAD_REQUEST; + } + + StateEnum(HttpStatus status) { + this.httpStatus = status; + } + + public HttpStatus getHttpStatus() { + return httpStatus; + } + + }; + + private final StateEnum state; + private Object details; /** * Lets the state be created with an HTTP status code. * - * @param status The HTTP status code for the given state. + * @param state The state enum. */ - MappingPluginState(HttpStatus status) { - this.httpStatus = status; + public MappingPluginState(StateEnum state) { + this.state = state; } - /** - * Default constructor. - * Sets the default HTTP status code on error to 400. - */ - MappingPluginState() { - this.httpStatus = HttpStatus.BAD_REQUEST; + public static MappingPluginState SUCCESS() { + return new MappingPluginState(StateEnum.SUCCESS); + } + + public static MappingPluginState NOT_FOUND() { + return new MappingPluginState(StateEnum.NOT_FOUND); + } + + public static MappingPluginState TIMEOUT() { + return new MappingPluginState(StateEnum.TIMEOUT); + } + + public static MappingPluginState EXECUTION_ERROR() { + return new MappingPluginState(StateEnum.EXECUTION_ERROR); } + + public static MappingPluginState INVALID_INPUT() { + return new MappingPluginState(StateEnum.INVALID_INPUT); + } + + public static MappingPluginState BAD_EXIT_CODE() { + return new MappingPluginState(StateEnum.BAD_EXIT_CODE); + } + + public static MappingPluginState INCORRECT_MIME_TYPE() { + return new MappingPluginState(StateEnum.INCORRECT_MIME_TYPE); + } + + public static MappingPluginState INSUFFICIENT_PRIVILEGES() { + return new MappingPluginState(StateEnum.INSUFFICIENT_PRIVILEGES); + } + + public static MappingPluginState UNKNOWN_ERROR() { + return new MappingPluginState(StateEnum.UNKNOWN_ERROR); + } + + public StateEnum getState() { + return state; + } + + public void setDetails(Object details) { + this.details = details; + } + + public Object getDetails() { + return details; + } + } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index ce9e91d0..d9a48e0b 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -118,8 +118,10 @@ public final List listPluginIds() { * @param mappingFile Path to the mapping schema. * @param inputFile Path to the input file. * @param outputFile Path where the output is temporarily stored. + * * @return MappingPluginState.SUCCESS if the plugin was executed * successfully. + * * @throws MappingPluginException If there is an error with the plugin or * the input. */ diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index a8a52924..47bb1482 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package edu.kit.datamanager.mappingservice.util; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; @@ -34,6 +33,7 @@ */ @Component public class PythonRunnerUtil { + private static ApplicationProperties configuration; private static final Logger LOGGER = LoggerFactory.getLogger(PythonRunnerUtil.class); @@ -70,31 +70,36 @@ public static MappingPluginState runPythonScript(String arg) throws MappingPlugi * This method executes a python script with the given arguments. * * @param script path to the python script to be executed. - * @param args arguments to be passed to the script. + * @param args arguments to be passed to the script. * @return State of the execution. * @throws MappingPluginException if an error occurs. */ public static MappingPluginState runPythonScript(String script, String... args) throws MappingPluginException { - return runPythonScript(script, new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.INFO), args); + return runPythonScript(script, new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.ERROR), args); } /** - * This method executes a python script with the given arguments and redirects the output and errors to the given streams. + * This method executes a python script with the given arguments and + * redirects the output and errors to the given streams. * * @param script path to the python script to be executed. * @param output OutputStream to redirect the output to. - * @param error OutputStream to redirect the errors to. - * @param args arguments to be passed to the script. - * @return State of the execution. + * @param error OutputStream to redirect the errors to. + * @param args arguments to be passed to the script. + * + * @return State of the execution if execution succeeds. Otherwise, a + * MappingPluginException is thrown. + * * @throws MappingPluginException if an error occurs. */ public static MappingPluginState runPythonScript(String script, OutputStream output, OutputStream error, String... args) throws MappingPluginException { - if (configuration == null || configuration.getPythonExecutable()== null) return MappingPluginState.UNKNOWN_ERROR; + if (configuration == null || configuration.getPythonExecutable() == null) { + return MappingPluginState.UNKNOWN_ERROR(); + } ArrayList command = new ArrayList<>(); command.add(configuration.getPythonExecutable().getPath()); command.add(script); Collections.addAll(command, args); - ShellRunnerUtil.run(output, error, command.toArray(new String[0])); - return MappingPluginState.SUCCESS; + return ShellRunnerUtil.run(output, error, command.toArray(String[]::new)); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java index 4ea28e76..bdc21696 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java @@ -12,10 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package edu.kit.datamanager.mappingservice.util; -import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import edu.kit.datamanager.mappingservice.exception.BadExitCodeException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import org.slf4j.Logger; @@ -25,8 +24,6 @@ import java.util.List; import java.util.concurrent.*; import java.util.stream.Collectors; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; /** * Utility class for running shell scripts. @@ -59,8 +56,9 @@ public static MappingPluginState run(String... command) throws MappingPluginExce /** * This method executes a shell command. * - * @param timeOutInSeconds Time in seconds when the script should throw a timeout exception. - * @param command The command to execute without spaces. + * @param timeOutInSeconds Time in seconds when the script should throw a + * timeout exception. + * @param command The command to execute without spaces. * @return State of the execution. * @throws MappingPluginException If an error occurs. */ @@ -69,10 +67,11 @@ public static MappingPluginState run(int timeOutInSeconds, String... command) th } /** - * This method executes a shell command and writes the output and errors to the given streams. + * This method executes a shell command and writes the output and errors to + * the given streams. * - * @param output OutputStream to redirect the output to. - * @param error OutputStream to redirect the errors to. + * @param output OutputStream to redirect the output to. + * @param error OutputStream to redirect the errors to. * @param command The command to execute without spaces. * @return State of the execution. * @throws MappingPluginException If an error occurs. @@ -81,22 +80,34 @@ public static MappingPluginState run(OutputStream output, OutputStream error, St return run(output, error, TIMEOUT, command); } - /** - * This method executes a shell command and writes the output and errors to the given streams. + * This method executes a shell command and writes the output and errors to + * the given streams. + * + * @param output OutputStream to redirect the output to. + * @param error OutputStream to redirect the errors to. + * @param timeOutInSeconds Time in seconds when the script should throw a + * timeout exception. + * @param command The command to execute without spaces. + * + * @return State of the execution only if execution was successful. + * Otherwise, MappingPluginException is thrown. * - * @param output OutputStream to redirect the output to. - * @param error OutputStream to redirect the errors to. - * @param timeOutInSeconds Time in seconds when the script should throw a timeout exception. - * @param command The command to execute without spaces. - * @return State of the execution. * @throws MappingPluginException If an error occurs. */ public static MappingPluginState run(OutputStream output, OutputStream error, int timeOutInSeconds, String... command) throws MappingPluginException { - if (output == null) throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Output stream is null."); - if (error == null) throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Error stream is null."); - if (timeOutInSeconds <= 0) throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Timeout is null or negative."); - if (command == null || command.length == 0) throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "No command given."); + if (output == null) { + throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Output stream is null."); + } + if (error == null) { + throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Error stream is null."); + } + if (timeOutInSeconds <= 0) { + throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Timeout is null or negative."); + } + if (command == null || command.length == 0) { + throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "No command given."); + } ExecutorService pool = Executors.newSingleThreadExecutor(); int result; @@ -106,50 +117,55 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in ProcessBuilder pb = new ProcessBuilder(command); Process p = pb.start(); + //connect to process out/err streams Future> errorFuture = pool.submit(new ShellRunnerUtil.ProcessReadTask(p.getErrorStream())); Future> inputFuture = pool.submit(new ShellRunnerUtil.ProcessReadTask(p.getInputStream())); + //wait for max timeOutInSeconds for stream to close aka. process to finish List stdErr = errorFuture.get(timeOutInSeconds, TimeUnit.SECONDS); List stdOut = inputFuture.get(timeOutInSeconds, TimeUnit.SECONDS); + //print all out/err messages at once for (String line : stdOut) { - LOGGER.trace("[OUT] {}", line); - if (output != null) { - output.write((line + "\n").getBytes()); - } + output.write((line + "\n").getBytes()); } - for (String line : stdErr) { - LOGGER.trace("[ERR] {}", line); - if (error != null) { - error.write((line + "\n").getBytes()); - } + error.write((line + "\n").getBytes()); } - result = p.waitFor(); - if (result != 0) { - throw new ExecutionException(new Throwable()); + if (!p.waitFor(timeOutInSeconds, TimeUnit.SECONDS)) { + throw new TimeoutException("Process did not return within " + TIMEOUT + " seconds."); + } + if (p.exitValue() != 0) { + throw new BadExitCodeException(p.exitValue()); } } catch (IOException ioe) { - LOGGER.error("Failed to execute command.", ioe); + LOGGER.error("Failed to run command or to access output/error streams.", ioe); returnValue = MappingPluginState.EXECUTION_ERROR; } catch (TimeoutException te) { LOGGER.error("Command did not return in expected timeframe of " + TIMEOUT + " seconds", te); returnValue = MappingPluginState.TIMEOUT; } catch (InterruptedException | ExecutionException e) { - LOGGER.error("Failed to execute command due to an unknown exception.", e); + LOGGER.error("Command execution has been interrupted.", e); + returnValue = MappingPluginState.UNKNOWN_ERROR; + } catch (BadExitCodeException e) { + LOGGER.error("Failed to execute command due to an unexpected exception.", e); returnValue = MappingPluginState.UNKNOWN_ERROR; } finally { pool.shutdown(); - if (returnValue != MappingPluginState.SUCCESS) throw new MappingPluginException(returnValue); + } + + if (returnValue != MappingPluginState.SUCCESS) { + throw new MappingPluginException(returnValue); } return returnValue; } private record ProcessReadTask(InputStream inputStream) implements Callable> { + @Override public List call() { return new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.toList()); } } -} \ No newline at end of file +} From 0f838a439e43a257dd9bb702a03e3b10defd945f Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Fri, 28 Feb 2025 15:21:47 +0100 Subject: [PATCH 19/80] Continued with rework, implemented loading plugins from classpath --- build.gradle | 4 +- .../curl-request.adoc | 7 ++ .../http-request.adoc | 34 ++++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 6 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 6 ++ .../http-request.adoc | 13 +++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 6 ++ .../http-request.adoc | 29 +++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 7 ++ .../http-request.adoc | 34 ++++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 6 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 7 ++ .../http-request.adoc | 34 ++++++++ .../http-response.adoc | 29 +++++++ .../httpie-request.adoc | 6 ++ .../request-body.adoc | 4 + .../response-body.adoc | 24 ++++++ .../curl-request.adoc | 7 ++ .../http-request.adoc | 18 +++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 6 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + custom/test-create-mapping/curl-request.adoc | 7 ++ custom/test-create-mapping/http-request.adoc | 34 ++++++++ custom/test-create-mapping/http-response.adoc | 29 +++++++ .../test-create-mapping/httpie-request.adoc | 6 ++ custom/test-create-mapping/request-body.adoc | 4 + custom/test-create-mapping/response-body.adoc | 24 ++++++ .../curl-request.adoc | 5 ++ .../http-request.adoc | 7 ++ .../http-response.adoc | 29 +++++++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 24 ++++++ .../curl-request.adoc | 5 ++ .../http-request.adoc | 7 ++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 5 ++ .../http-request.adoc | 7 ++ .../http-response.adoc | 29 +++++++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 24 ++++++ custom/test-delete-mapping/curl-request.adoc | 5 ++ custom/test-delete-mapping/http-request.adoc | 7 ++ custom/test-delete-mapping/http-response.adoc | 5 ++ .../test-delete-mapping/httpie-request.adoc | 5 ++ custom/test-delete-mapping/request-body.adoc | 4 + custom/test-delete-mapping/response-body.adoc | 4 + .../curl-request.adoc | 5 ++ .../http-request.adoc | 7 ++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../test-get-mapping-by-id/curl-request.adoc | 5 ++ .../test-get-mapping-by-id/http-request.adoc | 7 ++ .../test-get-mapping-by-id/http-response.adoc | 29 +++++++ .../httpie-request.adoc | 5 ++ .../test-get-mapping-by-id/request-body.adoc | 4 + .../test-get-mapping-by-id/response-body.adoc | 24 ++++++ .../curl-request.adoc | 4 + .../http-request.adoc | 6 ++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 4 + .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 4 + .../http-request.adoc | 6 ++ .../http-response.adoc | 26 ++++++ .../httpie-request.adoc | 4 + .../request-body.adoc | 4 + .../response-body.adoc | 20 +++++ .../curl-request.adoc | 5 ++ .../http-request.adoc | 7 ++ .../http-response.adoc | 29 +++++++ .../httpie-request.adoc | 5 ++ .../request-body.adoc | 4 + .../response-body.adoc | 24 ++++++ .../curl-request.adoc | 4 + .../http-request.adoc | 6 ++ .../http-response.adoc | 26 ++++++ .../httpie-request.adoc | 4 + .../request-body.adoc | 4 + .../response-body.adoc | 20 +++++ .../curl-request.adoc | 8 ++ .../http-request.adoc | 36 +++++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 7 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 8 ++ .../http-request.adoc | 36 +++++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 7 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 4 + .../http-request.adoc | 6 ++ .../http-response.adoc | 26 ++++++ .../httpie-request.adoc | 4 + .../request-body.adoc | 4 + .../response-body.adoc | 20 +++++ .../curl-request.adoc | 7 ++ .../http-request.adoc | 35 ++++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 6 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + .../curl-request.adoc | 7 ++ .../http-request.adoc | 31 ++++++++ .../http-response.adoc | 5 ++ .../httpie-request.adoc | 6 ++ .../request-body.adoc | 4 + .../response-body.adoc | 4 + custom/test-update-mapping/curl-request.adoc | 4 + custom/test-update-mapping/http-request.adoc | 6 ++ custom/test-update-mapping/http-response.adoc | 26 ++++++ .../test-update-mapping/httpie-request.adoc | 4 + custom/test-update-mapping/request-body.adoc | 4 + custom/test-update-mapping/response-body.adoc | 20 +++++ .../mappingservice/impl/MappingService.java | 2 +- .../plugins/MappingPluginException.java | 2 +- .../plugins/MappingPluginState.java | 16 +--- .../mappingservice/plugins/PluginLoader.java | 79 ++++++++++++++----- .../mappingservice/plugins/PluginManager.java | 10 +-- .../plugins/impl/GemmaPlugin.java | 2 +- .../plugins/impl/IdentifyPlugin.java | 4 +- .../plugins/impl/InOutPlugin.java | 4 +- .../rest/PluginInformation.java | 2 +- .../rest/impl/MappingExecutionController.java | 2 +- .../mappingservice/util/ShellRunnerUtil.java | 20 ++--- .../plugins/MappingPluginExceptionTest.java | 14 ++-- .../plugins/PluginLoaderTest.java | 2 +- .../plugins/PluginManagerTest.java | 17 ++-- .../rest/PluginInformationTest.java | 2 +- .../util/ShellRunnerUtilTest.java | 12 +-- 155 files changed, 1489 insertions(+), 82 deletions(-) create mode 100644 custom/test-create-mapping-empty-record/curl-request.adoc create mode 100644 custom/test-create-mapping-empty-record/http-request.adoc create mode 100644 custom/test-create-mapping-empty-record/http-response.adoc create mode 100644 custom/test-create-mapping-empty-record/httpie-request.adoc create mode 100644 custom/test-create-mapping-empty-record/request-body.adoc create mode 100644 custom/test-create-mapping-empty-record/response-body.adoc create mode 100644 custom/test-create-mapping-no-mapping/curl-request.adoc create mode 100644 custom/test-create-mapping-no-mapping/http-request.adoc create mode 100644 custom/test-create-mapping-no-mapping/http-response.adoc create mode 100644 custom/test-create-mapping-no-mapping/httpie-request.adoc create mode 100644 custom/test-create-mapping-no-mapping/request-body.adoc create mode 100644 custom/test-create-mapping-no-mapping/response-body.adoc create mode 100644 custom/test-create-mapping-no-record/curl-request.adoc create mode 100644 custom/test-create-mapping-no-record/http-request.adoc create mode 100644 custom/test-create-mapping-no-record/http-response.adoc create mode 100644 custom/test-create-mapping-no-record/httpie-request.adoc create mode 100644 custom/test-create-mapping-no-record/request-body.adoc create mode 100644 custom/test-create-mapping-no-record/response-body.adoc create mode 100644 custom/test-create-mapping-twice/curl-request.adoc create mode 100644 custom/test-create-mapping-twice/http-request.adoc create mode 100644 custom/test-create-mapping-twice/http-response.adoc create mode 100644 custom/test-create-mapping-twice/httpie-request.adoc create mode 100644 custom/test-create-mapping-twice/request-body.adoc create mode 100644 custom/test-create-mapping-twice/response-body.adoc create mode 100644 custom/test-create-mapping-with-acl/curl-request.adoc create mode 100644 custom/test-create-mapping-with-acl/http-request.adoc create mode 100644 custom/test-create-mapping-with-acl/http-response.adoc create mode 100644 custom/test-create-mapping-with-acl/httpie-request.adoc create mode 100644 custom/test-create-mapping-with-acl/request-body.adoc create mode 100644 custom/test-create-mapping-with-acl/response-body.adoc create mode 100644 custom/test-create-mapping-wrong-record/curl-request.adoc create mode 100644 custom/test-create-mapping-wrong-record/http-request.adoc create mode 100644 custom/test-create-mapping-wrong-record/http-response.adoc create mode 100644 custom/test-create-mapping-wrong-record/httpie-request.adoc create mode 100644 custom/test-create-mapping-wrong-record/request-body.adoc create mode 100644 custom/test-create-mapping-wrong-record/response-body.adoc create mode 100644 custom/test-create-mapping/curl-request.adoc create mode 100644 custom/test-create-mapping/http-request.adoc create mode 100644 custom/test-create-mapping/http-response.adoc create mode 100644 custom/test-create-mapping/httpie-request.adoc create mode 100644 custom/test-create-mapping/request-body.adoc create mode 100644 custom/test-create-mapping/response-body.adoc create mode 100644 custom/test-delete-mapping-missing-etag/curl-request.adoc create mode 100644 custom/test-delete-mapping-missing-etag/http-request.adoc create mode 100644 custom/test-delete-mapping-missing-etag/http-response.adoc create mode 100644 custom/test-delete-mapping-missing-etag/httpie-request.adoc create mode 100644 custom/test-delete-mapping-missing-etag/request-body.adoc create mode 100644 custom/test-delete-mapping-missing-etag/response-body.adoc create mode 100644 custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc create mode 100644 custom/test-delete-mapping-unknown-mapping-id/http-request.adoc create mode 100644 custom/test-delete-mapping-unknown-mapping-id/http-response.adoc create mode 100644 custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc create mode 100644 custom/test-delete-mapping-unknown-mapping-id/request-body.adoc create mode 100644 custom/test-delete-mapping-unknown-mapping-id/response-body.adoc create mode 100644 custom/test-delete-mapping-wrong-etag/curl-request.adoc create mode 100644 custom/test-delete-mapping-wrong-etag/http-request.adoc create mode 100644 custom/test-delete-mapping-wrong-etag/http-response.adoc create mode 100644 custom/test-delete-mapping-wrong-etag/httpie-request.adoc create mode 100644 custom/test-delete-mapping-wrong-etag/request-body.adoc create mode 100644 custom/test-delete-mapping-wrong-etag/response-body.adoc create mode 100644 custom/test-delete-mapping/curl-request.adoc create mode 100644 custom/test-delete-mapping/http-request.adoc create mode 100644 custom/test-delete-mapping/http-response.adoc create mode 100644 custom/test-delete-mapping/httpie-request.adoc create mode 100644 custom/test-delete-mapping/request-body.adoc create mode 100644 custom/test-delete-mapping/response-body.adoc create mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc create mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc create mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc create mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc create mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc create mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc create mode 100644 custom/test-get-mapping-by-id/curl-request.adoc create mode 100644 custom/test-get-mapping-by-id/http-request.adoc create mode 100644 custom/test-get-mapping-by-id/http-response.adoc create mode 100644 custom/test-get-mapping-by-id/httpie-request.adoc create mode 100644 custom/test-get-mapping-by-id/request-body.adoc create mode 100644 custom/test-get-mapping-by-id/response-body.adoc create mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc create mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc create mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc create mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc create mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc create mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc create mode 100644 custom/test-get-mapping-document-by-id/curl-request.adoc create mode 100644 custom/test-get-mapping-document-by-id/http-request.adoc create mode 100644 custom/test-get-mapping-document-by-id/http-response.adoc create mode 100644 custom/test-get-mapping-document-by-id/httpie-request.adoc create mode 100644 custom/test-get-mapping-document-by-id/request-body.adoc create mode 100644 custom/test-get-mapping-document-by-id/response-body.adoc create mode 100644 custom/test-update-mapping-with-invalid-record/curl-request.adoc create mode 100644 custom/test-update-mapping-with-invalid-record/http-request.adoc create mode 100644 custom/test-update-mapping-with-invalid-record/http-response.adoc create mode 100644 custom/test-update-mapping-with-invalid-record/httpie-request.adoc create mode 100644 custom/test-update-mapping-with-invalid-record/request-body.adoc create mode 100644 custom/test-update-mapping-with-invalid-record/response-body.adoc create mode 100644 custom/test-update-mapping-with-invalid-record2/curl-request.adoc create mode 100644 custom/test-update-mapping-with-invalid-record2/http-request.adoc create mode 100644 custom/test-update-mapping-with-invalid-record2/http-response.adoc create mode 100644 custom/test-update-mapping-with-invalid-record2/httpie-request.adoc create mode 100644 custom/test-update-mapping-with-invalid-record2/request-body.adoc create mode 100644 custom/test-update-mapping-with-invalid-record2/response-body.adoc create mode 100644 custom/test-update-mapping-with-wrong-etag/curl-request.adoc create mode 100644 custom/test-update-mapping-with-wrong-etag/http-request.adoc create mode 100644 custom/test-update-mapping-with-wrong-etag/http-response.adoc create mode 100644 custom/test-update-mapping-with-wrong-etag/httpie-request.adoc create mode 100644 custom/test-update-mapping-with-wrong-etag/request-body.adoc create mode 100644 custom/test-update-mapping-with-wrong-etag/response-body.adoc create mode 100644 custom/test-update-mapping-with-wrong-record3/curl-request.adoc create mode 100644 custom/test-update-mapping-with-wrong-record3/http-request.adoc create mode 100644 custom/test-update-mapping-with-wrong-record3/http-response.adoc create mode 100644 custom/test-update-mapping-with-wrong-record3/httpie-request.adoc create mode 100644 custom/test-update-mapping-with-wrong-record3/request-body.adoc create mode 100644 custom/test-update-mapping-with-wrong-record3/response-body.adoc create mode 100644 custom/test-update-mapping-without-document/curl-request.adoc create mode 100644 custom/test-update-mapping-without-document/http-request.adoc create mode 100644 custom/test-update-mapping-without-document/http-response.adoc create mode 100644 custom/test-update-mapping-without-document/httpie-request.adoc create mode 100644 custom/test-update-mapping-without-document/request-body.adoc create mode 100644 custom/test-update-mapping-without-document/response-body.adoc create mode 100644 custom/test-update-mapping-without-etag/curl-request.adoc create mode 100644 custom/test-update-mapping-without-etag/http-request.adoc create mode 100644 custom/test-update-mapping-without-etag/http-response.adoc create mode 100644 custom/test-update-mapping-without-etag/httpie-request.adoc create mode 100644 custom/test-update-mapping-without-etag/request-body.adoc create mode 100644 custom/test-update-mapping-without-etag/response-body.adoc create mode 100644 custom/test-update-mapping-without-record/curl-request.adoc create mode 100644 custom/test-update-mapping-without-record/http-request.adoc create mode 100644 custom/test-update-mapping-without-record/http-response.adoc create mode 100644 custom/test-update-mapping-without-record/httpie-request.adoc create mode 100644 custom/test-update-mapping-without-record/request-body.adoc create mode 100644 custom/test-update-mapping-without-record/response-body.adoc create mode 100644 custom/test-update-mapping/curl-request.adoc create mode 100644 custom/test-update-mapping/http-request.adoc create mode 100644 custom/test-update-mapping/http-response.adoc create mode 100644 custom/test-update-mapping/httpie-request.adoc create mode 100644 custom/test-update-mapping/request-body.adoc create mode 100644 custom/test-update-mapping/response-body.adoc diff --git a/build.gradle b/build.gradle index 08abb1a8..9de44cd6 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ repositories { ext { set('snippetsDir', file('build/generated-snippets')) applicationProperties = System.getProperty('applicationProperties', './src/test/resources/test-config/application-test.properties') - pythonExecutable = System.getProperty('pythonExecutable', 'file:///usr/bin/python') + pythonExecutable = System.getProperty('pythonExecutable', 'file:///opt/homebrew/bin/python3') userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") set('springDocVersion', "2.8.5") @@ -164,7 +164,7 @@ bootJar { manifest { attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher' } - exclude '**/plugins/impl/**' + // exclude '**/plugins/impl/**' launchScript() } diff --git a/custom/test-create-mapping-empty-record/curl-request.adoc b/custom/test-create-mapping-empty-record/curl-request.adoc new file mode 100644 index 00000000..8818d020 --- /dev/null +++ b/custom/test-create-mapping-empty-record/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/http-request.adoc b/custom/test-create-mapping-empty-record/http-request.adoc new file mode 100644 index 00000000..07fb3580 --- /dev/null +++ b/custom/test-create-mapping-empty-record/http-request.adoc @@ -0,0 +1,34 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "Publication Date":{ + "path": "publicationDate", + "type": "string" + } + } +} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/http-response.adoc b/custom/test-create-mapping-empty-record/http-response.adoc new file mode 100644 index 00000000..6bc944f3 --- /dev/null +++ b/custom/test-create-mapping-empty-record/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 400 Bad Request + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/httpie-request.adoc b/custom/test-create-mapping-empty-record/httpie-request.adoc new file mode 100644 index 00000000..f6687a5c --- /dev/null +++ b/custom/test-create-mapping-empty-record/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/request-body.adoc b/custom/test-create-mapping-empty-record/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping-empty-record/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/response-body.adoc b/custom/test-create-mapping-empty-record/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-create-mapping-empty-record/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/curl-request.adoc b/custom/test-create-mapping-no-mapping/curl-request.adoc new file mode 100644 index 00000000..78b426e8 --- /dev/null +++ b/custom/test-create-mapping-no-mapping/curl-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/http-request.adoc b/custom/test-create-mapping-no-mapping/http-request.adoc new file mode 100644 index 00000000..e5ae37bd --- /dev/null +++ b/custom/test-create-mapping-no-mapping/http-request.adoc @@ -0,0 +1,13 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/http-response.adoc b/custom/test-create-mapping-no-mapping/http-response.adoc new file mode 100644 index 00000000..6bc944f3 --- /dev/null +++ b/custom/test-create-mapping-no-mapping/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 400 Bad Request + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/httpie-request.adoc b/custom/test-create-mapping-no-mapping/httpie-request.adoc new file mode 100644 index 00000000..12eca7ef --- /dev/null +++ b/custom/test-create-mapping-no-mapping/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'record'@'record.json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/request-body.adoc b/custom/test-create-mapping-no-mapping/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping-no-mapping/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/response-body.adoc b/custom/test-create-mapping-no-mapping/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-create-mapping-no-mapping/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/curl-request.adoc b/custom/test-create-mapping-no-record/curl-request.adoc new file mode 100644 index 00000000..886f0f75 --- /dev/null +++ b/custom/test-create-mapping-no-record/curl-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/http-request.adoc b/custom/test-create-mapping-no-record/http-request.adoc new file mode 100644 index 00000000..d99bd7d0 --- /dev/null +++ b/custom/test-create-mapping-no-record/http-request.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "Publication Date":{ + "path": "publicationDate", + "type": "string" + } + } +} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/http-response.adoc b/custom/test-create-mapping-no-record/http-response.adoc new file mode 100644 index 00000000..6bc944f3 --- /dev/null +++ b/custom/test-create-mapping-no-record/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 400 Bad Request + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/httpie-request.adoc b/custom/test-create-mapping-no-record/httpie-request.adoc new file mode 100644 index 00000000..61e90bbe --- /dev/null +++ b/custom/test-create-mapping-no-record/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/request-body.adoc b/custom/test-create-mapping-no-record/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping-no-record/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/response-body.adoc b/custom/test-create-mapping-no-record/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-create-mapping-no-record/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/curl-request.adoc b/custom/test-create-mapping-twice/curl-request.adoc new file mode 100644 index 00000000..8818d020 --- /dev/null +++ b/custom/test-create-mapping-twice/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/http-request.adoc b/custom/test-create-mapping-twice/http-request.adoc new file mode 100644 index 00000000..39da1244 --- /dev/null +++ b/custom/test-create-mapping-twice/http-request.adoc @@ -0,0 +1,34 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[],"mappingDocumentUri":null,"documentHash":null} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "Publication Date":{ + "path": "publicationDate", + "type": "string" + } + } +} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/http-response.adoc b/custom/test-create-mapping-twice/http-response.adoc new file mode 100644 index 00000000..d863daa7 --- /dev/null +++ b/custom/test-create-mapping-twice/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 409 Conflict + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/httpie-request.adoc b/custom/test-create-mapping-twice/httpie-request.adoc new file mode 100644 index 00000000..f6687a5c --- /dev/null +++ b/custom/test-create-mapping-twice/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/request-body.adoc b/custom/test-create-mapping-twice/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping-twice/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/response-body.adoc b/custom/test-create-mapping-twice/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-create-mapping-twice/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/curl-request.adoc b/custom/test-create-mapping-with-acl/curl-request.adoc new file mode 100644 index 00000000..8818d020 --- /dev/null +++ b/custom/test-create-mapping-with-acl/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/http-request.adoc b/custom/test-create-mapping-with-acl/http-request.adoc new file mode 100644 index 00000000..36c8215d --- /dev/null +++ b/custom/test-create-mapping-with-acl/http-request.adoc @@ -0,0 +1,34 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "Publication Date":{ + "path": "publicationDate", + "type": "string" + } + } +} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/http-response.adoc b/custom/test-create-mapping-with-acl/http-response.adoc new file mode 100644 index 00000000..8745099d --- /dev/null +++ b/custom/test-create-mapping-with-acl/http-response.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 201 Created +Location: http://localhost:8095/api/v1/mappingAdministration/my_dc +Content-Type: application/json +Content-Length: 546 + +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : null, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : null, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : null, + "sid" : "test2", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/httpie-request.adoc b/custom/test-create-mapping-with-acl/httpie-request.adoc new file mode 100644 index 00000000..f6687a5c --- /dev/null +++ b/custom/test-create-mapping-with-acl/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/request-body.adoc b/custom/test-create-mapping-with-acl/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping-with-acl/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/response-body.adoc b/custom/test-create-mapping-with-acl/response-body.adoc new file mode 100644 index 00000000..74c13ef8 --- /dev/null +++ b/custom/test-create-mapping-with-acl/response-body.adoc @@ -0,0 +1,24 @@ +[source,json,options="nowrap"] +---- +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : null, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : null, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : null, + "sid" : "test2", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/curl-request.adoc b/custom/test-create-mapping-wrong-record/curl-request.adoc new file mode 100644 index 00000000..8818d020 --- /dev/null +++ b/custom/test-create-mapping-wrong-record/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/http-request.adoc b/custom/test-create-mapping-wrong-record/http-request.adoc new file mode 100644 index 00000000..3f563e82 --- /dev/null +++ b/custom/test-create-mapping-wrong-record/http-request.adoc @@ -0,0 +1,18 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":null,"title":null,"description":null,"acl":[],"mappingDocumentUri":null,"documentHash":null} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/http-response.adoc b/custom/test-create-mapping-wrong-record/http-response.adoc new file mode 100644 index 00000000..6bc944f3 --- /dev/null +++ b/custom/test-create-mapping-wrong-record/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 400 Bad Request + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/httpie-request.adoc b/custom/test-create-mapping-wrong-record/httpie-request.adoc new file mode 100644 index 00000000..f6687a5c --- /dev/null +++ b/custom/test-create-mapping-wrong-record/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/request-body.adoc b/custom/test-create-mapping-wrong-record/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping-wrong-record/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/response-body.adoc b/custom/test-create-mapping-wrong-record/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-create-mapping-wrong-record/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping/curl-request.adoc b/custom/test-create-mapping/curl-request.adoc new file mode 100644 index 00000000..8818d020 --- /dev/null +++ b/custom/test-create-mapping/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-create-mapping/http-request.adoc b/custom/test-create-mapping/http-request.adoc new file mode 100644 index 00000000..36c8215d --- /dev/null +++ b/custom/test-create-mapping/http-request.adoc @@ -0,0 +1,34 @@ +[source,http,options="nowrap"] +---- +POST /api/v1/mappingAdministration/ HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "Publication Date":{ + "path": "publicationDate", + "type": "string" + } + } +} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-create-mapping/http-response.adoc b/custom/test-create-mapping/http-response.adoc new file mode 100644 index 00000000..8745099d --- /dev/null +++ b/custom/test-create-mapping/http-response.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 201 Created +Location: http://localhost:8095/api/v1/mappingAdministration/my_dc +Content-Type: application/json +Content-Length: 546 + +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : null, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : null, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : null, + "sid" : "test2", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-create-mapping/httpie-request.adoc b/custom/test-create-mapping/httpie-request.adoc new file mode 100644 index 00000000..f6687a5c --- /dev/null +++ b/custom/test-create-mapping/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-create-mapping/request-body.adoc b/custom/test-create-mapping/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-create-mapping/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-create-mapping/response-body.adoc b/custom/test-create-mapping/response-body.adoc new file mode 100644 index 00000000..74c13ef8 --- /dev/null +++ b/custom/test-create-mapping/response-body.adoc @@ -0,0 +1,24 @@ +[source,json,options="nowrap"] +---- +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : null, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : null, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : null, + "sid" : "test2", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/curl-request.adoc b/custom/test-delete-mapping-missing-etag/curl-request.adoc new file mode 100644 index 00000000..71c4986c --- /dev/null +++ b/custom/test-delete-mapping-missing-etag/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ + -H 'Accept: application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/http-request.adoc b/custom/test-delete-mapping-missing-etag/http-request.adoc new file mode 100644 index 00000000..f03c1a0a --- /dev/null +++ b/custom/test-delete-mapping-missing-etag/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc HTTP/1.1 +Accept: application/vnd.datamanager.mapping-record+json +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/http-response.adoc b/custom/test-delete-mapping-missing-etag/http-response.adoc new file mode 100644 index 00000000..625b402d --- /dev/null +++ b/custom/test-delete-mapping-missing-etag/http-response.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Type: application/vnd.datamanager.mapping-record+json +Content-Length: 540 + +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 50, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 48, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : 49, + "sid" : "SELF", + "permission" : "READ" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/httpie-request.adoc b/custom/test-delete-mapping-missing-etag/httpie-request.adoc new file mode 100644 index 00000000..351810e7 --- /dev/null +++ b/custom/test-delete-mapping-missing-etag/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'Accept:application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/request-body.adoc b/custom/test-delete-mapping-missing-etag/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-delete-mapping-missing-etag/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/response-body.adoc b/custom/test-delete-mapping-missing-etag/response-body.adoc new file mode 100644 index 00000000..ee524be6 --- /dev/null +++ b/custom/test-delete-mapping-missing-etag/response-body.adoc @@ -0,0 +1,24 @@ +[source,json,options="nowrap"] +---- +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 50, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 48, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : 49, + "sid" : "SELF", + "permission" : "READ" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc new file mode 100644 index 00000000..890ac553 --- /dev/null +++ b/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/unknownMappingId' -i -X DELETE \ + -H 'If-Match: "104363025"' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc new file mode 100644 index 00000000..8113df33 --- /dev/null +++ b/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +DELETE /api/v1/mappingAdministration/unknownMappingId HTTP/1.1 +If-Match: "104363025" +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc b/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc new file mode 100644 index 00000000..b2e108f3 --- /dev/null +++ b/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 204 No Content + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc new file mode 100644 index 00000000..a0cc74a7 --- /dev/null +++ b/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http DELETE 'http://localhost:8095/api/v1/mappingAdministration/unknownMappingId' \ + 'If-Match:"104363025"' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc b/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc b/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/curl-request.adoc b/custom/test-delete-mapping-wrong-etag/curl-request.adoc new file mode 100644 index 00000000..71c4986c --- /dev/null +++ b/custom/test-delete-mapping-wrong-etag/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ + -H 'Accept: application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/http-request.adoc b/custom/test-delete-mapping-wrong-etag/http-request.adoc new file mode 100644 index 00000000..f03c1a0a --- /dev/null +++ b/custom/test-delete-mapping-wrong-etag/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc HTTP/1.1 +Accept: application/vnd.datamanager.mapping-record+json +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/http-response.adoc b/custom/test-delete-mapping-wrong-etag/http-response.adoc new file mode 100644 index 00000000..f15901cd --- /dev/null +++ b/custom/test-delete-mapping-wrong-etag/http-response.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Type: application/vnd.datamanager.mapping-record+json +Content-Length: 540 + +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 46, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : 47, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 45, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/httpie-request.adoc b/custom/test-delete-mapping-wrong-etag/httpie-request.adoc new file mode 100644 index 00000000..351810e7 --- /dev/null +++ b/custom/test-delete-mapping-wrong-etag/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'Accept:application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/request-body.adoc b/custom/test-delete-mapping-wrong-etag/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-delete-mapping-wrong-etag/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/response-body.adoc b/custom/test-delete-mapping-wrong-etag/response-body.adoc new file mode 100644 index 00000000..4ae542f4 --- /dev/null +++ b/custom/test-delete-mapping-wrong-etag/response-body.adoc @@ -0,0 +1,24 @@ +[source,json,options="nowrap"] +---- +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 46, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : 47, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 45, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-delete-mapping/curl-request.adoc b/custom/test-delete-mapping/curl-request.adoc new file mode 100644 index 00000000..71c4986c --- /dev/null +++ b/custom/test-delete-mapping/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ + -H 'Accept: application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping/http-request.adoc b/custom/test-delete-mapping/http-request.adoc new file mode 100644 index 00000000..f03c1a0a --- /dev/null +++ b/custom/test-delete-mapping/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc HTTP/1.1 +Accept: application/vnd.datamanager.mapping-record+json +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping/http-response.adoc b/custom/test-delete-mapping/http-response.adoc new file mode 100644 index 00000000..f3b256d0 --- /dev/null +++ b/custom/test-delete-mapping/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 404 Not Found + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping/httpie-request.adoc b/custom/test-delete-mapping/httpie-request.adoc new file mode 100644 index 00000000..351810e7 --- /dev/null +++ b/custom/test-delete-mapping/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'Accept:application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-delete-mapping/request-body.adoc b/custom/test-delete-mapping/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-delete-mapping/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-delete-mapping/response-body.adoc b/custom/test-delete-mapping/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-delete-mapping/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc new file mode 100644 index 00000000..36fb7cb1 --- /dev/null +++ b/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' -i -X GET \ + -H 'Accept: application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc new file mode 100644 index 00000000..07b9f8c0 --- /dev/null +++ b/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/invalidMappingId HTTP/1.1 +Accept: application/vnd.datamanager.mapping-record+json +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc new file mode 100644 index 00000000..f3b256d0 --- /dev/null +++ b/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 404 Not Found + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc new file mode 100644 index 00000000..f0ed9abb --- /dev/null +++ b/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' \ + 'Accept:application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/curl-request.adoc b/custom/test-get-mapping-by-id/curl-request.adoc new file mode 100644 index 00000000..71c4986c --- /dev/null +++ b/custom/test-get-mapping-by-id/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ + -H 'Accept: application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/http-request.adoc b/custom/test-get-mapping-by-id/http-request.adoc new file mode 100644 index 00000000..f03c1a0a --- /dev/null +++ b/custom/test-get-mapping-by-id/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc HTTP/1.1 +Accept: application/vnd.datamanager.mapping-record+json +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/http-response.adoc b/custom/test-get-mapping-by-id/http-response.adoc new file mode 100644 index 00000000..a4630c9e --- /dev/null +++ b/custom/test-get-mapping-by-id/http-response.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Type: application/vnd.datamanager.mapping-record+json +Content-Length: 540 + +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 57, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : 59, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 58, + "sid" : "SELF", + "permission" : "READ" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/httpie-request.adoc b/custom/test-get-mapping-by-id/httpie-request.adoc new file mode 100644 index 00000000..351810e7 --- /dev/null +++ b/custom/test-get-mapping-by-id/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'Accept:application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/request-body.adoc b/custom/test-get-mapping-by-id/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-get-mapping-by-id/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/response-body.adoc b/custom/test-get-mapping-by-id/response-body.adoc new file mode 100644 index 00000000..b9fa0796 --- /dev/null +++ b/custom/test-get-mapping-by-id/response-body.adoc @@ -0,0 +1,24 @@ +[source,json,options="nowrap"] +---- +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 57, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + }, { + "id" : 59, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 58, + "sid" : "SELF", + "permission" : "READ" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc new file mode 100644 index 00000000..443c291b --- /dev/null +++ b/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' -i -X GET +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc new file mode 100644 index 00000000..a2d8037e --- /dev/null +++ b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc @@ -0,0 +1,6 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/invalidMappingId HTTP/1.1 +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc new file mode 100644 index 00000000..f3b256d0 --- /dev/null +++ b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 404 Not Found + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc new file mode 100644 index 00000000..844f1b2c --- /dev/null +++ b/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/curl-request.adoc b/custom/test-get-mapping-document-by-id/curl-request.adoc new file mode 100644 index 00000000..4b167b7c --- /dev/null +++ b/custom/test-get-mapping-document-by-id/curl-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/http-request.adoc b/custom/test-get-mapping-document-by-id/http-request.adoc new file mode 100644 index 00000000..4aa6e413 --- /dev/null +++ b/custom/test-get-mapping-document-by-id/http-request.adoc @@ -0,0 +1,6 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/http-response.adoc b/custom/test-get-mapping-document-by-id/http-response.adoc new file mode 100644 index 00000000..007bbfb2 --- /dev/null +++ b/custom/test-get-mapping-document-by-id/http-response.adoc @@ -0,0 +1,26 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Length: 409 +Accept-Ranges: bytes +Content-Type: application/octet-stream + +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "Publication Date" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/httpie-request.adoc b/custom/test-get-mapping-document-by-id/httpie-request.adoc new file mode 100644 index 00000000..a954b9fc --- /dev/null +++ b/custom/test-get-mapping-document-by-id/httpie-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/request-body.adoc b/custom/test-get-mapping-document-by-id/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-get-mapping-document-by-id/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/response-body.adoc b/custom/test-get-mapping-document-by-id/response-body.adoc new file mode 100644 index 00000000..bd0e4ace --- /dev/null +++ b/custom/test-get-mapping-document-by-id/response-body.adoc @@ -0,0 +1,20 @@ +[source,octet-stream,options="nowrap"] +---- +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "Publication Date" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/curl-request.adoc b/custom/test-update-mapping-with-invalid-record/curl-request.adoc new file mode 100644 index 00000000..71c4986c --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record/curl-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ + -H 'Accept: application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/http-request.adoc b/custom/test-update-mapping-with-invalid-record/http-request.adoc new file mode 100644 index 00000000..f03c1a0a --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record/http-request.adoc @@ -0,0 +1,7 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc HTTP/1.1 +Accept: application/vnd.datamanager.mapping-record+json +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/http-response.adoc b/custom/test-update-mapping-with-invalid-record/http-response.adoc new file mode 100644 index 00000000..57ed668f --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record/http-response.adoc @@ -0,0 +1,29 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Type: application/vnd.datamanager.mapping-record+json +Content-Length: 540 + +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 53, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 52, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : 51, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/httpie-request.adoc b/custom/test-update-mapping-with-invalid-record/httpie-request.adoc new file mode 100644 index 00000000..351810e7 --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record/httpie-request.adoc @@ -0,0 +1,5 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'Accept:application/vnd.datamanager.mapping-record+json' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/request-body.adoc b/custom/test-update-mapping-with-invalid-record/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/response-body.adoc b/custom/test-update-mapping-with-invalid-record/response-body.adoc new file mode 100644 index 00000000..5322a2f5 --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record/response-body.adoc @@ -0,0 +1,24 @@ +[source,json,options="nowrap"] +---- +{ + "mappingId" : "my_dc", + "mappingType" : "GEMMA", + "title" : "TITEL", + "description" : "DESCRIPTION", + "acl" : [ { + "id" : 53, + "sid" : "test2", + "permission" : "ADMINISTRATE" + }, { + "id" : 52, + "sid" : "SELF", + "permission" : "READ" + }, { + "id" : 51, + "sid" : "anonymousUser", + "permission" : "ADMINISTRATE" + } ], + "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", + "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/curl-request.adoc b/custom/test-update-mapping-with-invalid-record2/curl-request.adoc new file mode 100644 index 00000000..4b167b7c --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record2/curl-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/http-request.adoc b/custom/test-update-mapping-with-invalid-record2/http-request.adoc new file mode 100644 index 00000000..4aa6e413 --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record2/http-request.adoc @@ -0,0 +1,6 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/http-response.adoc b/custom/test-update-mapping-with-invalid-record2/http-response.adoc new file mode 100644 index 00000000..67a3b84f --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record2/http-response.adoc @@ -0,0 +1,26 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Length: 418 +Accept-Ranges: bytes +Content-Type: application/octet-stream + +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping Version 2", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "PublicationDate" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc b/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc new file mode 100644 index 00000000..a954b9fc --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/request-body.adoc b/custom/test-update-mapping-with-invalid-record2/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record2/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/response-body.adoc b/custom/test-update-mapping-with-invalid-record2/response-body.adoc new file mode 100644 index 00000000..139a1028 --- /dev/null +++ b/custom/test-update-mapping-with-invalid-record2/response-body.adoc @@ -0,0 +1,20 @@ +[source,octet-stream,options="nowrap"] +---- +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping Version 2", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "PublicationDate" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/curl-request.adoc b/custom/test-update-mapping-with-wrong-etag/curl-request.adoc new file mode 100644 index 00000000..51612ec4 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-etag/curl-request.adoc @@ -0,0 +1,8 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ + -H 'Content-Type: multipart/form-data' \ + -H 'If-Match: wrongEtag' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/http-request.adoc b/custom/test-update-mapping-with-wrong-etag/http-request.adoc new file mode 100644 index 00000000..ae126741 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-etag/http-request.adoc @@ -0,0 +1,36 @@ +[source,http,options="nowrap"] +---- +PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +If-Match: wrongEtag +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"someoneelse","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b"} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping Version 2", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "PublicationDate":{ + "path": "publicationDate", + "type": "string" + } + } +} + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/http-response.adoc b/custom/test-update-mapping-with-wrong-etag/http-response.adoc new file mode 100644 index 00000000..5549e3fe --- /dev/null +++ b/custom/test-update-mapping-with-wrong-etag/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 412 Precondition Failed + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc b/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc new file mode 100644 index 00000000..51122c72 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'If-Match:wrongEtag' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/request-body.adoc b/custom/test-update-mapping-with-wrong-etag/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-etag/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/response-body.adoc b/custom/test-update-mapping-with-wrong-etag/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-with-wrong-etag/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/curl-request.adoc b/custom/test-update-mapping-with-wrong-record3/curl-request.adoc new file mode 100644 index 00000000..f6ea3824 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-record3/curl-request.adoc @@ -0,0 +1,8 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/unknownMaping' -i -X PUT \ + -H 'Content-Type: multipart/form-data' \ + -H 'If-Match: "104363025"' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/http-request.adoc b/custom/test-update-mapping-with-wrong-record3/http-request.adoc new file mode 100644 index 00000000..f9074c1e --- /dev/null +++ b/custom/test-update-mapping-with-wrong-record3/http-request.adoc @@ -0,0 +1,36 @@ +[source,http,options="nowrap"] +---- +PUT /api/v1/mappingAdministration/unknownMaping HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +If-Match: "104363025" +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":43,"sid":"SELF","permission":"READ"},{"id":42,"sid":"anonymousUser","permission":"ADMINISTRATE"},{"id":44,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b"} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping Version 2", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "PublicationDate":{ + "path": "publicationDate", + "type": "string" + } + } +} + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/http-response.adoc b/custom/test-update-mapping-with-wrong-record3/http-response.adoc new file mode 100644 index 00000000..f3b256d0 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-record3/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 404 Not Found + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc b/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc new file mode 100644 index 00000000..0a2f8d2b --- /dev/null +++ b/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/unknownMaping' \ + 'If-Match:"104363025"' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/request-body.adoc b/custom/test-update-mapping-with-wrong-record3/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-update-mapping-with-wrong-record3/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/response-body.adoc b/custom/test-update-mapping-with-wrong-record3/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-with-wrong-record3/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/curl-request.adoc b/custom/test-update-mapping-without-document/curl-request.adoc new file mode 100644 index 00000000..4b167b7c --- /dev/null +++ b/custom/test-update-mapping-without-document/curl-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/http-request.adoc b/custom/test-update-mapping-without-document/http-request.adoc new file mode 100644 index 00000000..4aa6e413 --- /dev/null +++ b/custom/test-update-mapping-without-document/http-request.adoc @@ -0,0 +1,6 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/http-response.adoc b/custom/test-update-mapping-without-document/http-response.adoc new file mode 100644 index 00000000..007bbfb2 --- /dev/null +++ b/custom/test-update-mapping-without-document/http-response.adoc @@ -0,0 +1,26 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Length: 409 +Accept-Ranges: bytes +Content-Type: application/octet-stream + +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "Publication Date" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/httpie-request.adoc b/custom/test-update-mapping-without-document/httpie-request.adoc new file mode 100644 index 00000000..a954b9fc --- /dev/null +++ b/custom/test-update-mapping-without-document/httpie-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/request-body.adoc b/custom/test-update-mapping-without-document/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-without-document/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/response-body.adoc b/custom/test-update-mapping-without-document/response-body.adoc new file mode 100644 index 00000000..bd0e4ace --- /dev/null +++ b/custom/test-update-mapping-without-document/response-body.adoc @@ -0,0 +1,20 @@ +[source,octet-stream,options="nowrap"] +---- +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "Publication Date" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/curl-request.adoc b/custom/test-update-mapping-without-etag/curl-request.adoc new file mode 100644 index 00000000..ea30de0b --- /dev/null +++ b/custom/test-update-mapping-without-etag/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ + -H 'Content-Type: multipart/form-data' \ + -F 'record=@record.json;type=application/json' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/http-request.adoc b/custom/test-update-mapping-without-etag/http-request.adoc new file mode 100644 index 00000000..d0b108c4 --- /dev/null +++ b/custom/test-update-mapping-without-etag/http-request.adoc @@ -0,0 +1,35 @@ +[source,http,options="nowrap"] +---- +PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=record; filename=record.json +Content-Type: application/json + +{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"someoneelse","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b"} +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping Version 2", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "PublicationDate":{ + "path": "publicationDate", + "type": "string" + } + } +} + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/http-response.adoc b/custom/test-update-mapping-without-etag/http-response.adoc new file mode 100644 index 00000000..7448deeb --- /dev/null +++ b/custom/test-update-mapping-without-etag/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 428 Precondition Required + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/httpie-request.adoc b/custom/test-update-mapping-without-etag/httpie-request.adoc new file mode 100644 index 00000000..3b932a63 --- /dev/null +++ b/custom/test-update-mapping-without-etag/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'record'@'record.json' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/request-body.adoc b/custom/test-update-mapping-without-etag/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-update-mapping-without-etag/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/response-body.adoc b/custom/test-update-mapping-without-etag/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-without-etag/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/curl-request.adoc b/custom/test-update-mapping-without-record/curl-request.adoc new file mode 100644 index 00000000..baee036f --- /dev/null +++ b/custom/test-update-mapping-without-record/curl-request.adoc @@ -0,0 +1,7 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ + -H 'Content-Type: multipart/form-data' \ + -H 'If-Match: "104363025"' \ + -F 'document=@my_dc4gemma.mapping;type=application/json' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/http-request.adoc b/custom/test-update-mapping-without-record/http-request.adoc new file mode 100644 index 00000000..2fab7976 --- /dev/null +++ b/custom/test-update-mapping-without-record/http-request.adoc @@ -0,0 +1,31 @@ +[source,http,options="nowrap"] +---- +PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 +Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +If-Match: "104363025" +Host: localhost:8095 + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm +Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping +Content-Type: application/json + +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://example.com/product.schema.json", + "title": "Simple Mapping Version 2", + "description": "Data resource mapping from json", + "type": "object", + "properties":{ + "Publisher":{ + "path": "publisher", + "type": "string" + }, + "PublicationDate":{ + "path": "publicationDate", + "type": "string" + } + } +} + +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/http-response.adoc b/custom/test-update-mapping-without-record/http-response.adoc new file mode 100644 index 00000000..6bc944f3 --- /dev/null +++ b/custom/test-update-mapping-without-record/http-response.adoc @@ -0,0 +1,5 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 400 Bad Request + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/httpie-request.adoc b/custom/test-update-mapping-without-record/httpie-request.adoc new file mode 100644 index 00000000..29510d9f --- /dev/null +++ b/custom/test-update-mapping-without-record/httpie-request.adoc @@ -0,0 +1,6 @@ +[source,bash] +---- +$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ + 'If-Match:"104363025"' \ + 'document'@'my_dc4gemma.mapping' +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/request-body.adoc b/custom/test-update-mapping-without-record/request-body.adoc new file mode 100644 index 00000000..d074c300 --- /dev/null +++ b/custom/test-update-mapping-without-record/request-body.adoc @@ -0,0 +1,4 @@ +[source,form-data,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/response-body.adoc b/custom/test-update-mapping-without-record/response-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping-without-record/response-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping/curl-request.adoc b/custom/test-update-mapping/curl-request.adoc new file mode 100644 index 00000000..4b167b7c --- /dev/null +++ b/custom/test-update-mapping/curl-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET +---- \ No newline at end of file diff --git a/custom/test-update-mapping/http-request.adoc b/custom/test-update-mapping/http-request.adoc new file mode 100644 index 00000000..4aa6e413 --- /dev/null +++ b/custom/test-update-mapping/http-request.adoc @@ -0,0 +1,6 @@ +[source,http,options="nowrap"] +---- +GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 +Host: localhost:8095 + +---- \ No newline at end of file diff --git a/custom/test-update-mapping/http-response.adoc b/custom/test-update-mapping/http-response.adoc new file mode 100644 index 00000000..67a3b84f --- /dev/null +++ b/custom/test-update-mapping/http-response.adoc @@ -0,0 +1,26 @@ +[source,http,options="nowrap"] +---- +HTTP/1.1 200 OK +ETag: "104363025" +Content-Length: 418 +Accept-Ranges: bytes +Content-Type: application/octet-stream + +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping Version 2", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "PublicationDate" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/custom/test-update-mapping/httpie-request.adoc b/custom/test-update-mapping/httpie-request.adoc new file mode 100644 index 00000000..a954b9fc --- /dev/null +++ b/custom/test-update-mapping/httpie-request.adoc @@ -0,0 +1,4 @@ +[source,bash] +---- +$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' +---- \ No newline at end of file diff --git a/custom/test-update-mapping/request-body.adoc b/custom/test-update-mapping/request-body.adoc new file mode 100644 index 00000000..dab5f81d --- /dev/null +++ b/custom/test-update-mapping/request-body.adoc @@ -0,0 +1,4 @@ +[source,options="nowrap"] +---- + +---- \ No newline at end of file diff --git a/custom/test-update-mapping/response-body.adoc b/custom/test-update-mapping/response-body.adoc new file mode 100644 index 00000000..139a1028 --- /dev/null +++ b/custom/test-update-mapping/response-body.adoc @@ -0,0 +1,20 @@ +[source,octet-stream,options="nowrap"] +---- +{ + "$schema" : "http://json-schema.org/draft-07/schema#", + "$id" : "http://example.com/product.schema.json", + "title" : "Simple Mapping Version 2", + "description" : "Data resource mapping from json", + "type" : "object", + "properties" : { + "Publisher" : { + "path" : "publisher", + "type" : "string" + }, + "PublicationDate" : { + "path" : "publicationDate", + "type" : "string" + } + } +} +---- \ No newline at end of file diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index f0f87903..81a12a27 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -184,7 +184,7 @@ public void deleteMapping(MappingRecord mappingRecord) { public Optional executeMapping(URI contentUrl, String mappingId) throws MappingPluginException { LOGGER.trace("Executing mapping of content {} using mapping with id {}.", contentUrl, mappingId); if (contentUrl == null || mappingId == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Either contentUrl or mappingId are not provided."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Either contentUrl or mappingId are not provided."); } Optional returnValue; diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java index 9937fb42..91cc150b 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java @@ -34,7 +34,7 @@ public class MappingPluginException extends Exception { * @param state State of the plugin. */ public MappingPluginException(MappingPluginState state) { - super(state.name()); + super(state.getState().name()); this.state = state; } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java index 8a55bc90..2c75bc5f 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginState.java @@ -15,12 +15,10 @@ public class MappingPluginState implements Serializable { public enum StateEnum { SUCCESS(HttpStatus.OK), NOT_FOUND(HttpStatus.NOT_FOUND), - TIMEOUT, + TIMEOUT(HttpStatus.GATEWAY_TIMEOUT), EXECUTION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), - INVALID_INPUT, - BAD_EXIT_CODE, - INCORRECT_MIME_TYPE, - INSUFFICIENT_PRIVILEGES(HttpStatus.INTERNAL_SERVER_ERROR), + INVALID_INPUT(HttpStatus.BAD_REQUEST), + BAD_EXIT_CODE(HttpStatus.INTERNAL_SERVER_ERROR), UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR); private final HttpStatus httpStatus; @@ -75,14 +73,6 @@ public static MappingPluginState BAD_EXIT_CODE() { return new MappingPluginState(StateEnum.BAD_EXIT_CODE); } - public static MappingPluginState INCORRECT_MIME_TYPE() { - return new MappingPluginState(StateEnum.INCORRECT_MIME_TYPE); - } - - public static MappingPluginState INSUFFICIENT_PRIVILEGES() { - return new MappingPluginState(StateEnum.INSUFFICIENT_PRIVILEGES); - } - public static MappingPluginState UNKNOWN_ERROR() { return new MappingPluginState(StateEnum.UNKNOWN_ERROR); } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java index daec7db6..efc0024e 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java @@ -14,6 +14,8 @@ */ package edu.kit.datamanager.mappingservice.plugins; +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,33 +55,46 @@ public static void unload() { /** * Load plugins from a given directory. * - * @param plugDir Directory containing plugins. + * @param pluginDir Directory containing plugins. * @return Map of plugins. * @throws IOException If there is an error with the file system. * @throws MappingPluginException If there is an error with the plugin or * the input. */ - public static Map loadPlugins(File plugDir) throws IOException, MappingPluginException { + public static Map loadPlugins(File pluginDir) throws IOException, MappingPluginException { Map result = new HashMap<>(); - if (plugDir == null || plugDir.getAbsolutePath().isBlank()) { - LOG.warn("Plugin folder " + plugDir + " is null. Unable to load plugins."); + File[] pluginJars = new File[0]; + if (pluginDir == null || pluginDir.getAbsolutePath().isBlank()) { + LOG.warn("Plugin folder {} is not defined. MappingService will only use plugins in classpath.", pluginDir); } else { - File[] plugJars = plugDir.listFiles(new JARFileFilter()); - if (plugJars == null || plugJars.length < 1) { + pluginJars = pluginDir.listFiles(new JARFileFilter()); + + //removed check as plugins are now also accepted from classpath + /*if (plugJars == null || plugJars.length < 1) { LOG.warn("Plugin folder " + plugDir + " is empty. Unable to load plugins."); - } else { - cl = new URLClassLoader(PluginLoader.fileArrayToURLArray(plugJars), Thread.currentThread().getContextClassLoader()); + } else {*/ + // } + } - List> plugClasses = PluginLoader.extractClassesFromJARs(plugJars, cl); - List IMappingPluginList = PluginLoader.createPluggableObjects(plugClasses); + if (pluginJars.length > 0) { + cl = new URLClassLoader(PluginLoader.fileArrayToURLArray(pluginJars), Thread.currentThread().getContextClassLoader()); + } else { + cl = Thread.currentThread().getContextClassLoader(); + } - for (IMappingPlugin i : IMappingPluginList) { - //TODO: Add error handling in case setup of one plugin fails - i.setup(); - result.put(i.id(), i); - } + List> plugClasses = PluginLoader.extractClassesFromJARs(pluginJars, cl); + List IMappingPluginList = PluginLoader.createPluggableObjects(plugClasses); + + for (IMappingPlugin i : IMappingPluginList) { + try { + i.setup(); + result.put(i.id(), i); + } catch (RuntimeException re) { + LOG.error("Caught RuntimeException while setting up plugin " + i.name() + ", version " + i.version() + ". Plugin will be ignored.", re); } + } + return result; } @@ -98,6 +113,27 @@ private static List> extractClassesFromJARs(File[] jars, C LOG.trace("Processing file {}.", jar.getAbsolutePath()); classes.addAll(PluginLoader.extractClassesFromJAR(jar, cl)); } + + LOG.trace("Found {} plugin classes in jar files.", classes.size()); + + LOG.trace("Extracting classes from classpath."); + ImmutableSet clazzes = ClassPath.from(cl).getTopLevelClasses("edu.kit.datamanager.mappingservice.plugins.impl"); + int pluginCnt = 0; + for (ClassPath.ClassInfo clazz : clazzes) { + try { + LOG.trace("Processing class {}.", clazz.getName()); + Class pl = (Class) clazz.load(); + + if (isPluggableClass(pl)) { + classes.add((Class) pl); + pluginCnt++; + } + } catch (ClassCastException ex) { + //failed to load, probably no implementation of IMappingPlugin + } + } + LOG.trace("Found {} plugin classes in classpath.", pluginCnt); + return classes; } @@ -117,7 +153,7 @@ private static List> extractClassesFromJAR(File jar, Class } } catch (ClassNotFoundException | NoClassDefFoundError e) { LOG.info("Can't load Class " + ent.getName()); - throw new MappingPluginException(MappingPluginState.UNKNOWN_ERROR, "Can't load Class " + ent.getName(), e); + throw new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "Can't load Class " + ent.getName(), e); } } } @@ -126,7 +162,7 @@ private static List> extractClassesFromJAR(File jar, Class } private static boolean isPluggableClass(Class cls) { - for (Class i : cls.getInterfaces()) { + /*for (Class i : cls.getInterfaces()) { LOG.trace("Checking {} against {}.", i, IMappingPlugin.class); LOG.trace("ASSIGN {}", IMappingPlugin.class.isAssignableFrom(cls)); if (i.equals(IMappingPlugin.class)) { @@ -134,7 +170,10 @@ private static boolean isPluggableClass(Class cls) { return true; } } - return false; + return false;*/ + + //this should be much easier and faster + return IMappingPlugin.class.isAssignableFrom(cls); } private static List createPluggableObjects(List> pluggable) throws MappingPluginException { @@ -146,10 +185,10 @@ private static List createPluggableObjects(List listPluginIds() { */ public final MappingPluginState mapFile(String pluginId, Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { if (pluginId == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Plugin ID is null."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Plugin ID is null."); } if (mappingFile == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Path to mapping schema is null."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Path to mapping schema is null."); } if (inputFile == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Path to input file is null."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Path to input file is null."); } if (outputFile == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Path to output file is null."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Path to output file is null."); } if (plugins.containsKey(pluginId)) { LOG.trace("Plugin found. Performing mapFile({}, {}, {}).", mappingFile, inputFile, outputFile); return plugins.get(pluginId).mapFile(mappingFile, inputFile, outputFile); } - throw new MappingPluginException(MappingPluginState.NOT_FOUND, "Plugin '" + pluginId + "' not found!"); + throw new MappingPluginException(MappingPluginState.NOT_FOUND(), "Plugin '" + pluginId + "' not found!"); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java index 0724d2af..64ccf2e2 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java @@ -81,7 +81,7 @@ public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputF return PythonRunnerUtil.runPythonScript(gemmaDir + "/mapping_single.py", mappingFile.toString(), inputFile.toString(), outputFile.toString()); } else { LOGGER.error("Plugin '" + name() + "' " + version() + " not initialized. Returning EXECUTION_ERROR."); - return MappingPluginState.EXECUTION_ERROR; + return MappingPluginState.EXECUTION_ERROR(); } } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java index 073f391c..384c1bfb 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java @@ -85,9 +85,9 @@ public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputF fout.close(); } catch (IOException ex) { LOG.error("Failed to execute plugin.", ex); - return MappingPluginState.EXECUTION_ERROR; + return MappingPluginState.EXECUTION_ERROR(); } - return MappingPluginState.SUCCESS; + return MappingPluginState.SUCCESS(); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java index 56a554fe..69bc985d 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java @@ -77,9 +77,9 @@ public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputF Files.copy(inputFile, outputFile, StandardCopyOption.REPLACE_EXISTING); } catch (IOException | MappingException ex) { LOG.error("Failed to execute plugin.", ex); - return MappingPluginState.EXECUTION_ERROR; + return MappingPluginState.EXECUTION_ERROR(); } - return MappingPluginState.SUCCESS; + return MappingPluginState.SUCCESS(); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java index 12e92225..9c9d635e 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java @@ -99,7 +99,7 @@ public PluginInformation(String id, PluginManager manager) throws MappingPluginE Arrays.stream(p.outputTypes()).toList().forEach(mimeType -> outputTypesList.add(mimeType.toString())); this.outputTypes = outputTypesList.toArray(new String[0]); } else { - throw new MappingPluginException(MappingPluginState.NOT_FOUND, "Plugin with id " + id + " not found."); + throw new MappingPluginException(MappingPluginState.NOT_FOUND(), "Plugin with id " + id + " not found."); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java index ba68bcaa..b2630b69 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java @@ -113,7 +113,7 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq if (resultPath.isPresent()) { LOG.trace("Mapping process finished. Output written to {}.", resultPath.toString()); } else { - throw new MappingPluginException(MappingPluginState.UNKNOWN_ERROR, "Mapping process finished, but no result was returned."); + throw new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "Mapping process finished, but no result was returned."); } } catch (MappingPluginException e) { LOG.error("Failed to execute mapping.", e); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java index bdc21696..660f919d 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java @@ -97,21 +97,21 @@ public static MappingPluginState run(OutputStream output, OutputStream error, St */ public static MappingPluginState run(OutputStream output, OutputStream error, int timeOutInSeconds, String... command) throws MappingPluginException { if (output == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Output stream is null."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Output stream is null."); } if (error == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Error stream is null."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Error stream is null."); } if (timeOutInSeconds <= 0) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "Timeout is null or negative."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Timeout is null or negative."); } if (command == null || command.length == 0) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT, "No command given."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "No command given."); } ExecutorService pool = Executors.newSingleThreadExecutor(); int result; - MappingPluginState returnValue = MappingPluginState.SUCCESS; + MappingPluginState returnValue = MappingPluginState.SUCCESS(); try { ProcessBuilder pb = new ProcessBuilder(command); @@ -141,21 +141,21 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in } } catch (IOException ioe) { LOGGER.error("Failed to run command or to access output/error streams.", ioe); - returnValue = MappingPluginState.EXECUTION_ERROR; + returnValue = MappingPluginState.EXECUTION_ERROR(); } catch (TimeoutException te) { LOGGER.error("Command did not return in expected timeframe of " + TIMEOUT + " seconds", te); - returnValue = MappingPluginState.TIMEOUT; + returnValue = MappingPluginState.TIMEOUT(); } catch (InterruptedException | ExecutionException e) { LOGGER.error("Command execution has been interrupted.", e); - returnValue = MappingPluginState.UNKNOWN_ERROR; + returnValue = MappingPluginState.UNKNOWN_ERROR(); } catch (BadExitCodeException e) { LOGGER.error("Failed to execute command due to an unexpected exception.", e); - returnValue = MappingPluginState.UNKNOWN_ERROR; + returnValue = MappingPluginState.UNKNOWN_ERROR(); } finally { pool.shutdown(); } - if (returnValue != MappingPluginState.SUCCESS) { + if (returnValue != MappingPluginState.SUCCESS()) { throw new MappingPluginException(returnValue); } return returnValue; diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java index 0cb2482d..0ef0f6b8 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java @@ -23,18 +23,18 @@ class MappingPluginExceptionTest { @Test void testConstructor() { - MappingPluginException ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR); - assertEquals(MappingPluginState.UNKNOWN_ERROR, ex.getState()); - assertEquals(MappingPluginState.UNKNOWN_ERROR.toString(), ex.getMessage()); + MappingPluginException ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR()); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getState().getState()); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState().toString(), ex.getMessage()); assertNull(ex.getCause()); - ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR, "test"); - assertEquals(MappingPluginState.UNKNOWN_ERROR, ex.getState()); + ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "test"); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getState().getState()); assertEquals("test", ex.getMessage()); assertNull(ex.getCause()); - ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR, "test", new Exception()); - assertEquals(MappingPluginState.UNKNOWN_ERROR, ex.getState()); + ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "test", new Exception()); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getState().getState()); assertEquals("test", ex.getMessage()); assertNotNull(ex.getCause()); } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java index 93cbf68b..e7a37fdb 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java @@ -72,7 +72,7 @@ void valid() { assertEquals(MimeTypeUtils.APPLICATION_JSON, plugins.get("TEST_0.0.0").inputTypes()[0]); assertEquals(MimeTypeUtils.APPLICATION_JSON, plugins.get("TEST_0.0.0").outputTypes()[0]); plugins.get("TEST_0.0.0").setup(); - assertEquals(MappingPluginState.SUCCESS, plugins.get("TEST_0.0.0").mapFile(new File("schema").toPath(), new File("input").toPath(), new File("output").toPath())); + assertEquals(MappingPluginState.SUCCESS().getState(), plugins.get("TEST_0.0.0").mapFile(new File("schema").toPath(), new File("input").toPath(), new File("output").toPath()).getState()); } catch (Exception e) { fail(e); } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java index d8832dc2..43ac75f8 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java @@ -39,11 +39,11 @@ class PluginManagerTest { @BeforeEach void setup() throws Exception { - try { + /*try { FileUtils.copyDirectory(Path.of("./plugins").toFile(), Path.of(applicationProperties.getPluginLocation().toURI()).toFile()); } catch (IOException ex) { ex.printStackTrace(); - } + }*/ pluginManager.reloadPlugins(); } @@ -72,35 +72,35 @@ void mapFileInvalidParameters() { try { pluginManager.mapFile(null, null, null, null); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT, e.getState()); + assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); assertEquals("Plugin ID is null.", e.getMessage()); } try { pluginManager.mapFile("test", null, null, null); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT, e.getState()); + assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); assertEquals("Path to mapping schema is null.", e.getMessage()); } try { pluginManager.mapFile("test", new File("test").toPath(), null, null); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT, e.getState()); + assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); assertEquals("Path to input file is null.", e.getMessage()); } try { pluginManager.mapFile("test", new File("test").toPath(), new File("testInput").toPath(), null); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT, e.getState()); + assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); assertEquals("Path to output file is null.", e.getMessage()); } try { pluginManager.mapFile("test", new File("test").toPath(), new File("testInput").toPath(), new File("testOutput").toPath()); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.NOT_FOUND, e.getState()); + assertEquals(MappingPluginState.NOT_FOUND(), e.getState()); assertEquals("Plugin 'test' not found!", e.getMessage()); } } @@ -109,7 +109,8 @@ void mapFileInvalidParameters() { void mapFile() { try { File outputFile = new File("/tmp/testOutput"); - pluginManager.mapFile("TEST_0.0.0", new File("mapping-schema").toPath(), new File("input").toPath(), outputFile.toPath()); + System.out.println("PLUGINS " + pluginManager.getPlugins()); + pluginManager.mapFile("InOutPlugin_1.1.2", new File("mapping-schema").toPath(), new File("input").toPath(), outputFile.toPath()); assertTrue(outputFile.exists()); outputFile.delete(); } catch (MappingPluginException e) { diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java index 10396646..873f7c9f 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java @@ -230,7 +230,7 @@ void testIDConstructor() { new PluginInformation(null, pluginManager); fail("Expected exception"); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.NOT_FOUND, e.getState()); + assertEquals(MappingPluginState.NOT_FOUND(), e.getState()); } } } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java b/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java index f3852b35..2af9870c 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java @@ -27,17 +27,17 @@ class ShellRunnerUtilTest { void runValid() { if (SystemUtils.IS_OS_WINDOWS) { try { - assertEquals(MappingPluginState.SUCCESS, ShellRunnerUtil.run("echo.bat", "test")); - assertEquals(MappingPluginState.SUCCESS, ShellRunnerUtil.run(5, "echo.bat", "test")); - assertEquals(MappingPluginState.SUCCESS, ShellRunnerUtil.run(System.out, System.err, "echo.bat", "test")); + assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run("echo.bat", "test")); + assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(5, "echo.bat", "test")); + assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(System.out, System.err, "echo.bat", "test")); } catch (MappingPluginException e) { fail(e); } } else { try { - assertEquals(MappingPluginState.SUCCESS, ShellRunnerUtil.run("echo", "test")); - assertEquals(MappingPluginState.SUCCESS, ShellRunnerUtil.run(5, "echo", "test")); - assertEquals(MappingPluginState.SUCCESS, ShellRunnerUtil.run(System.out, System.err, "echo", "test")); + assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run("echo", "test")); + assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(5, "echo", "test")); + assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(System.out, System.err, "echo", "test")); } catch (MappingPluginException e) { fail(e); } From 0bfe188bd2cc5817457841000e5e3ec30627280b Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Fri, 28 Feb 2025 15:22:44 +0100 Subject: [PATCH 20/80] Updated .gitignore to remove custom folder --- .gitignore | 1 + .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 6 ---- .../http-request.adoc | 13 ------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 6 ---- .../http-request.adoc | 29 --------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 34 ------------------ .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- .../curl-request.adoc | 7 ---- .../http-request.adoc | 18 ---------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- custom/test-create-mapping/curl-request.adoc | 7 ---- custom/test-create-mapping/http-request.adoc | 34 ------------------ custom/test-create-mapping/http-response.adoc | 29 --------------- .../test-create-mapping/httpie-request.adoc | 6 ---- custom/test-create-mapping/request-body.adoc | 4 --- custom/test-create-mapping/response-body.adoc | 24 ------------- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- custom/test-delete-mapping/curl-request.adoc | 5 --- custom/test-delete-mapping/http-request.adoc | 7 ---- custom/test-delete-mapping/http-response.adoc | 5 --- .../test-delete-mapping/httpie-request.adoc | 5 --- custom/test-delete-mapping/request-body.adoc | 4 --- custom/test-delete-mapping/response-body.adoc | 4 --- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 5 --- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../test-get-mapping-by-id/curl-request.adoc | 5 --- .../test-get-mapping-by-id/http-request.adoc | 7 ---- .../test-get-mapping-by-id/http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../test-get-mapping-by-id/request-body.adoc | 4 --- .../test-get-mapping-by-id/response-body.adoc | 24 ------------- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 5 --- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 26 -------------- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 20 ----------- .../curl-request.adoc | 5 --- .../http-request.adoc | 7 ---- .../http-response.adoc | 29 --------------- .../httpie-request.adoc | 5 --- .../request-body.adoc | 4 --- .../response-body.adoc | 24 ------------- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 26 -------------- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 20 ----------- .../curl-request.adoc | 8 ----- .../http-request.adoc | 36 ------------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 7 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 8 ----- .../http-request.adoc | 36 ------------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 7 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 4 --- .../http-request.adoc | 6 ---- .../http-response.adoc | 26 -------------- .../httpie-request.adoc | 4 --- .../request-body.adoc | 4 --- .../response-body.adoc | 20 ----------- .../curl-request.adoc | 7 ---- .../http-request.adoc | 35 ------------------ .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- .../curl-request.adoc | 7 ---- .../http-request.adoc | 31 ---------------- .../http-response.adoc | 5 --- .../httpie-request.adoc | 6 ---- .../request-body.adoc | 4 --- .../response-body.adoc | 4 --- custom/test-update-mapping/curl-request.adoc | 4 --- custom/test-update-mapping/http-request.adoc | 6 ---- custom/test-update-mapping/http-response.adoc | 26 -------------- .../test-update-mapping/httpie-request.adoc | 4 --- custom/test-update-mapping/request-body.adoc | 4 --- custom/test-update-mapping/response-body.adoc | 20 ----------- 139 files changed, 1 insertion(+), 1377 deletions(-) delete mode 100644 custom/test-create-mapping-empty-record/curl-request.adoc delete mode 100644 custom/test-create-mapping-empty-record/http-request.adoc delete mode 100644 custom/test-create-mapping-empty-record/http-response.adoc delete mode 100644 custom/test-create-mapping-empty-record/httpie-request.adoc delete mode 100644 custom/test-create-mapping-empty-record/request-body.adoc delete mode 100644 custom/test-create-mapping-empty-record/response-body.adoc delete mode 100644 custom/test-create-mapping-no-mapping/curl-request.adoc delete mode 100644 custom/test-create-mapping-no-mapping/http-request.adoc delete mode 100644 custom/test-create-mapping-no-mapping/http-response.adoc delete mode 100644 custom/test-create-mapping-no-mapping/httpie-request.adoc delete mode 100644 custom/test-create-mapping-no-mapping/request-body.adoc delete mode 100644 custom/test-create-mapping-no-mapping/response-body.adoc delete mode 100644 custom/test-create-mapping-no-record/curl-request.adoc delete mode 100644 custom/test-create-mapping-no-record/http-request.adoc delete mode 100644 custom/test-create-mapping-no-record/http-response.adoc delete mode 100644 custom/test-create-mapping-no-record/httpie-request.adoc delete mode 100644 custom/test-create-mapping-no-record/request-body.adoc delete mode 100644 custom/test-create-mapping-no-record/response-body.adoc delete mode 100644 custom/test-create-mapping-twice/curl-request.adoc delete mode 100644 custom/test-create-mapping-twice/http-request.adoc delete mode 100644 custom/test-create-mapping-twice/http-response.adoc delete mode 100644 custom/test-create-mapping-twice/httpie-request.adoc delete mode 100644 custom/test-create-mapping-twice/request-body.adoc delete mode 100644 custom/test-create-mapping-twice/response-body.adoc delete mode 100644 custom/test-create-mapping-with-acl/curl-request.adoc delete mode 100644 custom/test-create-mapping-with-acl/http-request.adoc delete mode 100644 custom/test-create-mapping-with-acl/http-response.adoc delete mode 100644 custom/test-create-mapping-with-acl/httpie-request.adoc delete mode 100644 custom/test-create-mapping-with-acl/request-body.adoc delete mode 100644 custom/test-create-mapping-with-acl/response-body.adoc delete mode 100644 custom/test-create-mapping-wrong-record/curl-request.adoc delete mode 100644 custom/test-create-mapping-wrong-record/http-request.adoc delete mode 100644 custom/test-create-mapping-wrong-record/http-response.adoc delete mode 100644 custom/test-create-mapping-wrong-record/httpie-request.adoc delete mode 100644 custom/test-create-mapping-wrong-record/request-body.adoc delete mode 100644 custom/test-create-mapping-wrong-record/response-body.adoc delete mode 100644 custom/test-create-mapping/curl-request.adoc delete mode 100644 custom/test-create-mapping/http-request.adoc delete mode 100644 custom/test-create-mapping/http-response.adoc delete mode 100644 custom/test-create-mapping/httpie-request.adoc delete mode 100644 custom/test-create-mapping/request-body.adoc delete mode 100644 custom/test-create-mapping/response-body.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/curl-request.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/http-request.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/http-response.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/httpie-request.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/request-body.adoc delete mode 100644 custom/test-delete-mapping-missing-etag/response-body.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/http-request.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/http-response.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/request-body.adoc delete mode 100644 custom/test-delete-mapping-unknown-mapping-id/response-body.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/curl-request.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/http-request.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/http-response.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/httpie-request.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/request-body.adoc delete mode 100644 custom/test-delete-mapping-wrong-etag/response-body.adoc delete mode 100644 custom/test-delete-mapping/curl-request.adoc delete mode 100644 custom/test-delete-mapping/http-request.adoc delete mode 100644 custom/test-delete-mapping/http-response.adoc delete mode 100644 custom/test-delete-mapping/httpie-request.adoc delete mode 100644 custom/test-delete-mapping/request-body.adoc delete mode 100644 custom/test-delete-mapping/response-body.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc delete mode 100644 custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc delete mode 100644 custom/test-get-mapping-by-id/curl-request.adoc delete mode 100644 custom/test-get-mapping-by-id/http-request.adoc delete mode 100644 custom/test-get-mapping-by-id/http-response.adoc delete mode 100644 custom/test-get-mapping-by-id/httpie-request.adoc delete mode 100644 custom/test-get-mapping-by-id/request-body.adoc delete mode 100644 custom/test-get-mapping-by-id/response-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id/curl-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id/http-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id/http-response.adoc delete mode 100644 custom/test-get-mapping-document-by-id/httpie-request.adoc delete mode 100644 custom/test-get-mapping-document-by-id/request-body.adoc delete mode 100644 custom/test-get-mapping-document-by-id/response-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/http-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/http-response.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/request-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record/response-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/http-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/http-response.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/request-body.adoc delete mode 100644 custom/test-update-mapping-with-invalid-record2/response-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/http-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/http-response.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/request-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-etag/response-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/curl-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/http-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/http-response.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/httpie-request.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/request-body.adoc delete mode 100644 custom/test-update-mapping-with-wrong-record3/response-body.adoc delete mode 100644 custom/test-update-mapping-without-document/curl-request.adoc delete mode 100644 custom/test-update-mapping-without-document/http-request.adoc delete mode 100644 custom/test-update-mapping-without-document/http-response.adoc delete mode 100644 custom/test-update-mapping-without-document/httpie-request.adoc delete mode 100644 custom/test-update-mapping-without-document/request-body.adoc delete mode 100644 custom/test-update-mapping-without-document/response-body.adoc delete mode 100644 custom/test-update-mapping-without-etag/curl-request.adoc delete mode 100644 custom/test-update-mapping-without-etag/http-request.adoc delete mode 100644 custom/test-update-mapping-without-etag/http-response.adoc delete mode 100644 custom/test-update-mapping-without-etag/httpie-request.adoc delete mode 100644 custom/test-update-mapping-without-etag/request-body.adoc delete mode 100644 custom/test-update-mapping-without-etag/response-body.adoc delete mode 100644 custom/test-update-mapping-without-record/curl-request.adoc delete mode 100644 custom/test-update-mapping-without-record/http-request.adoc delete mode 100644 custom/test-update-mapping-without-record/http-response.adoc delete mode 100644 custom/test-update-mapping-without-record/httpie-request.adoc delete mode 100644 custom/test-update-mapping-without-record/request-body.adoc delete mode 100644 custom/test-update-mapping-without-record/response-body.adoc delete mode 100644 custom/test-update-mapping/curl-request.adoc delete mode 100644 custom/test-update-mapping/http-request.adoc delete mode 100644 custom/test-update-mapping/http-response.adoc delete mode 100644 custom/test-update-mapping/httpie-request.adoc delete mode 100644 custom/test-update-mapping/request-body.adoc delete mode 100644 custom/test-update-mapping/response-body.adoc diff --git a/.gitignore b/.gitignore index d8c1bede..8f27be30 100644 --- a/.gitignore +++ b/.gitignore @@ -241,3 +241,4 @@ gradle-app.setting lib/gemma !/plugins/gemma-plugin-0.1.0-SNAPSHOT-plain.jar !/plugins/empty-plugin-0.0.0-SNAPSHOT-plain.jar +custom diff --git a/custom/test-create-mapping-empty-record/curl-request.adoc b/custom/test-create-mapping-empty-record/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-empty-record/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/http-request.adoc b/custom/test-create-mapping-empty-record/http-request.adoc deleted file mode 100644 index 07fb3580..00000000 --- a/custom/test-create-mapping-empty-record/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/http-response.adoc b/custom/test-create-mapping-empty-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-empty-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/httpie-request.adoc b/custom/test-create-mapping-empty-record/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-empty-record/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/request-body.adoc b/custom/test-create-mapping-empty-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-empty-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-empty-record/response-body.adoc b/custom/test-create-mapping-empty-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-empty-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/curl-request.adoc b/custom/test-create-mapping-no-mapping/curl-request.adoc deleted file mode 100644 index 78b426e8..00000000 --- a/custom/test-create-mapping-no-mapping/curl-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/http-request.adoc b/custom/test-create-mapping-no-mapping/http-request.adoc deleted file mode 100644 index e5ae37bd..00000000 --- a/custom/test-create-mapping-no-mapping/http-request.adoc +++ /dev/null @@ -1,13 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/http-response.adoc b/custom/test-create-mapping-no-mapping/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-no-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/httpie-request.adoc b/custom/test-create-mapping-no-mapping/httpie-request.adoc deleted file mode 100644 index 12eca7ef..00000000 --- a/custom/test-create-mapping-no-mapping/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/request-body.adoc b/custom/test-create-mapping-no-mapping/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-no-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-mapping/response-body.adoc b/custom/test-create-mapping-no-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-no-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/curl-request.adoc b/custom/test-create-mapping-no-record/curl-request.adoc deleted file mode 100644 index 886f0f75..00000000 --- a/custom/test-create-mapping-no-record/curl-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/http-request.adoc b/custom/test-create-mapping-no-record/http-request.adoc deleted file mode 100644 index d99bd7d0..00000000 --- a/custom/test-create-mapping-no-record/http-request.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/http-response.adoc b/custom/test-create-mapping-no-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-no-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/httpie-request.adoc b/custom/test-create-mapping-no-record/httpie-request.adoc deleted file mode 100644 index 61e90bbe..00000000 --- a/custom/test-create-mapping-no-record/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/request-body.adoc b/custom/test-create-mapping-no-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-no-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-no-record/response-body.adoc b/custom/test-create-mapping-no-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-no-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/curl-request.adoc b/custom/test-create-mapping-twice/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-twice/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/http-request.adoc b/custom/test-create-mapping-twice/http-request.adoc deleted file mode 100644 index 39da1244..00000000 --- a/custom/test-create-mapping-twice/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/http-response.adoc b/custom/test-create-mapping-twice/http-response.adoc deleted file mode 100644 index d863daa7..00000000 --- a/custom/test-create-mapping-twice/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 409 Conflict - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/httpie-request.adoc b/custom/test-create-mapping-twice/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-twice/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/request-body.adoc b/custom/test-create-mapping-twice/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-twice/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-twice/response-body.adoc b/custom/test-create-mapping-twice/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-twice/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/curl-request.adoc b/custom/test-create-mapping-with-acl/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-with-acl/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/http-request.adoc b/custom/test-create-mapping-with-acl/http-request.adoc deleted file mode 100644 index 36c8215d..00000000 --- a/custom/test-create-mapping-with-acl/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/http-response.adoc b/custom/test-create-mapping-with-acl/http-response.adoc deleted file mode 100644 index 8745099d..00000000 --- a/custom/test-create-mapping-with-acl/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 201 Created -Location: http://localhost:8095/api/v1/mappingAdministration/my_dc -Content-Type: application/json -Content-Length: 546 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/httpie-request.adoc b/custom/test-create-mapping-with-acl/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-with-acl/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/request-body.adoc b/custom/test-create-mapping-with-acl/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-with-acl/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-with-acl/response-body.adoc b/custom/test-create-mapping-with-acl/response-body.adoc deleted file mode 100644 index 74c13ef8..00000000 --- a/custom/test-create-mapping-with-acl/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/curl-request.adoc b/custom/test-create-mapping-wrong-record/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping-wrong-record/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/http-request.adoc b/custom/test-create-mapping-wrong-record/http-request.adoc deleted file mode 100644 index 3f563e82..00000000 --- a/custom/test-create-mapping-wrong-record/http-request.adoc +++ /dev/null @@ -1,18 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":null,"title":null,"description":null,"acl":[],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/http-response.adoc b/custom/test-create-mapping-wrong-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-create-mapping-wrong-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/httpie-request.adoc b/custom/test-create-mapping-wrong-record/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping-wrong-record/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/request-body.adoc b/custom/test-create-mapping-wrong-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping-wrong-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping-wrong-record/response-body.adoc b/custom/test-create-mapping-wrong-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-create-mapping-wrong-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping/curl-request.adoc b/custom/test-create-mapping/curl-request.adoc deleted file mode 100644 index 8818d020..00000000 --- a/custom/test-create-mapping/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/' -i -X POST \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-create-mapping/http-request.adoc b/custom/test-create-mapping/http-request.adoc deleted file mode 100644 index 36c8215d..00000000 --- a/custom/test-create-mapping/http-request.adoc +++ /dev/null @@ -1,34 +0,0 @@ -[source,http,options="nowrap"] ----- -POST /api/v1/mappingAdministration/ HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":null,"documentHash":null} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "Publication Date":{ - "path": "publicationDate", - "type": "string" - } - } -} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-create-mapping/http-response.adoc b/custom/test-create-mapping/http-response.adoc deleted file mode 100644 index 8745099d..00000000 --- a/custom/test-create-mapping/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 201 Created -Location: http://localhost:8095/api/v1/mappingAdministration/my_dc -Content-Type: application/json -Content-Length: 546 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-create-mapping/httpie-request.adoc b/custom/test-create-mapping/httpie-request.adoc deleted file mode 100644 index f6687a5c..00000000 --- a/custom/test-create-mapping/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart POST 'http://localhost:8095/api/v1/mappingAdministration/' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-create-mapping/request-body.adoc b/custom/test-create-mapping/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-create-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-create-mapping/response-body.adoc b/custom/test-create-mapping/response-body.adoc deleted file mode 100644 index 74c13ef8..00000000 --- a/custom/test-create-mapping/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : null, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : null, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : null, - "sid" : "test2", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/curl-request.adoc b/custom/test-delete-mapping-missing-etag/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-delete-mapping-missing-etag/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/http-request.adoc b/custom/test-delete-mapping-missing-etag/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-delete-mapping-missing-etag/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/http-response.adoc b/custom/test-delete-mapping-missing-etag/http-response.adoc deleted file mode 100644 index 625b402d..00000000 --- a/custom/test-delete-mapping-missing-etag/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 540 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 50, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 48, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 49, - "sid" : "SELF", - "permission" : "READ" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/httpie-request.adoc b/custom/test-delete-mapping-missing-etag/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-delete-mapping-missing-etag/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/request-body.adoc b/custom/test-delete-mapping-missing-etag/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-missing-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-missing-etag/response-body.adoc b/custom/test-delete-mapping-missing-etag/response-body.adoc deleted file mode 100644 index ee524be6..00000000 --- a/custom/test-delete-mapping-missing-etag/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 50, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 48, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 49, - "sid" : "SELF", - "permission" : "READ" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc deleted file mode 100644 index 890ac553..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/unknownMappingId' -i -X DELETE \ - -H 'If-Match: "104363025"' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc deleted file mode 100644 index 8113df33..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -DELETE /api/v1/mappingAdministration/unknownMappingId HTTP/1.1 -If-Match: "104363025" -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc b/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc deleted file mode 100644 index b2e108f3..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 204 No Content - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc b/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc deleted file mode 100644 index a0cc74a7..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http DELETE 'http://localhost:8095/api/v1/mappingAdministration/unknownMappingId' \ - 'If-Match:"104363025"' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc b/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc b/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-unknown-mapping-id/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/curl-request.adoc b/custom/test-delete-mapping-wrong-etag/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-delete-mapping-wrong-etag/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/http-request.adoc b/custom/test-delete-mapping-wrong-etag/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-delete-mapping-wrong-etag/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/http-response.adoc b/custom/test-delete-mapping-wrong-etag/http-response.adoc deleted file mode 100644 index f15901cd..00000000 --- a/custom/test-delete-mapping-wrong-etag/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 540 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 46, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 47, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 45, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/httpie-request.adoc b/custom/test-delete-mapping-wrong-etag/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-delete-mapping-wrong-etag/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/request-body.adoc b/custom/test-delete-mapping-wrong-etag/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping-wrong-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping-wrong-etag/response-body.adoc b/custom/test-delete-mapping-wrong-etag/response-body.adoc deleted file mode 100644 index 4ae542f4..00000000 --- a/custom/test-delete-mapping-wrong-etag/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 46, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 47, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 45, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/curl-request.adoc b/custom/test-delete-mapping/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-delete-mapping/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/http-request.adoc b/custom/test-delete-mapping/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-delete-mapping/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/http-response.adoc b/custom/test-delete-mapping/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-delete-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/httpie-request.adoc b/custom/test-delete-mapping/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-delete-mapping/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/request-body.adoc b/custom/test-delete-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-delete-mapping/response-body.adoc b/custom/test-delete-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-delete-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc deleted file mode 100644 index 36fb7cb1..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc deleted file mode 100644 index 07b9f8c0..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/invalidMappingId HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc deleted file mode 100644 index f0ed9abb..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc b/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-by-id-with-invalid-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/curl-request.adoc b/custom/test-get-mapping-by-id/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-get-mapping-by-id/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/http-request.adoc b/custom/test-get-mapping-by-id/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-get-mapping-by-id/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/http-response.adoc b/custom/test-get-mapping-by-id/http-response.adoc deleted file mode 100644 index a4630c9e..00000000 --- a/custom/test-get-mapping-by-id/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 540 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 57, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 59, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 58, - "sid" : "SELF", - "permission" : "READ" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/httpie-request.adoc b/custom/test-get-mapping-by-id/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-get-mapping-by-id/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/request-body.adoc b/custom/test-get-mapping-by-id/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-by-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-by-id/response-body.adoc b/custom/test-get-mapping-by-id/response-body.adoc deleted file mode 100644 index b9fa0796..00000000 --- a/custom/test-get-mapping-by-id/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 57, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - }, { - "id" : 59, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 58, - "sid" : "SELF", - "permission" : "READ" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc deleted file mode 100644 index 443c291b..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc deleted file mode 100644 index a2d8037e..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/invalidMappingId HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc deleted file mode 100644 index 844f1b2c..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/invalidMappingId' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc b/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-document-by-id-with-invalid-mapping/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/curl-request.adoc b/custom/test-get-mapping-document-by-id/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-get-mapping-document-by-id/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/http-request.adoc b/custom/test-get-mapping-document-by-id/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-get-mapping-document-by-id/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/http-response.adoc b/custom/test-get-mapping-document-by-id/http-response.adoc deleted file mode 100644 index 007bbfb2..00000000 --- a/custom/test-get-mapping-document-by-id/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 409 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/httpie-request.adoc b/custom/test-get-mapping-document-by-id/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-get-mapping-document-by-id/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/request-body.adoc b/custom/test-get-mapping-document-by-id/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-get-mapping-document-by-id/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-get-mapping-document-by-id/response-body.adoc b/custom/test-get-mapping-document-by-id/response-body.adoc deleted file mode 100644 index bd0e4ace..00000000 --- a/custom/test-get-mapping-document-by-id/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/curl-request.adoc b/custom/test-update-mapping-with-invalid-record/curl-request.adoc deleted file mode 100644 index 71c4986c..00000000 --- a/custom/test-update-mapping-with-invalid-record/curl-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X GET \ - -H 'Accept: application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/http-request.adoc b/custom/test-update-mapping-with-invalid-record/http-request.adoc deleted file mode 100644 index f03c1a0a..00000000 --- a/custom/test-update-mapping-with-invalid-record/http-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc HTTP/1.1 -Accept: application/vnd.datamanager.mapping-record+json -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/http-response.adoc b/custom/test-update-mapping-with-invalid-record/http-response.adoc deleted file mode 100644 index 57ed668f..00000000 --- a/custom/test-update-mapping-with-invalid-record/http-response.adoc +++ /dev/null @@ -1,29 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Type: application/vnd.datamanager.mapping-record+json -Content-Length: 540 - -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 53, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 52, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 51, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/httpie-request.adoc b/custom/test-update-mapping-with-invalid-record/httpie-request.adoc deleted file mode 100644 index 351810e7..00000000 --- a/custom/test-update-mapping-with-invalid-record/httpie-request.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'Accept:application/vnd.datamanager.mapping-record+json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/request-body.adoc b/custom/test-update-mapping-with-invalid-record/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-invalid-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record/response-body.adoc b/custom/test-update-mapping-with-invalid-record/response-body.adoc deleted file mode 100644 index 5322a2f5..00000000 --- a/custom/test-update-mapping-with-invalid-record/response-body.adoc +++ /dev/null @@ -1,24 +0,0 @@ -[source,json,options="nowrap"] ----- -{ - "mappingId" : "my_dc", - "mappingType" : "GEMMA", - "title" : "TITEL", - "description" : "DESCRIPTION", - "acl" : [ { - "id" : 53, - "sid" : "test2", - "permission" : "ADMINISTRATE" - }, { - "id" : 52, - "sid" : "SELF", - "permission" : "READ" - }, { - "id" : 51, - "sid" : "anonymousUser", - "permission" : "ADMINISTRATE" - } ], - "mappingDocumentUri" : "http://localhost:8095/api/v1/mappingAdministration/my_dc/document", - "documentHash" : "sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b" -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/curl-request.adoc b/custom/test-update-mapping-with-invalid-record2/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-update-mapping-with-invalid-record2/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/http-request.adoc b/custom/test-update-mapping-with-invalid-record2/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-update-mapping-with-invalid-record2/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/http-response.adoc b/custom/test-update-mapping-with-invalid-record2/http-response.adoc deleted file mode 100644 index 67a3b84f..00000000 --- a/custom/test-update-mapping-with-invalid-record2/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 418 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc b/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-update-mapping-with-invalid-record2/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/request-body.adoc b/custom/test-update-mapping-with-invalid-record2/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-invalid-record2/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-invalid-record2/response-body.adoc b/custom/test-update-mapping-with-invalid-record2/response-body.adoc deleted file mode 100644 index 139a1028..00000000 --- a/custom/test-update-mapping-with-invalid-record2/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/curl-request.adoc b/custom/test-update-mapping-with-wrong-etag/curl-request.adoc deleted file mode 100644 index 51612ec4..00000000 --- a/custom/test-update-mapping-with-wrong-etag/curl-request.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -H 'If-Match: wrongEtag' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/http-request.adoc b/custom/test-update-mapping-with-wrong-etag/http-request.adoc deleted file mode 100644 index ae126741..00000000 --- a/custom/test-update-mapping-with-wrong-etag/http-request.adoc +++ /dev/null @@ -1,36 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -If-Match: wrongEtag -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"someoneelse","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b"} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/http-response.adoc b/custom/test-update-mapping-with-wrong-etag/http-response.adoc deleted file mode 100644 index 5549e3fe..00000000 --- a/custom/test-update-mapping-with-wrong-etag/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 412 Precondition Failed - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc b/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc deleted file mode 100644 index 51122c72..00000000 --- a/custom/test-update-mapping-with-wrong-etag/httpie-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'If-Match:wrongEtag' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/request-body.adoc b/custom/test-update-mapping-with-wrong-etag/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-with-wrong-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-etag/response-body.adoc b/custom/test-update-mapping-with-wrong-etag/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-wrong-etag/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/curl-request.adoc b/custom/test-update-mapping-with-wrong-record3/curl-request.adoc deleted file mode 100644 index f6ea3824..00000000 --- a/custom/test-update-mapping-with-wrong-record3/curl-request.adoc +++ /dev/null @@ -1,8 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/unknownMaping' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -H 'If-Match: "104363025"' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/http-request.adoc b/custom/test-update-mapping-with-wrong-record3/http-request.adoc deleted file mode 100644 index f9074c1e..00000000 --- a/custom/test-update-mapping-with-wrong-record3/http-request.adoc +++ /dev/null @@ -1,36 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/unknownMaping HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -If-Match: "104363025" -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":43,"sid":"SELF","permission":"READ"},{"id":42,"sid":"anonymousUser","permission":"ADMINISTRATE"},{"id":44,"sid":"test2","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b"} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/http-response.adoc b/custom/test-update-mapping-with-wrong-record3/http-response.adoc deleted file mode 100644 index f3b256d0..00000000 --- a/custom/test-update-mapping-with-wrong-record3/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 404 Not Found - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc b/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc deleted file mode 100644 index 0a2f8d2b..00000000 --- a/custom/test-update-mapping-with-wrong-record3/httpie-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/unknownMaping' \ - 'If-Match:"104363025"' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/request-body.adoc b/custom/test-update-mapping-with-wrong-record3/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-with-wrong-record3/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-with-wrong-record3/response-body.adoc b/custom/test-update-mapping-with-wrong-record3/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-with-wrong-record3/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/curl-request.adoc b/custom/test-update-mapping-without-document/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-update-mapping-without-document/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/http-request.adoc b/custom/test-update-mapping-without-document/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-update-mapping-without-document/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/http-response.adoc b/custom/test-update-mapping-without-document/http-response.adoc deleted file mode 100644 index 007bbfb2..00000000 --- a/custom/test-update-mapping-without-document/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 409 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/httpie-request.adoc b/custom/test-update-mapping-without-document/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-update-mapping-without-document/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/request-body.adoc b/custom/test-update-mapping-without-document/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-without-document/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-document/response-body.adoc b/custom/test-update-mapping-without-document/response-body.adoc deleted file mode 100644 index bd0e4ace..00000000 --- a/custom/test-update-mapping-without-document/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "Publication Date" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/curl-request.adoc b/custom/test-update-mapping-without-etag/curl-request.adoc deleted file mode 100644 index ea30de0b..00000000 --- a/custom/test-update-mapping-without-etag/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -F 'record=@record.json;type=application/json' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/http-request.adoc b/custom/test-update-mapping-without-etag/http-request.adoc deleted file mode 100644 index d0b108c4..00000000 --- a/custom/test-update-mapping-without-etag/http-request.adoc +++ /dev/null @@ -1,35 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=record; filename=record.json -Content-Type: application/json - -{"mappingId":"my_dc","mappingType":"GEMMA","title":"TITEL","description":"DESCRIPTION","acl":[{"id":null,"sid":"SELF","permission":"READ"},{"id":null,"sid":"someoneelse","permission":"ADMINISTRATE"}],"mappingDocumentUri":"http://localhost:8095/api/v1/mappingAdministration/my_dc/document","documentHash":"sha256:de0cd19a4ffc603e8940e990cd2dc689e029d308224c71992c4cd099a588aa0b"} ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/http-response.adoc b/custom/test-update-mapping-without-etag/http-response.adoc deleted file mode 100644 index 7448deeb..00000000 --- a/custom/test-update-mapping-without-etag/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 428 Precondition Required - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/httpie-request.adoc b/custom/test-update-mapping-without-etag/httpie-request.adoc deleted file mode 100644 index 3b932a63..00000000 --- a/custom/test-update-mapping-without-etag/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'record'@'record.json' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/request-body.adoc b/custom/test-update-mapping-without-etag/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-without-etag/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-etag/response-body.adoc b/custom/test-update-mapping-without-etag/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-without-etag/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/curl-request.adoc b/custom/test-update-mapping-without-record/curl-request.adoc deleted file mode 100644 index baee036f..00000000 --- a/custom/test-update-mapping-without-record/curl-request.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc' -i -X PUT \ - -H 'Content-Type: multipart/form-data' \ - -H 'If-Match: "104363025"' \ - -F 'document=@my_dc4gemma.mapping;type=application/json' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/http-request.adoc b/custom/test-update-mapping-without-record/http-request.adoc deleted file mode 100644 index 2fab7976..00000000 --- a/custom/test-update-mapping-without-record/http-request.adoc +++ /dev/null @@ -1,31 +0,0 @@ -[source,http,options="nowrap"] ----- -PUT /api/v1/mappingAdministration/my_dc HTTP/1.1 -Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -If-Match: "104363025" -Host: localhost:8095 - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm -Content-Disposition: form-data; name=document; filename=my_dc4gemma.mapping -Content-Type: application/json - -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://example.com/product.schema.json", - "title": "Simple Mapping Version 2", - "description": "Data resource mapping from json", - "type": "object", - "properties":{ - "Publisher":{ - "path": "publisher", - "type": "string" - }, - "PublicationDate":{ - "path": "publicationDate", - "type": "string" - } - } -} - ---6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm-- ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/http-response.adoc b/custom/test-update-mapping-without-record/http-response.adoc deleted file mode 100644 index 6bc944f3..00000000 --- a/custom/test-update-mapping-without-record/http-response.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 400 Bad Request - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/httpie-request.adoc b/custom/test-update-mapping-without-record/httpie-request.adoc deleted file mode 100644 index 29510d9f..00000000 --- a/custom/test-update-mapping-without-record/httpie-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,bash] ----- -$ http --multipart PUT 'http://localhost:8095/api/v1/mappingAdministration/my_dc' \ - 'If-Match:"104363025"' \ - 'document'@'my_dc4gemma.mapping' ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/request-body.adoc b/custom/test-update-mapping-without-record/request-body.adoc deleted file mode 100644 index d074c300..00000000 --- a/custom/test-update-mapping-without-record/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,form-data,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping-without-record/response-body.adoc b/custom/test-update-mapping-without-record/response-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping-without-record/response-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping/curl-request.adoc b/custom/test-update-mapping/curl-request.adoc deleted file mode 100644 index 4b167b7c..00000000 --- a/custom/test-update-mapping/curl-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ curl 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' -i -X GET ----- \ No newline at end of file diff --git a/custom/test-update-mapping/http-request.adoc b/custom/test-update-mapping/http-request.adoc deleted file mode 100644 index 4aa6e413..00000000 --- a/custom/test-update-mapping/http-request.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[source,http,options="nowrap"] ----- -GET /api/v1/mappingAdministration/my_dc/document HTTP/1.1 -Host: localhost:8095 - ----- \ No newline at end of file diff --git a/custom/test-update-mapping/http-response.adoc b/custom/test-update-mapping/http-response.adoc deleted file mode 100644 index 67a3b84f..00000000 --- a/custom/test-update-mapping/http-response.adoc +++ /dev/null @@ -1,26 +0,0 @@ -[source,http,options="nowrap"] ----- -HTTP/1.1 200 OK -ETag: "104363025" -Content-Length: 418 -Accept-Ranges: bytes -Content-Type: application/octet-stream - -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file diff --git a/custom/test-update-mapping/httpie-request.adoc b/custom/test-update-mapping/httpie-request.adoc deleted file mode 100644 index a954b9fc..00000000 --- a/custom/test-update-mapping/httpie-request.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,bash] ----- -$ http GET 'http://localhost:8095/api/v1/mappingAdministration/my_dc/document' ----- \ No newline at end of file diff --git a/custom/test-update-mapping/request-body.adoc b/custom/test-update-mapping/request-body.adoc deleted file mode 100644 index dab5f81d..00000000 --- a/custom/test-update-mapping/request-body.adoc +++ /dev/null @@ -1,4 +0,0 @@ -[source,options="nowrap"] ----- - ----- \ No newline at end of file diff --git a/custom/test-update-mapping/response-body.adoc b/custom/test-update-mapping/response-body.adoc deleted file mode 100644 index 139a1028..00000000 --- a/custom/test-update-mapping/response-body.adoc +++ /dev/null @@ -1,20 +0,0 @@ -[source,octet-stream,options="nowrap"] ----- -{ - "$schema" : "http://json-schema.org/draft-07/schema#", - "$id" : "http://example.com/product.schema.json", - "title" : "Simple Mapping Version 2", - "description" : "Data resource mapping from json", - "type" : "object", - "properties" : { - "Publisher" : { - "path" : "publisher", - "type" : "string" - }, - "PublicationDate" : { - "path" : "publicationDate", - "type" : "string" - } - } -} ----- \ No newline at end of file From 4dc6e2fff1100f3112a4b0d5bbffbe24bd620c2d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 11:21:33 +0000 Subject: [PATCH 21/80] Update dependency net.bytebuddy:byte-buddy to v1.17.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9de44cd6..66ac46bb 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { testImplementation 'org.mockito:mockito-core:5.15.2' testImplementation 'org.powermock:powermock-module-junit4:2.0.9' testImplementation 'org.powermock:powermock-api-mockito2:2.0.9' - testImplementation 'net.bytebuddy:byte-buddy:1.17.1' + testImplementation 'net.bytebuddy:byte-buddy:1.17.2' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' From 11435c1fae0cd9f37891c962396c3652631a2a7d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 11:21:38 +0000 Subject: [PATCH 22/80] Update dependency org.mockito:mockito-core to v5.16.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9de44cd6..a0c5f0e7 100644 --- a/build.gradle +++ b/build.gradle @@ -94,7 +94,7 @@ dependencies { //testImplementation 'org.springframework:spring-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:3.0.3' - testImplementation 'org.mockito:mockito-core:5.15.2' + testImplementation 'org.mockito:mockito-core:5.16.0' testImplementation 'org.powermock:powermock-module-junit4:2.0.9' testImplementation 'org.powermock:powermock-api-mockito2:2.0.9' testImplementation 'net.bytebuddy:byte-buddy:1.17.1' From 82ba476cbe52597b278ff661daae8107c988b836 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 16:45:06 +0000 Subject: [PATCH 23/80] Update plugin io.freefair.maven-publish-java to v8.12.2.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9de44cd6..4adaa6f4 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'org.springframework.boot' version '3.4.2' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' - id 'io.freefair.maven-publish-java' version '8.12.1' + id 'io.freefair.maven-publish-java' version '8.12.2.1' id "org.owasp.dependencycheck" version "12.1.0" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.4.2" From 8467bcb219b33082a9e029ff08f90854ce323fa5 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Mon, 3 Mar 2025 23:43:55 +0100 Subject: [PATCH 24/80] Fixed tests, fixed several issues with Git adapter, improved error handling and adapted errors to real cause, fixed minor issues and improved logging --- README.md | 2 +- build.gradle | 2 +- settings/application-default.properties | 3 +- .../MappingServiceApplication.java | 22 +-- .../configuration/ApplicationProperties.java | 10 +- .../configuration/OpenApiDefinitions.java | 2 +- .../exception/BadExitCodeException.java | 13 +- .../exception/JobIdConflictException.java | 62 +++++++ .../exception/MappingNotFoundException.java | 4 +- .../exception/MappingServiceException.java | 61 +++++++ .../MappingServiceUserException.java | 61 +++++++ .../PluginInitializationFailedException.java | 58 +++++++ .../mappingservice/impl/MappingService.java | 156 +++++++++--------- .../plugins/MappingPluginException.java | 23 ++- .../mappingservice/plugins/PluginLoader.java | 57 ++++--- .../mappingservice/plugins/PluginManager.java | 21 ++- .../plugins/impl/GemmaPlugin.java | 6 +- .../plugins/impl/IdentifyPlugin.java | 17 +- .../plugins/impl/InOutPlugin.java | 6 +- .../impl/MappingAdministrationController.java | 11 +- .../rest/impl/MappingExecutionController.java | 70 ++++---- .../mappingservice/util/FileUtil.java | 22 ++- .../mappingservice/util/PythonRunnerUtil.java | 11 +- .../mappingservice/util/ShellRunnerUtil.java | 8 +- .../impl/MappingServiceTest.java | 5 +- .../plugins/MappingPluginExceptionTest.java | 6 +- .../plugins/PluginLoaderTest.java | 35 ++-- .../plugins/PluginManagerTest.java | 41 +++-- .../rest/PluginInformationTest.java | 2 +- .../MappingAdministrationControllerTest.java | 7 - .../impl/MappingExecutionControllerTest.java | 4 +- .../mappingservice/util/FileUtilTest.java | 28 ++-- .../util/ShellRunnerUtilTest.java | 12 +- 33 files changed, 584 insertions(+), 264 deletions(-) create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/exception/JobIdConflictException.java create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceException.java create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceUserException.java create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/exception/PluginInitializationFailedException.java diff --git a/README.md b/README.md index 15387a70..aaa9266d 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ used at compile time externally, i.e.: ## How to start -Before you can start the mapping-service, you first have to create an `application.properties` file in the source folder. As an example you may use `config/application.default.properties` +Before you can start the mapping-service, you first have to create an `application.properties` file in the source folder. As an example you may use `settings/application.default.properties` and modify it according to your needs. Espacially the following properties (at the end of the file) are important: - `spring.datasource.url=jdbc:h2:file:/tmp/mapping-service/database` The path points to the location of the database in which your configured mappings are stored. diff --git a/build.gradle b/build.gradle index 9de44cd6..5fe282be 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ repositories { ext { set('snippetsDir', file('build/generated-snippets')) applicationProperties = System.getProperty('applicationProperties', './src/test/resources/test-config/application-test.properties') - pythonExecutable = System.getProperty('pythonExecutable', 'file:///opt/homebrew/bin/python3') + pythonExecutable = System.getProperty('pythonExecutable', 'file:///C:/Python310/python.exe') userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") set('springDocVersion', "2.8.5") diff --git a/settings/application-default.properties b/settings/application-default.properties index e97d63d8..d0b1b42d 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -28,7 +28,8 @@ info.app.group=edu.kit.datamanager info.app.version=1.0.4 management.endpoint.health.probes.enabled=true management.endpoints.web.exposure.include=* - +management.health.rabbit.enabled:false +management.health.elasticsearch.enabled:false ############################################################################### # Spring Cloud ############################################################################### diff --git a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java index 77267aae..b1a889df 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java @@ -1,18 +1,14 @@ package edu.kit.datamanager.mappingservice; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; -import edu.kit.datamanager.mappingservice.exception.MappingJobException; import edu.kit.datamanager.mappingservice.plugins.PluginManager; -import java.io.File; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -38,10 +34,16 @@ public PluginManager pluginManager() { } public static void main(String[] args) { - SpringApplication.run(MappingServiceApplication.class, args); + ConfigurableApplicationContext ctx = SpringApplication.run(MappingServiceApplication.class, args); - //pluginManager().getListOfAvailableValidators().forEach((value) -> LOG.info("Found validator: " + value)); - //PythonRunnerUtil.printPythonVersion(); - System.out.println("Mapping service is running! Access it at http://localhost:8095"); + PluginManager mgr = ctx.getBean(PluginManager.class); + System.out.println("Found plugins: "); + mgr.getPlugins().forEach((k, v) -> { + System.out.println(String.format(" - %s (%s)", k, v)); + }); + System.out.println("Using Python Version: "); + PythonRunnerUtil.printPythonVersion(); + String port = ctx.getEnvironment().getProperty("server.port"); + System.out.println(String.format("Mapping service is running on port %s.", port)); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java index 2bd34558..2af59515 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java @@ -59,11 +59,19 @@ public class ApplicationProperties { @LocalFolderURL @Value("${mapping-service.mappingSchemasLocation}") private URL mappingsLocation; - + /** * The absolute path where job data is stored. */ @LocalFolderURL @Value("${mapping-service.jobOutput}") private URL jobOutputLocation; + + + /** + * One or more packages to scan for plugin classes. + */ + @Value("${mapping-service.packagesToScan:edu.kit.datamanager.mappingservice.plugins.impl}") + private String[] packagesToScan; + } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/OpenApiDefinitions.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/OpenApiDefinitions.java index ef51b657..e0378875 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/OpenApiDefinitions.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/OpenApiDefinitions.java @@ -36,7 +36,7 @@ public OpenAPI customOpenAPI() { .components(new Components()) .info(new Info().title("Mapping-Service - RESTful API"). description("This webpage describes the RESTful API of the KIT Data Manager Mapping-Service."). - version("0.1"). + version("1.1.2"). contact( new Contact(). name("KIT Data Manager Support"). diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java index 8577d1e9..4fc1964b 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/BadExitCodeException.java @@ -19,9 +19,16 @@ * @author jejkal */ public class BadExitCodeException extends Exception { - - + + private int exitCode = 0; + public BadExitCodeException(int exitCode) { - super(Integer.toString(exitCode)); + super("Process exited with code " + exitCode); + this.exitCode = exitCode; } + + public int getExitCode() { + return exitCode; + } + } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/JobIdConflictException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/JobIdConflictException.java new file mode 100644 index 00000000..d666040d --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/JobIdConflictException.java @@ -0,0 +1,62 @@ +/* + * Copyright 2024 Karlsruhe Institute of Technology. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.kit.datamanager.mappingservice.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * + * @author jejkal + */ +@ResponseStatus(value = HttpStatus.CONFLICT, reason = "Job Id already in use. Please try again later.") +public class JobIdConflictException extends RuntimeException { + + /** + * Default constructor. + */ + public JobIdConflictException() { + super(); + } + + /** + * Constructor with given message and cause. + * + * @param message Message. + * @param cause Cause. + */ + public JobIdConflictException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor with given message. + * + * @param message Message. + */ + public JobIdConflictException(String message) { + super(message); + } + + /** + * Constructor with given message and cause. + * + * @param cause Cause. + */ + public JobIdConflictException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingNotFoundException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingNotFoundException.java index d1e9cf2d..07ed7f78 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingNotFoundException.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingNotFoundException.java @@ -21,7 +21,7 @@ /** * Invalid json format of data. */ -@ResponseStatus(value = HttpStatus.NOT_FOUND) +@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "No mapping found for provided mappingId.") public class MappingNotFoundException extends RuntimeException { /** @@ -35,7 +35,7 @@ public MappingNotFoundException() { * Constructor with given message and cause. * * @param message Message. - * @param cause Cause. + * @param cause Cause. */ public MappingNotFoundException(String message, Throwable cause) { super(message, cause); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceException.java new file mode 100644 index 00000000..30b9b2ef --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceException.java @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Karlsruhe Institute of Technology. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.kit.datamanager.mappingservice.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Used for internal server errors that could not be or were not handled. + */ +@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) +public class MappingServiceException extends RuntimeException { + + /** + * Default constructor. + */ + public MappingServiceException() { + super(); + } + + /** + * Constructor with given message and cause. + * + * @param message Message. + * @param cause Cause. + */ + public MappingServiceException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor with given message. + * + * @param message Message. + */ + public MappingServiceException(String message) { + super(message); + } + + /** + * Constructor with given message and cause. + * + * @param cause Cause. + */ + public MappingServiceException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceUserException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceUserException.java new file mode 100644 index 00000000..2e4111f1 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/MappingServiceUserException.java @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Karlsruhe Institute of Technology. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.kit.datamanager.mappingservice.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Used for errors caused by user input. + */ +@ResponseStatus(value = HttpStatus.BAD_REQUEST) +public class MappingServiceUserException extends RuntimeException { + + /** + * Default constructor. + */ + public MappingServiceUserException() { + super(); + } + + /** + * Constructor with given message and cause. + * + * @param message Message. + * @param cause Cause. + */ + public MappingServiceUserException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor with given message. + * + * @param message Message. + */ + public MappingServiceUserException(String message) { + super(message); + } + + /** + * Constructor with given message and cause. + * + * @param cause Cause. + */ + public MappingServiceUserException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/exception/PluginInitializationFailedException.java b/src/main/java/edu/kit/datamanager/mappingservice/exception/PluginInitializationFailedException.java new file mode 100644 index 00000000..7fdcd033 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/exception/PluginInitializationFailedException.java @@ -0,0 +1,58 @@ +/* + * Copyright 2025 Karlsruhe Institute of Technology. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.kit.datamanager.mappingservice.exception; + +/** + * + * @author jejkal + */ +public class PluginInitializationFailedException extends RuntimeException { + + /** + * Default constructor. + */ + public PluginInitializationFailedException() { + super(); + } + + /** + * Constructor with given message and cause. + * + * @param message Message. + * @param cause Cause. + */ + public PluginInitializationFailedException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor with given message. + * + * @param message Message. + */ + public PluginInitializationFailedException(String message) { + super(message); + } + + /** + * Constructor with given message and cause. + * + * @param cause Cause. + */ + public PluginInitializationFailedException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index 81a12a27..9ea705f1 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -25,6 +25,8 @@ import edu.kit.datamanager.mappingservice.exception.MappingException; import edu.kit.datamanager.mappingservice.exception.MappingJobException; import edu.kit.datamanager.mappingservice.exception.MappingNotFoundException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceUserException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import edu.kit.datamanager.mappingservice.plugins.PluginManager; @@ -87,7 +89,7 @@ public class MappingService { */ private Path jobsOutputDirectory; - private ApplicationProperties applicationProperties; + private final ApplicationProperties applicationProperties; /** * Logger for this class. @@ -147,7 +149,6 @@ public void updateMapping(String content, MappingRecord mappingRecord) throws Ma LOGGER.trace("Persisting mapping record."); mappingRepo.save(mappingRecord); LOGGER.trace("Mapping with id {} successfully updated.", mappingRecord.getMappingId()); - } /** @@ -164,13 +165,13 @@ public void deleteMapping(MappingRecord mappingRecord) { } LOGGER.trace("Deleting mapping with id {}.", mappingRecord.getMappingId()); mappingRecord = findMapping.get(); + mappingRepo.delete(mappingRecord); + LOGGER.trace("Mapping with id {} deleted.", mappingRecord.getMappingId()); try { deleteMappingFile(mappingRecord); } catch (IOException e) { - LOGGER.error("Failed to delete mapping file at " + mappingRecord.getMappingDocumentUri() + ". Please remove it manually.", e); + LOGGER.error(String.format("Failed to delete mapping file at %s. Please remove it manually.", mappingRecord.getMappingDocumentUri()), e); } - mappingRepo.delete(mappingRecord); - LOGGER.trace("Mapping with id {} deleted.", mappingRecord.getMappingId()); } /** @@ -194,21 +195,24 @@ public Optional executeMapping(URI contentUrl, String mappingId) throws Ma LOGGER.trace("Searching for mapping with id {}.", mappingId); Optional optionalMappingRecord = mappingRepo.findByMappingId(mappingId); if (optionalMappingRecord.isPresent()) { - LOGGER.trace("Mapping for id {} found. Creating temporary output file.", mappingId); + LOGGER.trace("Mapping for id {} found.", mappingId); mappingRecord = optionalMappingRecord.get(); Path mappingFile = Paths.get(mappingRecord.getMappingDocumentUri()); // execute mapping Path resultFile; + LOGGER.trace("Preparing temporary output file."); resultFile = FileUtil.createTempFile(mappingId + "_" + srcFile.hashCode(), ".result"); LOGGER.trace("Temporary output file available at {}. Performing mapping.", resultFile); MappingPluginState result = pluginManager.mapFile(mappingRecord.getMappingType(), mappingFile, srcFile, resultFile); LOGGER.trace("Mapping returned with result {}. Returning result file.", result); returnValue = Optional.of(resultFile); // remove downloaded file + LOGGER.trace("Removing user upload."); FileUtil.removeFile(srcFile); + LOGGER.trace("User upload successfully removed."); } else { - LOGGER.error("Unable to find mapping with id {}.", mappingId); - throw new MappingNotFoundException("Unable to find mapping with id " + mappingId + "."); + LOGGER.error("Unable to find mapping for id {}.", mappingId); + throw new MappingNotFoundException(String.format("Unable to find mapping with id %s.", mappingId)); } return returnValue; } @@ -233,45 +237,45 @@ public CompletableFuture executeMappingAsync(String jobId, URI conten if (contentUrl == null || mappingId == null) { task.complete(JobStatus.error(jobId, JobStatus.STATUS.FAILED, "Either contentUrl or mappingId are not provided.")); - } - - Optional returnValue; - Path srcFile = Paths.get(contentUrl); - MappingRecord mappingRecord; - - // Get mapping file - LOGGER.trace("Searching for mapping with id {}.", mappingId); - Optional optionalMappingRecord = mappingRepo.findByMappingId(mappingId); - if (optionalMappingRecord.isPresent()) { - LOGGER.trace("Mapping for id {} found. Creating temporary output file.", mappingId); - mappingRecord = optionalMappingRecord.get(); - Path mappingFile = Paths.get(mappingRecord.getMappingDocumentUri()); - // execute mapping - Path resultFile = getOutputFile(jobId).toPath(); - LOGGER.trace("Temporary output file available at {}. Performing mapping.", resultFile); - try { - MappingPluginState result = pluginManager.mapFile(mappingRecord.getMappingType(), mappingFile, srcFile, resultFile); - - LOGGER.trace("Mapping returned with result {}. Returning result file.", result); - returnValue = Optional.of(resultFile); - LOGGER.trace("Fixing file extension for output {}", returnValue.get()); - Path outputPath = FileUtil.fixFileExtension(returnValue.get()); - LOGGER.trace("Fixed output path: {}", outputPath); - - task.complete(JobStatus.complete(jobId, JobStatus.STATUS.SUCCEEDED, outputPath.toFile())); - } catch (Throwable t) { - task.complete(JobStatus.error(jobId, JobStatus.STATUS.FAILED, t.getMessage())); - } finally { - // remove downloaded file - LOGGER.trace("Removing user upload at {}.", srcFile); - FileUtil.removeFile(srcFile); - LOGGER.trace("User upload successfully removed."); - - } } else { - LOGGER.error("Unable to find mapping with id {}.", mappingId); - task.complete(JobStatus.error(jobId, JobStatus.STATUS.FAILED, "Unable to find mapping with id " + mappingId + ".")); - //throw new MappingNotFoundException("Unable to find mapping with id " + mappingId + "."); + Optional returnValue; + Path srcFile = Paths.get(contentUrl); + MappingRecord mappingRecord; + + // Get mapping file + LOGGER.trace("Searching for mapping with id {}.", mappingId); + Optional optionalMappingRecord = mappingRepo.findByMappingId(mappingId); + if (optionalMappingRecord.isPresent()) { + LOGGER.trace("Mapping for id {} found. Creating temporary output file.", mappingId); + mappingRecord = optionalMappingRecord.get(); + Path mappingFile = Paths.get(mappingRecord.getMappingDocumentUri()); + // execute mapping + Path resultFile = getOutputFile(jobId).toPath(); + LOGGER.trace("Temporary output file available at {}. Performing mapping.", resultFile); + try { + MappingPluginState result = pluginManager.mapFile(mappingRecord.getMappingType(), mappingFile, srcFile, resultFile); + + LOGGER.trace("Mapping returned with result state {}. Returning result file.", result.getState()); + returnValue = Optional.of(resultFile); + LOGGER.trace("Fixing file extension for output {}", returnValue.get()); + Path outputPath = FileUtil.fixFileExtension(returnValue.get()); + LOGGER.trace("Fixed output path: {}", outputPath); + + task.complete(JobStatus.complete(jobId, JobStatus.STATUS.SUCCEEDED, outputPath.toFile())); + } catch (MappingPluginException t) { + LOGGER.error("Asynchronous job execution failed with error.", t); + task.complete(JobStatus.error(jobId, JobStatus.STATUS.FAILED, t.getMessage())); + } finally { + // remove downloaded file + LOGGER.trace("Removing user upload at {}.", srcFile); + FileUtil.removeFile(srcFile); + LOGGER.trace("User upload successfully removed."); + } + } else { + LOGGER.error("Unable to find mapping with id {}.", mappingId); + task.complete(JobStatus.error(jobId, JobStatus.STATUS.FAILED, "Unable to find mapping with id " + mappingId + ".")); + //throw new MappingNotFoundException("Unable to find mapping with id " + mappingId + "."); + } } return task; } @@ -288,7 +292,7 @@ public CompletableFuture executeMappingAsync(String jobId, URI conten public CompletableFuture fetchJobElseThrowException(String jobId) throws JobNotFoundException { CompletableFuture job = fetchJob(jobId); if (null == job) { - LOGGER.error("Job-id {} not found.", jobId); + LOGGER.error("Job with id {} not found.", jobId); throw new JobNotFoundException(JOB_WITH_SUPPLIED_JOB_ID_NOT_FOUND); } return job; @@ -323,15 +327,15 @@ public JobStatus getJobStatus(String jobId) throws Throwable { if (ex != null) { errors[0] = ex.getCause(); } else { - StringBuilder outputFileUri = new StringBuilder("/api/v1/mappingExecution/schedule/"); - outputFileUri.append(jobId).append("/"); - outputFileUri.append("download"); - response.setOutputFileURI(outputFileUri.toString()); + response.setOutputFileURI(String.format("/api/v1/mappingExecution/schedule/%s/download", jobId)); simpleResponses[0] = response; } }); if (errors[0] != null) { + if (errors[0] instanceof MappingPluginException mappingPluginException) { + mappingPluginException.throwMe(); + } throw errors[0]; } @@ -354,18 +358,21 @@ public File getJobOutputFile(String jobId) throws Throwable { CompletableFuture completableFuture = fetchJob(jobId); if (null == completableFuture) { + //return output file in case it still exists (even after the job was removed from the queue) File outputFile = getOutputFile(jobId); if (outputFile.exists()) { return outputFile; } - + //nothing left, return error throw new JobNotFoundException(JOB_WITH_SUPPLIED_JOB_ID_NOT_FOUND); } if (!completableFuture.isDone()) { + LOGGER.trace("Job {} not finished, yet. Returning RUNNING state.", jobId); throw new JobProcessingException("Job is still in progress...", true); } + LOGGER.trace("Obtaining output from job status."); Throwable[] errors = new Throwable[1]; JobStatus[] jobStatus = new JobStatus[1]; completableFuture.whenComplete((response, ex) -> { @@ -377,6 +384,9 @@ public File getJobOutputFile(String jobId) throws Throwable { }); if (errors[0] != null) { + if (errors[0] instanceof MappingPluginException mappingPluginException) { + mappingPluginException.throwMe(); + } throw errors[0]; } @@ -397,35 +407,38 @@ public JobStatus deleteJobAndAssociatedData(String jobId) { CompletableFuture completableFuture = fetchJob(jobId); if (null == completableFuture) { + //delete output file if file still exists (even after the job was removed from the queue) File outputFile = getOutputFile(jobId); if (outputFile.exists()) { outputFile.delete(); } else { - LOGGER.debug("No output file for job {} found. Returning.", jobId); + LOGGER.debug("No output file for job {} found.", jobId); } return JobStatus.status(jobId, JobStatus.STATUS.DELETED); } if (!completableFuture.isDone()) { + LOGGER.trace("Job {} not finished, yet. Returning RUNNING state.", jobId); return JobStatus.status(jobId, JobStatus.STATUS.RUNNING); } + LOGGER.trace("Cleaning up all job artifacts"); completableFuture.whenComplete((response, ex) -> { if (ex != null) { LOGGER.error("Job failed with exception.", ex); } - + final File jobOutput; if (null != response && null != response.getJobOutput()) { - if (response.getJobOutput().exists()) { - response.getJobOutput().delete(); - } + jobOutput = response.getJobOutput(); } else { - File outputFile = getOutputFile(jobId); - if (outputFile.exists()) { - outputFile.delete(); - } + jobOutput = getOutputFile(jobId); } + if (jobOutput.exists()) { + LOGGER.trace(" - Deleting job output"); + jobOutput.delete(); + } + LOGGER.trace("Removing job from queue."); jobManager.removeJob(jobId); }); @@ -442,12 +455,12 @@ public JobStatus deleteJobAndAssociatedData(String jobId) { private File getOutputFile(String jobId) { Matcher m = Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$").matcher(jobId); if (!m.matches()) { - throw new MappingJobException("Invalid jobId provided."); + throw new MappingJobException(String.format("Invalid jobId %s provided.", jobId)); } - Path outputPath = jobsOutputDirectory.resolve(jobId + ".out").normalize(); + Path outputPath = jobsOutputDirectory.resolve(String.format("%s.out", jobId)).normalize(); if (!outputPath.startsWith(jobsOutputDirectory)) { - throw new IllegalArgumentException("Invalid jobId provided."); + throw new IllegalArgumentException(String.format("Invalid jobId %s provided.", jobId)); } return outputPath.toFile(); } @@ -463,16 +476,15 @@ private void init(ApplicationProperties applicationProperties) { try { mappingsDirectory = Files.createDirectories(new File(applicationProperties.getMappingsLocation().getPath()).getAbsoluteFile().toPath()); } catch (IOException e) { - throw new MappingException("Could not initialize directory '" + applicationProperties.getMappingsLocation() + "' for mapping.", e); + throw new MappingServiceException(String.format("Could not initialize mappings directory '%s' for mapping.", applicationProperties.getMappingsLocation()), e); } try { jobsOutputDirectory = Files.createDirectories(new File(applicationProperties.getJobOutputLocation().getPath()).getAbsoluteFile().toPath()); } catch (IOException e) { - throw new MappingException("Could not initialize directory '" + applicationProperties.getJobOutputLocation() + "' for job outputs.", e); + throw new MappingServiceException(String.format("Could not initialize job output directory '%s'.", applicationProperties.getJobOutputLocation()), e); } - } else { - throw new MappingException("Could not initialize mapping directory due to missing location!"); + throw new MappingServiceException("Cannot configure MappingService due to missing application.properties."); } } @@ -504,14 +516,10 @@ private void saveMappingFile(String content, MappingRecord mapping) throws IOExc } catch (NoSuchAlgorithmException ex) { String message = "Failed to initialize SHA256 MessageDigest."; LOGGER.error(message, ex); - throw new MappingException(message, ex); - } catch (IllegalArgumentException iae) { - String message = "Error: Unkown mapping! (" + mapping.getMappingType() + ")"; - LOGGER.error(message, iae); - throw new MappingException(message, iae); + throw new MappingServiceException(message, ex); } } else { - throw new MappingException("Error saving mapping file! (no content)"); + throw new MappingServiceUserException("Failed to update mapping file. No content or mapping record provided."); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java index 91cc150b..24cde918 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginException.java @@ -13,9 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package edu.kit.datamanager.mappingservice.plugins; +import org.springdoc.core.fn.builders.apiresponse.Builder; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.server.ResponseStatusException; + /** * Exception thrown by mapping plugins. * @@ -26,7 +30,7 @@ public class MappingPluginException extends Exception { /** * State of the plugin. */ - private MappingPluginState state; + private MappingPluginState mappingPluginState; /** * Default constructor. @@ -35,7 +39,7 @@ public class MappingPluginException extends Exception { */ public MappingPluginException(MappingPluginState state) { super(state.getState().name()); - this.state = state; + this.mappingPluginState = state; } /** @@ -46,7 +50,7 @@ public MappingPluginException(MappingPluginState state) { */ public MappingPluginException(MappingPluginState state, String message) { super(message); - this.state = state; + this.mappingPluginState = state; } /** @@ -58,7 +62,7 @@ public MappingPluginException(MappingPluginState state, String message) { */ public MappingPluginException(MappingPluginState state, String message, Throwable cause) { super(message, cause); - this.state = state; + this.mappingPluginState = state; } /** @@ -66,8 +70,11 @@ public MappingPluginException(MappingPluginState state, String message, Throwabl * * @return The state of the plugin. */ - public MappingPluginState getState() { - return state; + public MappingPluginState getMappingPluginState() { + return mappingPluginState; } -} + public void throwMe() throws ResponseStatusException { + throw new ResponseStatusException(this.mappingPluginState.getState().getHttpStatus(), "Cause: " + this.mappingPluginState.getDetails()); + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java index efc0024e..6d8d4e8d 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java @@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.reflect.ClassPath; +import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,12 +57,15 @@ public static void unload() { * Load plugins from a given directory. * * @param pluginDir Directory containing plugins. + * @param packagesToScan Packages to scan in addition for plugins. + * * @return Map of plugins. + * * @throws IOException If there is an error with the file system. * @throws MappingPluginException If there is an error with the plugin or * the input. */ - public static Map loadPlugins(File pluginDir) throws IOException, MappingPluginException { + public static Map loadPlugins(File pluginDir, String[] packagesToScan) throws IOException, MappingPluginException { Map result = new HashMap<>(); File[] pluginJars = new File[0]; if (pluginDir == null || pluginDir.getAbsolutePath().isBlank()) { @@ -76,23 +80,22 @@ public static Map loadPlugins(File pluginDir) throws IOE // } } - if (pluginJars.length > 0) { + if (pluginJars != null && pluginJars.length > 0) { cl = new URLClassLoader(PluginLoader.fileArrayToURLArray(pluginJars), Thread.currentThread().getContextClassLoader()); } else { cl = Thread.currentThread().getContextClassLoader(); } - List> plugClasses = PluginLoader.extractClassesFromJARs(pluginJars, cl); + List> plugClasses = PluginLoader.extractClassesFromJARs(pluginJars, packagesToScan, cl); List IMappingPluginList = PluginLoader.createPluggableObjects(plugClasses); for (IMappingPlugin i : IMappingPluginList) { try { i.setup(); result.put(i.id(), i); - } catch (RuntimeException re) { - LOG.error("Caught RuntimeException while setting up plugin " + i.name() + ", version " + i.version() + ". Plugin will be ignored.", re); + } catch (PluginInitializationFailedException re) { + LOG.error("Failed to initialize plugin " + i.name() + ", version " + i.version() + ". Plugin will be ignored.", re); } - } return result; @@ -106,33 +109,39 @@ private static URL[] fileArrayToURLArray(File[] files) throws MalformedURLExcept return urls; } - private static List> extractClassesFromJARs(File[] jars, ClassLoader cl) throws IOException, MappingPluginException { + private static List> extractClassesFromJARs(File[] jars, String[] packagesToScan, ClassLoader cl) throws IOException, MappingPluginException { LOG.trace("Extracting classes from plugin JARs."); List> classes = new ArrayList<>(); - for (File jar : jars) { - LOG.trace("Processing file {}.", jar.getAbsolutePath()); - classes.addAll(PluginLoader.extractClassesFromJAR(jar, cl)); + if (jars != null) { + for (File jar : jars) { + LOG.trace("Processing file {}.", jar.getAbsolutePath()); + classes.addAll(PluginLoader.extractClassesFromJAR(jar, cl)); + } } - LOG.trace("Found {} plugin classes in jar files.", classes.size()); - LOG.trace("Extracting classes from classpath."); - ImmutableSet clazzes = ClassPath.from(cl).getTopLevelClasses("edu.kit.datamanager.mappingservice.plugins.impl"); - int pluginCnt = 0; - for (ClassPath.ClassInfo clazz : clazzes) { - try { - LOG.trace("Processing class {}.", clazz.getName()); - Class pl = (Class) clazz.load(); + if (packagesToScan != null) { + LOG.trace("Extracting classes from classpath."); + int pluginCnt = 0; + for (String pkg : packagesToScan) { + LOG.trace(" - Scanning package {}", pkg); + ImmutableSet clazzes = ClassPath.from(cl).getTopLevelClasses(pkg); + for (ClassPath.ClassInfo clazz : clazzes) { + try { + LOG.trace(" - Processing class {}.", clazz.getName()); + Class pl = clazz.load(); - if (isPluggableClass(pl)) { - classes.add((Class) pl); - pluginCnt++; + if (isPluggableClass(pl)) { + classes.add((Class) pl); + pluginCnt++; + } + } catch (ClassCastException ex) { + //failed to load, probably no implementation of IMappingPlugin + } } - } catch (ClassCastException ex) { - //failed to load, probably no implementation of IMappingPlugin } + LOG.trace("Found {} plugin classes in classpath.", pluginCnt); } - LOG.trace("Found {} plugin classes in classpath.", pluginCnt); return classes; } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index b1334feb..4c7ee256 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -15,6 +15,7 @@ package edu.kit.datamanager.mappingservice.plugins; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -78,7 +79,7 @@ public final void unload() { public final void reloadPlugins() { unload(); try { - plugins = PluginLoader.loadPlugins(Paths.get(applicationProperties.getPluginLocation().toURI()).toFile()); + plugins = PluginLoader.loadPlugins(Paths.get(applicationProperties.getPluginLocation().toURI()).toFile(), applicationProperties.getPackagesToScan()); } catch (URISyntaxException ex) { LOG.error("Mapping plugin location " + applicationProperties.getPluginLocation() + " cannot be converted to URI", ex); } catch (IOException ioe) { @@ -118,31 +119,33 @@ public final List listPluginIds() { * @param mappingFile Path to the mapping schema. * @param inputFile Path to the input file. * @param outputFile Path where the output is temporarily stored. - * + * * @return MappingPluginState.SUCCESS if the plugin was executed * successfully. - * + * * @throws MappingPluginException If there is an error with the plugin or * the input. */ - public final MappingPluginState mapFile(String pluginId, Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { + public final MappingPluginState mapFile(String pluginId, Path mappingFile, Path inputFile, Path outputFile) throws MappingServiceException, MappingPluginException { + //The following issues should never happen as they are checked before. + //If they occur, it's a server fault, nothing a user can solve. if (pluginId == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Plugin ID is null."); + throw new MappingServiceException("PluginId is null."); } if (mappingFile == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Path to mapping schema is null."); + throw new MappingServiceException("Path to mapping file is null."); } if (inputFile == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Path to input file is null."); + throw new MappingServiceException("Path to input file is null."); } if (outputFile == null) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Path to output file is null."); + throw new MappingServiceException("Path to output file is null."); } if (plugins.containsKey(pluginId)) { LOG.trace("Plugin found. Performing mapFile({}, {}, {}).", mappingFile, inputFile, outputFile); return plugins.get(pluginId).mapFile(mappingFile, inputFile, outputFile); } - throw new MappingPluginException(MappingPluginState.NOT_FOUND(), "Plugin '" + pluginId + "' not found!"); + throw new MappingPluginException(MappingPluginState.NOT_FOUND(), String.format("Plugin '%s' not found!", pluginId)); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java index 64ccf2e2..d7a4d9ca 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java @@ -65,7 +65,7 @@ public MimeType[] outputTypes() { public void setup() { LOGGER.info("Checking and installing dependencies for Gemma: gemma, xmltodict, wget"); try { - PythonRunnerUtil.runPythonScript("-m", "pip", "install", "xmltodict", "wget"); + //PythonRunnerUtil.runPythonScript("-m", "pip", "install", "xmltodict", "wget"); PythonRunnerUtil.runPythonScript("-m", new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), "pip", "install", "xmltodict", "wget"); gemmaDir = FileUtil.cloneGitRepository(GEMMA_REPOSITORY, GEMMA_BRANCH); initialized = true; @@ -81,7 +81,9 @@ public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputF return PythonRunnerUtil.runPythonScript(gemmaDir + "/mapping_single.py", mappingFile.toString(), inputFile.toString(), outputFile.toString()); } else { LOGGER.error("Plugin '" + name() + "' " + version() + " not initialized. Returning EXECUTION_ERROR."); - return MappingPluginState.EXECUTION_ERROR(); + MappingPluginState result = MappingPluginState.EXECUTION_ERROR(); + result.setDetails("Plugin not initialized, probably due to missing dependencies or external plugin repository."); + return result; } } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java index 384c1bfb..cdd1c9b4 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java @@ -15,6 +15,7 @@ */ package edu.kit.datamanager.mappingservice.plugins.impl; +import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import edu.kit.datamanager.mappingservice.plugins.IMappingPlugin; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; @@ -73,21 +74,25 @@ public MimeType[] outputTypes() { public void setup() { if (Paths.get("/usr/bin/identify").toFile().exists()) { initialized = true; + } else { + throw new PluginInitializationFailedException("Required executable /usr/bin/identify not found."); } } @Override public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { + MappingPluginState result; try { - FileOutputStream fout = new FileOutputStream(outputFile.toFile()); - ShellRunnerUtil.run(fout, fout, "/usr/bin/identify", "-verbose", inputFile.toAbsolutePath().toString()); - fout.flush(); - fout.close(); + try (FileOutputStream fout = new FileOutputStream(outputFile.toFile())) { + result = ShellRunnerUtil.run(fout, fout, "/usr/bin/identify", "-verbose", inputFile.toAbsolutePath().toString()); + fout.flush(); + } } catch (IOException ex) { LOG.error("Failed to execute plugin.", ex); - return MappingPluginState.EXECUTION_ERROR(); + result = MappingPluginState.EXECUTION_ERROR(); + result.setDetails(ex.getMessage()); } - return MappingPluginState.SUCCESS(); + return result; } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java index 69bc985d..4b32a265 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java @@ -73,13 +73,15 @@ public void setup() { @Override public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { + MappingPluginState result = MappingPluginState.SUCCESS(); try { Files.copy(inputFile, outputFile, StandardCopyOption.REPLACE_EXISTING); } catch (IOException | MappingException ex) { LOG.error("Failed to execute plugin.", ex); - return MappingPluginState.EXECUTION_ERROR(); + result = MappingPluginState.EXECUTION_ERROR(); + result.setDetails("Failed to copy input to output, probably due to an I/O error."); } - return MappingPluginState.SUCCESS(); + return result; } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java index cdd7ae98..1502e888 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java @@ -15,6 +15,7 @@ */ package edu.kit.datamanager.mappingservice.rest.impl; +import com.google.common.base.Strings; import edu.kit.datamanager.entities.PERMISSION; import edu.kit.datamanager.mappingservice.dao.IMappingRecordDao; import edu.kit.datamanager.mappingservice.domain.MappingRecord; @@ -56,7 +57,6 @@ import java.util.List; import java.util.Optional; - /** * Controller for managing mapping files. * @@ -109,7 +109,11 @@ public ResponseEntity createMapping( } catch (IOException ex) { LOG.error("Unable to deserialize mapping record.", ex); return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); -//.body("Unable to deserialize provided mapping record."); + } + + if (Strings.isNullOrEmpty(mappingRecord.getMappingId()) || Strings.isNullOrEmpty(mappingRecord.getMappingType())) { + LOG.error("Invalid mapping record. Either mappingId or mappingType are null."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); } LOG.trace("Obtaining caller principle for authorization purposes."); @@ -145,8 +149,7 @@ public ResponseEntity createMapping( mappingRecord = mappingService.createMapping(contentOfFile, mappingRecord); } catch (IOException ioe) { LOG.error("Unable to create mapping for provided inputs.", ioe); - //return ResponseEntity.internalServerError().body("Unable to create mapping for provided inputs."); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } LOG.trace("Mapping successfully persisted. Updating document URI."); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java index b2630b69..eaab5b3c 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java @@ -18,11 +18,14 @@ import edu.kit.datamanager.mappingservice.dao.IMappingRecordDao; import edu.kit.datamanager.mappingservice.domain.JobStatus; import edu.kit.datamanager.mappingservice.domain.MappingRecord; +import edu.kit.datamanager.mappingservice.exception.JobIdConflictException; import edu.kit.datamanager.mappingservice.exception.JobProcessingException; import edu.kit.datamanager.mappingservice.exception.MappingException; import edu.kit.datamanager.mappingservice.exception.MappingExecutionException; import edu.kit.datamanager.mappingservice.exception.MappingJobException; import edu.kit.datamanager.mappingservice.exception.MappingNotFoundException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceUserException; import edu.kit.datamanager.mappingservice.impl.JobManager; import edu.kit.datamanager.mappingservice.impl.MappingService; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; @@ -49,7 +52,6 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import org.apache.tomcat.util.file.Matcher; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; @@ -81,7 +83,7 @@ public MappingExecutionController(MappingService mappingService, IMappingRecordD public void mapDocument(MultipartFile document, String mappingID, HttpServletRequest request, HttpServletResponse response, UriComponentsBuilder uriBuilder) { LOG.trace("Performing mapDocument(File#{}, {})", document.getOriginalFilename(), mappingID); - Optional resultPath; + Optional resultPath = Optional.empty(); if (!document.isEmpty() && !mappingID.isBlank()) { LOG.trace("Obtaining mapping for id {}.", mappingID); Optional record = mappingRecordDao.findByMappingId(mappingID); @@ -89,25 +91,24 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq String message = String.format("No mapping found for mapping id %s.", mappingID); LOG.error(message + " Returning HTTP 404."); throw new MappingNotFoundException(message); - //return ResponseEntity.status(HttpStatus.NOT_FOUND).body(message); } - LOG.trace("Receiving mapping input file."); + LOG.trace("Processing mapping input file."); String extension = "." + FilenameUtils.getExtension(document.getOriginalFilename()); - LOG.trace("Found file extension: {}", extension); + LOG.trace(" - Determined file extension: {}", extension); Path inputPath = FileUtil.createTempFile("inputMultipart", extension); - LOG.trace("Writing user upload to: {}", inputPath); + LOG.trace(" - Writing user upload to: {}", inputPath); File inputFile = inputPath.toFile(); try { document.transferTo(inputFile); - LOG.trace("Successfully received user upload."); + LOG.trace("Successfully stored user upload at {}.", inputPath); } catch (IOException e) { - LOG.error("Failed to receive upload from user.", e); + LOG.error("Failed to store user upload.", e); throw new MappingExecutionException("Unable to write user upload to disk."); } try { - LOG.trace("Performing mapping process of file {} via mapping service", inputPath.toString()); + LOG.trace("Performing mapping process of file {} via mapping service", inputPath); resultPath = mappingService.executeMapping(inputFile.toURI(), mappingID); if (resultPath.isPresent()) { @@ -117,7 +118,8 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq } } catch (MappingPluginException e) { LOG.error("Failed to execute mapping.", e); - throw new MappingExecutionException("Failed to execute mapping with id " + mappingID + " on provided input document."); + e.throwMe(); + //throw new MappingExecutionException("Failed to execute mapping with id " + mappingID + " on provided input document."); } finally { LOG.trace("Removing user upload at {}.", inputFile); FileUtil.removeFile(inputPath); @@ -126,24 +128,24 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq } else { String message = "Either mapping id or input document are missing. Unable to perform mapping."; LOG.error(message); - throw new MappingException(message); + throw new MappingServiceUserException(message); } + Path result = resultPath.get(); if (!Files.exists(result) || !Files.isRegularFile(result) || !Files.isReadable(result)) { String message = "The mapping result expected at path " + result + " is not accessible. This indicates an error of the mapper implementation."; LOG.error(message); - throw new MappingExecutionException(message); + throw new MappingServiceException(message); } - LOG.trace("Determining mime type for mapping result."); + LOG.trace("Determining mime type for mapping result {}.", result); result = FileUtil.fixFileExtension(result); String mimeType = FileUtil.getMimeType(result); - LOG.trace("Determining file extension for mapping result."); + LOG.trace("Mime type {} determined. Identifying file extension.", mimeType); String extension = FileUtil.getExtensionForMimeType(mimeType); - LOG.trace("Using mime type {} and extension {}.", mimeType, extension); - + LOG.trace("Returning result using mime type {} and file extension {}.", mimeType, extension); response.setStatus(HttpStatus.OK.value()); response.setHeader("Content-Type", mimeType); response.setHeader(HttpHeaders.CONTENT_LENGTH, Long.toString(result.toFile().length())); @@ -152,12 +154,12 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq response.setHeader("Expires", "0"); response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;" + "filename=result" + extension); try { + LOG.trace("Writing file to response output stream."); Files.copy(result, response.getOutputStream()); - } catch (IOException ex) { String message = "Failed to write mapping result file to stream."; LOG.error(message, ex); - throw new MappingExecutionException(message); + throw new MappingServiceException(message); } finally { LOG.trace("Result file successfully transferred to client. Removing file {} from disk.", result); try { @@ -171,14 +173,21 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq @Override public ResponseEntity scheduleMapDocument(String mappingID, MultipartFile document, HttpServletRequest request, HttpServletResponse response, UriComponentsBuilder uriBuilder) throws Throwable { - LOG.trace("Performing mapDocument(File#{}, {})", document.getOriginalFilename(), mappingID); - String jobId = UUID.randomUUID().toString(); + LOG.trace("Performing scheduleMapDocument(File#{}, {})", document.getOriginalFilename(), mappingID); + String jobId = null; + for (int i = 1; i < 4; i++) { + jobId = UUID.randomUUID().toString(); + if (jobManager.getJob(jobId) == null) { + jobId = null; + } + LOG.trace("Duplicated job id detected. Attempt {}/{}", i, 3); + } - if (null != jobManager.getJob(jobId)) { - throw new JobProcessingException("JobId conflict, please retry again.", true); + if (jobId == null) { + throw new JobIdConflictException(); } - LOG.info("Generated job-id {} for this request.", jobId); + LOG.info("Generated job id {} for this request.", jobId); if (!document.isEmpty() && !mappingID.isBlank()) { LOG.trace("Obtaining mapping for id {}.", mappingID); Optional record = mappingRecordDao.findByMappingId(mappingID); @@ -186,7 +195,6 @@ public ResponseEntity scheduleMapDocument(String mappingID, Multipart String message = String.format("No mapping found for mapping id %s.", mappingID); LOG.error(message + " Returning HTTP 404."); throw new MappingNotFoundException(message); - //return ResponseEntity.status(HttpStatus.NOT_FOUND).body(message); } LOG.trace("Receiving mapping input file."); @@ -200,31 +208,27 @@ public ResponseEntity scheduleMapDocument(String mappingID, Multipart LOG.trace("Successfully received user upload."); } catch (IOException e) { LOG.error("Failed to receive upload from user.", e); - throw new JobProcessingException("Unable to write user upload to disk."); + throw new MappingExecutionException("Unable to write user upload to disk."); } try { LOG.trace("Scheduling mapping process of file {} via mapping service", inputPath.toString()); CompletableFuture completableFuture = mappingService.executeMappingAsync(jobId, inputFile.toURI(), mappingID); jobManager.putJob(jobId, completableFuture); - LOG.info("Job-id {} submitted for processing. Returning from controller.", jobId); + LOG.info("Job id {} scheduled for processing. Returning job status.", jobId); return ResponseEntity.ok(JobStatus.status(jobId, JobStatus.STATUS.SUBMITTED)); } catch (MappingPluginException e) { LOG.error("Failed to execute mapping.", e); + return ResponseEntity.status(500).body(JobStatus.error(jobId, JobStatus.STATUS.FAILED, String.format("Failed to schedule mapping with id '%s' on provided input document.", mappingID))); + } finally { LOG.trace("Removing user upload at {}.", inputFile); FileUtil.removeFile(inputPath); LOG.trace("User upload successfully removed."); - return ResponseEntity.status(500).body(JobStatus.error(jobId, JobStatus.STATUS.FAILED, "Failed to execute mapping with id " + mappingID + " on provided input document.")); } - /*finally { - LOG.trace("Removing user upload at {}.", inputFile); - FileUtil.removeFile(inputPath); - LOG.trace("User upload successfully removed."); - }*/ } else { String message = "Either mapping id or input document are missing. Unable to perform mapping."; LOG.error(message); - throw new JobProcessingException(message); + throw new MappingServiceUserException(message); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java index 8eb4a69d..d80a3aac 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java @@ -17,6 +17,7 @@ import edu.kit.datamanager.clients.SimpleServiceClient; import edu.kit.datamanager.mappingservice.exception.MappingException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.eclipse.jgit.api.Git; @@ -41,6 +42,7 @@ import org.apache.tika.mime.MimeType; import org.apache.tika.mime.MimeTypeException; import org.apache.tika.mime.MimeTypes; +import org.eclipse.jgit.errors.RepositoryNotFoundException; /** * Various utility methods for file handling. @@ -259,7 +261,7 @@ private static String guessFileExtension(String filename, byte[] fewKilobytesOfF returnValue = ".xml"; } } - + if (returnValue == null) { // Use tika library to estimate extension LOGGER.trace("Use tika library to estimate extension."); @@ -304,20 +306,26 @@ public static Path cloneGitRepository(String repositoryUrl, String branch, Strin File target = new File(targetFolder); if (target.exists()) { try { - Git.open(target).pull().call(); - } catch (IOException | JGitInternalException | GitAPIException e) { - LOGGER.error("Error pulling git repository at '" + target + "'!", e); - throw new MappingException("Error pulling git repository at '" + target + "'!", e); + try (Git g = Git.open(target)) { + LOGGER.trace("Repository already exists at {}. Active branch is: {}", target, g.getRepository().getBranch()); + g.getRepository().close(); + } + } catch (IOException e) { + String message = String.format("Folder '%s' already exists but contains not Git repository.", target); + LOGGER.error(message, e); + throw new MappingServiceException("Failed to prepare plugin. Plugin code destination already exists but is empty."); } } else { target.mkdirs(); LOGGER.info("Cloning branch '{}' of repository '{}' to '{}'", branch, repositoryUrl, target.getPath()); try { - Git.cloneRepository().setURI(repositoryUrl).setBranch(branch).setDirectory(target).call(); + try (Git res = Git.cloneRepository().setURI(repositoryUrl).setBranch(branch).setDirectory(target).call()) { + res.getRepository().close(); + } } catch (JGitInternalException | GitAPIException e) { LOGGER.error("Error cloning git repository '" + repositoryUrl + "' to '" + target + "'!", e); - throw new MappingException("Error cloning git repository '" + repositoryUrl + "' to '" + target + "'!", e); + throw new MappingServiceException("Failed to prepare plugin. Plugin code destination not accessible."); } } return target.toPath(); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index 47bb1482..0fb9a93d 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -33,11 +33,11 @@ */ @Component public class PythonRunnerUtil { - + private static ApplicationProperties configuration; - + private static final Logger LOGGER = LoggerFactory.getLogger(PythonRunnerUtil.class); - + @Autowired public PythonRunnerUtil(ApplicationProperties configuration) { PythonRunnerUtil.configuration = configuration; @@ -48,10 +48,9 @@ public PythonRunnerUtil(ApplicationProperties configuration) { */ public static void printPythonVersion() { try { - LOGGER.info("Configured Python version:"); - PythonRunnerUtil.runPythonScript("--version", new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.INFO), new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.INFO)); + PythonRunnerUtil.runPythonScript("--version", System.out, System.err); } catch (MappingPluginException e) { - e.printStackTrace(); + LOGGER.error("Failed to obtain python version.", e); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java index 660f919d..5efa8065 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java @@ -110,7 +110,6 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in } ExecutorService pool = Executors.newSingleThreadExecutor(); - int result; MappingPluginState returnValue = MappingPluginState.SUCCESS(); try { @@ -150,12 +149,13 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in returnValue = MappingPluginState.UNKNOWN_ERROR(); } catch (BadExitCodeException e) { LOGGER.error("Failed to execute command due to an unexpected exception.", e); - returnValue = MappingPluginState.UNKNOWN_ERROR(); + returnValue = MappingPluginState.BAD_EXIT_CODE(); + returnValue.setDetails(e.getExitCode()); } finally { pool.shutdown(); } - - if (returnValue != MappingPluginState.SUCCESS()) { + + if (returnValue.getState() != MappingPluginState.SUCCESS().getState()) { throw new MappingPluginException(returnValue); } return returnValue; diff --git a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java index c5be7194..15a6601e 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java @@ -21,6 +21,7 @@ import edu.kit.datamanager.mappingservice.domain.MappingRecord; import edu.kit.datamanager.mappingservice.exception.MappingException; import edu.kit.datamanager.mappingservice.exception.MappingNotFoundException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.BeforeEach; @@ -128,8 +129,8 @@ public void testConstructorRelativePath() throws IOException, URISyntaxException public void testConstructorFailing() throws IOException, URISyntaxException { try { new MappingService(null); - fail(); - } catch (MappingException ie) { + fail("Expected MappingServiceException"); + } catch (MappingServiceException ie) { assertTrue(true); } //seems to be no problem under Windows and if run as root this is also no issue, so let's skip this test for the moment. diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java index 0ef0f6b8..5144038b 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/MappingPluginExceptionTest.java @@ -24,17 +24,17 @@ class MappingPluginExceptionTest { @Test void testConstructor() { MappingPluginException ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR()); - assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getState().getState()); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getMappingPluginState().getState()); assertEquals(MappingPluginState.UNKNOWN_ERROR().getState().toString(), ex.getMessage()); assertNull(ex.getCause()); ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "test"); - assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getState().getState()); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getMappingPluginState().getState()); assertEquals("test", ex.getMessage()); assertNull(ex.getCause()); ex = new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "test", new Exception()); - assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getState().getState()); + assertEquals(MappingPluginState.UNKNOWN_ERROR().getState(), ex.getMappingPluginState().getState()); assertEquals("test", ex.getMessage()); assertNotNull(ex.getCause()); } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java index e7a37fdb..c4f09adb 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java @@ -23,6 +23,7 @@ import java.nio.file.Path; import java.util.Map; import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Assertions; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -56,23 +57,25 @@ void valid() { System.out.println("Test valid"); Map plugins = null; try { - plugins = PluginLoader.loadPlugins(Path.of(applicationProperties.getPluginLocation().toURI()).toFile()); + plugins = PluginLoader.loadPlugins(Path.of(applicationProperties.getPluginLocation().toURI()).toFile(), applicationProperties.getPackagesToScan()); } catch (Exception e) { fail(e); } - for (var entry : plugins.entrySet()) { - System.out.println(entry.getValue().id()); - } + try { - assertEquals("TEST_0.0.0", plugins.get("TEST_0.0.0").id()); - assertEquals("TEST", plugins.get("TEST_0.0.0").name()); - assertEquals("Hello world! This is a non functional test plugin.", plugins.get("TEST_0.0.0").description()); - assertEquals("0.0.0", plugins.get("TEST_0.0.0").version()); - assertEquals("https://github.com/kit-data-manager/gemma", plugins.get("TEST_0.0.0").uri()); - assertEquals(MimeTypeUtils.APPLICATION_JSON, plugins.get("TEST_0.0.0").inputTypes()[0]); - assertEquals(MimeTypeUtils.APPLICATION_JSON, plugins.get("TEST_0.0.0").outputTypes()[0]); - plugins.get("TEST_0.0.0").setup(); - assertEquals(MappingPluginState.SUCCESS().getState(), plugins.get("TEST_0.0.0").mapFile(new File("schema").toPath(), new File("input").toPath(), new File("output").toPath()).getState()); + assertEquals("InOutPlugin_1.1.2", plugins.get("InOutPlugin_1.1.2").id()); + assertEquals("InOutPlugin", plugins.get("InOutPlugin_1.1.2").name()); + assertEquals("Simple plugin for testing just returning the input file.", plugins.get("InOutPlugin_1.1.2").description()); + assertEquals("1.1.2", plugins.get("InOutPlugin_1.1.2").version()); + assertEquals("https://github.com/kit-data-manager/mapping-service", plugins.get("InOutPlugin_1.1.2").uri()); + assertEquals("application/*", plugins.get("InOutPlugin_1.1.2").inputTypes()[0].toString()); + assertEquals("application/*", plugins.get("InOutPlugin_1.1.2").outputTypes()[0].toString()); + plugins.get("InOutPlugin_1.1.2").setup(); + File inputFile = new File("/tmp/imputFile"); + if (!inputFile.exists()) { + Assertions.assertTrue(inputFile.createNewFile()); + } + assertEquals(MappingPluginState.SUCCESS().getState(), plugins.get("InOutPlugin_1.1.2").mapFile(new File("schema").toPath(), inputFile.toPath(), new File("output").toPath()).getState()); } catch (Exception e) { fail(e); } @@ -82,7 +85,7 @@ void valid() { void invalidPath() { Map plugins = null; try { - PluginLoader.loadPlugins(new File("./invalid/test")); + PluginLoader.loadPlugins(new File("./invalid/test"), applicationProperties.getPackagesToScan()); } catch (IOException e) { fail(e); } catch (MappingPluginException validationWarning) { @@ -102,7 +105,7 @@ void invalidPath() { void nullInput() { Map plugins = null; try { - plugins = PluginLoader.loadPlugins(null); + plugins = PluginLoader.loadPlugins(null, null); } catch (IOException e) { fail(e); } catch (MappingPluginException validationWarning) { @@ -113,7 +116,7 @@ void nullInput() { void emptyinput() { Map plugins = null; try { - plugins = PluginLoader.loadPlugins(new File("")); + plugins = PluginLoader.loadPlugins(new File(""), null); } catch (IOException e) { fail(e); } catch (MappingPluginException validationWarning) { diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java index 43ac75f8..93632a51 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java @@ -15,6 +15,7 @@ package edu.kit.datamanager.mappingservice.plugins; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; @@ -71,37 +72,42 @@ void getListOfAvailableValidators() { void mapFileInvalidParameters() { try { pluginManager.mapFile(null, null, null, null); - } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); + } catch (MappingServiceException e) { assertEquals("Plugin ID is null.", e.getMessage()); + } catch (MappingPluginException ex) { + fail("Expected MappingServiceException"); } try { pluginManager.mapFile("test", null, null, null); - } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); + } catch (MappingServiceException e) { assertEquals("Path to mapping schema is null.", e.getMessage()); + } catch (MappingPluginException ex) { + fail("Expected MappingServiceException"); } try { pluginManager.mapFile("test", new File("test").toPath(), null, null); - } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); + } catch (MappingServiceException e) { assertEquals("Path to input file is null.", e.getMessage()); + } catch (MappingPluginException ex) { + fail("Expected MappingServiceException"); } try { pluginManager.mapFile("test", new File("test").toPath(), new File("testInput").toPath(), null); - } catch (MappingPluginException e) { - assertEquals(MappingPluginState.INVALID_INPUT(), e.getState()); + } catch (MappingServiceException e) { assertEquals("Path to output file is null.", e.getMessage()); + } catch (MappingPluginException ex) { + fail("Expected MappingServiceException"); } try { pluginManager.mapFile("test", new File("test").toPath(), new File("testInput").toPath(), new File("testOutput").toPath()); - } catch (MappingPluginException e) { - assertEquals(MappingPluginState.NOT_FOUND(), e.getState()); - assertEquals("Plugin 'test' not found!", e.getMessage()); + } catch (MappingServiceException e) { + fail("Expected MappingPluginException"); + } catch (MappingPluginException ex) { + assertEquals("Plugin 'test' not found!", ex.getMessage()); } } @@ -109,13 +115,16 @@ void mapFileInvalidParameters() { void mapFile() { try { File outputFile = new File("/tmp/testOutput"); - System.out.println("PLUGINS " + pluginManager.getPlugins()); - pluginManager.mapFile("InOutPlugin_1.1.2", new File("mapping-schema").toPath(), new File("input").toPath(), outputFile.toPath()); + File inputFile = new File("/tmp/testInput"); + if (!inputFile.exists()) { + assertTrue(inputFile.createNewFile()); + } + pluginManager.mapFile("InOutPlugin_1.1.2", new File("mapping-schema").toPath(), inputFile.toPath(), outputFile.toPath()); assertTrue(outputFile.exists()); + inputFile.delete(); outputFile.delete(); - } catch (MappingPluginException e) { - e.printStackTrace(); - fail("Mapping failed"); + } catch (MappingPluginException | IOException e) { + fail("Mapping failed", e); } } } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java index 873f7c9f..e9284241 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/PluginInformationTest.java @@ -230,7 +230,7 @@ void testIDConstructor() { new PluginInformation(null, pluginManager); fail("Expected exception"); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.NOT_FOUND(), e.getState()); + assertEquals(MappingPluginState.NOT_FOUND(), e.getMappingPluginState()); } } } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java index 7333e871..6e08b6df 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java @@ -18,7 +18,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import edu.kit.datamanager.entities.PERMISSION; -import edu.kit.datamanager.mappingservice.MappingServiceApplication; import edu.kit.datamanager.mappingservice.dao.IMappingRecordDao; import edu.kit.datamanager.mappingservice.domain.AclEntry; import edu.kit.datamanager.mappingservice.domain.MappingRecord; @@ -26,7 +25,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -66,16 +64,11 @@ import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.runner.RunWith; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.restdocs.RestDocumentationContextProvider; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionControllerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionControllerTest.java index 1c2c5adb..c76c74f8 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionControllerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionControllerTest.java @@ -61,7 +61,7 @@ public class MappingExecutionControllerTest { private final static String TEMP_DIR_4_ALL = "/tmp/mapping-service/"; private final static String TEMP_DIR_4_MAPPING = TEMP_DIR_4_ALL + "mapping/"; private static final String MAPPING_ID = "my_dc"; - private static final String MAPPING_TYPE = "TEST_0.0.0"; + private static final String MAPPING_TYPE = "InOutPlugin_1.1.2"; private static final String MAPPING_URL = "/api/v1/mappingExecution/" + MAPPING_ID; private static final String MAPPING_TITLE = "TITEL"; private static final String MAPPING_DESCRIPTION = "DESCRIPTION"; @@ -155,7 +155,7 @@ void mapValidDocument() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.multipart(MAPPING_URL).file(mappingFile)). andDo(print()). andExpect(status().isOk()). - andExpect(header().string("content-disposition", "attachment;filename=result.txt")).andReturn(); + andExpect(header().string("content-disposition", "attachment;filename=result.json")).andReturn(); } @Test diff --git a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java index e4df43d7..52f18705 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java @@ -17,6 +17,7 @@ import com.google.common.io.Files; import edu.kit.datamanager.mappingservice.exception.MappingException; +import edu.kit.datamanager.mappingservice.exception.MappingServiceException; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -27,8 +28,10 @@ import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.HashSet; import java.util.Optional; +import org.apache.commons.io.filefilter.HiddenFileFilter; import static org.junit.jupiter.api.Assertions.*; @@ -323,30 +326,31 @@ void cloneValidGitRepository() { util = FileUtil.cloneGitRepository("https://github.com/kit-data-manager/mapping-service.git", "main", "/tmp/test"); } catch (Exception e) { fail(e); + } finally { + try { + FileUtils.deleteDirectory(new File("/tmp/test")); + } catch (IOException e) { + } } - try { - FileUtils.deleteDirectory(new File("tmp/test")); - } catch (IOException e) { - } + assertNotNull(util); util = null; try { util = FileUtil.cloneGitRepository("https://github.com/kit-data-manager/mapping-service.git", "main"); } catch (Exception e) { fail(e); + } finally { + try { + FileUtils.deleteDirectory(new File(util.toUri())); + } catch (IOException e) { + } } - assertNotNull(util); - try { - FileUtils.deleteDirectory(new File(util.toUri())); - } catch (IOException e) { - } - util = null; } @Test void cloneInvalidGitRepository() { - assertThrows(MappingException.class, () -> FileUtil.cloneGitRepository("test", "test", "test")); - assertThrows(MappingException.class, () -> FileUtil.cloneGitRepository("test", "test")); + assertThrows(MappingServiceException.class, () -> FileUtil.cloneGitRepository("test", "test", "test")); + assertThrows(MappingServiceException.class, () -> FileUtil.cloneGitRepository("test", "test")); } @AfterEach diff --git a/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java b/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java index 2af9870c..59478d2c 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtilTest.java @@ -27,17 +27,17 @@ class ShellRunnerUtilTest { void runValid() { if (SystemUtils.IS_OS_WINDOWS) { try { - assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run("echo.bat", "test")); - assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(5, "echo.bat", "test")); - assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(System.out, System.err, "echo.bat", "test")); + assertEquals(MappingPluginState.SUCCESS().getState(), ShellRunnerUtil.run("echo.bat", "test").getState()); + assertEquals(MappingPluginState.SUCCESS().getState(), ShellRunnerUtil.run(5, "echo.bat", "test").getState()); + assertEquals(MappingPluginState.SUCCESS().getState(), ShellRunnerUtil.run(System.out, System.err, "echo.bat", "test").getState()); } catch (MappingPluginException e) { fail(e); } } else { try { - assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run("echo", "test")); - assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(5, "echo", "test")); - assertEquals(MappingPluginState.SUCCESS(), ShellRunnerUtil.run(System.out, System.err, "echo", "test")); + assertEquals(MappingPluginState.SUCCESS().getState(), ShellRunnerUtil.run("echo", "test").getState()); + assertEquals(MappingPluginState.SUCCESS().getState(), ShellRunnerUtil.run(5, "echo", "test").getState()); + assertEquals(MappingPluginState.SUCCESS().getState(), ShellRunnerUtil.run(System.out, System.err, "echo", "test").getState()); } catch (MappingPluginException e) { fail(e); } From 492082f4b932e6075fc676f53d70d50df9bf9800 Mon Sep 17 00:00:00 2001 From: Jejkal Date: Tue, 4 Mar 2025 12:11:11 +0100 Subject: [PATCH 25/80] Commit test --- HELP.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/HELP.md b/HELP.md index 42f291da..f8f3cfed 100644 --- a/HELP.md +++ b/HELP.md @@ -1,8 +1,3 @@ -# Read Me First -The following was discovered as part of building this project: - -* The original package name 'edu.kit.datamanager.mapping-service' is invalid and this project uses 'edu.kit.datamanager.mappingservice' instead. - # Getting Started ### Reference Documentation From 044f5af8d7f393306e03fcea58208013f5e3b53c Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Wed, 5 Mar 2025 09:23:43 +0100 Subject: [PATCH 26/80] First working version allowing to load plugin in code base, further testing required --- build.gradle | 19 +-- plugins/empty-plugin-0.0.0-SNAPSHOT-plain.jar | Bin 75179 -> 0 bytes plugins/gemma-plugin-0.1.0-SNAPSHOT-plain.jar | Bin 76885 -> 0 bytes .../MappingServiceApplication.java | 13 +- .../mappingservice/plugins/PluginLoader.java | 119 ++++++++++++++---- .../mappingservice/plugins/PluginManager.java | 9 +- .../mappingservice/TestConfig.java | 8 +- .../plugins/PluginLoaderTest.java | 13 +- .../plugins/PluginManagerTest.java | 4 +- .../mappingservice/util/FileUtilTest.java | 1 + 10 files changed, 134 insertions(+), 52 deletions(-) delete mode 100644 plugins/empty-plugin-0.0.0-SNAPSHOT-plain.jar delete mode 100644 plugins/gemma-plugin-0.1.0-SNAPSHOT-plain.jar diff --git a/build.gradle b/build.gradle index 5fe282be..92a66b9f 100644 --- a/build.gradle +++ b/build.gradle @@ -142,20 +142,10 @@ asciidoctor { dependsOn test } -/*jar { - manifest { - attributes 'Main-Class': 'edu.kit.datamanager.mapping-service.MappingServiceApplication' - } - archiveBaseName = 'mapping-service' - // version is defined in file 'gradle.properties' - archiveVersion = System.getenv('version') - // disable plain jar file - enabled = false -}*/ - bootJar { dependsOn asciidoctor - println 'Create bootable jar...' + dependsOn 'buildPluginJar' + from ("${asciidoctor.outputDir}/html5") { into 'static/docs' } @@ -164,8 +154,11 @@ bootJar { manifest { attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher' } - // exclude '**/plugins/impl/**' + exclude '**/plugins/impl/**' + from('build/libs/default-plugins-1.1.2-SNAPSHOT.jar') { + into('BOOT-INF/lib/plugins' ) + } launchScript() } diff --git a/plugins/empty-plugin-0.0.0-SNAPSHOT-plain.jar b/plugins/empty-plugin-0.0.0-SNAPSHOT-plain.jar deleted file mode 100644 index 61bdbe1f368ed334d0784c6ac47f42f9bea07009..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75179 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≷1e|(%H(6T-DHt{lW!6;X}FTVC34h$k-cYsdJ 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 literal 0 HcmV?d00001 diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pythonw.exe b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pythonw.exe new file mode 100644 index 0000000000000000000000000000000000000000..c1c2531d554b91055a8ec54c2e6be096d3b2160c GIT binary patch literal 232688 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 Date: Mon, 17 Mar 2025 09:11:48 +0100 Subject: [PATCH 34/80] Add monitoring with prometheus --- build.gradle | 4 ++++ settings/application-default.properties | 3 +++ .../MappingServiceApplication.java | 18 +++++++++++------- .../mappingservice/plugins/PluginManager.java | 6 +++++- .../impl/MappingAdministrationController.java | 6 +++++- .../datamanager/mappingservice/TestConfig.java | 6 +++++- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index 5c1cfeae..b03d0ca1 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-actuator' + // monitoring + implementation 'io.micronaut.micrometer:micronaut-micrometer-registry-prometheus:5.8.0' + implementation 'org.springframework.boot:spring-boot-starter-actuator:3.3.4' + // springdoc implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springDocVersion}" implementation "org.springdoc:springdoc-openapi-starter-common:${springDocVersion}" diff --git a/settings/application-default.properties b/settings/application-default.properties index e97d63d8..1308ecd6 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -54,3 +54,6 @@ mapping-service.pluginLocation=file://INSTALLATION_DIR/plugins # Absolute path to the local gemma mappings folder. mapping-service.mappingSchemasLocation=file://INSTALLATION_DIR/mappingSchemas mapping-service.jobOutput=file://INSTALLATION_DIR/jobOutput + +management.metrics.export.prometheus.enabled=true +management.endpoint.metrics.enabled=true diff --git a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java index 77267aae..37297f59 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java @@ -1,18 +1,15 @@ package edu.kit.datamanager.mappingservice; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; -import edu.kit.datamanager.mappingservice.exception.MappingJobException; import edu.kit.datamanager.mappingservice.plugins.PluginManager; -import java.io.File; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; + +import io.micrometer.core.instrument.MeterRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -27,6 +24,13 @@ public class MappingServiceApplication { private static final Logger LOG = LoggerFactory.getLogger(MappingServiceApplication.class); + @Autowired + private final MeterRegistry meterRegistry; + + MappingServiceApplication(MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + } + @Bean public ApplicationProperties applicationProperties() { return new ApplicationProperties(); @@ -34,7 +38,7 @@ public ApplicationProperties applicationProperties() { @Bean public PluginManager pluginManager() { - return new PluginManager(applicationProperties()); + return new PluginManager(applicationProperties(), meterRegistry); } public static void main(String[] args) { diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index ce9e91d0..48333a9a 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -15,6 +15,8 @@ package edu.kit.datamanager.mappingservice.plugins; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,9 +61,11 @@ public class PluginManager { * instantiation time. */ @Autowired - public PluginManager(ApplicationProperties applicationProperties) { + public PluginManager(ApplicationProperties applicationProperties, MeterRegistry meterRegistry) { this.applicationProperties = applicationProperties; reloadPlugins(); + + Gauge.builder("plugins-total", () -> plugins.size()).register(meterRegistry); } /** diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java index cdd7ae98..e38992b9 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java @@ -27,6 +27,8 @@ import edu.kit.datamanager.mappingservice.rest.PluginInformation; import edu.kit.datamanager.util.AuthenticationHelper; import edu.kit.datamanager.util.ControllerUtils; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; import io.swagger.v3.core.util.Json; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -86,10 +88,12 @@ public class MappingAdministrationController implements IMappingAdministrationCo */ private final MappingService mappingService; - public MappingAdministrationController(IMappingRecordDao mappingRecordDao, PluginManager pluginManager, MappingService mappingService) { + public MappingAdministrationController(IMappingRecordDao mappingRecordDao, PluginManager pluginManager, MappingService mappingService, MeterRegistry meterRegistry) { this.mappingRecordDao = mappingRecordDao; this.mappingService = mappingService; this.pluginManager = pluginManager; + + Gauge.builder("mapping-schemes-total", mappingRecordDao::count).register(meterRegistry); } @Override diff --git a/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java b/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java index 6c8feb62..265b2aa3 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java @@ -6,6 +6,8 @@ import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.plugins.PluginManager; +import io.micrometer.core.instrument.MeterRegistry; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -17,6 +19,8 @@ @Configuration @ComponentScan("edu.kit.datamanager.mappingservice") public class TestConfig { + @Autowired + private MeterRegistry meterRegistry; @Bean public ApplicationProperties applicationProperties() { @@ -25,6 +29,6 @@ public ApplicationProperties applicationProperties() { @Bean public PluginManager pluginManager() { - return new PluginManager(applicationProperties()); + return new PluginManager(applicationProperties(), meterRegistry); } } From e1b985e340902988fe9009b3ad1dd8c1f67514c3 Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Mon, 17 Mar 2025 10:28:54 +0100 Subject: [PATCH 35/80] Add some more metrics --- .../StaticResourcesConfiguration.java | 14 +++++++ .../mappingservice/plugins/PluginManager.java | 2 +- .../impl/MappingAdministrationController.java | 2 +- .../rest/impl/MappingExecutionController.java | 13 ++++++- .../rest/impl/PreHandleInterceptor.java | 38 +++++++++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/StaticResourcesConfiguration.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/StaticResourcesConfiguration.java index 9ff92c77..948850d3 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/StaticResourcesConfiguration.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/StaticResourcesConfiguration.java @@ -15,7 +15,10 @@ */ package edu.kit.datamanager.mappingservice.configuration; +import edu.kit.datamanager.mappingservice.rest.impl.PreHandleInterceptor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -28,10 +31,16 @@ */ @Configuration public class StaticResourcesConfiguration implements WebMvcConfigurer { + private final PreHandleInterceptor preHandleInterceptor; private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/static/"}; + @Autowired + public StaticResourcesConfiguration(PreHandleInterceptor preHandleInterceptor) { + this.preHandleInterceptor = preHandleInterceptor; + } + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); @@ -43,4 +52,9 @@ public void configurePathMatch(PathMatchConfigurer configurer) { urlPathHelper.setUrlDecode(false); configurer.setUrlPathHelper(urlPathHelper); } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(preHandleInterceptor); + } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index 48333a9a..a6f94dae 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -65,7 +65,7 @@ public PluginManager(ApplicationProperties applicationProperties, MeterRegistry this.applicationProperties = applicationProperties; reloadPlugins(); - Gauge.builder("plugins-total", () -> plugins.size()).register(meterRegistry); + Gauge.builder("mapping.plugins-total", () -> plugins.size()).register(meterRegistry); } /** diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java index e38992b9..af9575b0 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java @@ -93,7 +93,7 @@ public MappingAdministrationController(IMappingRecordDao mappingRecordDao, Plugi this.mappingService = mappingService; this.pluginManager = pluginManager; - Gauge.builder("mapping-schemes-total", mappingRecordDao::count).register(meterRegistry); + Gauge.builder("mapping.schemes-total", mappingRecordDao::count).register(meterRegistry); } @Override diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java index ba68bcaa..4b33bd8b 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java @@ -29,6 +29,8 @@ import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import edu.kit.datamanager.mappingservice.rest.IMappingExecutionController; import edu.kit.datamanager.mappingservice.util.FileUtil; +import io.micrometer.core.instrument.DistributionSummary; +import io.micrometer.core.instrument.MeterRegistry; import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +51,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import org.apache.tomcat.util.file.Matcher; + import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; @@ -70,11 +72,16 @@ public class MappingExecutionController implements IMappingExecutionController { private final MappingService mappingService; protected JobManager jobManager; private final IMappingRecordDao mappingRecordDao; + private final DistributionSummary documentsInSizeMetric; + private final DistributionSummary documentsOutSizeMetric; - public MappingExecutionController(MappingService mappingService, IMappingRecordDao mappingRecordDao, JobManager jobManager) { + public MappingExecutionController(MappingService mappingService, IMappingRecordDao mappingRecordDao, JobManager jobManager, MeterRegistry meterRegistry) { this.mappingService = mappingService; this.mappingRecordDao = mappingRecordDao; this.jobManager = jobManager; + + this.documentsInSizeMetric = DistributionSummary.builder("mapping.documents.input-size").baseUnit("bytes").register(meterRegistry); + this.documentsOutSizeMetric = DistributionSummary.builder("mapping.documents.output-size").baseUnit("bytes").register(meterRegistry); } @Override @@ -159,6 +166,8 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq LOG.error(message, ex); throw new MappingExecutionException(message); } finally { + this.documentsInSizeMetric.record(document.getSize()); + this.documentsOutSizeMetric.record(result.toFile().length()); LOG.trace("Result file successfully transferred to client. Removing file {} from disk.", result); try { Files.delete(result); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java new file mode 100644 index 00000000..ecd7e2f4 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java @@ -0,0 +1,38 @@ +package edu.kit.datamanager.mappingservice.rest.impl; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.HandlerInterceptor; + +import java.security.MessageDigest; +import java.util.HashSet; + +@Service +public class PreHandleInterceptor implements HandlerInterceptor { + private final HashSet uniqueUsers = new HashSet<>(); + private final Counter counter; + + @Autowired + PreHandleInterceptor(MeterRegistry meterRegistry) { + Gauge.builder("mapping.unique-users", uniqueUsers::size).register(meterRegistry); + counter = Counter.builder("mapping.requests-served").register(meterRegistry); + } + + @Override + public boolean preHandle(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Object handler) throws Exception { + String ip = request.getRemoteAddr(); + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + messageDigest.update(ip.getBytes()); + uniqueUsers.add(new String(messageDigest.digest())); + + counter.increment(); + + return true; + } +} From 6210f12c1cd74c9e4fff4c80da84ae7ac2fb87bf Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Mon, 17 Mar 2025 15:19:14 +0100 Subject: [PATCH 36/80] Monitor specific plugin and mapping usage --- .../mappingservice/impl/MappingService.java | 9 ++++++++- .../rest/impl/MappingExecutionController.java | 6 +++++- .../mappingservice/impl/MappingServiceTest.java | 13 ++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index c6b83611..5e7968e7 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -29,6 +29,8 @@ import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import edu.kit.datamanager.mappingservice.plugins.PluginManager; import edu.kit.datamanager.mappingservice.util.FileUtil; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; import org.apache.commons.codec.binary.Hex; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; @@ -88,6 +90,7 @@ public class MappingService { private Path jobsOutputDirectory; private ApplicationProperties applicationProperties; + private final MeterRegistry meterRegistry; /** * Logger for this class. @@ -95,8 +98,9 @@ public class MappingService { private final static Logger LOGGER = LoggerFactory.getLogger(MappingService.class); @Autowired - public MappingService(ApplicationProperties applicationProperties) { + public MappingService(ApplicationProperties applicationProperties, MeterRegistry meterRegistry) { this.applicationProperties = applicationProperties; + this.meterRegistry = meterRegistry; init(this.applicationProperties); } @@ -196,6 +200,9 @@ public Optional executeMapping(URI contentUrl, String mappingId) throws Ma if (optionalMappingRecord.isPresent()) { LOGGER.trace("Mapping for id {} found. Creating temporary output file."); mappingRecord = optionalMappingRecord.get(); + + Counter.builder("mappings.plugin_usage").tag("plugin", mappingRecord.getMappingType()).register(meterRegistry).increment(); + Path mappingFile = Paths.get(mappingRecord.getMappingDocumentUri()); // execute mapping Path resultFile; diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java index 4b33bd8b..4e3cd48c 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java @@ -29,6 +29,7 @@ import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import edu.kit.datamanager.mappingservice.rest.IMappingExecutionController; import edu.kit.datamanager.mappingservice.util.FileUtil; +import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.MeterRegistry; import org.apache.commons.io.FilenameUtils; @@ -72,6 +73,7 @@ public class MappingExecutionController implements IMappingExecutionController { private final MappingService mappingService; protected JobManager jobManager; private final IMappingRecordDao mappingRecordDao; + private final MeterRegistry meterRegistry; private final DistributionSummary documentsInSizeMetric; private final DistributionSummary documentsOutSizeMetric; @@ -79,7 +81,7 @@ public MappingExecutionController(MappingService mappingService, IMappingRecordD this.mappingService = mappingService; this.mappingRecordDao = mappingRecordDao; this.jobManager = jobManager; - + this.meterRegistry = meterRegistry; this.documentsInSizeMetric = DistributionSummary.builder("mapping.documents.input-size").baseUnit("bytes").register(meterRegistry); this.documentsOutSizeMetric = DistributionSummary.builder("mapping.documents.output-size").baseUnit("bytes").register(meterRegistry); } @@ -166,8 +168,10 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq LOG.error(message, ex); throw new MappingExecutionException(message); } finally { + Counter.builder("mappings.mapping_usage").tag("mappingID", mappingID).register(meterRegistry).increment(); this.documentsInSizeMetric.record(document.getSize()); this.documentsOutSizeMetric.record(result.toFile().length()); + LOG.trace("Result file successfully transferred to client. Removing file {} from disk.", result); try { Files.delete(result); diff --git a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java index c5be7194..8fec65b4 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java @@ -22,6 +22,7 @@ import edu.kit.datamanager.mappingservice.exception.MappingException; import edu.kit.datamanager.mappingservice.exception.MappingNotFoundException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; +import io.micrometer.core.instrument.MeterRegistry; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -86,6 +87,12 @@ public class MappingServiceTest { private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/"; + private final MeterRegistry meterRegistry; + + MappingServiceTest(MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + } + @BeforeEach public void setUp() { try { @@ -103,7 +110,7 @@ public void setUp() { @Test public void testConstructor() throws URISyntaxException { - new MappingService(applicationProperties); + new MappingService(applicationProperties, meterRegistry); } @Test @@ -115,7 +122,7 @@ public void testConstructorRelativePath() throws IOException, URISyntaxException ap.setMappingsLocation(relativePath); File file = new File(relativePath.getPath()); assertFalse(file.exists()); - new MappingService(ap); + new MappingService(ap, meterRegistry); assertTrue(file.exists()); FileUtils.deleteDirectory(file); assertFalse(file.exists()); @@ -127,7 +134,7 @@ public void testConstructorRelativePath() throws IOException, URISyntaxException @Test public void testConstructorFailing() throws IOException, URISyntaxException { try { - new MappingService(null); + new MappingService(null, meterRegistry); fail(); } catch (MappingException ie) { assertTrue(true); From 62b296bc3907c42a2c4f957f75991a899d57770d Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Tue, 18 Mar 2025 15:31:38 +0100 Subject: [PATCH 37/80] Try to fix test issues --- .../mappingservice/impl/MappingServiceTest.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java index 8fec65b4..5481e816 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java @@ -75,7 +75,6 @@ @TestPropertySource(properties = {"metastore.indexer.mappingsLocation=file:///tmp/metastore2/mapping"}) //@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MappingServiceTest { - @Autowired ApplicationProperties applicationProperties; @@ -85,13 +84,10 @@ public class MappingServiceTest { @Autowired MappingService mappingService4Test; - private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/"; - - private final MeterRegistry meterRegistry; + @Autowired + MeterRegistry meterRegistry; - MappingServiceTest(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - } + private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/"; @BeforeEach public void setUp() { From f01b57a535bec04b5b844a160076a9c85966e882 Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Tue, 18 Mar 2025 16:05:00 +0100 Subject: [PATCH 38/80] Consistent naming for all metrics --- .../kit/datamanager/mappingservice/impl/MappingService.java | 2 +- .../datamanager/mappingservice/plugins/PluginManager.java | 2 +- .../rest/impl/MappingAdministrationController.java | 2 +- .../rest/impl/MappingExecutionController.java | 6 +++--- .../mappingservice/rest/impl/PreHandleInterceptor.java | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index 5e7968e7..0a4d3be1 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -201,7 +201,7 @@ public Optional executeMapping(URI contentUrl, String mappingId) throws Ma LOGGER.trace("Mapping for id {} found. Creating temporary output file."); mappingRecord = optionalMappingRecord.get(); - Counter.builder("mappings.plugin_usage").tag("plugin", mappingRecord.getMappingType()).register(meterRegistry).increment(); + Counter.builder("mapping_service.plugin_usage").tag("plugin", mappingRecord.getMappingType()).register(meterRegistry).increment(); Path mappingFile = Paths.get(mappingRecord.getMappingDocumentUri()); // execute mapping diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index a6f94dae..bccfdbe3 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -65,7 +65,7 @@ public PluginManager(ApplicationProperties applicationProperties, MeterRegistry this.applicationProperties = applicationProperties; reloadPlugins(); - Gauge.builder("mapping.plugins-total", () -> plugins.size()).register(meterRegistry); + Gauge.builder("mapping_service.plugins-total", () -> plugins.size()).register(meterRegistry); } /** diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java index af9575b0..144ec87e 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java @@ -93,7 +93,7 @@ public MappingAdministrationController(IMappingRecordDao mappingRecordDao, Plugi this.mappingService = mappingService; this.pluginManager = pluginManager; - Gauge.builder("mapping.schemes-total", mappingRecordDao::count).register(meterRegistry); + Gauge.builder("mapping_service.schemes-total", mappingRecordDao::count).register(meterRegistry); } @Override diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java index 4e3cd48c..7c4d41eb 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java @@ -82,8 +82,8 @@ public MappingExecutionController(MappingService mappingService, IMappingRecordD this.mappingRecordDao = mappingRecordDao; this.jobManager = jobManager; this.meterRegistry = meterRegistry; - this.documentsInSizeMetric = DistributionSummary.builder("mapping.documents.input-size").baseUnit("bytes").register(meterRegistry); - this.documentsOutSizeMetric = DistributionSummary.builder("mapping.documents.output-size").baseUnit("bytes").register(meterRegistry); + this.documentsInSizeMetric = DistributionSummary.builder("mapping_service.documents.input-size").baseUnit("bytes").register(meterRegistry); + this.documentsOutSizeMetric = DistributionSummary.builder("mapping_service.documents.output-size").baseUnit("bytes").register(meterRegistry); } @Override @@ -168,7 +168,7 @@ public void mapDocument(MultipartFile document, String mappingID, HttpServletReq LOG.error(message, ex); throw new MappingExecutionException(message); } finally { - Counter.builder("mappings.mapping_usage").tag("mappingID", mappingID).register(meterRegistry).increment(); + Counter.builder("mapping_service.mapping_usage").tag("mappingID", mappingID).register(meterRegistry).increment(); this.documentsInSizeMetric.record(document.getSize()); this.documentsOutSizeMetric.record(result.toFile().length()); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java index ecd7e2f4..dc7b3979 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java @@ -20,8 +20,8 @@ public class PreHandleInterceptor implements HandlerInterceptor { @Autowired PreHandleInterceptor(MeterRegistry meterRegistry) { - Gauge.builder("mapping.unique-users", uniqueUsers::size).register(meterRegistry); - counter = Counter.builder("mapping.requests-served").register(meterRegistry); + Gauge.builder("mapping_service.unique-users", uniqueUsers::size).register(meterRegistry); + counter = Counter.builder("mapping_service.requests-served").register(meterRegistry); } @Override From 314cd7bacbd3e133674ccf16559c98b1b1b58149 Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Tue, 18 Mar 2025 16:10:15 +0100 Subject: [PATCH 39/80] Consistent naming for all metrics (2) --- .../kit/datamanager/mappingservice/plugins/PluginManager.java | 2 +- .../rest/impl/MappingAdministrationController.java | 2 +- .../mappingservice/rest/impl/MappingExecutionController.java | 4 ++-- .../mappingservice/rest/impl/PreHandleInterceptor.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index bccfdbe3..623dc135 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -65,7 +65,7 @@ public PluginManager(ApplicationProperties applicationProperties, MeterRegistry this.applicationProperties = applicationProperties; reloadPlugins(); - Gauge.builder("mapping_service.plugins-total", () -> plugins.size()).register(meterRegistry); + Gauge.builder("mapping_service.plugins_total", () -> plugins.size()).register(meterRegistry); } /** diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java index 144ec87e..040fe7de 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationController.java @@ -93,7 +93,7 @@ public MappingAdministrationController(IMappingRecordDao mappingRecordDao, Plugi this.mappingService = mappingService; this.pluginManager = pluginManager; - Gauge.builder("mapping_service.schemes-total", mappingRecordDao::count).register(meterRegistry); + Gauge.builder("mapping_service.schemes_total", mappingRecordDao::count).register(meterRegistry); } @Override diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java index 7c4d41eb..184cbff6 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/MappingExecutionController.java @@ -82,8 +82,8 @@ public MappingExecutionController(MappingService mappingService, IMappingRecordD this.mappingRecordDao = mappingRecordDao; this.jobManager = jobManager; this.meterRegistry = meterRegistry; - this.documentsInSizeMetric = DistributionSummary.builder("mapping_service.documents.input-size").baseUnit("bytes").register(meterRegistry); - this.documentsOutSizeMetric = DistributionSummary.builder("mapping_service.documents.output-size").baseUnit("bytes").register(meterRegistry); + this.documentsInSizeMetric = DistributionSummary.builder("mapping_service.documents.input_size").baseUnit("bytes").register(meterRegistry); + this.documentsOutSizeMetric = DistributionSummary.builder("mapping_service.documents.output_size").baseUnit("bytes").register(meterRegistry); } @Override diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java index dc7b3979..7c510133 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java @@ -20,8 +20,8 @@ public class PreHandleInterceptor implements HandlerInterceptor { @Autowired PreHandleInterceptor(MeterRegistry meterRegistry) { - Gauge.builder("mapping_service.unique-users", uniqueUsers::size).register(meterRegistry); - counter = Counter.builder("mapping_service.requests-served").register(meterRegistry); + Gauge.builder("mapping_service.unique_users", uniqueUsers::size).register(meterRegistry); + counter = Counter.builder("mapping_service.requests_served").register(meterRegistry); } @Override From f7817a494b40bb86503b64b504a19e20328ea5f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 09:29:28 +0000 Subject: [PATCH 40/80] Update dependency org.eclipse.jgit:org.eclipse.jgit to v7.2.0.202503040940-r --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..8d400a7f 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,7 @@ ext { } dependencies { - implementation 'org.eclipse.jgit:org.eclipse.jgit:7.1.0.202411261347-r' + implementation 'org.eclipse.jgit:org.eclipse.jgit:7.2.0.202503040940-r' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' implementation "org.springframework.boot:spring-boot-starter-data-rest" From b673d499c37567d5f98f466443c8c11c1077c78c Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 20 Mar 2025 14:48:25 +0100 Subject: [PATCH 41/80] Update WebSecurityConfig.java Removed anonymous-role access to actuator endpoints Added basic auth to allow authentication to actuator endpoints --- .../mappingservice/configuration/WebSecurityConfig.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java index 8fb9c842..3a5ee55f 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java @@ -34,6 +34,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.config.Customizer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.firewall.DefaultHttpFirewall; @@ -80,7 +81,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { InfoEndpoint.class, HealthEndpoint.class )).permitAll(). - requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyRole("ANONYMOUS", "ADMIN", "ACTUATOR", "SERVICE_WRITE"). + requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyRole("ADMIN", "ACTUATOR", "SERVICE_WRITE"). // requestMatchers(new AntPathRequestMatcher("/oaipmh")).permitAll(). requestMatchers(new AntPathRequestMatcher("/static/**")).permitAll(). requestMatchers(new AntPathRequestMatcher("/error")).permitAll(). @@ -88,6 +89,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { requestMatchers(AUTH_WHITELIST_SWAGGER_UI).permitAll(). anyRequest().authenticated() ). + httpBasic(Customizer.withDefaults()). cors(cors -> cors.configurationSource(corsConfigurationSource())). sessionManagement( session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); From d294ecc8cc647c417673ccdfe83a2fb99e6f1e15 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 20 Mar 2025 14:50:28 +0100 Subject: [PATCH 42/80] Update application-default.properties Added additional properties to default settings for authorization to actuator endpoints --- settings/application-default.properties | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/settings/application-default.properties b/settings/application-default.properties index 1308ecd6..e10549a7 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -27,7 +27,14 @@ info.app.description=Generic mapping service supporting different mapping implem info.app.group=edu.kit.datamanager info.app.version=1.0.4 management.endpoint.health.probes.enabled=true -management.endpoints.web.exposure.include=* +management.endpoint.health.enabled: true +management.endpoint.health.show-details: when-authorized +management.endpoint.health.sensitive: true +management.endpoints.web.exposure.include: health,info + +#spring.security.user.name=admin +#spring.security.user.password=secret +#spring.security.user.roles=ADMIN ############################################################################### # Spring Cloud From 42ce3090105a3a22a173f88735f04a7dd1f6b02c Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 20 Mar 2025 15:22:00 +0100 Subject: [PATCH 43/80] Update WebSecurityConfig.java Removed SERVICE_WRITE from actuator role list --- .../mappingservice/configuration/WebSecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java index 3a5ee55f..1f7af2b4 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java @@ -81,7 +81,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { InfoEndpoint.class, HealthEndpoint.class )).permitAll(). - requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyRole("ADMIN", "ACTUATOR", "SERVICE_WRITE"). + requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyRole("ADMIN", "ACTUATOR"). // requestMatchers(new AntPathRequestMatcher("/oaipmh")).permitAll(). requestMatchers(new AntPathRequestMatcher("/static/**")).permitAll(). requestMatchers(new AntPathRequestMatcher("/error")).permitAll(). From 738fb17c71eb7c11b739a6bcc850bf39c53ee61b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 06:48:53 +0000 Subject: [PATCH 44/80] Update plugin org.springframework.boot to v3.4.4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..dd257a04 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.boot' version '3.4.3' + id 'org.springframework.boot' version '3.4.4' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' id 'io.freefair.maven-publish-java' version '8.12.2.1' From f6d551bfcf853298aad49c4bbf8483fb00935af1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 23 Mar 2025 17:31:49 +0000 Subject: [PATCH 45/80] Update springDocVersion to v2.8.6 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..55ce34e4 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ ext { pythonExecutable = System.getProperty('pythonExecutable', "file:///usr/bin/python3") userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") - set('springDocVersion', "2.8.5") + set('springDocVersion', "2.8.6") set('javersVersion', "7.8.0") set('keycloakVersion', "19.0.0") } From 4c417abd0fc9d536fdd642dbf07281f32e8ddeab Mon Sep 17 00:00:00 2001 From: Christopher Raquet Date: Mon, 24 Mar 2025 14:18:36 +0100 Subject: [PATCH 46/80] Try to parse X-Forwarded-For header for client ip --- settings/application-default.properties | 2 +- .../rest/impl/PreHandleInterceptor.java | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/settings/application-default.properties b/settings/application-default.properties index e10549a7..52bcadf9 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -19,7 +19,7 @@ spring.servlet.multipart.max-file-size=100MB spring.servlet.multipart.max-request-size=100MB # Logging settings logging.level.root=ERROR -logging.level.edu.kit.datamanager=INFO +logging.level.edu.kit.datamanager=DEBUG springdoc.swagger-ui.disable-swagger-default-url=true # Actuator settings info.app.name=Mapping-Service diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java index 7c510133..37dd3906 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/impl/PreHandleInterceptor.java @@ -5,6 +5,8 @@ import io.micrometer.core.instrument.MeterRegistry; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; @@ -18,6 +20,11 @@ public class PreHandleInterceptor implements HandlerInterceptor { private final HashSet uniqueUsers = new HashSet<>(); private final Counter counter; + /** + * Logger for this class. + */ + private final static Logger LOGGER = LoggerFactory.getLogger(PreHandleInterceptor.class); + @Autowired PreHandleInterceptor(MeterRegistry meterRegistry) { Gauge.builder("mapping_service.unique_users", uniqueUsers::size).register(meterRegistry); @@ -26,7 +33,21 @@ public class PreHandleInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Object handler) throws Exception { - String ip = request.getRemoteAddr(); + String forwardedFor = request.getHeader("X-Forwarded-For"); + LOGGER.debug("X-Forwarded-For: {}", forwardedFor); + String clientIp = null; + + if (forwardedFor != null) { + String[] ipList = forwardedFor.split(", "); + if (ipList.length > 0) clientIp = ipList[0]; + LOGGER.debug("Client IP from X-Forwarded-For: {}", clientIp); + } + + String remoteIp = request.getRemoteAddr(); + LOGGER.debug("Client IP from getRemoteAddr: {}", remoteIp); + String ip = clientIp == null ? remoteIp : clientIp; + LOGGER.debug("Using {} for monitoring", ip); + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(ip.getBytes()); uniqueUsers.add(new String(messageDigest.digest())); From bea7019aa153ffee34d105e27d8c077c19ffd978 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 19:29:20 +0000 Subject: [PATCH 47/80] Update plugin io.freefair.lombok to v8.13.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..f5a383be 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id "org.owasp.dependencycheck" version "12.1.0" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.5.0" - id 'io.freefair.lombok' version '8.12.2.1' + id 'io.freefair.lombok' version '8.13.1' id 'java' id 'jacoco' } From b7e270217bb3deca97d272ccdaa463e0c96f5cb2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 19:29:24 +0000 Subject: [PATCH 48/80] Update plugin io.freefair.maven-publish-java to v8.13.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..9480fe92 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'org.springframework.boot' version '3.4.3' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' - id 'io.freefair.maven-publish-java' version '8.12.2.1' + id 'io.freefair.maven-publish-java' version '8.13.1' id "org.owasp.dependencycheck" version "12.1.0" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.5.0" From 3a17e01c7fa0a22763719f65119b33d73a2a716b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 11:15:18 +0000 Subject: [PATCH 49/80] Update dependency net.bytebuddy:byte-buddy to v1.17.5 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..1c01d377 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { testImplementation 'org.mockito:mockito-core:5.16.0' testImplementation 'org.powermock:powermock-module-junit4:2.0.9' testImplementation 'org.powermock:powermock-api-mockito2:2.0.9' - testImplementation 'net.bytebuddy:byte-buddy:1.17.2' + testImplementation 'net.bytebuddy:byte-buddy:1.17.5' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' From 7111d3d781fa661bb1291cea63d4f06ceafe0456 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:06:07 +0000 Subject: [PATCH 50/80] Update dependency org.mockito:mockito-core to v5.17.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..f834a445 100644 --- a/build.gradle +++ b/build.gradle @@ -94,7 +94,7 @@ dependencies { //testImplementation 'org.springframework:spring-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:3.0.3' - testImplementation 'org.mockito:mockito-core:5.16.0' + testImplementation 'org.mockito:mockito-core:5.17.0' testImplementation 'org.powermock:powermock-module-junit4:2.0.9' testImplementation 'org.powermock:powermock-api-mockito2:2.0.9' testImplementation 'net.bytebuddy:byte-buddy:1.17.2' From 150dd5b4120b9c602a9a4383c194abf14577f5c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 19:51:42 +0000 Subject: [PATCH 51/80] Update dependency com.google.guava:guava to v33.4.8-jre --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dbea6ef4..19c2248f 100644 --- a/build.gradle +++ b/build.gradle @@ -77,7 +77,7 @@ dependencies { implementation 'org.apache.commons:commons-collections4:4.4' implementation 'org.json:json:20250107' implementation 'com.github.jknack:handlebars:4.4.0' - implementation 'com.google.guava:guava:33.4.0-jre' + implementation 'com.google.guava:guava:33.4.8-jre' implementation 'commons-io:commons-io:2.18.0' implementation 'javax.validation:validation-api:2.0.1.Final' implementation 'edu.kit.datamanager:service-base:1.3.3' From e79bdfac6841ffb7fbf9a7fe1f652b82ae16b199 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Tue, 15 Apr 2025 15:06:15 +0200 Subject: [PATCH 52/80] Update CI.yml Removed copy plugins step from CI as this is no longer required --- .github/workflows/CI.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 045dc95b..191fb97a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -39,11 +39,7 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Prepare - run: mkdir -p /tmp/mapping-service/{schemas,plugins} - - name: Copy Plugins - run: cp plugins/* /tmp/mapping-service/plugins - - name: List Plugins - run: ls -la /tmp/mapping-service/plugins + run: mkdir -p /tmp/mapping-service/{schemas} - name: Clean run: ./gradlew clean # - if: matrix.os == 'windows-latest' From 83416f8231b84e1163f080eb134d89c85cb5e929 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 13:33:07 +0000 Subject: [PATCH 53/80] Update dependency jacoco to v0.8.13 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 550f873d..c8b1d59d 100644 --- a/build.gradle +++ b/build.gradle @@ -125,7 +125,7 @@ test { } jacoco { - toolVersion = "0.8.12" + toolVersion = "0.8.13" } jacocoTestReport{ From 470016843ded194bbae343a3fa05745e0e1984c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 13:33:13 +0000 Subject: [PATCH 54/80] Update plugin org.owasp.dependencycheck to v12.1.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 550f873d..af2b1350 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' id 'io.freefair.maven-publish-java' version '8.12.2.1' - id "org.owasp.dependencycheck" version "12.1.0" + id "org.owasp.dependencycheck" version "12.1.1" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.5.0" id 'io.freefair.lombok' version '8.12.2.1' From c2aa345a9d1b6a82e85dcb2badce4f4e265c27fd Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Tue, 15 Apr 2025 16:07:26 +0200 Subject: [PATCH 55/80] Fixed failed tests --- .../kit/datamanager/mappingservice/impl/MappingServiceTest.java | 2 +- .../datamanager/mappingservice/python/util/PythonUtilsTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java index 0ff2e9cb..c5d23c75 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/impl/MappingServiceTest.java @@ -133,7 +133,7 @@ public void testConstructorFailing() throws IOException, URISyntaxException { try { new MappingService(null, meterRegistry); fail("Expected MappingServiceException"); - } catch (MappingException ie) { + } catch (MappingServiceException ie) { assertTrue(true); } //seems to be no problem under Windows and if run as root this is also no issue, so let's skip this test for the moment. diff --git a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java index 1a7bd6ce..245f51b5 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java @@ -125,7 +125,7 @@ public void testRun_3args_withNoOutputStreams() { PythonRunnerUtil.runPythonScript(scriptLocation, null, null, arguments); fail("Expected MappingPluginException"); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.StateEnum.INVALID_INPUT, e.getMappingPluginState().getState()); + assertEquals(MappingPluginState.StateEnum.UNKNOWN_ERROR, e.getMappingPluginState().getState()); } } } From 83e851c99257dab9ec8d5b55b3ddba2ea73969eb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 19:38:18 +0000 Subject: [PATCH 56/80] Update dependency commons-io:commons-io to v2.19.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f363f278..e9c74a13 100644 --- a/build.gradle +++ b/build.gradle @@ -78,7 +78,7 @@ dependencies { implementation 'org.json:json:20250107' implementation 'com.github.jknack:handlebars:4.4.0' implementation 'com.google.guava:guava:33.4.8-jre' - implementation 'commons-io:commons-io:2.18.0' + implementation 'commons-io:commons-io:2.19.0' implementation 'javax.validation:validation-api:2.0.1.Final' implementation 'edu.kit.datamanager:service-base:1.3.3' // apache From d501c89aaec81d2262930b68cc56a004b60461c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 19:38:23 +0000 Subject: [PATCH 57/80] Update eclipse-temurin Docker tag to v24 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 423c9ce3..c62092f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ ARG SERVICE_ROOT_DIRECTORY_DEFAULT=/spring/ #################################################### # Building environment (java & git) #################################################### -FROM eclipse-temurin:23 AS build-env-java +FROM eclipse-temurin:24 AS build-env-java LABEL maintainer=webmaster@datamanager.kit.edu LABEL stage=build-env @@ -48,7 +48,7 @@ RUN bash ./build.sh $SERVICE_DIRECTORY #################################################### # Runtime environment 4 metastore2 #################################################### -FROM eclipse-temurin:23 AS run-service-mapping-service +FROM eclipse-temurin:24 AS run-service-mapping-service LABEL maintainer=webmaster@datamanager.kit.edu LABEL stage=run From c3af072b622058014a4ded3c466d03096f8b1c86 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Tue, 15 Apr 2025 23:01:24 +0200 Subject: [PATCH 58/80] Added check for mappingId and mappingType during mapping creation, tests failing and must be adapted --- .../mappingservice/impl/MappingService.java | 17 ++- .../MappingAdministrationControllerTest.java | 131 ++++++++++++++++-- 2 files changed, 133 insertions(+), 15 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index 9ea705f1..10e4d74c 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -15,6 +15,7 @@ */ package edu.kit.datamanager.mappingservice.impl; +import edu.kit.datamanager.exceptions.BadArgumentException; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.dao.IMappingRecordDao; import edu.kit.datamanager.mappingservice.domain.JobStatus; @@ -22,7 +23,6 @@ import edu.kit.datamanager.mappingservice.exception.DuplicateMappingException; import edu.kit.datamanager.mappingservice.exception.JobNotFoundException; import edu.kit.datamanager.mappingservice.exception.JobProcessingException; -import edu.kit.datamanager.mappingservice.exception.MappingException; import edu.kit.datamanager.mappingservice.exception.MappingJobException; import edu.kit.datamanager.mappingservice.exception.MappingNotFoundException; import edu.kit.datamanager.mappingservice.exception.MappingServiceException; @@ -114,6 +114,21 @@ public MappingService(ApplicationProperties applicationProperties) { */ public MappingRecord createMapping(String content, MappingRecord mappingRecord) throws IOException { LOGGER.trace("Creating mapping with id {}.", mappingRecord.getMappingId()); + // Check for valid mapping ID (should contain at least one non whitespace. + String mappingId = mappingRecord.getMappingId(); + if ((mappingId == null) || (mappingId.isBlank())) { + String message = String.format("MappingID shouldn't be empty or contain only whitespaces. You provide '%s'", mappingId); + LOGGER.error(message); + throw new BadArgumentException(message); + } + + String mappingType = mappingRecord.getMappingType(); + if ((mappingType == null) || (mappingType.isBlank() || !pluginManager.getPlugins().containsKey(mappingType))) { + String message = String.format("MappingType shouldn't be empty or contain only whitespaces and must be a registered plugin id. You provide '%s'", mappingType); + LOGGER.error(message); + throw new BadArgumentException(message); + } + Iterable findMapping = mappingRepo.findByMappingIdIn(Collections.singletonList(mappingRecord.getMappingId())); if (findMapping.iterator().hasNext()) { LOGGER.error("Unable to create mapping with id {}. Mapping id is alreadyy used.", mappingRecord.getMappingId()); diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java index 6e08b6df..fbe5850e 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java @@ -74,6 +74,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + /** * */ @@ -95,13 +96,12 @@ public class MappingAdministrationControllerTest { private static final String MAPPING_TITLE = "TITEL"; private static final String MAPPING_DESCRIPTION = "DESCRIPTION"; - @RegisterExtension - final RestDocumentationExtension restDocumentation = new RestDocumentationExtension ("custom"); - + final RestDocumentationExtension restDocumentation = new RestDocumentationExtension("custom"); + @Autowired private MockMvc mockMvc; - + @Autowired private WebApplicationContext webApplicationContext; @@ -109,7 +109,7 @@ public class MappingAdministrationControllerTest { private IMappingRecordDao mappingRecordDao; @BeforeEach - public void setUp(RestDocumentationContextProvider restDocumentation) { + public void setUp(RestDocumentationContextProvider restDocumentation) { mappingRecordDao.deleteAll(); try { try (Stream walk = Files.walk(Paths.get(URI.create("file://" + TEMP_DIR_4_MAPPING)))) { @@ -131,6 +131,111 @@ public void setUp(RestDocumentationContextProvider restDocumentation) { .build(); } + /** + * Test of createMapping method, of class MappingAdministrationController. + */ + @Test + public void testCreateMappingWithoutID() throws Exception { + System.out.println("createMapping"); + Path mappingsDir = Paths.get(URI.create("file://" + TEMP_DIR_4_MAPPING)); + + String mappingContent = FileUtils.readFileToString(new File("src/test/resources/mapping/gemma/simple.mapping"), StandardCharsets.UTF_8); + MappingRecord record = new MappingRecord(); + record.setMappingId(null); + record.setMappingType(MAPPING_TYPE); + record.setTitle(MAPPING_TITLE); + record.setDescription(MAPPING_DESCRIPTION); + Set aclEntries = new HashSet<>(); + aclEntries.add(new AclEntry("SELF", PERMISSION.READ)); + aclEntries.add(new AclEntry("test2", PERMISSION.ADMINISTRATE)); + record.setAcl(aclEntries); + ObjectMapper mapper = new ObjectMapper(); + + MockMultipartFile recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); + MockMultipartFile mappingFile = new MockMultipartFile("document", "my_dc4gemma.mapping", "application/json", mappingContent.getBytes()); + + //long before = Files.list(mappingsDir).count(); + this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). + file(recordFile). + file(mappingFile)). + andDo(print()). + andExpect(status().isBadRequest()); + + //assertEquals(before+1, Files.list(mappingsDir).count()); + } + + /** + * Test of createMapping method, of class MappingAdministrationController. + */ + @Test + public void testCreateMappingWithWrongID() throws Exception { + System.out.println("createMapping"); + Path mappingsDir = Paths.get(URI.create("file://" + TEMP_DIR_4_MAPPING)); + + String mappingContent = FileUtils.readFileToString(new File("src/test/resources/mapping/gemma/simple.mapping"), StandardCharsets.UTF_8); + MappingRecord record = new MappingRecord(); + record.setMappingId(""); + record.setMappingType(MAPPING_TYPE); + record.setTitle(MAPPING_TITLE); + record.setDescription(MAPPING_DESCRIPTION); + Set aclEntries = new HashSet<>(); + aclEntries.add(new AclEntry("SELF", PERMISSION.READ)); + aclEntries.add(new AclEntry("test2", PERMISSION.ADMINISTRATE)); + record.setAcl(aclEntries); + ObjectMapper mapper = new ObjectMapper(); + + MockMultipartFile recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); + MockMultipartFile mappingFile = new MockMultipartFile("document", "my_dc4gemma.mapping", "application/json", mappingContent.getBytes()); + + //long before = Files.list(mappingsDir).count(); + this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). + file(recordFile). + file(mappingFile)). + andDo(print()). + andExpect(status().isBadRequest()); + + record.setMappingId(""); + + recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); + + this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). + file(recordFile). + file(mappingFile)). + andDo(print()). + andExpect(status().isBadRequest()); + + record.setMappingId(" "); + + recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); + + this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). + file(recordFile). + file(mappingFile)). + andDo(print()). + andExpect(status().isBadRequest()); + + record.setMappingId("\t"); + + recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); + + this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). + file(recordFile). + file(mappingFile)). + andDo(print()). + andExpect(status().isBadRequest()); + + record.setMappingId(" "); + + recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); + + this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). + file(recordFile). + file(mappingFile)). + andDo(print()). + andExpect(status().isBadRequest()); + //assertEquals(before+1, Files.list(mappingsDir).count()); + } + /** * Test of createMapping method, of class MappingAdministrationController. */ @@ -154,9 +259,7 @@ public void testCreateMapping() throws Exception { MockMultipartFile recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); MockMultipartFile mappingFile = new MockMultipartFile("document", "my_dc4gemma.mapping", "application/json", mappingContent.getBytes()); - //long before = Files.list(mappingsDir).count(); - this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). file(recordFile). file(mappingFile)). @@ -292,7 +395,7 @@ public void testCreateMappingWithAcl() throws Exception { MockMultipartFile recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); MockMultipartFile mappingFile = new MockMultipartFile("document", "my_dc4gemma.mapping", "application/json", mappingContent.getBytes()); - // assertEquals(0, mappingsDir.list().length); + // assertEquals(0, mappingsDir.list().length); this.mockMvc.perform(MockMvcRequestBuilders.multipart("/api/v1/mappingAdministration/"). file(recordFile). file(mappingFile)).andDo(print()).andExpect(status().isCreated()).andExpect(redirectedUrlPattern("http://*:*//api/v1/mappingAdministration/*")).andReturn(); @@ -431,9 +534,9 @@ public void testUpdateMapping() throws JsonProcessingException, Exception { aclEntries.add(new AclEntry("SELF", PERMISSION.READ)); aclEntries.add(new AclEntry("someoneelse", PERMISSION.ADMINISTRATE)); record.setAcl(aclEntries); - + int before = mappingsDir.list().length; - + String mappingContent = FileUtils.readFileToString(new File("src/test/resources/mapping/gemma/simple_v2.mapping"), StandardCharsets.UTF_8); MockMultipartFile recordFile = new MockMultipartFile("record", "record.json", "application/json", mapper.writeValueAsString(record).getBytes()); @@ -761,7 +864,7 @@ public void testDeleteMapping() throws JsonProcessingException, Exception { String deleteMappingIdUrl = "/api/v1/mappingAdministration/" + mappingId; result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isNoContent()).andReturn(); - // assertEquals(1, mappingsDir.list().length); + // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; assertNotEquals(expectedFilename, mappingsDir.list()[0]); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isNotFound()).andReturn(); @@ -785,7 +888,7 @@ public void testDeleteMappingUnknownMappingId() throws JsonProcessingException, String deleteMappingIdUrl = "/api/v1/mappingAdministration/" + "unknownMappingId"; result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isNoContent()).andReturn(); - // assertEquals(1, mappingsDir.list().length); + // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; assertEquals("my_dc_GEMMA.mapping", expectedFilename); assertEquals(1, mappingRecordDao.count()); @@ -830,7 +933,7 @@ public void testDeleteMappingMissingEtag() throws JsonProcessingException, Excep String deleteMappingIdUrl = "/api/v1/mappingAdministration/" + mappingId; result = this.mockMvc.perform(delete(deleteMappingIdUrl)).andDo(print()).andExpect(status().isPreconditionRequired()).andReturn(); - // assertEquals(1, mappingsDir.list().length); + // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; assertEquals("my_dc_GEMMA.mapping", expectedFilename); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn(); @@ -854,7 +957,7 @@ public void testDeleteMappingWrongEtag() throws JsonProcessingException, Excepti String deleteMappingIdUrl = "/api/v1/mappingAdministration/" + mappingId; result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isPreconditionFailed()).andReturn(); - // assertEquals(1, mappingsDir.list().length); + // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; assertEquals("my_dc_GEMMA.mapping", expectedFilename); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn(); From 0e07de585b3560eec32ef853bf634799a6bbdac6 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Wed, 16 Apr 2025 15:52:22 +0200 Subject: [PATCH 59/80] Fixed tests to work with new plugin availability check --- .../rest/impl/MappingAdministrationControllerTest.java | 8 ++++---- .../1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java index fbe5850e..3594e2fc 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java @@ -92,7 +92,7 @@ public class MappingAdministrationControllerTest { private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/"; private static final String MAPPING_ID = "my_dc"; - private static final String MAPPING_TYPE = "GEMMA"; + private static final String MAPPING_TYPE = "GEMMA_1.0.0"; private static final String MAPPING_TITLE = "TITEL"; private static final String MAPPING_DESCRIPTION = "DESCRIPTION"; @@ -890,7 +890,7 @@ public void testDeleteMappingUnknownMappingId() throws JsonProcessingException, result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isNoContent()).andReturn(); // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; - assertEquals("my_dc_GEMMA.mapping", expectedFilename); + assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename); assertEquals(1, mappingRecordDao.count()); } @@ -935,7 +935,7 @@ public void testDeleteMappingMissingEtag() throws JsonProcessingException, Excep result = this.mockMvc.perform(delete(deleteMappingIdUrl)).andDo(print()).andExpect(status().isPreconditionRequired()).andReturn(); // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; - assertEquals("my_dc_GEMMA.mapping", expectedFilename); + assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn(); assertEquals(1, mappingRecordDao.count()); } @@ -959,7 +959,7 @@ public void testDeleteMappingWrongEtag() throws JsonProcessingException, Excepti result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isPreconditionFailed()).andReturn(); // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; - assertEquals("my_dc_GEMMA.mapping", expectedFilename); + assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn(); assertEquals(1, mappingRecordDao.count()); } diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg index 732cca15..13b576f9 100644 --- a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg +++ b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg @@ -1,3 +1,3 @@ -home = c:\python310 +home = /Library/Developer/CommandLineTools/usr/bin include-system-site-packages = true -version = 3.10.0 +version = 3.9.6 From 45617b841217fac1583d543fa3ee6b861f4339ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 17:38:41 +0000 Subject: [PATCH 60/80] Update plugin org.springframework.boot to v3.4.5 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e9c74a13..a150ffc7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.boot' version '3.4.4' + id 'org.springframework.boot' version '3.4.5' id 'io.spring.dependency-management' version '1.1.7' id 'org.asciidoctor.jvm.convert' version '4.0.4' id 'io.freefair.maven-publish-java' version '8.13.1' From fac2302d4fe0bf85883007e0ee216611ae3968d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 17:13:09 +0000 Subject: [PATCH 61/80] Update dependency gradle to v8.14 --- gradle/wrapper/gradle-wrapper.jar | Bin 43705 -> 43764 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 4 ++-- gradlew.bat | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9bbc975c742b298b441bfb90dbc124400a3751b9..1b33c55baabb587c669f562ae36f953de2481846 100644 GIT binary patch delta 642 zcmdmamFde>rVZJA^}0Q$xegf!xPEW^+5YDM%iT2bEgct9o+jH~+sJas#HZ=szO|** z=Pj=X_vx?W&DSwKck|WWn~hffsvnQ+42*W$b7b0$SCcOoZ`{W{^$^pk;4>8-A*-)$ z?n(Po`1$6Jn_u?t-L+tsPyZ2#X}8T6OS8pAU;kdgd+_Hw4z4TW0p9E!T+=f7-c&O% zFic^X{7^$?^Ho04eona9n#mGMxKhA=~8B%JN`M zMhm5wc-2v)$``sY$!Q`9xiU@DhI73ZxiGEKg>yIPs)NmWwMdF-ngLXpZSqV5ez36n zVkxF2rjrjWR+_xr6e6@_u@s~2uv{9vi*1pj2)BjFD+-%@&pRVP1f{O1glxTOp2-62Ph;v z`N1+vCd)9ea)af*Ol1*JCfnp$%Uu}%OuoN7g2}3C@`L5FlP#(sA=|h@iixuZC?qp^ z=L$=v$ZoI}|87Wh=&h7udff{aieKr*l+zDp?pf)_bbRvUf>kn;HCDMXNlgbbo!QRK I1x7am0No)LiU0rr delta 584 zcmexzm1*ZyrVZJAexH5Moc8h7)w{^+t*dqJ%=yhh23L$9JpFV=_k`zJ-?Q4DI*eSe z+ES)HSrVnWLtJ&)lO%hRkV9zl5qqWRt0e;bb zPPo`)y?HTAyZI&u&X<|2$FDHCf4;!v8}p=?Tm`^F0`u(|1ttf~&t$qP3KUSD>@TJQ zRwJ}Pim6NzEc8KA6)e;S6gs8=7IIL8sQL*MYEuRYO;Uj<%3UbMbV&^&!Zvx+LKmjT z8Zch6rYP7Tw?$Hn(UTJwWiS=$f{lB(C=e*%usDV})0AQIK~sat=ND@+Gg*Pyij!rR z*fa02W|%BsV++>4W{DKDGSIUEHd2$P+8ct!RF+CHDowUuTEZOZ%rJSQv*qOXOSPDN zT|sP-$p*_3ncsWB*qoD7JQcyZ9xan%cJP6Tb4-?AZpr*F6v98hoNaPJm@HV`yya5N z))6pqFXn@}P(3T0nEzM8*c_9KtE9o|_pFd&K35GBXP^9Kg(b6GH-z8S4GDzIl~T+b zdLd#meKKHu$5u))8cu$=GKINkGDPOUD)!0$C(BH(U!}!-e;Q0ok8Sc?V1zRO04>ts AA^-pY diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37f853b1..ca025c83 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index faf93008..23d15a93 100755 --- a/gradlew +++ b/gradlew @@ -114,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9b42019c..5eed7ee8 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 778b062405e5ae64309231772d26a8ae432f07e7 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Mon, 28 Apr 2025 15:36:31 +0200 Subject: [PATCH 62/80] Started integrating possibility for Python version check --- build.gradle | 2 + .../configuration/ApplicationProperties.java | 1 - .../mappingservice/util/PythonRunnerUtil.java | 103 +++++++++++++++++- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e9c74a13..830f57bd 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,7 @@ plugins { id "com.gorylenko.gradle-git-properties" version "2.5.0" id 'io.freefair.lombok' version '8.13.1' id 'java' + id 'application' id 'jacoco' } @@ -75,6 +76,7 @@ dependencies { implementation "org.javers:javers-spring-boot-starter-sql:${javersVersion}" implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.commons:commons-collections4:4.4' + implementation 'org.apache.maven:maven-artifact:3.6.3' implementation 'org.json:json:20250107' implementation 'com.github.jknack:handlebars:4.4.0' implementation 'com.google.guava:guava:33.4.8-jre' diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java index 702089a6..2cb9f704 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java @@ -15,7 +15,6 @@ */ package edu.kit.datamanager.mappingservice.configuration; -import edu.kit.datamanager.annotations.ExecutableFileURL; import edu.kit.datamanager.annotations.LocalFolderURL; import edu.kit.datamanager.validator.ExecutableFileValidator; import lombok.Data; diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index eb48f921..1b3eaafc 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -17,6 +17,7 @@ import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; +import java.io.ByteArrayOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -24,6 +25,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; +import org.apache.maven.artifact.versioning.ComparableVersion; /** * Utility class for running python scripts. @@ -37,7 +39,6 @@ public class PythonRunnerUtil { private static final Logger LOGGER = LoggerFactory.getLogger(PythonRunnerUtil.class); - public static void init(ApplicationProperties configuration) { PythonRunnerUtil.configuration = configuration; } @@ -53,6 +54,85 @@ public static void printPythonVersion() { } } + + + + /** + * This method checks if the local Python installation version is larger or + * equal the provided version number. The version should be provided as + * semantic version number, i.e., 3.13.2 + * + * The method will return TRUE if the minimal requirements are met and false + * otherwise. False is also returned if obtaining/parsing the local python + * version fails. for any reason. + * + * @param versionString The semantic version string to compare the local Python version against. + * + * @return True if versionString is smaller or equal the local Python version, false otherwise. + */ + public static boolean hasMinimalPythonVersion(String versionString) { + boolean result = false; + try { + LOGGER.trace("Checking for minimal Python version {}.", versionString); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + PythonRunnerUtil.runPythonScript("--version", bout, System.err); + LOGGER.trace("Version command output: {}", bout.toString()); + + String[] split = bout.toString().split(" "); + + if (split.length == 2) { + String localPythonVersion = bout.toString().split(" ")[1].trim(); + LOGGER.trace("Obtained local Python version: {}", localPythonVersion); + ComparableVersion localVersion = new ComparableVersion(localPythonVersion); + ComparableVersion minimalVersion = new ComparableVersion(versionString); + result = minimalVersion.compareTo(localVersion) <= 0; + } else { + LOGGER.info("Unexpected Python version output. Unable to check for minimal version."); + } + } catch (MappingPluginException e) { + LOGGER.error("Failed to obtain python version.", e); + } + return result; + } + + /** + * This method checks if the local Python installation version is larger or + * equal the provided version number. The version should be provided as + * semantic version number, i.e., 3.13.2 + * + * The method will return TRUE if the minimal requirements are met and false + * otherwise. False is also returned if obtaining/parsing the local python + * version fails. for any reason. + * + * @param versionString The semantic version string to compare the local Python version against. + * + * @return True if versionString is smaller or equal the local Python version, false otherwise. + */ + public static boolean hasMaximalPythonVersion(String versionString) { + boolean result = false; + try { + LOGGER.trace("Checking for minimal Python version {}.", versionString); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + PythonRunnerUtil.runPythonScript("--version", bout, System.err); + LOGGER.trace("Version command output: {}", bout.toString()); + + String[] split = bout.toString().split(" "); + + if (split.length == 2) { + String localPythonVersion = bout.toString().split(" ")[1].trim(); + LOGGER.trace("Obtained local Python version: {}", localPythonVersion); + ComparableVersion localVersion = new ComparableVersion(localPythonVersion); + ComparableVersion minimalVersion = new ComparableVersion(versionString); + result = minimalVersion.compareTo(localVersion) > 0; + } else { + LOGGER.info("Unexpected Python version output. Unable to check for minimal version."); + } + } catch (MappingPluginException e) { + LOGGER.error("Failed to obtain python version.", e); + } + return result; + } + /** * This method executes an argument/option on the python interpreter. * @@ -102,4 +182,25 @@ public static MappingPluginState runPythonScript(String script, OutputStream out } return ShellRunnerUtil.run(output, error, command.toArray(String[]::new)); } + + public static void main(String[] args) throws Exception { + ArrayList command = new ArrayList<>(); + command.add("/opt/homebrew/bin/python3"); + command.add("--version"); + if (args != null) { + Collections.addAll(command, args); + } + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + ShellRunnerUtil.run(bout, System.err, command.toArray(String[]::new)); + System.out.println("VERS " + bout.toString()); + System.out.println(bout.toString().split(" ")[1]); + ComparableVersion verr = new ComparableVersion("unknown"); + System.out.println("ER " + verr.getCanonical()); + ComparableVersion v = new ComparableVersion(bout.toString().split(" ")[1].trim()); + ComparableVersion vMin = new ComparableVersion("4"); + System.out.println(verr.compareTo(v)); + + } } From 89d9d24092504d2d20ba005d5ff28945b99a24bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 13:37:00 +0000 Subject: [PATCH 63/80] Update dependency org.apache.commons:commons-collections4 to v4.5.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 830f57bd..57f772d1 100644 --- a/build.gradle +++ b/build.gradle @@ -75,7 +75,7 @@ dependencies { implementation "org.javers:javers-spring-boot-starter-sql:${javersVersion}" implementation 'org.apache.httpcomponents:httpclient:4.5.14' - implementation 'org.apache.commons:commons-collections4:4.4' + implementation 'org.apache.commons:commons-collections4:4.5.0' implementation 'org.apache.maven:maven-artifact:3.6.3' implementation 'org.json:json:20250107' implementation 'com.github.jknack:handlebars:4.4.0' From b08b339f8c0404196eef890fc152f8ecf9cb113d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 13:37:02 +0000 Subject: [PATCH 64/80] Update dependency org.apache.maven:maven-artifact to v3.9.9 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 830f57bd..7b4cc71e 100644 --- a/build.gradle +++ b/build.gradle @@ -76,7 +76,7 @@ dependencies { implementation "org.javers:javers-spring-boot-starter-sql:${javersVersion}" implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.commons:commons-collections4:4.4' - implementation 'org.apache.maven:maven-artifact:3.6.3' + implementation 'org.apache.maven:maven-artifact:3.9.9' implementation 'org.json:json:20250107' implementation 'com.github.jknack:handlebars:4.4.0' implementation 'com.google.guava:guava:33.4.8-jre' From f2e3db266fbd9043736ca6fb1e2dcb232b94e5d3 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Sun, 4 May 2025 22:12:37 +0200 Subject: [PATCH 65/80] Started new base plugin for Python-based mappers --- .../plugins/AbstractPythonMappingPlugin.java | 205 ++++++++++++++++++ .../plugins/impl/GemmaPlugin.java | 38 +--- .../plugins/impl/PythonCheckPlugin.java | 140 ------------ .../mappingservice/util/PythonRunnerUtil.java | 1 + .../mappingservice/util/ShellRunnerUtil.java | 37 ++-- 5 files changed, 232 insertions(+), 189 deletions(-) create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java delete mode 100644 src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java new file mode 100644 index 00000000..430035b8 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java @@ -0,0 +1,205 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package edu.kit.datamanager.mappingservice.plugins; + +import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; +import edu.kit.datamanager.mappingservice.util.FileUtil; +import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; +import edu.kit.datamanager.mappingservice.util.ShellRunnerUtil; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author jejkal + */ +public abstract class AbstractPythonMappingPlugin implements IMappingPlugin { + + private final Logger LOGGER = LoggerFactory.getLogger(AbstractPythonMappingPlugin.class); + /** + * The plugin name. + */ + private String name; + /** + * The URL of the Git repository where the plugin code is located. + */ + private String repositoryUrl; + + /** + * The tag which should be used to checkout a specific version from + * repositoryUrl. + */ + private String tag; + + /** + * The minimal python version required by the plugin + */ + private String minPython; + + /** + * The folder where the code is checked out from repositoryUrl. + */ + private Path dir; + + private String pluginVenv = "venv/PluginVenv"; + private String venvInterpreter; + + /** + * Default constructor for instantiating a Python-based mapping plugin. It + * is assumed, that the code for the plugin is stored in a Git repository + * located at 'repositoryUrl'. Furthermore, it is assumed, that the plugin + * itself is delivered as a single Jar file which contains at least the + * plugin class and a file PLUGIN_NAME.properties, where PLUGIN_NAME must be + * identical to the 'pluginName' argument and the file must be located in + * the root of the Jar file. The properties file must contain one property + * 'version' which represents an existing Git tag matching a released + * version of the Python plugin code, e.g., version=v1.0.0 + * + * Furthermore, the properties file may contain a minimal Python version + * that is required by the plugin to work. The minimal Python version is set + * via the 'min.python' property, e.g.., min.python=3.10.0 If the minimal + * Python version is not met, the plugin will be ignored. + * + * @param pluginName The name of the plugin. + * @param repositoryUrl The Git repository where the plugin Python code is + * located. + */ + public AbstractPythonMappingPlugin(String pluginName, String repositoryUrl) { + try { + name = pluginName; + this.repositoryUrl = repositoryUrl; + // Get the context class loader + ClassLoader classLoader = this.getClass().getClassLoader(); + // TODO: do we need to make sure that the resource path is somehow related to the current plugin to avoid loading the wrong property file in case of identical property names? + URL resource = classLoader.getResource(pluginName.toLowerCase() + ".properties"); + LOGGER.info("Resource file: {}", resource); + if (resource != null) { + // Load the properties file + try (InputStream input = resource.openStream()) { + Properties properties = new Properties(); + properties.load(input); + tag = properties.getProperty("version"); + minPython = properties.getProperty("min.python"); + } + } else { + System.err.println("Properties file not found!"); + tag = "unavailable"; + } + + if (System.getProperty("os.name").startsWith("Windows")) { + venvInterpreter = pluginVenv + "/Scripts/python.exe"; + } else { + venvInterpreter = pluginVenv + "/bin/python3"; + } + } catch (IOException e) { + throw new PluginInitializationFailedException("Failed to instantiate plugin class.", e); + } + } + + /** + * Abstract method that is supposed to be implemented by each Python mapping + * plugin the gather all information required for starting a Python process + * executing the mapping script. The returned array should contain at least + * the following information: + * + * <ul> <li>The absolute path of the main script. It must start + * with the working dir given as argument, where all checked out code is + * located.</li> <li>Script-specific parameters to provide + * mappingFile, inputFile, and outputFile. Depending on the script + * implementation the number of required arguments may differ.</li> + * </ul> + * + * Example: In standalone mode, your script is called via `plugin_wrapper.py + * sem -m mappingFile -i inputFile -o outputFile`. In that case, the + * resulting array should look as follows: [workingDir + + * "plugin_wrapper.py", "sem", "-m", mappingFile.toString(), "-i", + * inputFile.toString(), "-o", outputFile.toString()]. The Python call + * itself will be added depending on the local installation and must not be + * included. + * + * @param workingDir The working directory, i.e., where the plugin code was + * checked out into. + * @param mappingFile The file which contains the mapping rules registered + * at the mapping-service and used by the script. + * @param inputFile The file which was uploaded by the user, i.e., the + * source of the mapping process. + * @param outputFile The destination where mapping results must be written + * to in order to allow the mapping-service to return the result to the + * user. + * + * @return A string array containing the single elements of the command line + * call of the script. + */ + public abstract String[] getCommandArray(Path workingDir, Path mappingFile, Path inputFile, Path outputFile); + + @Override + public String name() { + return this.name; + } + + @Override + public String version() { + return this.tag; + } + + @Override + public String description() { + return "Plugin " + name() + ", Version " + version() + ", Implementation: " + uri(); + } + + @Override + public String uri() { + return this.repositoryUrl; + } + + @Override + public void setup() { + LOGGER.trace("Setting up mapping plugin {} {}", name(), version()); + + //testing minimal Python version + + + + + try { + LOGGER.info("Cloning git repository {}, Tag {}", repositoryUrl, tag); + dir = FileUtil.cloneGitRepository(repositoryUrl, tag); + // Install Python dependencies + MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", dir + "/" + pluginVenv); + if (MappingPluginState.SUCCESS().getState().equals(venvState.getState())) { + LOGGER.info("Venv for plugin installed successfully. Installing packages."); + ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt"); + } else { + throw new PluginInitializationFailedException("Venv installation was not successful. Status: " + venvState.getState()); + } + } catch (MappingPluginException e) { + throw new PluginInitializationFailedException("Unexpected error during plugin setup.", e); + } + } + + @Override + public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { + long startTime = System.currentTimeMillis(); + LOGGER.trace("Run SEM-Mapping-Tool on '{}' with mapping '{}' -> '{}'", mappingFile, inputFile, outputFile); + String[] commandArray = getCommandArray(dir, mappingFile, inputFile, outputFile); + List command = new LinkedList<>(); + command.add(dir + "/" + venvInterpreter); + command.addAll(Arrays.asList(commandArray)); + //MappingPluginState result = ShellRunnerUtil.run(dir + "/" + venvInterpreter, dir + "/plugin_wrapper.py", "sem", "-m", mappingFile.toString(), "-i", inputFile.toString(), "-o", outputFile.toString()); + MappingPluginState result = ShellRunnerUtil.run(command.toArray(String[]::new)); + long endTime = System.currentTimeMillis(); + long totalTime = endTime - startTime; + LOGGER.info("Execution time of mapFile: {} milliseconds", totalTime); + return result; + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java index 3bb4681e..2cbfbb9c 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java @@ -24,7 +24,7 @@ import org.springframework.util.MimeTypeUtils; import java.nio.file.Path; -public class GemmaPlugin implements IMappingPlugin { +public class GemmaPlugin extends AbstractPythonMappingPlugin { private final Logger LOGGER = LoggerFactory.getLogger(GemmaPlugin.class); private static final String GEMMA_REPOSITORY = "https://github.com/kit-data-manager/gemma.git"; @@ -32,9 +32,8 @@ public class GemmaPlugin implements IMappingPlugin { private static Path gemmaDir; private boolean initialized = false; - @Override - public String name() { - return "GEMMA"; + public GemmaPlugin() { + super("GEMMA", GEMMA_REPOSITORY); } @Override @@ -42,16 +41,6 @@ public String description() { return "GEMMA is a tool written in Python that allows to map from JSON and XML to JSON. Furthermore, it allows to map with a mapping schema."; } - @Override - public String version() { - return "1.0.0"; - } - - @Override - public String uri() { - return "https://github.com/kit-data-manager/gemma"; - } - @Override public MimeType[] inputTypes() { return new MimeType[]{MimeTypeUtils.APPLICATION_JSON, MimeTypeUtils.APPLICATION_XML}; @@ -63,19 +52,16 @@ public MimeType[] outputTypes() { } @Override - public void setup() { - LOGGER.info("Checking and installing dependencies for Gemma: gemma, xmltodict, wget"); - try { - PythonRunnerUtil.runPythonScript("-m", new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), "pip", "install", "xmltodict", "wget"); - gemmaDir = FileUtil.cloneGitRepository(GEMMA_REPOSITORY, GEMMA_BRANCH); - initialized = true; - } catch (MappingPluginException e) { - throw new PluginInitializationFailedException("Failed to setup plugin '" + name() + "' " + version() + ".", e); - - } + public String[] getCommandArray(Path workingDir, Path mappingFile, Path inputFile, Path outputFile) { + return new String[]{ + workingDir + "/mapping_single.py", + mappingFile.toString(), + inputFile.toString(), + outputFile.toString() + }; } - @Override + /* @Override public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { if (initialized) { LOGGER.trace("Running plugin '{}' v{} on '{}' with mapping '{}' -> '{}'", name(), version(), inputFile, mappingFile, outputFile); @@ -86,5 +72,5 @@ public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputF result.setDetails("Plugin not initialized, probably due to missing dependencies or external plugin repository."); return result; } - } + }*/ } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java deleted file mode 100644 index 4bec0629..00000000 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java +++ /dev/null @@ -1,140 +0,0 @@ -package edu.kit.datamanager.mappingservice.plugins.impl; - -import com.google.common.io.Files; -import edu.kit.datamanager.mappingservice.plugins.*; -import edu.kit.datamanager.mappingservice.util.*; -import java.io.File; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.MimeType; -import org.springframework.util.MimeTypeUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Properties; -import org.apache.commons.io.FileUtils; - -public class PythonCheckPlugin implements IMappingPlugin { - - private static String version; - - private final Logger LOGGER = LoggerFactory.getLogger(PythonCheckPlugin.class); - private final String REPOSITORY = "https://github.com/kit-data-manager/mapping-service"; - private String TAG; - private Path dir; - private String pluginVenv = "venv/PluginVenv"; - private String venvInterpreter; - - public PythonCheckPlugin() { - try { - // Get the context class loader - ClassLoader classLoader = this.getClass().getClassLoader(); - Properties props = new Properties(); - props.load(classLoader.getResourceAsStream("META-INF/build-info.properties")); - - version = props.getProperty("build.version"); - - // TODO: do we need to make sure that the resource path is somehow related to the current plugin to avoid loading the wrong property file in case of identical property names? - /*URL resource = classLoader.getResource("sempluginversion.properties"); - LOGGER.info("Resource file: {}", resource); - if (resource != null) { - // Load the properties file - try (InputStream input = resource.openStream()) { - Properties properties = new Properties(); - properties.load(input); - version = properties.getProperty("version"); - TAG = version; - } - } else { - System.err.println("Properties file not found!"); - version = "unavailable"; - TAG = "unavailable"; - }*/ - if (System.getProperty("os.name").startsWith("Windows")) { - venvInterpreter = pluginVenv + "/Scripts/python.exe"; - } else { - venvInterpreter = pluginVenv + "/bin/python3"; - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public String name() { - return "PythonCheckPlugin"; - } - - @Override - public String description() { - return "This is a sample plugin that can be used to check the python version used by this mapping-service instance."; - } - - @Override - public String version() { - return version; - } - - @Override - public String uri() { - return REPOSITORY; - } - - @Override - public MimeType[] inputTypes() { - return new MimeType[]{MimeTypeUtils.parseMimeType("plain/text")}; //should currently be IMAGE/TIFF - } - - @Override - public MimeType[] outputTypes() { - return new MimeType[]{MimeTypeUtils.parseMimeType("plain/text")}; - } - - @Override - public void setup() { - LOGGER.info("Checking and installing dependencies for the tool: "); - //TODO: test for minimal python version? - try { - //LOGGER.info("Cloning git repository {}, Tag {}", REPOSITORY, TAG); - //dir = FileUtil.cloneGitRepository(REPOSITORY, TAG); - // Install Python dependencies - - Path p = Paths.get("tmp", name(), version()); - if (!p.toFile().exists()) { - FileUtils.forceMkdir(p.toFile()); - } - - - - - - - MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", p.toAbsolutePath().toString() + "/" + pluginVenv); - if (venvState.getState() == MappingPluginState.StateEnum.SUCCESS) { - LOGGER.info("Venv for plugin installed succesfully."); - LOGGER.info("Installing packages"); - ShellRunnerUtil.run(p.toAbsolutePath().toString() + "/" + venvInterpreter, "-m", "pip", "install", "-r", p.toAbsolutePath().toString() + "/" + pluginVenv + "/requirements.dist.txt"); - } else { - LOGGER.error("venv installation was not successful"); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { - long startTime = System.currentTimeMillis(); - LOGGER.trace("Run SEM-Mapping-Tool on '{}' with mapping '{}' -> '{}'", mappingFile, inputFile, outputFile); - MappingPluginState result = ShellRunnerUtil.run(dir + "/" + venvInterpreter, dir + "/plugin_wrapper.py", "sem", "-m", mappingFile.toString(), "-i", inputFile.toString(), "-o", outputFile.toString()); - long endTime = System.currentTimeMillis(); - long totalTime = endTime - startTime; - LOGGER.info("Execution time of mapFile: {} milliseconds", totalTime); - return result; - } -} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index eb48f921..96118dcc 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -97,6 +97,7 @@ public static MappingPluginState runPythonScript(String script, OutputStream out ArrayList command = new ArrayList<>(); command.add(configuration.getPythonExecutable().getPath()); command.add(script); + if (args != null) { Collections.addAll(command, args); } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java index b3fc7471..d00a58ae 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java @@ -23,6 +23,7 @@ import java.io.*; import java.util.List; +import java.util.Scanner; import java.util.concurrent.*; import java.util.stream.Collectors; @@ -33,7 +34,6 @@ */ public class ShellRunnerUtil { - private static ApplicationProperties configuration; /** @@ -119,21 +119,8 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in ProcessBuilder pb = new ProcessBuilder(command); Process p = pb.start(); - //connect to process out/err streams - Future> errorFuture = pool.submit(new ShellRunnerUtil.ProcessReadTask(p.getErrorStream())); - Future> inputFuture = pool.submit(new ShellRunnerUtil.ProcessReadTask(p.getInputStream())); - - //wait for max timeOutInSeconds for stream to close aka. process to finish - List stdErr = errorFuture.get(timeOutInSeconds, TimeUnit.SECONDS); - List stdOut = inputFuture.get(timeOutInSeconds, TimeUnit.SECONDS); - - //print all out/err messages at once - for (String line : stdOut) { - output.write((line + "\n").getBytes()); - } - for (String line : stdErr) { - error.write((line + "\n").getBytes()); - } + pipeStream(p.getInputStream(), new PrintStream(output)); + pipeStream(p.getErrorStream(), new PrintStream(error)); if (!p.waitFor(timeOutInSeconds, TimeUnit.SECONDS)) { throw new TimeoutException("Process did not return within " + timeOutInSeconds + " seconds."); @@ -147,7 +134,7 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in } catch (TimeoutException te) { LOGGER.error("Command did not return in expected timeframe of " + timeOutInSeconds + " seconds", te); returnValue = MappingPluginState.TIMEOUT(); - } catch (InterruptedException | ExecutionException e) { + } catch (InterruptedException e) { LOGGER.error("Command execution has been interrupted.", e); returnValue = MappingPluginState.UNKNOWN_ERROR(); } catch (BadExitCodeException e) { @@ -164,11 +151,15 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in return returnValue; } - private record ProcessReadTask(InputStream inputStream) implements Callable> { - - @Override - public List call() { - return new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.toList()); - } + private static void pipeStream(final InputStream src, final OutputStream dest) { + new Thread(() -> { + Scanner sc = new Scanner(src); + try (PrintStream print = new PrintStream(dest)) { + while (sc.hasNextLine()) { + print.println(sc.nextLine()); + } + print.flush(); + } + }).start(); } } From 8b572dd15def87d979f4426f0e99138a129a8fb7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 May 2025 22:03:09 +0000 Subject: [PATCH 66/80] Update springDocVersion to v2.8.8 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 830f57bd..2de1c526 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ ext { pythonExecutable = System.getProperty('pythonExecutable', "file:///usr/bin/python3") userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") - set('springDocVersion', "2.8.6") + set('springDocVersion', "2.8.8") set('javersVersion', "7.8.0") set('keycloakVersion', "19.0.0") } From 63351d87bfba28b7c998c901cf93161e6d2616b7 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Tue, 6 May 2025 13:32:56 +0200 Subject: [PATCH 67/80] Continued with AbstractPythonMappingPlugin, integrated Python version check, added new property for codeLocation, still required proper integration --- .../configuration/ApplicationProperties.java | 8 ++ .../plugins/AbstractPythonMappingPlugin.java | 133 ++++++++++++++---- .../plugins/impl/GemmaPlugin.java | 2 - .../mappingservice/util/FileUtil.java | 19 +-- .../mappingservice/util/PythonRunnerUtil.java | 103 +------------- .../mappingservice/util/FileUtilTest.java | 11 -- 6 files changed, 121 insertions(+), 155 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java index 2cb9f704..062ac1ba 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java @@ -59,6 +59,14 @@ public class ApplicationProperties { @Value("${mapping-service.mappingSchemasLocation}") private URL mappingsLocation; + /** + * The absolute path where mapping plugin code is checked out into, i.e., + * for Python-based plugins. + */ + @LocalFolderURL + @Value("${mapping-service.codeLocation}") + private URL codeLocation; + /** * The absolute path where job data is stored. */ diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java index 430035b8..b38f9dab 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java @@ -1,31 +1,55 @@ /* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + * Copyright 2025 Karlsruhe Institute of Technology. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package edu.kit.datamanager.mappingservice.plugins; +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import edu.kit.datamanager.mappingservice.util.FileUtil; import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; import edu.kit.datamanager.mappingservice.util.ShellRunnerUtil; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Properties; +import org.apache.maven.artifact.versioning.ComparableVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; /** * * @author jejkal */ +@Component public abstract class AbstractPythonMappingPlugin implements IMappingPlugin { private final Logger LOGGER = LoggerFactory.getLogger(AbstractPythonMappingPlugin.class); + + /** + * Application properties autowired at instantiation time. + */ + @Autowired + private final ApplicationProperties applicationProperties; /** * The plugin name. */ @@ -108,27 +132,28 @@ public AbstractPythonMappingPlugin(String pluginName, String repositoryUrl) { /** * Abstract method that is supposed to be implemented by each Python mapping - * plugin the gather all information required for starting a Python process - * executing the mapping script. The returned array should contain at least + * plugin to gather all information required for starting a Python process + * executing the mapping script. The returned array must contain at least * the following information: * * <ul> <li>The absolute path of the main script. It must start - * with the working dir given as argument, where all checked out code is + * with the working dir received as argument, where all checked-out code is * located.</li> <li>Script-specific parameters to provide - * mappingFile, inputFile, and outputFile. Depending on the script - * implementation the number of required arguments may differ.</li> - * </ul> + * mappingFile, inputFile, and outputFile to the script execution. Depending + * on the script implementation, the number and kind of required arguments + * may differ.</li> </ul> * - * Example: In standalone mode, your script is called via `plugin_wrapper.py - * sem -m mappingFile -i inputFile -o outputFile`. In that case, the + * Example: In standalone mode, a script is called via `plugin_wrapper.py + * sem -m mappingFile -i inputFile -o outputFile -debug`. In that case, the * resulting array should look as follows: [workingDir + * "plugin_wrapper.py", "sem", "-m", mappingFile.toString(), "-i", - * inputFile.toString(), "-o", outputFile.toString()]. The Python call - * itself will be added depending on the local installation and must not be - * included. + * inputFile.toString(), "-o", outputFile.toString(), "-debug"]. + * + * The Python call itself will be added according to the Venv used for + * plugin execution and must not be included. * * @param workingDir The working directory, i.e., where the plugin code was - * checked out into. + * checked-out into. * @param mappingFile The file which contains the mapping rules registered * at the mapping-service and used by the script. * @param inputFile The file which was uploaded by the user, i.e., the @@ -165,23 +190,33 @@ public String uri() { @Override public void setup() { LOGGER.trace("Setting up mapping plugin {} {}", name(), version()); - + //testing minimal Python version - - - - + if (minPython != null) { + if (!hasMinimalPythonVersion(minPython)) { + throw new PluginInitializationFailedException("Minimal Python version '" + minPython + "' required by plugin not met."); + } + } + + //checkout and install plugin try { - LOGGER.info("Cloning git repository {}, Tag {}", repositoryUrl, tag); - dir = FileUtil.cloneGitRepository(repositoryUrl, tag); + LOGGER.info("Cloning git repository {}, tag {}", repositoryUrl, tag); + dir = FileUtil.cloneGitRepository(repositoryUrl, tag, Paths.get(applicationProperties.getCodeLocation().toURI()).toAbsolutePath().toString()); // Install Python dependencies MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", dir + "/" + pluginVenv); if (MappingPluginState.SUCCESS().getState().equals(venvState.getState())) { LOGGER.info("Venv for plugin installed successfully. Installing packages."); - ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt"); + MappingPluginState requirementsInstallState = ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt"); + if (MappingPluginState.SUCCESS().getState().equals(requirementsInstallState.getState())) { + LOGGER.info("Requirements for plugin installed successfully. Setup complete."); + } else { + throw new PluginInitializationFailedException("Failed to install plugin requirements. Status: " + venvState.getState()); + } } else { - throw new PluginInitializationFailedException("Venv installation was not successful. Status: " + venvState.getState()); + throw new PluginInitializationFailedException("Venv installation has failed. Status: " + venvState.getState()); } + } catch (URISyntaxException e) { + throw new PluginInitializationFailedException("Invalid codeLocation configured in application.properties.", e); } catch (MappingPluginException e) { throw new PluginInitializationFailedException("Unexpected error during plugin setup.", e); } @@ -190,16 +225,64 @@ public void setup() { @Override public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { long startTime = System.currentTimeMillis(); - LOGGER.trace("Run SEM-Mapping-Tool on '{}' with mapping '{}' -> '{}'", mappingFile, inputFile, outputFile); + LOGGER.trace("Run mapping plugin {} {} on '{}' with mapping '{}' -> '{}'", name(), version(), mappingFile, inputFile, outputFile); String[] commandArray = getCommandArray(dir, mappingFile, inputFile, outputFile); List command = new LinkedList<>(); command.add(dir + "/" + venvInterpreter); command.addAll(Arrays.asList(commandArray)); - //MappingPluginState result = ShellRunnerUtil.run(dir + "/" + venvInterpreter, dir + "/plugin_wrapper.py", "sem", "-m", mappingFile.toString(), "-i", inputFile.toString(), "-o", outputFile.toString()); MappingPluginState result = ShellRunnerUtil.run(command.toArray(String[]::new)); long endTime = System.currentTimeMillis(); long totalTime = endTime - startTime; LOGGER.info("Execution time of mapFile: {} milliseconds", totalTime); return result; } + + /** + * This method checks if the local Python installation version is larger or + * equal the provided version number. The version should be provided as + * semantic version number, i.e., 3.13.2 + * + * The method will return TRUE if the minimal requirements are met and false + * otherwise. False is also returned if obtaining/parsing the local python + * version fails. for any reason. + * + * @param versionString The semantic version string to compare the local + * Python version against. + * + * @return True if versionString is smaller or equal the local Python + * version, false otherwise. + */ + private boolean hasMinimalPythonVersion(String versionString) { + boolean result = false; + try { + LOGGER.trace("Checking for minimal Python version {}.", versionString); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + List command = new LinkedList<>(); + command.add(dir + "/" + venvInterpreter); + command.addAll(Arrays.asList("--version")); + MappingPluginState state = ShellRunnerUtil.run(bout, System.err, command.toArray(String[]::new)); + + if (!MappingPluginState.StateEnum.SUCCESS.equals(state.getState())) { + LOGGER.error("Failed to obtain Python version. python --version returned with status {}.", state.getState()); + } else { + + LOGGER.trace("Version command output: {}", bout.toString()); + + String[] split = bout.toString().split(" "); + + if (split.length == 2) { + String localPythonVersion = bout.toString().split(" ")[1].trim(); + LOGGER.trace("Obtained local Python version: {}", localPythonVersion); + ComparableVersion localVersion = new ComparableVersion(localPythonVersion); + ComparableVersion minimalVersion = new ComparableVersion(versionString); + result = minimalVersion.compareTo(localVersion) <= 0; + } else { + LOGGER.info("Unexpected Python version output. Unable to check for minimal version."); + } + } + } catch (MappingPluginException e) { + LOGGER.error("Failed to obtain Python version.", e); + } + return result; + } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java index 2cbfbb9c..af9171af 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java @@ -15,9 +15,7 @@ */ package edu.kit.datamanager.mappingservice.plugins.impl; -import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import edu.kit.datamanager.mappingservice.plugins.*; -import edu.kit.datamanager.mappingservice.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.MimeType; diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java index d80a3aac..cea557cd 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java @@ -42,7 +42,6 @@ import org.apache.tika.mime.MimeType; import org.apache.tika.mime.MimeTypeException; import org.apache.tika.mime.MimeTypes; -import org.eclipse.jgit.errors.RepositoryNotFoundException; /** * Various utility methods for file handling. @@ -282,20 +281,10 @@ private static String guessFileExtension(String filename, byte[] fewKilobytesOfF } /** - * This method clones a git repository into the 'lib' folder. - * - * @param repositoryUrl the url of the repository to clone - * @param branch the branch to clone - * @return the path to the cloned repository - */ - public static Path cloneGitRepository(String repositoryUrl, String branch) { - String target = "lib/" + repositoryUrl.trim().replace("https://", "").replace("http://", "").replace(".git", "") + "_" + branch; - return cloneGitRepository(repositoryUrl, branch, target); - } - - /** - * This method clones a git repository into the 'lib' folder. If the folder - * already exists, a pull is performed. + * This method clones a git repository into the provided target folder. If + * the folder already exists, a pull is performed, otherwise it is created + * before. Typically, the target folder should be takes from property + * 'mapping-service.codeLocation' obtained from ApplicationProperties. * * @param repositoryUrl the url of the repository to clone * @param branch the branch to clone diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index 1fac38f9..c515f90b 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -17,7 +17,6 @@ import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; -import java.io.ByteArrayOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -25,7 +24,6 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; -import org.apache.maven.artifact.versioning.ComparableVersion; /** * Utility class for running python scripts. @@ -44,7 +42,7 @@ public static void init(ApplicationProperties configuration) { } /** - * This method prints the python version to Log.info. + * This method prints the python version to System.out. */ public static void printPythonVersion() { try { @@ -55,84 +53,6 @@ public static void printPythonVersion() { } - - - /** - * This method checks if the local Python installation version is larger or - * equal the provided version number. The version should be provided as - * semantic version number, i.e., 3.13.2 - * - * The method will return TRUE if the minimal requirements are met and false - * otherwise. False is also returned if obtaining/parsing the local python - * version fails. for any reason. - * - * @param versionString The semantic version string to compare the local Python version against. - * - * @return True if versionString is smaller or equal the local Python version, false otherwise. - */ - public static boolean hasMinimalPythonVersion(String versionString) { - boolean result = false; - try { - LOGGER.trace("Checking for minimal Python version {}.", versionString); - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - PythonRunnerUtil.runPythonScript("--version", bout, System.err); - LOGGER.trace("Version command output: {}", bout.toString()); - - String[] split = bout.toString().split(" "); - - if (split.length == 2) { - String localPythonVersion = bout.toString().split(" ")[1].trim(); - LOGGER.trace("Obtained local Python version: {}", localPythonVersion); - ComparableVersion localVersion = new ComparableVersion(localPythonVersion); - ComparableVersion minimalVersion = new ComparableVersion(versionString); - result = minimalVersion.compareTo(localVersion) <= 0; - } else { - LOGGER.info("Unexpected Python version output. Unable to check for minimal version."); - } - } catch (MappingPluginException e) { - LOGGER.error("Failed to obtain python version.", e); - } - return result; - } - - /** - * This method checks if the local Python installation version is larger or - * equal the provided version number. The version should be provided as - * semantic version number, i.e., 3.13.2 - * - * The method will return TRUE if the minimal requirements are met and false - * otherwise. False is also returned if obtaining/parsing the local python - * version fails. for any reason. - * - * @param versionString The semantic version string to compare the local Python version against. - * - * @return True if versionString is smaller or equal the local Python version, false otherwise. - */ - public static boolean hasMaximalPythonVersion(String versionString) { - boolean result = false; - try { - LOGGER.trace("Checking for minimal Python version {}.", versionString); - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - PythonRunnerUtil.runPythonScript("--version", bout, System.err); - LOGGER.trace("Version command output: {}", bout.toString()); - - String[] split = bout.toString().split(" "); - - if (split.length == 2) { - String localPythonVersion = bout.toString().split(" ")[1].trim(); - LOGGER.trace("Obtained local Python version: {}", localPythonVersion); - ComparableVersion localVersion = new ComparableVersion(localPythonVersion); - ComparableVersion minimalVersion = new ComparableVersion(versionString); - result = minimalVersion.compareTo(localVersion) > 0; - } else { - LOGGER.info("Unexpected Python version output. Unable to check for minimal version."); - } - } catch (MappingPluginException e) { - LOGGER.error("Failed to obtain python version.", e); - } - return result; - } - /** * This method executes an argument/option on the python interpreter. * @@ -183,25 +103,4 @@ public static MappingPluginState runPythonScript(String script, OutputStream out } return ShellRunnerUtil.run(output, error, command.toArray(String[]::new)); } - - public static void main(String[] args) throws Exception { - ArrayList command = new ArrayList<>(); - command.add("/opt/homebrew/bin/python3"); - command.add("--version"); - if (args != null) { - Collections.addAll(command, args); - } - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - - ShellRunnerUtil.run(bout, System.err, command.toArray(String[]::new)); - System.out.println("VERS " + bout.toString()); - System.out.println(bout.toString().split(" ")[1]); - ComparableVersion verr = new ComparableVersion("unknown"); - System.out.println("ER " + verr.getCanonical()); - ComparableVersion v = new ComparableVersion(bout.toString().split(" ")[1].trim()); - ComparableVersion vMin = new ComparableVersion("4"); - System.out.println(verr.compareTo(v)); - - } } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java index f67df91e..89efb2a1 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java @@ -335,17 +335,6 @@ void cloneValidGitRepository() { } assertNotNull(util); - util = null; - try { - util = FileUtil.cloneGitRepository("https://github.com/kit-data-manager/mapping-service.git", "main"); - } catch (Exception e) { - fail(e); - } finally { - try { - FileUtils.deleteDirectory(new File(util.toUri())); - } catch (IOException e) { - } - } } @Test From b86d2debdf20b13ae45ad951df4e3527ff18219f Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Wed, 7 May 2025 16:33:42 +0200 Subject: [PATCH 68/80] Fixed autowire of applicationProperties in AbstractPythongMappingPlugin, fixed dependency duplication issue, tests may still fail --- build.gradle | 6 +++++- .../plugins/AbstractPythonMappingPlugin.java | 18 ++++++++++++++---- .../plugins/impl/GemmaPlugin.java | 19 ------------------- src/main/resources/gemma.properties | 2 ++ .../mappingservice/util/FileUtilTest.java | 3 +-- .../test-config/application-test.properties | 1 + 6 files changed, 23 insertions(+), 26 deletions(-) create mode 100644 src/main/resources/gemma.properties diff --git a/build.gradle b/build.gradle index 830f57bd..a52c7c7f 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,11 @@ dependencies { implementation 'com.google.guava:guava:33.4.8-jre' implementation 'commons-io:commons-io:2.19.0' implementation 'javax.validation:validation-api:2.0.1.Final' - implementation 'edu.kit.datamanager:service-base:1.3.3' + implementation ('edu.kit.datamanager:service-base:1.3.3'){ + //exclude dependency as spring boot includes + //org.glassfish.jaxb:jaxb-core:4.0.5 which leads to a duplication conflict + exclude group: "com.sun.xml.bind" + } // apache implementation "org.apache.tika:tika-core:2.9.3" diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java index b38f9dab..5b55bc6d 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java @@ -40,16 +40,15 @@ * * @author jejkal */ -@Component public abstract class AbstractPythonMappingPlugin implements IMappingPlugin { private final Logger LOGGER = LoggerFactory.getLogger(AbstractPythonMappingPlugin.class); /** - * Application properties autowired at instantiation time. + * Application properties autowired at instantiation time via + * setApplicationProperties. */ - @Autowired - private final ApplicationProperties applicationProperties; + private ApplicationProperties applicationProperties; /** * The plugin name. */ @@ -130,6 +129,17 @@ public AbstractPythonMappingPlugin(String pluginName, String repositoryUrl) { } } + /** + * Setter to autowire ApplicationProperties into all implementations of this + * abstract class. + * + * @param applicationProperties The applicationProperties bean. + */ + @Autowired + public final void setApplicationProperties(ApplicationProperties applicationProperties) { + this.applicationProperties = applicationProperties; + } + /** * Abstract method that is supposed to be implemented by each Python mapping * plugin to gather all information required for starting a Python process diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java index af9171af..52ba8fa2 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java @@ -16,19 +16,13 @@ package edu.kit.datamanager.mappingservice.plugins.impl; import edu.kit.datamanager.mappingservice.plugins.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.util.MimeType; import org.springframework.util.MimeTypeUtils; import java.nio.file.Path; public class GemmaPlugin extends AbstractPythonMappingPlugin { - private final Logger LOGGER = LoggerFactory.getLogger(GemmaPlugin.class); private static final String GEMMA_REPOSITORY = "https://github.com/kit-data-manager/gemma.git"; - private static final String GEMMA_BRANCH = "master"; - private static Path gemmaDir; - private boolean initialized = false; public GemmaPlugin() { super("GEMMA", GEMMA_REPOSITORY); @@ -58,17 +52,4 @@ public String[] getCommandArray(Path workingDir, Path mappingFile, Path inputFil outputFile.toString() }; } - - /* @Override - public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { - if (initialized) { - LOGGER.trace("Running plugin '{}' v{} on '{}' with mapping '{}' -> '{}'", name(), version(), inputFile, mappingFile, outputFile); - return PythonRunnerUtil.runPythonScript(gemmaDir + "/mapping_single.py", mappingFile.toString(), inputFile.toString(), outputFile.toString()); - } else { - LOGGER.error("Plugin '" + name() + "' " + version() + " not initialized. Returning EXECUTION_ERROR."); - MappingPluginState result = MappingPluginState.EXECUTION_ERROR(); - result.setDetails("Plugin not initialized, probably due to missing dependencies or external plugin repository."); - return result; - } - }*/ } diff --git a/src/main/resources/gemma.properties b/src/main/resources/gemma.properties new file mode 100644 index 00000000..0dbc8802 --- /dev/null +++ b/src/main/resources/gemma.properties @@ -0,0 +1,2 @@ +version=master +min.python=3.0.0 \ No newline at end of file diff --git a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java index 89efb2a1..f409189f 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java @@ -322,7 +322,7 @@ public void testFixFileExtensionWrongFile() { @Test void cloneValidGitRepository() { Path util = null; - + try { util = FileUtil.cloneGitRepository("https://github.com/kit-data-manager/mapping-service.git", "main", "/tmp/test"); } catch (Exception e) { @@ -340,7 +340,6 @@ void cloneValidGitRepository() { @Test void cloneInvalidGitRepository() { assertThrows(MappingServiceException.class, () -> FileUtil.cloneGitRepository("test", "test", "test")); - assertThrows(MappingServiceException.class, () -> FileUtil.cloneGitRepository("test", "test")); } @AfterEach diff --git a/src/test/resources/test-config/application-test.properties b/src/test/resources/test-config/application-test.properties index b5e143da..92033e94 100644 --- a/src/test/resources/test-config/application-test.properties +++ b/src/test/resources/test-config/application-test.properties @@ -67,6 +67,7 @@ eureka.client.enabled: false mapping-service.pythonExecutable=${pythonExecutable:file:///usr/bin/python} # Absolute path to the folder where all plugins are located mapping-service.pluginLocation=file:///tmp/mapping-service/plugins +mapping-service.codeLocation=file:///tmp/mapping-service/code # Absolute path to the local gemma mappings folder mapping-service.mappingSchemasLocation=file:///tmp/mapping-service/schemas # Folder where job output files for async mapping executions are stored From 778c1098231bbec6b97a165281064aa553aebc2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 14:34:17 +0000 Subject: [PATCH 69/80] Update dependency edu.kit.datamanager:service-base to v1.3.4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a52c7c7f..ca45bb28 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ dependencies { implementation 'com.google.guava:guava:33.4.8-jre' implementation 'commons-io:commons-io:2.19.0' implementation 'javax.validation:validation-api:2.0.1.Final' - implementation ('edu.kit.datamanager:service-base:1.3.3'){ + implementation ('edu.kit.datamanager:service-base:1.3.4'){ //exclude dependency as spring boot includes //org.glassfish.jaxb:jaxb-core:4.0.5 which leads to a duplication conflict exclude group: "com.sun.xml.bind" From 6d16d7b0b0511561f622656052597f358811261a Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 8 May 2025 11:27:13 +0200 Subject: [PATCH 70/80] Fixed tests, made requirements.dist.txt optional, fixed providing code location, fixed checkout folder to contain repository name --- .../mappingservice/impl/MappingService.java | 5 + .../plugins/AbstractPythonMappingPlugin.java | 44 +- .../plugins/IMappingPlugin.java | 35 +- .../mappingservice/plugins/PluginLoader.java | 6 +- .../plugins/impl/IdentifyPlugin.java | 3 +- .../plugins/impl/InOutPlugin.java | 3 +- .../plugins/PluginLoaderTest.java | 2 +- .../MappingAdministrationControllerTest.java | 8 +- .../venv/PluginVenv/Scripts/Activate.ps1 | 405 ------------------ .../venv/PluginVenv/Scripts/activate | 69 --- .../venv/PluginVenv/Scripts/activate.bat | 34 -- .../venv/PluginVenv/Scripts/deactivate.bat | 22 - .../venv/PluginVenv/Scripts/pip.exe | Bin 106427 -> 0 bytes .../venv/PluginVenv/Scripts/pip3.10.exe | Bin 106427 -> 0 bytes .../venv/PluginVenv/Scripts/pip3.exe | Bin 106427 -> 0 bytes .../venv/PluginVenv/Scripts/python.exe | Bin 242920 -> 0 bytes .../venv/PluginVenv/Scripts/pythonw.exe | Bin 232688 -> 0 bytes .../1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg | 3 - 18 files changed, 55 insertions(+), 584 deletions(-) delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip.exe delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip3.10.exe delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip3.exe delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/python.exe delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pythonw.exe delete mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java index 10e4d74c..45336e83 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java @@ -498,6 +498,11 @@ private void init(ApplicationProperties applicationProperties) { } catch (IOException e) { throw new MappingServiceException(String.format("Could not initialize job output directory '%s'.", applicationProperties.getJobOutputLocation()), e); } + try { + Files.createDirectories(new File(applicationProperties.getCodeLocation().getPath()).getAbsoluteFile().toPath()); + } catch (IOException e) { + throw new MappingServiceException(String.format("Could not initialize code target directory '%s'.", applicationProperties.getCodeLocation()), e); + } } else { throw new MappingServiceException("Cannot configure MappingService due to missing application.properties."); } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java index 5b55bc6d..e0860dcd 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java @@ -44,11 +44,6 @@ public abstract class AbstractPythonMappingPlugin implements IMappingPlugin { private final Logger LOGGER = LoggerFactory.getLogger(AbstractPythonMappingPlugin.class); - /** - * Application properties autowired at instantiation time via - * setApplicationProperties. - */ - private ApplicationProperties applicationProperties; /** * The plugin name. */ @@ -129,17 +124,6 @@ public AbstractPythonMappingPlugin(String pluginName, String repositoryUrl) { } } - /** - * Setter to autowire ApplicationProperties into all implementations of this - * abstract class. - * - * @param applicationProperties The applicationProperties bean. - */ - @Autowired - public final void setApplicationProperties(ApplicationProperties applicationProperties) { - this.applicationProperties = applicationProperties; - } - /** * Abstract method that is supposed to be implemented by each Python mapping * plugin to gather all information required for starting a Python process @@ -198,7 +182,7 @@ public String uri() { } @Override - public void setup() { + public void setup(ApplicationProperties applicationProperties) { LOGGER.trace("Setting up mapping plugin {} {}", name(), version()); //testing minimal Python version @@ -211,16 +195,25 @@ public void setup() { //checkout and install plugin try { LOGGER.info("Cloning git repository {}, tag {}", repositoryUrl, tag); - dir = FileUtil.cloneGitRepository(repositoryUrl, tag, Paths.get(applicationProperties.getCodeLocation().toURI()).toAbsolutePath().toString()); + Path path = Paths.get(applicationProperties.getCodeLocation().toURI()); + path = path.resolve(repositoryUrl.trim().replace("https://", "").replace("http://", "").replace(".git", "") + "_" + version()); + LOGGER.info("Target path: {}", path); + dir = FileUtil.cloneGitRepository(repositoryUrl, tag, path.toAbsolutePath().toString()); // Install Python dependencies MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", dir + "/" + pluginVenv); if (MappingPluginState.SUCCESS().getState().equals(venvState.getState())) { - LOGGER.info("Venv for plugin installed successfully. Installing packages."); - MappingPluginState requirementsInstallState = ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt"); - if (MappingPluginState.SUCCESS().getState().equals(requirementsInstallState.getState())) { - LOGGER.info("Requirements for plugin installed successfully. Setup complete."); + LOGGER.info("Venv for plugin installed successfully. Installing requirements."); + + Path requirementsFile = Paths.get(dir + "/" + "requirements.dist.txt"); + if (requirementsFile.toFile().exists()) { + MappingPluginState requirementsInstallState = ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt"); + if (MappingPluginState.SUCCESS().getState().equals(requirementsInstallState.getState())) { + LOGGER.info("Requirements for plugin installed successfully. Setup complete."); + } else { + throw new PluginInitializationFailedException("Failed to install plugin requirements. Status: " + venvState.getState()); + } } else { - throw new PluginInitializationFailedException("Failed to install plugin requirements. Status: " + venvState.getState()); + LOGGER.info("No requirements file found. Skipping dependency installation."); } } else { throw new PluginInitializationFailedException("Venv installation has failed. Status: " + venvState.getState()); @@ -267,10 +260,7 @@ private boolean hasMinimalPythonVersion(String versionString) { try { LOGGER.trace("Checking for minimal Python version {}.", versionString); ByteArrayOutputStream bout = new ByteArrayOutputStream(); - List command = new LinkedList<>(); - command.add(dir + "/" + venvInterpreter); - command.addAll(Arrays.asList("--version")); - MappingPluginState state = ShellRunnerUtil.run(bout, System.err, command.toArray(String[]::new)); + MappingPluginState state = PythonRunnerUtil.runPythonScript("--version", bout, System.err); if (!MappingPluginState.StateEnum.SUCCESS.equals(state.getState())) { LOGGER.error("Failed to obtain Python version. python --version returned with status {}.", state.getState()); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java index 5b1e69c9..3110e940 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java @@ -12,16 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package edu.kit.datamanager.mappingservice.plugins; +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import org.springframework.util.MimeType; import java.nio.file.Path; /** - * Interface for mapping plugins. - * Every plugin which implements this interface and is placed in the plugins folder will be loaded and usable via the REST-API. + * Interface for mapping plugins. Every plugin which implements this interface + * and is placed in the plugins folder will be loaded and usable via the + * REST-API. * * @author maximilianiKIT */ @@ -42,15 +43,17 @@ public interface IMappingPlugin { String description(); /** - * The version of the plugin which gets displayed in the UI and is part of the id. + * The version of the plugin which gets displayed in the UI and is part of + * the id. * * @return The version of the plugin. */ String version(); /** - * A URI which refers to the plugin or the technology used by the plugin (e.g. a link to a GitHub repository). - * This URI will be displayed in the UI. + * A URI which refers to the plugin or the technology used by the plugin + * (e.g. a link to a GitHub repository). This URI will be displayed in the + * UI. * * @return The URI of the plugin. */ @@ -71,8 +74,9 @@ public interface IMappingPlugin { MimeType[] outputTypes(); /** - * The id of the plugin which is used to identify the plugin. - * By default, the id is composed of the name and the version of the plugin (e.g. testPlugin_2.1.0). + * The id of the plugin which is used to identify the plugin. By default, + * the id is composed of the name and the version of the plugin (e.g. + * testPlugin_2.1.0). * * @return The id of the plugin. */ @@ -81,19 +85,22 @@ default String id() { } /** - * This method is called when the plugin is loaded. - * It can be used to initialize the plugin and install dependencies. + * This method is called when the plugin is loaded. It can be used to + * initialize the plugin and install dependencies. + * + * @param applicationProperties Properties object containing all + * mapping-service settings. */ - void setup(); + void setup(ApplicationProperties applicationProperties); /** * The method which is called to execute the plugin. * - * @param inputFile The path to the output document. - * @param outputFile The path to the output document. + * @param inputFile The path to the output document. + * @param outputFile The path to the output document. * @param mappingFile The path to the mapping schema. * @return The exit code of the plugin. - * + * * @throws MappingPluginException If the mapping execution fails. */ MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException; diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java index 9c4a03f4..9cfea49e 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java @@ -100,12 +100,12 @@ public Map loadPlugins(File pluginDir, String[] packages cl = Thread.currentThread().getContextClassLoader(); } - List> plugClasses = extractClassesFromJARs(pluginJars, packagesToScan, cl); - List IMappingPluginList = createPluggableObjects(plugClasses); + List> pluginClasses = extractClassesFromJARs(pluginJars, packagesToScan, cl); + List IMappingPluginList = createPluggableObjects(pluginClasses); for (IMappingPlugin i : IMappingPluginList) { try { - i.setup(); + i.setup(applicationProperties); LOG.trace(" - Adding new plugin {}, v{} to available list", i.name(), i.version()); result.put(i.id(), i); } catch (PluginInitializationFailedException re) { diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java index cdd1c9b4..d0b315e0 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java @@ -15,6 +15,7 @@ */ package edu.kit.datamanager.mappingservice.plugins.impl; +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import edu.kit.datamanager.mappingservice.plugins.IMappingPlugin; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; @@ -71,7 +72,7 @@ public MimeType[] outputTypes() { } @Override - public void setup() { + public void setup(ApplicationProperties applicationProperties) { if (Paths.get("/usr/bin/identify").toFile().exists()) { initialized = true; } else { diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java index 4b32a265..23e5d050 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java @@ -15,6 +15,7 @@ */ package edu.kit.datamanager.mappingservice.plugins.impl; +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.exception.MappingException; import edu.kit.datamanager.mappingservice.plugins.IMappingPlugin; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; @@ -66,7 +67,7 @@ public MimeType[] outputTypes() { } @Override - public void setup() { + public void setup(ApplicationProperties applicationProperties) { //nothing to do here LOG.trace("Plugin {} {} successfully set up.", name(), version()); } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java index 9c6b1faa..b30ebdd1 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java @@ -73,7 +73,7 @@ void valid() { assertEquals("https://github.com/kit-data-manager/mapping-service", plugins.get("InOutPlugin_1.1.2").uri()); assertEquals("application/*", plugins.get("InOutPlugin_1.1.2").inputTypes()[0].toString()); assertEquals("application/*", plugins.get("InOutPlugin_1.1.2").outputTypes()[0].toString()); - plugins.get("InOutPlugin_1.1.2").setup(); + plugins.get("InOutPlugin_1.1.2").setup(applicationProperties); File inputFile = new File("/tmp/imputFile"); if (!inputFile.exists()) { Assertions.assertTrue(inputFile.createNewFile()); diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java index 3594e2fc..0e431b5b 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java @@ -92,7 +92,7 @@ public class MappingAdministrationControllerTest { private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/"; private static final String MAPPING_ID = "my_dc"; - private static final String MAPPING_TYPE = "GEMMA_1.0.0"; + private static final String MAPPING_TYPE = "GEMMA_master"; private static final String MAPPING_TITLE = "TITEL"; private static final String MAPPING_DESCRIPTION = "DESCRIPTION"; @@ -890,7 +890,7 @@ public void testDeleteMappingUnknownMappingId() throws JsonProcessingException, result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isNoContent()).andReturn(); // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; - assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename); + assertEquals("my_dc_" + MAPPING_TYPE + ".mapping", expectedFilename); assertEquals(1, mappingRecordDao.count()); } @@ -935,7 +935,7 @@ public void testDeleteMappingMissingEtag() throws JsonProcessingException, Excep result = this.mockMvc.perform(delete(deleteMappingIdUrl)).andDo(print()).andExpect(status().isPreconditionRequired()).andReturn(); // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; - assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename); + assertEquals("my_dc_" + MAPPING_TYPE + ".mapping", expectedFilename); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn(); assertEquals(1, mappingRecordDao.count()); } @@ -959,7 +959,7 @@ public void testDeleteMappingWrongEtag() throws JsonProcessingException, Excepti result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isPreconditionFailed()).andReturn(); // assertEquals(1, mappingsDir.list().length); String expectedFilename = mappingId + "_" + mappingType + ".mapping"; - assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename); + assertEquals("my_dc_" + MAPPING_TYPE + ".mapping", expectedFilename); result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn(); assertEquals(1, mappingRecordDao.count()); } diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 deleted file mode 100644 index 181c1eff..00000000 --- a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 +++ /dev/null @@ -1,405 +0,0 @@ -<# -.Synopsis -Activate a Python virtual environment for the current PowerShell session. - -.Description -Pushes the python executable for a virtual environment to the front of the -$Env:PATH environment variable and sets the prompt to signify that you are -in a Python virtual environment. Makes use of the command line switches as -well as the `pyvenv.cfg` file values present in the virtual environment. - -.Parameter VenvDir -Path to the directory that contains the virtual environment to activate. The -default value for this is the parent of the directory that the Activate.ps1 -script is located within. - -.Parameter Prompt -The prompt prefix to display when this virtual environment is activated. By -default, this prompt is the name of the virtual environment folder (VenvDir) -surrounded by parentheses and followed by a single space (ie. '(.venv) '). - -.Example -Activate.ps1 -Activates the Python virtual environment that contains the Activate.ps1 script. - -.Example -Activate.ps1 -Verbose -Activates the Python virtual environment that contains the Activate.ps1 script, -and shows extra information about the activation as it executes. - -.Example -Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv -Activates the Python virtual environment located in the specified location. - -.Example -Activate.ps1 -Prompt "MyPython" -Activates the Python virtual environment that contains the Activate.ps1 script, -and prefixes the current prompt with the specified string (surrounded in -parentheses) while the virtual environment is active. - -.Notes -On Windows, it may be required to enable this Activate.ps1 script by setting the -execution policy for the user. You can do this by issuing the following PowerShell -command: - -PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser - -For more information on Execution Policies: -https://go.microsoft.com/fwlink/?LinkID=135170 - -#> -Param( - [Parameter(Mandatory = $false)] - [String] - $VenvDir, - [Parameter(Mandatory = $false)] - [String] - $Prompt -) - -<# Function declarations --------------------------------------------------- #> - -<# -.Synopsis -Remove all shell session elements added by the Activate script, including the -addition of the virtual environment's Python executable from the beginning of -the PATH variable. - -.Parameter NonDestructive -If present, do not remove this function from the global namespace for the -session. - -#> -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - - # The prior prompt: - if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { - Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt - Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT - } - - # The prior PYTHONHOME: - if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { - Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME - Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME - } - - # The prior PATH: - if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { - Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH - Remove-Item -Path Env:_OLD_VIRTUAL_PATH - } - - # Just remove the VIRTUAL_ENV altogether: - if (Test-Path -Path Env:VIRTUAL_ENV) { - Remove-Item -Path env:VIRTUAL_ENV - } - - # Just remove VIRTUAL_ENV_PROMPT altogether. - if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { - Remove-Item -Path env:VIRTUAL_ENV_PROMPT - } - - # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: - if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { - Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force - } - - # Leave deactivate function in the global namespace if requested: - if (-not $NonDestructive) { - Remove-Item -Path function:deactivate - } -} - -<# -.Description -Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the -given folder, and returns them in a map. - -For each line in the pyvenv.cfg file, if that line can be parsed into exactly -two strings separated by `=` (with any amount of whitespace surrounding the =) -then it is considered a `key = value` line. The left hand string is the key, -the right hand is the value. - -If the value starts with a `'` or a `"` then the first and last character is -stripped from the value before being captured. - -.Parameter ConfigDir -Path to the directory that contains the `pyvenv.cfg` file. -#> -function Get-PyVenvConfig( - [String] - $ConfigDir -) { - Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" - - # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). - $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue - - # An empty map will be returned if no config file is found. - $pyvenvConfig = @{ } - - if ($pyvenvConfigPath) { - - Write-Verbose "File exists, parse `key = value` lines" - $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath - - $pyvenvConfigContent | ForEach-Object { - $keyval = $PSItem -split "\s*=\s*", 2 - if ($keyval[0] -and $keyval[1]) { - $val = $keyval[1] - - # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0, 1))) { - $val = $val.Substring(1, $val.Length - 2) - } - - $pyvenvConfig[$keyval[0]] = $val - Write-Verbose "Adding Key: '$($keyval[0])'='$val'" - } - } - } - return $pyvenvConfig -} - - -<# Begin Activate script --------------------------------------------------- #> - -# Determine the containing directory of this script -$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition -$VenvExecDir = Get-Item -Path $VenvExecPath - -Write-Verbose "Activation script is located in path: '$VenvExecPath'" -Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" -Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" - -# Set values required in priority: CmdLine, ConfigFile, Default -# First, get the location of the virtual environment, it might not be -# VenvExecDir if specified on the command line. -if ($VenvDir) { - Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} -else { - Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." - $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - Write-Verbose "VenvDir=$VenvDir" -} - -# Next, read the `pyvenv.cfg` file to determine any required value such -# as `prompt`. -$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir - -# Next, set the prompt from the command line, or the config file, or -# just use the name of the virtual environment folder. -if ($Prompt) { - Write-Verbose "Prompt specified as argument, using '$Prompt'" -} -else { - Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" - if ($pyvenvCfg -and $pyvenvCfg['prompt']) { - Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" - $Prompt = $pyvenvCfg['prompt']; - } - else { - Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" - Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" - $Prompt = Split-Path -Path $venvDir -Leaf - } -} - -Write-Verbose "Prompt = '$Prompt'" -Write-Verbose "VenvDir='$VenvDir'" - -# Deactivate any currently active virtual environment, but leave the -# deactivate function in place. -deactivate -nondestructive - -# Now set the environment variable VIRTUAL_ENV, used by many tools to determine -# that there is an activated venv. -$env:VIRTUAL_ENV = $VenvDir - -if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { - - Write-Verbose "Setting prompt to '$Prompt'" - - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT { "" } - Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT - New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt - - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " - _OLD_VIRTUAL_PROMPT - } - $env:VIRTUAL_ENV_PROMPT = $Prompt -} - -# Clear PYTHONHOME -if (Test-Path -Path Env:PYTHONHOME) { - Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME - Remove-Item -Path Env:PYTHONHOME -} - -# Add the venv to the PATH -Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH -$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" - -# SIG # Begin signature block -# MIIc+QYJKoZIhvcNAQcCoIIc6jCCHOYCAQExDzANBglghkgBZQMEAgEFADB5Bgor -# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB/jbdIOBl7aFn0 -# IOwX0LZ7IuNFjwXgmb5mWup4AsyxRaCCC38wggUwMIIEGKADAgECAhAECRgbX9W7 -# ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK -# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV -# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBa -# Fw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy -# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD -# ZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3 -# DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/l -# qJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fT -# eyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqH -# CN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+ -# bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLo -# LFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIB -# yTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK -# BggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9v -# Y3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGln -# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHow -# eDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl -# ZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp -# Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwA -# AgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAK -# BghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0j -# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7s -# DVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGS -# dQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6 -# r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo -# +MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qz -# sIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHq -# aGxEMrJmoecYpJpkUe8wggZHMIIFL6ADAgECAhADPtXtoGXRuMkd/PkqbJvYMA0G -# CSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ -# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0 -# IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTgxMjE4MDAwMDAw -# WhcNMjExMjIyMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU5ldyBI -# YW1wc2hpcmUxEjAQBgNVBAcTCVdvbGZlYm9ybzEjMCEGA1UEChMaUHl0aG9uIFNv -# ZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMTGlB5dGhvbiBTb2Z0d2FyZSBGb3Vu -# ZGF0aW9uMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqr2kS7J1uW7o -# JRxlsdrETAjKarfoH5TI8PWST6Yb2xPooP7vHT4iaVXyL5Lze1f53Jw67Sp+u524 -# fJXf30qHViEWxumy2RWG0nciU2d+mMqzjlaAWSZNF0u4RcvyDJokEV0RUOqI5CG5 -# zPI3W9uQ6LiUk3HCYW6kpH177A5T3pw/Po8O8KErJGn1anaqtIICq99ySxrMad/2 -# hPMBRf6Ndah7f7HPn1gkSSTAoejyuqF5h+B0qI4+JK5+VLvz659VTbAWJsYakkxZ -# xVWYpFv4KeQSSwoo0DzMvmERsTzNvVBMWhu9OriJNg+QfFmf96zVTu93cZ+r7xMp -# bXyfIOGKhHMaRuZ8ihuWIx3gI9WHDFX6fBKR8+HlhdkaiBEWIsXRoy+EQUyK7zUs -# +FqOo2sRYttbs8MTF9YDKFZwyPjn9Wn+gLGd5NUEVyNvD9QVGBEtN7vx87bduJUB -# 8F4DylEsMtZTfjw/au6AmOnmneK5UcqSJuwRyZaGNk7y3qj06utx+HTTqHgi975U -# pxfyrwAqkovoZEWBVSpvku8PVhkBXcLmNe6MEHlFiaMoiADAeKmX5RFRkN+VrmYG -# Tg4zajxfdHeIY8TvLf48tTfmnQJd98geJQv/01NUy/FxuwqAuTkaez5Nl1LxP0Cp -# THhghzO4FRD4itT2wqTh4jpojw9QZnsCAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaA -# FFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBT8Kr9+1L6s84KcpM97IgE7 -# uI8H8jAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0f -# BHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl -# ZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEy -# LWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYI -# KwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQB -# MIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj -# ZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t -# L0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB -# /wQCMAAwDQYJKoZIhvcNAQELBQADggEBAEt1oS21X0axiafPjyY+vlYqjWKuUu/Y -# FuYWIEq6iRRaFabNDhj9RBFQF/aJiE5msrQEOfAD6/6gVSH91lZWBqg6NEeG9T9S -# XbiAPvJ9CEWFsdkXUrjbWhvCnuZ7kqUuU5BAumI1QRbpYgZL3UA+iZXkmjbGh1ln -# 8rUhWIxbBYL4Sg2nqpB44p7CUFYkPj/MbwU2gvBV2pXjj5WaskoZtsACMv5g42BN -# oVLoRAi+ev6s07POt+JtHRIm87lTyuc8wh0swTPUwksKbLU1Zdj9CpqtzXnuVE0w -# 50exJvRSK3Vt4g+0vigpI3qPmDdpkf9+4Mvy0XMNcqrthw20R+PkIlMxghDQMIIQ -# zAIBATCBhjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw -# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEy -# IEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBAhADPtXtoGXRuMkd/PkqbJvYMA0G -# CWCGSAFlAwQCAQUAoIGaMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG -# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC4GCisGAQQBgjcCAQwxIDAeoByAGgBQ -# AHkAdABoAG8AbgAgADMALgAxADAALgAwMC8GCSqGSIb3DQEJBDEiBCBSbvNxuLmL -# Fyf70+vzWnE86JSS2JLTJbh9WhRqgW9MeDANBgkqhkiG9w0BAQEFAASCAgCAiz/E -# icJSsvY4x2vZnY3UjThg0S9qs+r104rhPxj39k4Qw7szI4yjQQbb2bvnoJA3LoFo -# RROlFg9dXJ8YWRZRNkla+zHX7bIsWO2aIFCnOCOUFH19ttlrTvnal6uLp7P9+wQs -# rller1aRyNIM47dYn+CGxD4NEJ/NIqhCjuRKl0v1Dkps/2md0YkoEcnRXNb3vq6x -# +2L9x3zAcBmVwVM4SFFZ2ZZQG/aHgihbVoNxxTXhYDcwaL5uRrNelz9KXDn+GYpk -# K7ZUFbmNfgnhieLHqF0hk7wLZtHI1BSmsOAFrkApcuIVLzD8aSgDbAMVZEv3GkTx -# Img7jKusLIITGuUWT8wO1LDUXT54qBkQhue6kJ3rqSa2agtg/OWxtQ9JwGSOiRaW -# wlRJjsihrw8Nx1Kcr5EwruBBLFiF+mv/C5ikLvwES1ZKoLccqCftuEptcbmsyEZS -# ov39SslaIWvqfy7rfz+KFfP9WHJxobV6DY4essDCMNcoYXkRwhbT+rr0ydDH23DS -# 3hbXpCuKsy5IAMB7Xk8/uuXV2The/qKmkkmu0KuFOu2/3oqVOC4a27IjkvBCSRhp -# /yWQSM/JQk+KwQ31XCVHeGWf7kqMgCXwkZfkw/lvusXzMuWZqT6bfZ0eGjqX/6jC -# kNwr4fCZtxx0cFLzmCr6/yClCYoDCfGoc1I+D6GCDX0wgg15BgorBgEEAYI3AwMB -# MYINaTCCDWUGCSqGSIb3DQEHAqCCDVYwgg1SAgEDMQ8wDQYJYIZIAWUDBAIBBQAw -# dwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQC -# AQUABCBEd30afcCyVMH4hw1ZZPb4JotijhQZtXQ42klvgjTVGwIQDDJTIO6lXwNY -# 7qTonYA8LxgPMjAyMTEwMDQxOTExMzFaoIIKNzCCBP4wggPmoAMCAQICEA1CSuC+ -# Ooj/YEAhzhQA8N0wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNV -# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G -# A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQTAe -# Fw0yMTAxMDEwMDAwMDBaFw0zMTAxMDYwMDAwMDBaMEgxCzAJBgNVBAYTAlVTMRcw -# FQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0 -# YW1wIDIwMjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC5mGEZ8WK -# 9Q0IpEXKY2tR1zoRQr0KdXVNlLQMULUmEP4dyG+RawyW5xpcSO9E5b+bYc0VkWJa -# uP9nC5xj/TZqgfop+N0rcIXeAhjzeG28ffnHbQk9vmp2h+mKvfiEXR52yeTGdnY6 -# U9HR01o2j8aj4S8bOrdh1nPsTm0zinxdRS1LsVDmQTo3VobckyON91Al6GTm3dOP -# L1e1hyDrDo4s1SPa9E14RuMDgzEpSlwMMYpKjIjF9zBa+RSvFV9sQ0kJ/SYjU/aN -# Y+gaq1uxHTDCm2mCtNv8VlS8H6GHq756WwogL0sJyZWnjbL61mOLTqVyHO6fegFz -# +BnW/g1JhL0BAgMBAAGjggG4MIIBtDAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/ -# BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDBBBgNVHSAEOjA4MDYGCWCGSAGG -# /WwHATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMw -# HwYDVR0jBBgwFoAU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHQYDVR0OBBYEFDZEho6k -# urBmvrwoLR1ENt3janq8MHEGA1UdHwRqMGgwMqAwoC6GLGh0dHA6Ly9jcmwzLmRp -# Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtdHMuY3JsMDKgMKAuhixodHRwOi8vY3Js -# NC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDCBhQYIKwYBBQUHAQEE -# eTB3MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTwYIKwYB -# BQUHMAKGQ2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJB -# c3N1cmVkSURUaW1lc3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggEBAEgc -# 3LXpmiO85xrnIA6OZ0b9QnJRdAojR6OrktIlxHBZvhSg5SeBpU0UFRkHefDRBMOG -# 2Tu9/kQCZk3taaQP9rhwz2Lo9VFKeHk2eie38+dSn5On7UOee+e03UEiifuHokYD -# Tvz0/rdkd2NfI1Jpg4L6GlPtkMyNoRdzDfTzZTlwS/Oc1np72gy8PTLQG8v1Yfx1 -# CAB2vIEO+MDhXM/EEXLnG2RJ2CKadRVC9S0yOIHa9GCiurRS+1zgYSQlT7LfySmo -# c0NR2r1j1h9bm/cuG08THfdKDXF+l7f0P4TrweOjSaH6zqe/Vs+6WXZhiV9+p7SO -# Z3j5NpjhyyjaW4emii8wggUxMIIEGaADAgECAhAKoSXW1jIbfkHkBdo2l8IVMA0G -# CSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ -# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0 -# IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBaFw0zMTAxMDcxMjAw -# MDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV -# BAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNz -# dXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -# ggEKAoIBAQC90DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQfdD5fU1ofue2oPSN -# s4jkl79jIZCYvxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9lP+Cb6+NGRwYaVX4L -# J37AovWg4N4iPw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3ImgtU46gJcWvgzyIQ -# D3XPcXJOCq3fQDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDqR9mIUF79Zm5WYScp -# iYRR5oLnRlD9lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZchfxFwbvPc3WTe8G -# Qv2iUypPhR3EHTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIByjAdBgNVHQ4EFgQU -# 9LbhIB3+Ka7S5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6ch -# nfNtyA8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0l -# BAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRw -# Oi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRz -# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1Ud -# HwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz -# c3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv -# bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0gBEkwRzA4BgpghkgB -# hv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9D -# UFMwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBxlRLpUYdWac3v3dp8 -# qmN6s3jPBjdAhO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3BTQdaq6Z+CeiZr8J -# qmDfdqQ6kw/4stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy23UC4HLHmNY8ZOUf -# SBAYX4k4YU1iRiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWThZN+tpJn+1Nhiaj1 -# a5bA9FhpDXzIAbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZspe6HUSHkWGCbugwt -# K22ixH67xCUrRwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VWMyIvIjayS6JKldj1 -# po5SMYIChjCCAoICAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD -# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln -# aUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQQIQDUJK4L46iP9g -# QCHOFADw3TANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcN -# AQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIxMTAwNDE5MTEzMVowKwYLKoZIhvcNAQkQ -# AgwxHDAaMBgwFgQU4deCqOGRvu9ryhaRtaq0lKYkm/MwLwYJKoZIhvcNAQkEMSIE -# ILvICiD0Bu7OdD0pC2wAqLO9UGMzUOfGejuSENvWkuXdMDcGCyqGSIb3DQEJEAIv -# MSgwJjAkMCIEILMQkAa8CtmDB5FXKeBEA0Fcg+MpK2FPJpZMjTVx7PWpMA0GCSqG -# SIb3DQEBAQUABIIBAIaCoJWKRd6cHB/KrrlVmBY469068xG7ok+T18bfcLmNrvPF -# 7PGY5a4qcMZj+rBevyfWTrOreNAWyNhnxIT0qYneSTJOMytTPYnJI+GhvGwQjDhC -# Eg/JeLOe9guMq7P/ZNvFur+VoCz6sgR/Q+9IGUhJ/7liABdMwNLK38r5VEaSAnSW -# RetjuSqtMoZc2KtjL/MUY26sUwjsMD0tgt0EOF4nrcv3rWl++TsJUEqYr+aFpNu4 -# eVaTNeS0V7sRGQbWAQohkES879Lpqv7KaEW+h426+cc5el260gynz7vTzUuaamvW -# Nfbvu83P5Tk1nRA1Ds2aSqn/RMu6cNNjD8ntV5o= -# SIG # End signature block diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate deleted file mode 100644 index 8b73b92a..00000000 --- a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate +++ /dev/null @@ -1,69 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then - PATH="${_OLD_VIRTUAL_PATH:-}" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then - PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r 2> /dev/null - fi - - if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then - PS1="${_OLD_VIRTUAL_PS1:-}" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - unset VIRTUAL_ENV_PROMPT - if [ ! "${1:-}" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV="E:\Software\NetbeansProjects\mapping-service\tmp\PythonCheckPlugin\1.1.2-SNAPSHOT\venv\PluginVenv" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/Scripts:$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "${PYTHONHOME:-}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1:-}" - PS1="(PluginVenv) ${PS1:-}" - export PS1 - VIRTUAL_ENV_PROMPT="(PluginVenv) " - export VIRTUAL_ENV_PROMPT -fi - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r 2> /dev/null -fi diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat deleted file mode 100644 index 9d82899c..00000000 --- a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat +++ /dev/null @@ -1,34 +0,0 @@ -@echo off - -rem This file is UTF-8 encoded, so we need to update the current code page while executing it -for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( - set _OLD_CODEPAGE=%%a -) -if defined _OLD_CODEPAGE ( - "%SystemRoot%\System32\chcp.com" 65001 > nul -) - -set VIRTUAL_ENV=E:\Software\NetbeansProjects\mapping-service\tmp\PythonCheckPlugin\1.1.2-SNAPSHOT\venv\PluginVenv - -if not defined PROMPT set PROMPT=$P$G - -if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% -if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% - -set _OLD_VIRTUAL_PROMPT=%PROMPT% -set PROMPT=(PluginVenv) %PROMPT% - -if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% -set PYTHONHOME= - -if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% -if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% - -set PATH=%VIRTUAL_ENV%\Scripts;%PATH% -set VIRTUAL_ENV_PROMPT=(PluginVenv) - -:END -if defined _OLD_CODEPAGE ( - "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul - set _OLD_CODEPAGE= -) diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat deleted file mode 100644 index 62a39a75..00000000 --- a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat +++ /dev/null @@ -1,22 +0,0 @@ -@echo off - -if defined _OLD_VIRTUAL_PROMPT ( - set "PROMPT=%_OLD_VIRTUAL_PROMPT%" -) -set _OLD_VIRTUAL_PROMPT= - -if defined _OLD_VIRTUAL_PYTHONHOME ( - set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" - set _OLD_VIRTUAL_PYTHONHOME= -) - -if defined _OLD_VIRTUAL_PATH ( - set "PATH=%_OLD_VIRTUAL_PATH%" -) - -set _OLD_VIRTUAL_PATH= - -set VIRTUAL_ENV= -set VIRTUAL_ENV_PROMPT= - -:END diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip.exe b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip.exe deleted file mode 100644 index 01cdf58b3adc8d405715fca33493e17abc4c3280..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106427 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%0DR4z)WQcb>Rku)_txjy8TEHVs#H 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%0DqcKFn%RX-DF>qCHtfd(>0m&Tp(1(DRhHdoti)C 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%0DS07BAj6-njF-qy0mJ8pj3rJ?3!<- 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 z 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 Date: Thu, 8 May 2025 14:06:21 +0200 Subject: [PATCH 71/80] Reworked closing Git repo after failed checkout --- .../kit/datamanager/mappingservice/util/FileUtil.java | 11 +++++++---- src/main/resources/gemma.properties | 2 +- .../impl/MappingAdministrationControllerTest.java | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java index cea557cd..65b2b477 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java @@ -294,15 +294,18 @@ private static String guessFileExtension(String filename, byte[] fewKilobytesOfF public static Path cloneGitRepository(String repositoryUrl, String branch, String targetFolder) { File target = new File(targetFolder); if (target.exists()) { + Git g = null; try { - try (Git g = Git.open(target)) { - LOGGER.trace("Repository already exists at {}. Active branch is: {}", target, g.getRepository().getBranch()); - g.getRepository().close(); - } + g = Git.open(target); + LOGGER.trace("Repository already exists at {}. Active branch is: {}", target, g.getRepository().getBranch()); } catch (IOException e) { String message = String.format("Folder '%s' already exists but contains not Git repository.", target); LOGGER.error(message, e); throw new MappingServiceException("Failed to prepare plugin. Plugin code destination already exists but is empty."); + } finally { + if (g != null) { + g.getRepository().close(); + } } } else { target.mkdirs(); diff --git a/src/main/resources/gemma.properties b/src/main/resources/gemma.properties index 0dbc8802..2588f31b 100644 --- a/src/main/resources/gemma.properties +++ b/src/main/resources/gemma.properties @@ -1,2 +1,2 @@ -version=master +version=v1.0.0 min.python=3.0.0 \ No newline at end of file diff --git a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java index 0e431b5b..611d632f 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java @@ -92,7 +92,7 @@ public class MappingAdministrationControllerTest { private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/"; private static final String MAPPING_ID = "my_dc"; - private static final String MAPPING_TYPE = "GEMMA_master"; + private static final String MAPPING_TYPE = "GEMMA_v1.0.0"; private static final String MAPPING_TITLE = "TITEL"; private static final String MAPPING_DESCRIPTION = "DESCRIPTION"; From 45d9a40ba4f9ce5910fde23510447469e4e6b9ab Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 8 May 2025 14:35:22 +0200 Subject: [PATCH 72/80] Updated tika-core to 3.1.0 --- build.gradle | 2 +- .../kit/datamanager/mappingservice/util/FileUtil.java | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index a52c7c7f..6f0060a9 100644 --- a/build.gradle +++ b/build.gradle @@ -88,7 +88,7 @@ dependencies { exclude group: "com.sun.xml.bind" } // apache - implementation "org.apache.tika:tika-core:2.9.3" + implementation "org.apache.tika:tika-core:3.1.0" testImplementation platform('org.junit:junit-bom') testImplementation 'org.junit.jupiter:junit-jupiter' diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java index 65b2b477..e29796a8 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java @@ -311,13 +311,17 @@ public static Path cloneGitRepository(String repositoryUrl, String branch, Strin target.mkdirs(); LOGGER.info("Cloning branch '{}' of repository '{}' to '{}'", branch, repositoryUrl, target.getPath()); + Git g = null; try { - try (Git res = Git.cloneRepository().setURI(repositoryUrl).setBranch(branch).setDirectory(target).call()) { - res.getRepository().close(); - } + g = Git.cloneRepository().setURI(repositoryUrl).setBranch(branch).setDirectory(target).call(); + LOGGER.trace("Repository successfully cloned to {}.", target); } catch (JGitInternalException | GitAPIException e) { LOGGER.error("Error cloning git repository '" + repositoryUrl + "' to '" + target + "'!", e); throw new MappingServiceException("Failed to prepare plugin. Plugin code destination not accessible."); + } finally { + if (g != null) { + g.getRepository().close(); + } } } return target.toPath(); From 6a8e839b5550ed676d1bc1ee4628bef068c3a2db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 03:55:07 +0000 Subject: [PATCH 73/80] Update dependency org.eclipse.jgit:org.eclipse.jgit to v7.2.1.202505142326-r --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5c6a9416..2e534b56 100644 --- a/build.gradle +++ b/build.gradle @@ -55,7 +55,7 @@ ext { } dependencies { - implementation 'org.eclipse.jgit:org.eclipse.jgit:7.2.0.202503040940-r' + implementation 'org.eclipse.jgit:org.eclipse.jgit:7.2.1.202505142326-r' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' implementation "org.springframework.boot:spring-boot-starter-data-rest" From b982788ee12aff47b8fbc6f0888100c1c2ff7f95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 06:25:02 +0000 Subject: [PATCH 74/80] Update dependency org.springframework.boot:spring-boot-starter-actuator to v3.4.5 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bc1012cd..339c86a9 100644 --- a/build.gradle +++ b/build.gradle @@ -65,7 +65,7 @@ dependencies { // monitoring implementation 'io.micronaut.micrometer:micronaut-micrometer-registry-prometheus:5.8.0' - implementation 'org.springframework.boot:spring-boot-starter-actuator:3.3.4' + implementation 'org.springframework.boot:spring-boot-starter-actuator:3.4.5' // springdoc implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springDocVersion}" From 2c3f7d8ba2b1f2870b39b3d77d981c8eb393286a Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 15 May 2025 22:28:32 +0200 Subject: [PATCH 75/80] Started working on separate release of plugin-core jar --- README.md | 11 -- build.gradle | 37 +++-- gradle/profile-deploy.gradle | 132 ++++++++++++++++++ .../mappingservice/impl/JobManager.java | 2 +- .../mappingservice/util/ShellRunnerUtil.java | 2 - .../python/util/PythonUtilsTest.java | 2 +- 6 files changed, 163 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 5e55d8a0..b2106c5c 100644 --- a/README.md +++ b/README.md @@ -48,17 +48,6 @@ and modify it according to your needs. Espacially the following properties (at t | mapping-service.packagesToScan | Packages scanned for mapping plugins in addition to plugins located in mapping-service.pluginLocation. Typically, this property has not the be changed. | edu.kit.datamanager.mappingservice.plugins.impl | | mapping-service.executionTimeout | The timeout in seconds a plugin process, i.e., Python of Shell, may take before it is assumed to be stale. | 30 | -## Creating Mapping Plugins - -There are some sample plugins available at 'edu.kit.datamanager.mappingservice.plugins.impl'. You may add your plugins to the same package and they will be available -for your mapping-service instance (as long as you kept 'mapping-service.packagesToScan' unchanged). - -Optionally, you may also develop plugins in an own repository. -However, in order to do so you'll have to build the mapping-service once and you should provide 'build/libs/mapping-service--plain.jar' at -as build time dependency to have the mapping plugin interface available. After building and packaging your plugin, you can copy the resulting jar file -to 'mapping-service.pluginLocation' to make the plugin available in your mapping-service instance. - - ## Starting the Mapping-Service The executable jar of the mapping-service is located at 'build/libs/mapping-service-.jar' You should copy it to some dedicated folder, diff --git a/build.gradle b/build.gradle index bc1012cd..c8aac131 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,10 @@ plugins { id 'java' id 'application' id 'jacoco' + // plugins for release and publishing to maven repo + id "signing" + id "io.github.gradle-nexus.publish-plugin" version "2.0.0" + id 'maven-publish' } description = 'Generic mapping service supporting different mapping implementations.' @@ -164,14 +168,19 @@ bootJar { manifest { attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher' } - exclude '**/plugins/impl/**' + //exclude '**/plugins/impl/**' - from('build/libs/default-plugins-1.1.2-SNAPSHOT.jar') { - into('BOOT-INF/lib/plugins' ) - } + // from('build/libs/default-plugins-1.1.2-SNAPSHOT.jar') { + // into('BOOT-INF/lib/plugins' ) + // } launchScript() } +if (project.hasProperty('release')) { + println 'Using \'release\' profile for building ' + project.getName() + apply from: 'gradle/profile-deploy.gradle' +} + springBoot { buildInfo() } @@ -185,11 +194,23 @@ release { tagTemplate = 'v${version}' } +tasks.named("jar") { + enabled = false +} + task buildPluginJar(type: Jar) { - description = 'Bundeling only plugin classes' - archiveFileName.set("default-plugins-${version}.jar") - from sourceSets.main.output - include '**/plugins/impl/*.class' + description = 'Bundeling plugin core classes' + archiveFileName.set("plugin-core-${version}.jar") + from sourceSets.main.output + include '**/configuration/ApplicationProperties.class', + '**/exception.BadExitCodeException.class', + '**/plugins/AbstractPythonMappingPlugin.class', + '**/plugins/IMappingPlugin.class', + '**/plugins/MappingPluginException.class', + '**/plugins/MappingPluginState.class', + '**/util/PythonRunnerUtil.class', + '**/util/ShellRunnerUtil.class' + includeEmptyDirs false } // task for printing project name. diff --git a/gradle/profile-deploy.gradle b/gradle/profile-deploy.gradle index d94f2fe8..5023f938 100644 --- a/gradle/profile-deploy.gradle +++ b/gradle/profile-deploy.gradle @@ -14,6 +14,44 @@ * limitations under the License. */ + +// Main jar with only selected classes +task selectedClassesJar(type: Jar) { + archiveClassifier = '' + from sourceSets.main.output + include '**/configuration/ApplicationProperties.class', + '**/exception.BadExitCodeException.class', + '**/plugins/AbstractPythonMappingPlugin.class', + '**/plugins/IMappingPlugin.class', + '**/plugins/MappingPluginException.class', + '**/plugins/MappingPluginState.class', + '**/util/PythonRunnerUtil.class', + '**/util/ShellRunnerUtil.class' +} + +// Sources jar +task sourcesJar(type: Jar) { + archiveClassifier = 'sources' + from sourceSets.main.allSource +} + +// Javadoc jar +task javadocJar(type: Jar) { + archiveClassifier = 'javadoc' + from javadoc +} + +//////////////////////////////////////////////////////////////////////////////// +//for java plugin +//see https://docs.gradle.org/current/userguide/java_plugin.html +//////////////////////////////////////////////////////////////////////////////// +java { + //package JavaDoc as part of publication + withJavadocJar() + //package Sources as part of publication + withSourcesJar() +} + //////////////////////////////////////////////////////////////////////////////// //for plugin net.researchgate.release //see https://github.com/researchgate/gradle-release @@ -25,4 +63,98 @@ release { versionPropertyFile = 'gradle.properties' //set possible properties which may contain the version versionProperties = ['version', 'mainversion'] + git { + //branch from where to release (default: main) + requireBranch.set('main') + } +} + +//////////////////////////////////////////////////////////////////////////////// +//for javadoc task +//see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html +//////////////////////////////////////////////////////////////////////////////// +javadoc { + if(JavaVersion.current().isJava9Compatible()) { + options.addBooleanOption('html5', true) + } +} + +//////////////////////////////////////////////////////////////////////////////// +//for plugin io.github.gradle-nexus.publish-plugin +//see https://github.com/gradle-nexus/publish-plugin +//////////////////////////////////////////////////////////////////////////////// +nexusPublishing { + repositories { + sonatype() + } +} +//////////////////////////////////////////////////////////////////////////////// +//for plugin maven-publish/io.github.gradle-nexus.publish-plugin +//see https://docs.gradle.org/current/userguide/publishing_maven.html +//////////////////////////////////////////////////////////////////////////////// +publishing { + publications { + //define publication identity, e.g. maven, which will be used + //by the signing plugin, e.g. sign publishing.publications.maven + mavenJava(MavenPublication) { + artifact selectedClassesJar + artifact sourcesJar + artifact javadocJar + + groupId = "edu.kit.datamanager" + artifactId = "mapping-plugin-core" + version = project.version + + pom { + name = project['name'] + description = project['description'] + url = 'http://datamanager.kit.edu' + licenses { + license { + name = 'The Apache License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = 'Jejkal' + name = 'Thomas Jejkal' + email = 'webmaster@datamanager.kit.edu' + } + } + scm { + connection = 'scm:git:github.com/kit-data-manager/service-base' + developerConnection = 'scm:git:github.com/kit-data-manager/service-base' + url = 'https://github.com/kit-data-manager/service-base' + } + } + } + } +} +//////////////////////////////////////////////////////////////////////////////// +//for plugin signing +//see https://docs.gradle.org/current/userguide/signing_plugin.html +//////////////////////////////////////////////////////////////////////////////// +signing { + //make signing required unless for SNAPSHOT releases or if signing is explicitly skipped + required { !project.version.endsWith("-SNAPSHOT") && !project.hasProperty("skipSigning") } + + //look for property 'signingKey' + if (project.findProperty("signingKey")) { + //If required, read a sub-key specified by its ID in property signingKeyId + //def signingKeyId = findProperty("signingKeyId") + //read property 'signingKey' + def signingKey = findProperty("signingKey") + //read property 'signingPassword' + def signingPassword = findProperty("signingPassword") + //Select to use in-memory ascii-armored keys + useInMemoryPgpKeys(signingKey, signingPassword) + //Only if also using signingKeyId + //useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) + + //Apply signing to publication identity 'publishing.publications.maven' + sign publishing.publications.maven + }else { + println 'WARNING: No property \'signingKey\' found. Artifact signing will be skipped.' + } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/impl/JobManager.java b/src/main/java/edu/kit/datamanager/mappingservice/impl/JobManager.java index 8a058472..7abdcba6 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/impl/JobManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/impl/JobManager.java @@ -62,7 +62,7 @@ public CompletableFuture getJob(String jobId) { * Remove the job with the provided id. Keep in mind, that removing the job * from the JobManager won't remove job outputs. * - * @param The job's id. + * @param jobId The job's id. */ public void removeJob(String jobId) { mapOfJobs.remove(jobId); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java index d00a58ae..45303408 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java @@ -22,10 +22,8 @@ import org.slf4j.LoggerFactory; import java.io.*; -import java.util.List; import java.util.Scanner; import java.util.concurrent.*; -import java.util.stream.Collectors; /** * Utility class for running shell scripts. diff --git a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java index 245f51b5..1a7bd6ce 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java @@ -125,7 +125,7 @@ public void testRun_3args_withNoOutputStreams() { PythonRunnerUtil.runPythonScript(scriptLocation, null, null, arguments); fail("Expected MappingPluginException"); } catch (MappingPluginException e) { - assertEquals(MappingPluginState.StateEnum.UNKNOWN_ERROR, e.getMappingPluginState().getState()); + assertEquals(MappingPluginState.StateEnum.INVALID_INPUT, e.getMappingPluginState().getState()); } } } From 8987d9290e1055d3d29594f26b22d2504289f4ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 14:03:12 +0000 Subject: [PATCH 76/80] Update dependency org.json:json to v20250517 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c8aac131..0a154059 100644 --- a/build.gradle +++ b/build.gradle @@ -85,7 +85,7 @@ dependencies { implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.commons:commons-collections4:4.5.0' implementation 'org.apache.maven:maven-artifact:3.9.9' - implementation 'org.json:json:20250107' + implementation 'org.json:json:20250517' implementation 'com.github.jknack:handlebars:4.4.0' implementation 'com.google.guava:guava:33.4.8-jre' implementation 'commons-io:commons-io:2.19.0' From a864642d5b96917bdbf4f8d4104d67828e4ddb7e Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Mon, 19 May 2025 14:37:40 +0200 Subject: [PATCH 77/80] Creating only mapping-plugin-core if release is called, testing of signing and publishing still to do --- build.gradle | 36 ++++++++++++++++++------------------ gradle/profile-deploy.gradle | 27 ++++++++++++++++++++------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/build.gradle b/build.gradle index c8aac131..80e28f89 100644 --- a/build.gradle +++ b/build.gradle @@ -158,7 +158,7 @@ asciidoctor { bootJar { dependsOn asciidoctor - dependsOn 'buildPluginJar' + //dependsOn 'buildPluginJar' from ("${asciidoctor.outputDir}/html5") { into 'static/docs' @@ -195,23 +195,23 @@ release { } tasks.named("jar") { - enabled = false -} - -task buildPluginJar(type: Jar) { - description = 'Bundeling plugin core classes' - archiveFileName.set("plugin-core-${version}.jar") - from sourceSets.main.output - include '**/configuration/ApplicationProperties.class', - '**/exception.BadExitCodeException.class', - '**/plugins/AbstractPythonMappingPlugin.class', - '**/plugins/IMappingPlugin.class', - '**/plugins/MappingPluginException.class', - '**/plugins/MappingPluginState.class', - '**/util/PythonRunnerUtil.class', - '**/util/ShellRunnerUtil.class' - includeEmptyDirs false -} + enabled = false +} + +//task buildPluginJar(type: Jar) { +// description = 'Bundeling plugin core classes' +// archiveFileName.set("plugin-core-${version}.jar") +// from sourceSets.main.output +// include '**/configuration/ApplicationProperties.class', +// '**/exception.BadExitCodeException.class', +// '**/plugins/AbstractPythonMappingPlugin.class', +// '**/plugins/IMappingPlugin.class', +// '**/plugins/MappingPluginException.class', +// '**/plugins/MappingPluginState.class', +// '**/util/PythonRunnerUtil.class', +// '**/util/ShellRunnerUtil.class' +// includeEmptyDirs false +//} // task for printing project name. // should be the last task inside file diff --git a/gradle/profile-deploy.gradle b/gradle/profile-deploy.gradle index 5023f938..05ae8e89 100644 --- a/gradle/profile-deploy.gradle +++ b/gradle/profile-deploy.gradle @@ -17,6 +17,7 @@ // Main jar with only selected classes task selectedClassesJar(type: Jar) { + archiveBaseName = 'mapping-plugin-core' archiveClassifier = '' from sourceSets.main.output include '**/configuration/ApplicationProperties.class', @@ -27,16 +28,28 @@ task selectedClassesJar(type: Jar) { '**/plugins/MappingPluginState.class', '**/util/PythonRunnerUtil.class', '**/util/ShellRunnerUtil.class' + includeEmptyDirs false } -// Sources jar -task sourcesJar(type: Jar) { +// Sources jar with only selected classes +task selectedSourcesJar(type: Jar) { + archiveBaseName = 'mapping-plugin-core' archiveClassifier = 'sources' from sourceSets.main.allSource + include '**/configuration/ApplicationProperties.java', + '**/exception.BadExitCodeException.java', + '**/plugins/AbstractPythonMappingPlugin.java', + '**/plugins/IMappingPlugin.java', + '**/plugins/MappingPluginException.java', + '**/plugins/MappingPluginState.java', + '**/util/PythonRunnerUtil.java', + '**/util/ShellRunnerUtil.java' + includeEmptyDirs false } // Javadoc jar task javadocJar(type: Jar) { + archiveBaseName = 'mapping-plugin-core' archiveClassifier = 'javadoc' from javadoc } @@ -45,12 +58,12 @@ task javadocJar(type: Jar) { //for java plugin //see https://docs.gradle.org/current/userguide/java_plugin.html //////////////////////////////////////////////////////////////////////////////// -java { +//java { //package JavaDoc as part of publication - withJavadocJar() +// withJavadocJar() //package Sources as part of publication - withSourcesJar() -} +// withSourcesJar() +//} //////////////////////////////////////////////////////////////////////////////// //for plugin net.researchgate.release @@ -98,7 +111,7 @@ publishing { //by the signing plugin, e.g. sign publishing.publications.maven mavenJava(MavenPublication) { artifact selectedClassesJar - artifact sourcesJar + artifact selectedSourcesJar artifact javadocJar groupId = "edu.kit.datamanager" From cdda2e261b54be5b5040d36b86fd95ce0dae1e48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 20:53:10 +0000 Subject: [PATCH 78/80] Update dependency io.micronaut.micrometer:micronaut-micrometer-registry-prometheus to v5.10.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 80e28f89..89e5c16a 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' // monitoring - implementation 'io.micronaut.micrometer:micronaut-micrometer-registry-prometheus:5.8.0' + implementation 'io.micronaut.micrometer:micronaut-micrometer-registry-prometheus:5.10.2' implementation 'org.springframework.boot:spring-boot-starter-actuator:3.3.4' // springdoc From 1626598d9650c6461a6aad74f72a9176d6ca3b86 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 20:55:25 +0000 Subject: [PATCH 79/80] Update dependency gradle to v8.14.1 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ca025c83..002b867c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 85d4e3dea381ac0d9215ec3fe4b618642b79c766 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Sun, 25 May 2025 21:15:02 +0200 Subject: [PATCH 80/80] Finished plugin-core publication, added new CI workflow for publishing plugin-core, started documenting plugin development, cleaned up build target definitions and naming --- .github/dependabot.yml | 13 -- .github/issue-branch.yml | 19 --- .github/workflows/CI.yml | 9 +- .github/workflows/publish-plugin-core.yml | 22 ++++ README.md | 22 +++- build.gradle | 62 ++++----- ...complete.gradle => profile-default.gradle} | 0 gradle/profile-deploy.gradle | 124 +++++++++++------- gradle/profile-minimal.gradle | 8 +- settings/application-default.properties | 2 + settings/application-docker.properties | 2 + .../plugins/IMappingPlugin.java | 5 +- .../mappingservice/plugins/README.md | 97 ++++++++++++++ .../rest/PluginInformation.java | 4 +- 14 files changed, 248 insertions(+), 141 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/issue-branch.yml create mode 100644 .github/workflows/publish-plugin-core.yml rename gradle/{profile-complete.gradle => profile-default.gradle} (100%) create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/plugins/README.md diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index d2339b41..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,13 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "gradle" # See documentation for possible values - directory: "/" # Location of package manifests - target-branch: "development" - schedule: - interval: "weekly" - open-pull-requests-limit: 0 diff --git a/.github/issue-branch.yml b/.github/issue-branch.yml deleted file mode 100644 index 7309f19d..00000000 --- a/.github/issue-branch.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Automatically close issue after a pull request merge -autoCloseIssue: true - -# Override the source branch -defaultBranch: 'development' - -#Skip branch creation based on issue label 'question' -branches: - - label: question - skip: true - -# Automatically open a Pull Request -openPR: true - -# Copy attributes from issue -copyIssueDescriptionToPR: true -copyIssueLabelsToPR: true -copyIssueAssigneeToPR: true -copyIssueMilestoneToPR: true diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6e9a3d9a..8143cc99 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,7 +18,7 @@ jobs: matrix: # os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest] - jdk: [17] + jdk: [17, 21] runs-on: ${{ matrix.os }} steps: - name: Checkout repo @@ -42,15 +42,8 @@ jobs: run: mkdir -p /tmp/mapping-service/{schemas} - name: Clean run: ./gradlew clean -# - if: matrix.os == 'windows-latest' -# name: Test with Gradle on Windows -# run: ./gradlew build -DapplicationProperties="src\test\resources\test-config\application-test-windows.properties" - if: matrix.os != 'windows-latest' name: Test with Gradle on ${{ matrix.os }} run: ./gradlew build -DapplicationProperties="src/test/resources/test-config/application-test.properties" - name: Generate report run: ./gradlew jacocoTestReport -# - name: Codecov -# uses: codecov/codecov-action@v1 -# with: -# files: ./build/reports/jacoco/test/jacocoTestReport.xml diff --git a/.github/workflows/publish-plugin-core.yml b/.github/workflows/publish-plugin-core.yml new file mode 100644 index 00000000..6aba3caf --- /dev/null +++ b/.github/workflows/publish-plugin-core.yml @@ -0,0 +1,22 @@ +name: Publish mapping-plugin-core to the Maven Central Repository +on: + release: + types: [published] +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4.7.0 + with: + java-version: 17 + distribution: 'zulu' # openjdk + - name: Publish package + run: ./gradlew -Prelease publishToSonatype closeAndReleaseSonatypeStagingRepository + env: + ORG_GRADLE_PROJECT_sonatypeUsername : ${{ secrets.OSSRH_USERNAME }} + ORG_GRADLE_PROJECT_sonatypePassword : ${{ secrets.OSSRH_PASSWORD }} + ORG_GRADLE_PROJECT_signingKey : ${{ secrets.SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingPassword : ${{ secrets.SIGNING_SECRET }} + diff --git a/README.md b/README.md index b2106c5c..e36a07f5 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,24 @@ Dependencies that are needed to build and are not being downloaded via gradle: `./gradlew build` +The build can be further customized via different build profiles. Available profiles are: + +* default - Default build including tests. Used by default. +* minimal - Minimal build without tests for fast local builds +* deploy - Full build including tests, packaging of mapping-plugin-core, and + deployment to maven-central. This build profile is supposed to be + used inside a CI environment, as it requires further configuration, + i.e., credentials for deployment. + +The different build profiles can be activated via: + +`./gradlew build -PbuildProfile=minimal` + ### Python Location -The mapping-service supports plugins running Python code. To provide basic testing for this feature, some tests require configured Python in order to be executed. +The mapping-service supports plugins running Python code. To provide basic testing for this feature, some tests require configured Python in order to be executable. While at runtime, the Python executable is configured in application.properties, at build time the Python location may differ depending on the build environment. -By default, '/usr/bin/python' is assumed as Python location. If you are using a different Python installation, e.g., under Windows or MacOS, you may either modify +By default, '/usr/bin/python3' is assumed as Python location. If you are using a different Python installation, e.g., under Windows or MacOS, you may either modify 'build.gradle' (look out for pythonExecutable) or you provide the Python executable as command line argument, e.g., ``` @@ -43,10 +56,15 @@ and modify it according to your needs. Espacially the following properties (at t | spring.datasource.url | The path points to the location of the database in which your configured mappings are stored. For production use it is not recommended to use the pre-configured H2 database! | jdbc:h2:file:/tmp/mapping-service/database | | mapping-service.pythonExecutable | The path to your local Python executable. The default uses the pythonExecutable system property provided via -DpythonExecutable= or file:///usr/bin/python3 if no such system property is provided. | ${pythonExecutable:'file:///usr/bin/python3'} | | mapping-service.pluginLocation | The local folder from where plugins are loaded. The folder will be created on startup if it does not exist. | None | +| mapping-service.codeLocation | The local folder where plugins can checkout code from GitHub. For Python-based plugins, also the virtual env is created in this folder. The folder will be created on startup if it does not exist. | None | | mapping-service.mappingSchemasLocation | The local folder where the mapping files are stored. The folder will be created on startup if it does not exist. | None | | mapping-service.jobOutput | The local folder where asynchronous mapping execution job outputs are stored. The folder will be created on startup if it does not exist. | None | | mapping-service.packagesToScan | Packages scanned for mapping plugins in addition to plugins located in mapping-service.pluginLocation. Typically, this property has not the be changed. | edu.kit.datamanager.mappingservice.plugins.impl | | mapping-service.executionTimeout | The timeout in seconds a plugin process, i.e., Python of Shell, may take before it is assumed to be stale. | 30 | +| mapping-service.authEnabled | Defines if authentication is enabled or not. If enabled, additional keycloak configuration is required. | false | +| mapping-service.mappingAdminRole | Defines the user role which must be present to be able to administrate the mapping service, i.e., add or remove mappings. | MAPPING_ADMIN | +| management.metrics.export.prometheus.enabled | Enables or disabled capturing of prometheus metrics. | true | +| management.endpoint.metrics.enabled | Enables or disabled the metrics actuator endpoint. This is only needed, if metrics are captured at all. | true | ## Starting the Mapping-Service diff --git a/build.gradle b/build.gradle index 80e28f89..d705748c 100644 --- a/build.gradle +++ b/build.gradle @@ -34,12 +34,17 @@ configurations { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 -if (System.getProperty('profile') == 'minimal') { - println 'Using minimal profile for building ' + project.getName() +def buildPofile = project.findProperty("buildProfile") ?: "complete" + +if (buildPofile == "minimal") { + println 'Using minimal profile (no tests) for building ' + project.getName() apply from: 'gradle/profile-minimal.gradle' -} else { - println 'Using default profile executing all tests for building ' + project.getName() - apply from: 'gradle/profile-complete.gradle' +} else if (buildPofile == "deploy") { + println 'Using release profile for building ' + project.getName() + apply from: 'gradle/profile-deploy.gradle' +}else { + println 'Using default profile (all tests) for building ' + project.getName() + apply from: 'gradle/profile-default.gradle' } repositories { @@ -122,10 +127,12 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor:3.0.3' } +//customization of java compile task tasks.withType(JavaCompile) { options.compilerArgs += ['-Xlint:unchecked'] } +//test configuration test { outputs.dir snippetsDir finalizedBy jacocoTestReport @@ -138,24 +145,19 @@ test { testLogging.showStandardStreams = true } +//jacoco configuration jacoco { toolVersion = "0.8.13" } -jacocoTestReport{ - dependsOn test - reports { - xml.required = true - html.required = true - } -} - +//asciidoctor configuration, i.e., snippet dir asciidoctor { inputs.dir snippetsDir configurations 'asciidoctorExt' dependsOn test } +//generation task of boot jar bootJar { dependsOn asciidoctor //dependsOn 'buildPluginJar' @@ -168,50 +170,36 @@ bootJar { manifest { attributes 'Main-Class': 'org.springframework.boot.loader.launch.PropertiesLauncher' } - //exclude '**/plugins/impl/**' - - // from('build/libs/default-plugins-1.1.2-SNAPSHOT.jar') { - // into('BOOT-INF/lib/plugins' ) - // } launchScript() } -if (project.hasProperty('release')) { - println 'Using \'release\' profile for building ' + project.getName() - apply from: 'gradle/profile-deploy.gradle' -} - +//add build info into manifest springBoot { buildInfo() } +//properties made available for bootRun task execution bootRun { systemProperty "spring.config.location", "file:$projectDir/" systemProperty "pythonLocation", pythonExecutable } +//define how a new version is tagged and where version information may come from release { tagTemplate = 'v${version}' + versionPropertyFile = 'gradle.properties' + versionProperties = ['version', 'mainversion'] } +//Do not generate entire project jar tasks.named("jar") { enabled = false } -//task buildPluginJar(type: Jar) { -// description = 'Bundeling plugin core classes' -// archiveFileName.set("plugin-core-${version}.jar") -// from sourceSets.main.output -// include '**/configuration/ApplicationProperties.class', -// '**/exception.BadExitCodeException.class', -// '**/plugins/AbstractPythonMappingPlugin.class', -// '**/plugins/IMappingPlugin.class', -// '**/plugins/MappingPluginException.class', -// '**/plugins/MappingPluginState.class', -// '**/util/PythonRunnerUtil.class', -// '**/util/ShellRunnerUtil.class' -// includeEmptyDirs false -//} +// Disable generation of Gradle module metadata (.module file) +tasks.withType(GenerateModuleMetadata).configureEach { + enabled = false +} // task for printing project name. // should be the last task inside file diff --git a/gradle/profile-complete.gradle b/gradle/profile-default.gradle similarity index 100% rename from gradle/profile-complete.gradle rename to gradle/profile-default.gradle diff --git a/gradle/profile-deploy.gradle b/gradle/profile-deploy.gradle index 05ae8e89..27046cc5 100644 --- a/gradle/profile-deploy.gradle +++ b/gradle/profile-deploy.gradle @@ -14,39 +14,54 @@ * limitations under the License. */ - -// Main jar with only selected classes -task selectedClassesJar(type: Jar) { +// Classes jar for plugin-core +task pluginCoreClassesJar(type: Jar) { archiveBaseName = 'mapping-plugin-core' archiveClassifier = '' from sourceSets.main.output include '**/configuration/ApplicationProperties.class', - '**/exception.BadExitCodeException.class', + '**/exception/BadExitCodeException.class', + '**/exception/PluginInitializationFailedException.class', + '**/exception/MappingPluginException.class', + '**/exception/MappingException.class', + '**/exception/MappingServiceException.class', '**/plugins/AbstractPythonMappingPlugin.class', '**/plugins/IMappingPlugin.class', '**/plugins/MappingPluginException.class', '**/plugins/MappingPluginState.class', + '**/plugins/MappingPluginState$StateEnum.class', + '**/util/FileUtil.class', '**/util/PythonRunnerUtil.class', '**/util/ShellRunnerUtil.class' includeEmptyDirs false } -// Sources jar with only selected classes -task selectedSourcesJar(type: Jar) { +// Sources jar for plugin-core +task pluginCoreSourcesJar(type: Jar) { archiveBaseName = 'mapping-plugin-core' archiveClassifier = 'sources' from sourceSets.main.allSource include '**/configuration/ApplicationProperties.java', - '**/exception.BadExitCodeException.java', + '**/exception/BadExitCodeException.java', + '**/exception/PluginInitializationFailedException.java', + '**/exception/MappingPluginException.java', + '**/exception/MappingException.java', + '**/exception/MappingServiceException.java', '**/plugins/AbstractPythonMappingPlugin.java', '**/plugins/IMappingPlugin.java', '**/plugins/MappingPluginException.java', - '**/plugins/MappingPluginState.java', + '**/plugins/MappingPluginState.java', + '**/plugins/MappingPluginState$StateEnum.java', + '**/util/FileUtil.java', '**/util/PythonRunnerUtil.java', '**/util/ShellRunnerUtil.java' includeEmptyDirs false } +javadoc { + failOnError = false +} + // Javadoc jar task javadocJar(type: Jar) { archiveBaseName = 'mapping-plugin-core' @@ -54,17 +69,6 @@ task javadocJar(type: Jar) { from javadoc } -//////////////////////////////////////////////////////////////////////////////// -//for java plugin -//see https://docs.gradle.org/current/userguide/java_plugin.html -//////////////////////////////////////////////////////////////////////////////// -//java { - //package JavaDoc as part of publication -// withJavadocJar() - //package Sources as part of publication -// withSourcesJar() -//} - //////////////////////////////////////////////////////////////////////////////// //for plugin net.researchgate.release //see https://github.com/researchgate/gradle-release @@ -97,8 +101,13 @@ javadoc { //see https://github.com/gradle-nexus/publish-plugin //////////////////////////////////////////////////////////////////////////////// nexusPublishing { - repositories { - sonatype() + repositories { + sonatype{ + //Only needed for deploying snapshots. + //Otherwise, username and password are configured in the CI pipeline. + username = findProperty("sonatypeToken") + password = findProperty("sonatypeTokenPassword") + } } } //////////////////////////////////////////////////////////////////////////////// @@ -108,20 +117,29 @@ nexusPublishing { publishing { publications { //define publication identity, e.g. maven, which will be used - //by the signing plugin, e.g. sign publishing.publications.maven + //by the signing plugin, e.g. sign publishing.publications.mavenJava mavenJava(MavenPublication) { - artifact selectedClassesJar - artifact selectedSourcesJar + //include custom artifacts + artifact pluginCoreClassesJar + artifact pluginCoreSourcesJar artifact javadocJar - - groupId = "edu.kit.datamanager" - artifactId = "mapping-plugin-core" + + //defined base properties for pom + groupId = 'edu.kit.datamanager' + artifactId = 'mapping-plugin-core' version = project.version + pom { - name = project['name'] - description = project['description'] + name = artifactId + description = 'Core classes for mapping service plugins.' url = 'http://datamanager.kit.edu' + + //add packaging property + withXml { + asNode().appendNode('packaging', 'jar') + } + //add misc information licenses { license { name = 'The Apache License, Version 2.0' @@ -136,38 +154,44 @@ publishing { } } scm { - connection = 'scm:git:github.com/kit-data-manager/service-base' - developerConnection = 'scm:git:github.com/kit-data-manager/service-base' - url = 'https://github.com/kit-data-manager/service-base' + connection = 'scm:git:github.com/kit-data-manager/mapping-service' + developerConnection = 'scm:git:github.com/kit-data-manager/mapping-service' + url = 'https://github.com/kit-data-manager/mapping-service' } } } } } + //////////////////////////////////////////////////////////////////////////////// //for plugin signing //see https://docs.gradle.org/current/userguide/signing_plugin.html //////////////////////////////////////////////////////////////////////////////// signing { //make signing required unless for SNAPSHOT releases or if signing is explicitly skipped - required { !project.version.endsWith("-SNAPSHOT") && !project.hasProperty("skipSigning") } - - //look for property 'signingKey' - if (project.findProperty("signingKey")) { - //If required, read a sub-key specified by its ID in property signingKeyId - //def signingKeyId = findProperty("signingKeyId") - //read property 'signingKey' - def signingKey = findProperty("signingKey") - //read property 'signingPassword' - def signingPassword = findProperty("signingPassword") - //Select to use in-memory ascii-armored keys - useInMemoryPgpKeys(signingKey, signingPassword) - //Only if also using signingKeyId - //useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) + def currentVersion = project.version?.toString() ?: "" + def shouldSign = !currentVersion.endsWith("-SNAPSHOT") && !project.hasProperty("skipSigning") - //Apply signing to publication identity 'publishing.publications.maven' - sign publishing.publications.maven - }else { - println 'WARNING: No property \'signingKey\' found. Artifact signing will be skipped.' + required { shouldSign } + + if(shouldSign){ + //look for property 'signingKey' + if (project.findProperty("signingKey")) { + //If required, read a sub-key specified by its ID in property signingKeyId + //def signingKeyId = findProperty("signingKeyId") + //read property 'signingKey' + def signingKey = findProperty("signingKey") + //read property 'signingPassword' + def signingPassword = findProperty("signingPassword") + //Select to use in-memory ascii-armored keys + useInMemoryPgpKeys(signingKey, signingPassword) + //Only if also using signingKeyId + //useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) + + //Apply signing to publication identity 'publishing.publications.maven' + sign publishing.publications.mavenJava + }else { + println 'WARNING: No property \'signingKey\' found. Artifact signing will be skipped.' + } } } diff --git a/gradle/profile-minimal.gradle b/gradle/profile-minimal.gradle index ccaafaef..fa1e51be 100644 --- a/gradle/profile-minimal.gradle +++ b/gradle/profile-minimal.gradle @@ -1,9 +1,3 @@ test { exclude '**/*' -} - -release { - tagTemplate = 'v${version}' - versionPropertyFile = 'gradle.properties' - versionProperties = ['version', 'mainversion'] -} +} \ No newline at end of file diff --git a/settings/application-default.properties b/settings/application-default.properties index 921214cf..f2e50efb 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -58,6 +58,8 @@ spring.jpa.hibernate.ddl-auto=update mapping-service.pythonExecutable=file:///usr/bin/python3 # Absolute path to the folder where all plugins are located. mapping-service.pluginLocation=file://INSTALLATION_DIR/plugins +# Absolute path to the folder where all plugin code is checked out into. +mapping-service.codeLocation=file://INSTALLATION_DIR/code # Absolute path to the local gemma mappings folder. mapping-service.mappingSchemasLocation=file://INSTALLATION_DIR/mappingSchemas # Folder where job output files for async mapping executions are stored diff --git a/settings/application-docker.properties b/settings/application-docker.properties index 73ca39fa..90aaeed9 100644 --- a/settings/application-docker.properties +++ b/settings/application-docker.properties @@ -45,6 +45,8 @@ eureka.client.enabled: false mapping-service.pythonExecutable=file:///usr/bin/python3 # Absolute path to the folder where all plugins are located. mapping-service.pluginLocation=file://INSTALLATION_DIR/plugins +# Absolute path to the folder where all plugin code is checked out into. +mapping-service.codeLocation=file://INSTALLATION_DIR/code # Absolute path to the local gemma mappings folder. mapping-service.mappingSchemasLocation=file://INSTALLATION_DIR/mappingSchemas # Folder where job output files for async mapping executions are stored diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java index 3110e940..80593dbf 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java @@ -15,7 +15,6 @@ package edu.kit.datamanager.mappingservice.plugins; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; -import org.springframework.util.MimeType; import java.nio.file.Path; @@ -64,14 +63,14 @@ public interface IMappingPlugin { * * @return The mime type of the input data. */ - MimeType[] inputTypes(); + String[] inputTypes(); /** * The mime type of the output data. * * @return The mime type of the output data. */ - MimeType[] outputTypes(); + String[] outputTypes(); /** * The id of the plugin which is used to identify the plugin. By default, diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/README.md b/src/main/java/edu/kit/datamanager/mappingservice/plugins/README.md new file mode 100644 index 00000000..3a6de8f6 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/README.md @@ -0,0 +1,97 @@ +# Mapping-Service - How to implement Plugins? + +While the mapping-service itself is just a management and code execution service, the actual functionality comes from deployed plugins. +A plugin implements a specific kind of mapping functionality, typically reading from one file format and mapping, e.g., contained metadata, +following a set of rules into another file format, i.e., a structure metadata format like XML or JSON. + +Currently, there are two main types of mapping plugins: + +* Java-only plugin: This plugin type is fully implemented in Java. It is called within the service runtime environment and may only need additional libraries +shipped together with the plugin. In special cases, they may even execute local binaries, but must handle availability checks and error handling on their own. +* Python-based plugins: As the name says, these plugins offer their functionality as Python implementation and serve as wrappers. +The Python code is loaded from a Git repository and they are running in a virtual environment as process monitored by the mapping-service. + +Depending on which plugin type you plan to implement, there is a slight difference where you start from. Let's begin with Java-only plugins. + +## Implement Java-only plugins + +Before you start implementing, you should setup a new Java project, e.g., using Gradle or Maven. If you are finished, add the following dependency to your project: + +Gradle: +``` + implementation 'edu.kit.datamanager:mapping-plugin-core:1.1.2' +``` + +Maven: +``` + + edu.kit.datamanager + mapping-plugin-core + 1.1.2 + +``` + +Please check that the version of 'mapping-plugin-core' matches the version of the mapping-service instance you plan to deploy the plugin for. +If there are breaking changes they will be indicated by a major version change. + +Now we can start implementing the actual plugin code. As an example, let's take the InOutPlugin shipped with the mapping-service and go through the single elements. + +```java +public class InOutPlugin implements IMappingPlugin { + + static Logger LOG = LoggerFactory.getLogger(InOutPlugin.class); + + @Override + public String name() { + return "InOutPlugin"; + } + + @Override + public String description() { + return "Simple plugin for testing just returning the input file."; + } + + @Override + public String version() { + return "1.1.2"; + } + + @Override + public String uri() { + return "https://github.com/kit-data-manager/mapping-service"; + } + + @Override + public MimeType[] inputTypes() { + return new MimeType[]{MimeType.valueOf("application/*")}; + } + + @Override + public MimeType[] outputTypes() { + return new MimeType[]{MimeType.valueOf("application/*")}; + } + + @Override + public void setup(ApplicationProperties applicationProperties) { + //nothing to do here + LOG.trace("Plugin {} {} successfully set up.", name(), version()); + } + + @Override + public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { + MappingPluginState result = MappingPluginState.SUCCESS(); + try { + Files.copy(inputFile, outputFile, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException | MappingException ex) { + LOG.error("Failed to execute plugin.", ex); + result = MappingPluginState.EXECUTION_ERROR(); + result.setDetails("Failed to copy input to output, probably due to an I/O error."); + } + return result; + } + +} +``` + +1. InOutPlugin implements IMappingPlugin - All Java-only plugins must implement IMappingPlugin, which defined the interface used by the mapping-service to interact with the plugin. +2. name(), description(), version(), uri() - These methods provide metadata and to uniquely address plugins, e.g., the plugin id will be **name()_version()** \ No newline at end of file diff --git a/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java b/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java index 9c9d635e..941e5bdc 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/rest/PluginInformation.java @@ -94,10 +94,10 @@ public PluginInformation(String id, PluginManager manager) throws MappingPluginE this.uri = p.uri(); ArrayList inputTypesList = new ArrayList<>(); Arrays.stream(p.inputTypes()).toList().forEach(mimeType -> inputTypesList.add(mimeType.toString())); - this.inputTypes = inputTypesList.toArray(new String[0]); + this.inputTypes = inputTypesList.toArray(String[]::new); ArrayList outputTypesList = new ArrayList<>(); Arrays.stream(p.outputTypes()).toList().forEach(mimeType -> outputTypesList.add(mimeType.toString())); - this.outputTypes = outputTypesList.toArray(new String[0]); + this.outputTypes = outputTypesList.toArray(String[]::new); } else { throw new MappingPluginException(MappingPluginState.NOT_FOUND(), "Plugin with id " + id + " not found."); }

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 diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pythonw.exe b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pythonw.exe deleted file mode 100644 index c1c2531d554b91055a8ec54c2e6be096d3b2160c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232688 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 BM34Xg diff --git a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java index b1a889df..607967c7 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java @@ -1,8 +1,12 @@ package edu.kit.datamanager.mappingservice; +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import edu.kit.datamanager.mappingservice.plugins.PluginLoader; import edu.kit.datamanager.mappingservice.plugins.PluginManager; import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; @@ -28,12 +32,17 @@ public ApplicationProperties applicationProperties() { return new ApplicationProperties(); } + @Bean + public PluginLoader pluginLoader() { + return new PluginLoader(applicationProperties()); + } + @Bean public PluginManager pluginManager() { - return new PluginManager(applicationProperties()); + return new PluginManager(applicationProperties(), pluginLoader()); } - public static void main(String[] args) { + public static void main(String[] args) throws IOException { ConfigurableApplicationContext ctx = SpringApplication.run(MappingServiceApplication.class, args); PluginManager mgr = ctx.getBean(PluginManager.class); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java index 6d8d4e8d..47db1c8e 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java @@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.reflect.ClassPath; +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,12 +34,23 @@ import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.ClassUtils; /** * Class for loading plugins. * * @author maximilianiKIT */ +@Component public class PluginLoader { /** @@ -46,9 +58,19 @@ public class PluginLoader { */ static Logger LOG = LoggerFactory.getLogger(PluginLoader.class); - static ClassLoader cl = null; + private ClassLoader cl = null; - public static void unload() { + private ApplicationProperties applicationProperties; + + @Autowired + private ApplicationContext applicationContext; + + @Autowired + public PluginLoader(ApplicationProperties applicationProperties) { + this.applicationProperties = applicationProperties; + } + + public void unload() { cl = null; System.gc(); } @@ -65,7 +87,7 @@ public static void unload() { * @throws MappingPluginException If there is an error with the plugin or * the input. */ - public static Map loadPlugins(File pluginDir, String[] packagesToScan) throws IOException, MappingPluginException { + public Map loadPlugins(File pluginDir, String[] packagesToScan) throws IOException, MappingPluginException { Map result = new HashMap<>(); File[] pluginJars = new File[0]; if (pluginDir == null || pluginDir.getAbsolutePath().isBlank()) { @@ -81,13 +103,13 @@ public static Map loadPlugins(File pluginDir, String[] p } if (pluginJars != null && pluginJars.length > 0) { - cl = new URLClassLoader(PluginLoader.fileArrayToURLArray(pluginJars), Thread.currentThread().getContextClassLoader()); + cl = new URLClassLoader(fileArrayToURLArray(pluginJars), Thread.currentThread().getContextClassLoader()); } else { cl = Thread.currentThread().getContextClassLoader(); } - List> plugClasses = PluginLoader.extractClassesFromJARs(pluginJars, packagesToScan, cl); - List IMappingPluginList = PluginLoader.createPluggableObjects(plugClasses); + List> plugClasses = extractClassesFromJARs(pluginJars, packagesToScan, cl); + List IMappingPluginList = createPluggableObjects(plugClasses); for (IMappingPlugin i : IMappingPluginList) { try { @@ -101,7 +123,7 @@ public static Map loadPlugins(File pluginDir, String[] p return result; } - private static URL[] fileArrayToURLArray(File[] files) throws MalformedURLException { + private URL[] fileArrayToURLArray(File[] files) throws MalformedURLException { URL[] urls = new URL[files.length]; for (int i = 0; i < files.length; i++) { urls[i] = files[i].toURI().toURL(); @@ -109,13 +131,13 @@ private static URL[] fileArrayToURLArray(File[] files) throws MalformedURLExcept return urls; } - private static List> extractClassesFromJARs(File[] jars, String[] packagesToScan, ClassLoader cl) throws IOException, MappingPluginException { + private List> extractClassesFromJARs(File[] jars, String[] packagesToScan, ClassLoader cl) throws IOException, MappingPluginException { LOG.trace("Extracting classes from plugin JARs."); List> classes = new ArrayList<>(); if (jars != null) { for (File jar : jars) { LOG.trace("Processing file {}.", jar.getAbsolutePath()); - classes.addAll(PluginLoader.extractClassesFromJAR(jar, cl)); + classes.addAll(extractClassesFromJAR(jar, cl)); } } LOG.trace("Found {} plugin classes in jar files.", classes.size()); @@ -123,9 +145,20 @@ private static List> extractClassesFromJARs(File[] jars, S if (packagesToScan != null) { LOG.trace("Extracting classes from classpath."); int pluginCnt = 0; + + findAllClasses("edu.kit.datamanager.mappingservice", cl); + for (String pkg : packagesToScan) { LOG.trace(" - Scanning package {}", pkg); - ImmutableSet clazzes = ClassPath.from(cl).getTopLevelClasses(pkg); + + List> result = findAllClasses(pkg, cl); + + for (Class res : result) { + classes.add((Class) res); + pluginCnt++; + } + + /*ImmutableSet clazzes = ClassPath.from(cl).getTopLevelClassesRecursive(pkg); for (ClassPath.ClassInfo clazz : clazzes) { try { LOG.trace(" - Processing class {}.", clazz.getName()); @@ -138,7 +171,7 @@ private static List> extractClassesFromJARs(File[] jars, S } catch (ClassCastException ex) { //failed to load, probably no implementation of IMappingPlugin } - } + }*/ } LOG.trace("Found {} plugin classes in classpath.", pluginCnt); } @@ -146,7 +179,7 @@ private static List> extractClassesFromJARs(File[] jars, S return classes; } - private static List> extractClassesFromJAR(File jar, ClassLoader cl) throws IOException, MappingPluginException { + private List> extractClassesFromJAR(File jar, ClassLoader cl) throws IOException, MappingPluginException { LOG.trace("Extracting plugin classes from file {}.", jar.getAbsolutePath()); List> classes = new ArrayList<>(); try (JarInputStream jaris = new JarInputStream(new FileInputStream(jar))) { @@ -156,7 +189,7 @@ private static List> extractClassesFromJAR(File jar, Class try { Class cls = cl.loadClass(ent.getName().substring(0, ent.getName().length() - 6).replace('/', '.')); LOG.trace("Checking {}.", cls); - if (PluginLoader.isPluggableClass(cls)) { + if (isPluggableClass(cls)) { LOG.trace("Plugin class found."); classes.add((Class) cls); } @@ -170,22 +203,12 @@ private static List> extractClassesFromJAR(File jar, Class return classes; } - private static boolean isPluggableClass(Class cls) { - /*for (Class i : cls.getInterfaces()) { - LOG.trace("Checking {} against {}.", i, IMappingPlugin.class); - LOG.trace("ASSIGN {}", IMappingPlugin.class.isAssignableFrom(cls)); - if (i.equals(IMappingPlugin.class)) { - LOG.trace("IMappingPlugin interface found."); - return true; - } - } - return false;*/ - + private boolean isPluggableClass(Class cls) { //this should be much easier and faster - return IMappingPlugin.class.isAssignableFrom(cls); + return IMappingPlugin.class.isAssignableFrom(cls) && !cls.isInterface(); } - private static List createPluggableObjects(List> pluggable) throws MappingPluginException { + private List createPluggableObjects(List> pluggable) throws MappingPluginException { LOG.trace("Instantiating plugins from list: {}", pluggable); List plugs = new ArrayList<>(pluggable.size()); for (Class plug : pluggable) { @@ -202,4 +225,48 @@ private static List createPluggableObjects(List> findAllClasses(String packageName, ClassLoader loader) { + List> result = new ArrayList<>(); + MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory( + loader); + try { + Resource[] resources = scan(loader, packageName); + for (Resource resource : resources) { + Class clazz = loadClass(loader, metadataReaderFactory, resource); + if (clazz != null && isPluggableClass(clazz)) { + //System.out.println("CLASS " + clazz); + result.add(clazz); + } + } + } catch (IOException ex) { + //throw new IllegalStateException(ex); + return result; + } + return result; + } + + private Resource[] scan(ClassLoader loader, String packageName) throws IOException { + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver( + loader); + String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + + ClassUtils.convertClassNameToResourcePath(packageName) + "/**/*.class"; + Resource[] resources = resolver.getResources(pattern); + return resources; + } + + private Class loadClass(ClassLoader loader, MetadataReaderFactory readerFactory, + Resource resource) { + try { + MetadataReader reader = readerFactory.getMetadataReader(resource); + return ClassUtils.forName(reader.getClassMetadata().getClassName(), loader); + } catch (ClassNotFoundException ex) { + return null; + } catch (LinkageError ex) { + return null; + } catch (Throwable ex) { + + return null; + } + } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java index 4c7ee256..4632a4d9 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginManager.java @@ -48,6 +48,8 @@ public class PluginManager { */ private final ApplicationProperties applicationProperties; + private final PluginLoader pluginLoader; + /** * Map of plugins. */ @@ -60,8 +62,9 @@ public class PluginManager { * instantiation time. */ @Autowired - public PluginManager(ApplicationProperties applicationProperties) { + public PluginManager(ApplicationProperties applicationProperties, PluginLoader pluginLoader) { this.applicationProperties = applicationProperties; + this.pluginLoader = pluginLoader; reloadPlugins(); } @@ -69,7 +72,7 @@ public PluginManager(ApplicationProperties applicationProperties) { * Unload all plugins and reload them from the configured plugin folder. */ public final void unload() { - PluginLoader.unload(); + pluginLoader.unload(); plugins.clear(); } @@ -79,7 +82,7 @@ public final void unload() { public final void reloadPlugins() { unload(); try { - plugins = PluginLoader.loadPlugins(Paths.get(applicationProperties.getPluginLocation().toURI()).toFile(), applicationProperties.getPackagesToScan()); + plugins = pluginLoader.loadPlugins(Paths.get(applicationProperties.getPluginLocation().toURI()).toFile(), applicationProperties.getPackagesToScan()); } catch (URISyntaxException ex) { LOG.error("Mapping plugin location " + applicationProperties.getPluginLocation() + " cannot be converted to URI", ex); } catch (IOException ioe) { diff --git a/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java b/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java index 6c8feb62..5e156b73 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/TestConfig.java @@ -5,6 +5,7 @@ package edu.kit.datamanager.mappingservice; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import edu.kit.datamanager.mappingservice.plugins.PluginLoader; import edu.kit.datamanager.mappingservice.plugins.PluginManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -23,8 +24,13 @@ public ApplicationProperties applicationProperties() { return new ApplicationProperties(); } + @Bean + public PluginLoader pluginLoader() { + return new PluginLoader(applicationProperties()); + } + @Bean public PluginManager pluginManager() { - return new PluginManager(applicationProperties()); + return new PluginManager(applicationProperties(), pluginLoader()); } } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java index c4f09adb..9c6b1faa 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java @@ -16,7 +16,6 @@ import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import org.junit.jupiter.api.Test; -import org.springframework.util.MimeTypeUtils; import java.io.File; import java.io.IOException; @@ -38,10 +37,14 @@ class PluginLoaderTest { @Autowired private PluginManager pluginManager; + + @Autowired + private PluginLoader pluginLoader; @Autowired private ApplicationProperties applicationProperties; + @BeforeEach void setUp() throws Exception { try { @@ -57,7 +60,7 @@ void valid() { System.out.println("Test valid"); Map plugins = null; try { - plugins = PluginLoader.loadPlugins(Path.of(applicationProperties.getPluginLocation().toURI()).toFile(), applicationProperties.getPackagesToScan()); + plugins = pluginLoader.loadPlugins(Path.of(applicationProperties.getPluginLocation().toURI()).toFile(), applicationProperties.getPackagesToScan()); } catch (Exception e) { fail(e); } @@ -85,7 +88,7 @@ void valid() { void invalidPath() { Map plugins = null; try { - PluginLoader.loadPlugins(new File("./invalid/test"), applicationProperties.getPackagesToScan()); + pluginLoader.loadPlugins(new File("./invalid/test"), applicationProperties.getPackagesToScan()); } catch (IOException e) { fail(e); } catch (MappingPluginException validationWarning) { @@ -105,7 +108,7 @@ void invalidPath() { void nullInput() { Map plugins = null; try { - plugins = PluginLoader.loadPlugins(null, null); + plugins = pluginLoader.loadPlugins(null, null); } catch (IOException e) { fail(e); } catch (MappingPluginException validationWarning) { @@ -116,7 +119,7 @@ void nullInput() { void emptyinput() { Map plugins = null; try { - plugins = PluginLoader.loadPlugins(new File(""), null); + plugins = pluginLoader.loadPlugins(new File(""), null); } catch (IOException e) { fail(e); } catch (MappingPluginException validationWarning) { diff --git a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java index 93632a51..86819f03 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginManagerTest.java @@ -73,7 +73,7 @@ void mapFileInvalidParameters() { try { pluginManager.mapFile(null, null, null, null); } catch (MappingServiceException e) { - assertEquals("Plugin ID is null.", e.getMessage()); + assertEquals("PluginId is null.", e.getMessage()); } catch (MappingPluginException ex) { fail("Expected MappingServiceException"); } @@ -81,7 +81,7 @@ void mapFileInvalidParameters() { try { pluginManager.mapFile("test", null, null, null); } catch (MappingServiceException e) { - assertEquals("Path to mapping schema is null.", e.getMessage()); + assertEquals("Path to mapping file is null.", e.getMessage()); } catch (MappingPluginException ex) { fail("Expected MappingServiceException"); } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java index 52f18705..f67df91e 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/util/FileUtilTest.java @@ -322,6 +322,7 @@ public void testFixFileExtensionWrongFile() { @Test void cloneValidGitRepository() { Path util = null; + try { util = FileUtil.cloneGitRepository("https://github.com/kit-data-manager/mapping-service.git", "main", "/tmp/test"); } catch (Exception e) { From 9abba2a1fb3661a4d288d8de5b8b16d0d8212884 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Wed, 5 Mar 2025 22:18:16 +0100 Subject: [PATCH 27/80] Working on making python dependency optional --- .../mappingservice/util/PythonRunnerUtil.java | 13 +- .../python/util/PythonUtilsTest.java | 274 +++++++++--------- .../test-config/application-test.properties | 6 +- 3 files changed, 148 insertions(+), 145 deletions(-) diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index 0fb9a93d..4ca65e29 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -33,13 +33,13 @@ */ @Component public class PythonRunnerUtil { - + private static ApplicationProperties configuration; - + private static final Logger LOGGER = LoggerFactory.getLogger(PythonRunnerUtil.class); + - @Autowired - public PythonRunnerUtil(ApplicationProperties configuration) { + public void init(ApplicationProperties configuration) { PythonRunnerUtil.configuration = configuration; } @@ -96,9 +96,12 @@ public static MappingPluginState runPythonScript(String script, OutputStream out return MappingPluginState.UNKNOWN_ERROR(); } ArrayList command = new ArrayList<>(); + System.out.println("SET TPPY " + configuration.getPythonExecutable()); command.add(configuration.getPythonExecutable().getPath()); command.add(script); - Collections.addAll(command, args); + if (args != null) { + Collections.addAll(command, args); + } return ShellRunnerUtil.run(output, error, command.toArray(String[]::new)); } } diff --git a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java index b92c8cbd..bed7ad3c 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java @@ -1,137 +1,137 @@ -///* -// * Copyright 2019 Karlsruhe Institute of Technology. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -//package edu.kit.datamanager.mappingservice.python.util; -// -//import org.junit.jupiter.api.BeforeAll; -//import org.junit.jupiter.api.Test; -// -//import java.io.ByteArrayOutputStream; -//import java.io.File; -//import java.io.IOException; -//import java.io.OutputStream; -// -//import static org.junit.jupiter.api.Assertions.*; -// -///** -// * -// */ -//public class PythonUtilsTest { -// -// private static String PYTHON_EXECUTABLE; -// -// public PythonUtilsTest() { -// } -// -// @BeforeAll -// public static void setUpClass() throws IOException { -// // Determine python location -// OutputStream os = new ByteArrayOutputStream(); -// PythonUtils.run("which", "python3", os, null); -// String pythonExecutable = os.toString(); -// os.flush(); -// if (pythonExecutable.trim().isEmpty()) { -// PythonUtils.run("which", "python", os, null); -// pythonExecutable = os.toString(); -// } -// if (pythonExecutable.trim().isEmpty()) { -// throw new IOException("Python seems not to be available!"); -// } -// System.out.println("Location of python: " + pythonExecutable); -// PYTHON_EXECUTABLE = pythonExecutable.trim(); -// } -// -// /** -// */ -// @Test -// public void testRun_Constructor() { -// assertNotNull(new PythonUtils()); -// } -// -// /** -// * Test of run method, of class PythonUtils. -// */ -// @Test -// public void testRun_3args_withWrongPython() { -// System.out.println("testRun_3args_withWrongPython"); -// String pythonLocation = "/usr/bin/invalidpython"; -// String scriptLocation = ""; -// String[] arguments = null; -// int expResult = PythonUtils.PYTHON_NOT_FOUND_ERROR; -// int result = PythonUtils.run(pythonLocation, scriptLocation, arguments); -// assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); -// } -// -// /** -// * Test of run method, of class PythonUtils. -// */ -// @Test -// public void testRun_3args_withWrongClass() { -// System.out.println("testRun_3args_withWrongClass"); -// String pythonLocation = PYTHON_EXECUTABLE; -// String scriptLocation = new File("src/test/resources/python/invalid.py").getAbsolutePath(); -// String[] arguments = null; -// int expResult = PythonUtils.EXECUTION_ERROR; -// int result = PythonUtils.run(pythonLocation, scriptLocation, arguments); -// assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); -// } -// -// /** -// * Test of run method, of class PythonUtils. -// */ -// @Test -// public void testRun_3args_withTimeout() { -// System.out.println("testRun_3args_withTimeout"); -// String pythonLocation = PYTHON_EXECUTABLE; -// String scriptLocation = new File("src/test/resources/python/sleep.py").getAbsolutePath(); -// String[] arguments = null; -// int expResult = PythonUtils.TIMEOUT_ERROR; -// int result = PythonUtils.run(pythonLocation, scriptLocation, 1, arguments); -// assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); -// expResult = PythonUtils.SUCCESS; -// result = PythonUtils.run(pythonLocation, scriptLocation, 5, arguments); -// assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); -// -// } -// -// /** -// * Test of run method, of class PythonUtils. -// */ -// @Test -// public void testRun_3args_withNoOutputStreams() { -// System.out.println("testRun_3args_withTimeout"); -// String pythonLocation = PYTHON_EXECUTABLE; -// String scriptLocation = new File("src/test/resources/python/printOutput.py").getAbsolutePath(); -// String[] arguments = null; -// int expResult = PythonUtils.SUCCESS; -// int result = PythonUtils.run(pythonLocation, scriptLocation, null, null, arguments); -// assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); -// } -// -// /** -// * Test of run method, of class PythonUtils. -// */ -// @Test -// public void testRun_3args_withInvalidPython() { -// System.out.println("testRun_3args_withInvalidPython"); -// String pythonLocation = PYTHON_EXECUTABLE; -// String scriptLocation = "/notExistingFile.py"; -// String[] arguments = null; -// int expResult = PythonUtils.EXECUTION_ERROR; -// int result = PythonUtils.run(pythonLocation, scriptLocation, arguments); -// assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); -// } -// -//} +/* + * Copyright 2019 Karlsruhe Institute of Technology. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.kit.datamanager.mappingservice.python.util; + +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; +import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; +import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; +import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; +import edu.kit.datamanager.mappingservice.util.ShellRunnerUtil; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +import static org.junit.jupiter.api.Assertions.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +/** + * + */ +@SpringBootTest +@ActiveProfiles("test") +public class PythonUtilsTest { + + private static String PYTHON_EXECUTABLE; + + @Autowired + private ApplicationProperties applicationProperties; + + public PythonUtilsTest() { + } + + /** + */ + @Test + public void testRun_Constructor() { + assertNotNull(new PythonRunnerUtil(applicationProperties)); + } + + /** + * Test of run method, of class PythonUtils. + */ + @Test + public void testRun_3args_withWrongPython() { + System.out.println("testRun_3args_withWrongPython"); + ApplicationProperties props =new ApplicationProperties(); + props.setPythonExecutable(null); + new PythonRunnerUtil(props); + String scriptLocation = ""; + String[] arguments = null; + try { + MappingPluginState result = PythonRunnerUtil.runPythonScript(scriptLocation, arguments); + fail("Expected MappingPluginException"); + } catch (MappingPluginException e) { + fail("Unexpected MappingPluginException"); + } + } + + /** + * Test of run method, of class PythonUtils. + */ + @Test + public void testRun_3args_withWrongClass() { + System.out.println("testRun_3args_withWrongClass"); + String scriptLocation = new File("src/test/resources/python/invalid.py").getAbsolutePath(); + String[] arguments = null; + try { + PythonRunnerUtil.runPythonScript(scriptLocation, arguments); + fail("Expected MappingPluginException"); + } catch (MappingPluginException e) { + assertEquals(MappingPluginState.StateEnum.BAD_EXIT_CODE, e.getMappingPluginState().getState()); + } + } + + /** + * Test of run method, of class PythonUtils. + */ + /*@Test + public void testRun_3args_withTimeout() { + System.out.println("testRun_3args_withTimeout"); + String pythonLocation = PYTHON_EXECUTABLE; + String scriptLocation = new File("src/test/resources/python/sleep.py").getAbsolutePath(); + String[] arguments = null; + int result = PythonRunnerUtil.run(pythonLocation, scriptLocation, 1, arguments); + + result = PythonRunnerUtil.runPythonScript(scriptLocation, arguments); + assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); + + }*/ + /** + * Test of run method, of class PythonUtils. + */ + @Test + public void testRun_3args_withNoOutputStreams() { + System.out.println("testRun_3args_withTimeout"); + String scriptLocation = new File("src/test/resources/python/printOutput.py").getAbsolutePath(); + String[] arguments = null; + try { + PythonRunnerUtil.runPythonScript(scriptLocation, null, null, arguments); + fail("Expected MappingPluginException"); + } catch (MappingPluginException e) { + assertEquals(MappingPluginState.StateEnum.INVALID_INPUT, e.getMappingPluginState().getState()); + } + } + + /** + * Test of run method, of class PythonUtils. + */ + /* @Test + public void testRun_3args_withInvalidPython() { + System.out.println("testRun_3args_withInvalidPython"); + String pythonLocation = PYTHON_EXECUTABLE; + String scriptLocation = "/notExistingFile.py"; + String[] arguments = null; + int expResult = PythonUtils.EXECUTION_ERROR; + int result = PythonUtils.run(pythonLocation, scriptLocation, arguments); + assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); + }*/ +} diff --git a/src/test/resources/test-config/application-test.properties b/src/test/resources/test-config/application-test.properties index 808f9e3d..097b2400 100644 --- a/src/test/resources/test-config/application-test.properties +++ b/src/test/resources/test-config/application-test.properties @@ -27,9 +27,9 @@ spring.servlet.multipart.max-request-size=100MB # Logging settings logging.level.root=WARN -logging.level.web=TRACE -logging.level.org.springframework.web=TRACE -logging.level.edu.kit.datamanager=INFO +logging.level.web=WARN +logging.level.org.springframework.web=WARN +logging.level.edu.kit.datamanager=TRACE #springdoc.swagger-ui.disable-swagger-default-url=true # Actuator settings info.app.name=Mapping-Service From 382c1da371798ccc219d9396b5fd7a9ca1f9d181 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Thu, 6 Mar 2025 15:25:44 +0100 Subject: [PATCH 28/80] Fixed runner configuration issues, integrated keycloak support and authorized access to admin endpoints, re-added python execution test, made execution timeout configurable, started working on python+venv example plugin --- build.gradle | 2 +- settings/application-default.properties | 9 ++ settings/application-docker.properties | 3 + .../MappingServiceApplication.java | 26 ++++ .../configuration/ApplicationProperties.java | 25 +++- .../configuration/WebSecurityConfig.java | 73 +++++---- .../mappingservice/plugins/PluginLoader.java | 24 --- .../plugins/impl/GemmaPlugin.java | 7 +- .../plugins/impl/PythonCheckPlugin.java | 140 ++++++++++++++++++ .../mappingservice/util/PythonRunnerUtil.java | 6 +- .../mappingservice/util/ShellRunnerUtil.java | 21 +-- src/main/resources/python/check.py | 37 +++++ .../resources/python/requirements.dist.txt | 3 + .../python/util/PythonUtilsTest.java | 62 +++----- src/test/resources/python/invalid.py | 6 + src/test/resources/python/printOutput.py | 6 + src/test/resources/python/sleep.py | 5 + .../test-config/application-test.properties | 5 +- 18 files changed, 347 insertions(+), 113 deletions(-) create mode 100644 src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java create mode 100644 src/main/resources/python/check.py create mode 100644 src/main/resources/python/requirements.dist.txt create mode 100644 src/test/resources/python/invalid.py create mode 100644 src/test/resources/python/printOutput.py create mode 100644 src/test/resources/python/sleep.py diff --git a/build.gradle b/build.gradle index 92a66b9f..7072b520 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ repositories { ext { set('snippetsDir', file('build/generated-snippets')) applicationProperties = System.getProperty('applicationProperties', './src/test/resources/test-config/application-test.properties') - pythonExecutable = System.getProperty('pythonExecutable', 'file:///C:/Python310/python.exe') + pythonExecutable = System.getProperty('pythonExecutable', "file:///opt/homebrew/bin/python3") userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") set('springDocVersion', "2.8.5") diff --git a/settings/application-default.properties b/settings/application-default.properties index d0b1b42d..68c9e581 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -54,4 +54,13 @@ mapping-service.pythonExecutable=file:///usr/bin/python3 mapping-service.pluginLocation=file://INSTALLATION_DIR/plugins # Absolute path to the local gemma mappings folder. mapping-service.mappingSchemasLocation=file://INSTALLATION_DIR/mappingSchemas +# Folder where job output files for async mapping executions are stored mapping-service.jobOutput=file://INSTALLATION_DIR/jobOutput +# Execution timeout for script calls +mapping-service.executionTimeout=30 + +mapping-service.authEnabled:false +mapping-service.mappingAdminRole:MAPPING_ADMIN + +repo.security.enable-csrf=false +repo.security.allowedOriginPattern=http://localhost:* \ No newline at end of file diff --git a/settings/application-docker.properties b/settings/application-docker.properties index 3fb5481f..ce36a129 100644 --- a/settings/application-docker.properties +++ b/settings/application-docker.properties @@ -47,4 +47,7 @@ mapping-service.pythonExecutable=file:///usr/bin/python3 mapping-service.pluginLocation=file://INSTALLATION_DIR/plugins # Absolute path to the local gemma mappings folder. mapping-service.mappingSchemasLocation=file://INSTALLATION_DIR/mappingSchemas +# Folder where job output files for async mapping executions are stored mapping-service.jobOutput=file://INSTALLATION_DIR/jobOutput +# Execution timeout for script calls +mapping-service.executionTimeout=30 \ No newline at end of file diff --git a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java index 607967c7..42ec2d57 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java @@ -6,11 +6,16 @@ import edu.kit.datamanager.mappingservice.plugins.PluginLoader; import edu.kit.datamanager.mappingservice.plugins.PluginManager; import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; +import edu.kit.datamanager.mappingservice.util.ShellRunnerUtil; +import edu.kit.datamanager.security.filter.KeycloakJwtProperties; +import edu.kit.datamanager.security.filter.KeycloakTokenFilter; +import edu.kit.datamanager.security.filter.KeycloakTokenValidator; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @@ -39,9 +44,30 @@ public PluginLoader pluginLoader() { @Bean public PluginManager pluginManager() { + PythonRunnerUtil.init(applicationProperties()); + ShellRunnerUtil.init(applicationProperties()); return new PluginManager(applicationProperties(), pluginLoader()); } + @Bean + public KeycloakJwtProperties keycloakProperties() { + return new KeycloakJwtProperties(); + } + + @Bean + @ConditionalOnProperty( + value = "mapping-service.authEnabled", + havingValue = "true", + matchIfMissing = false) + public KeycloakTokenFilter keycloaktokenFilterBean() throws Exception { + return new KeycloakTokenFilter(KeycloakTokenValidator.builder() + .readTimeout(keycloakProperties().getReadTimeoutms()) + .connectTimeout(keycloakProperties().getConnectTimeoutms()) + .sizeLimit(keycloakProperties().getSizeLimit()) + .jwtLocalSecret("vkfvoswsohwrxgjaxipuiyyjgubggzdaqrcuupbugxtnalhiegkppdgjgwxsmvdb") + .build(keycloakProperties().getJwkUrl(), keycloakProperties().getResource(), keycloakProperties().getJwtClaim())); + } + public static void main(String[] args) throws IOException { ConfigurableApplicationContext ctx = SpringApplication.run(MappingServiceApplication.class, args); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java index 2af59515..ddb020bf 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java @@ -67,11 +67,32 @@ public class ApplicationProperties { @Value("${mapping-service.jobOutput}") private URL jobOutputLocation; - - /** + /** * One or more packages to scan for plugin classes. */ @Value("${mapping-service.packagesToScan:edu.kit.datamanager.mappingservice.plugins.impl}") private String[] packagesToScan; + @Value("${mapping-service.executionTimeout:30}") + private int executionTimeout; + + /** + * Auth and permission properties + */ + @Value("${mapping-service.authEnabled:FALSE}") + private boolean authEnabled; + @Value("${mapping-service.mappingAdminRole:MAPPING_ADMIN}") + private String mappingAdminRole; + /** + * CORS and CSRF properties + */ + @Value("${repo.security.allowedOriginPattern:*}") + private String allowedOriginPattern; + @Value("${repo.security.allowedMethods:GET,POST,PUT,PATCH,DELETE,OPTIONS}") + private String[] allowedMethods; + @Value("${repo.security.exposedHeaders:Content-Range,ETag,Link}") + private String[] exposedHeaders; + @Value("${repo.security.allowedHeaders:*}") + private String[] allowedHeaders; + } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java index 8fb9c842..d01bcb93 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/WebSecurityConfig.java @@ -18,6 +18,7 @@ import edu.kit.datamanager.security.filter.KeycloakTokenFilter; import edu.kit.datamanager.security.filter.NoAuthenticationFilter; import java.util.Arrays; +import java.util.List; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,10 +53,12 @@ public class WebSecurityConfig { private static final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class); - + @Autowired private Optional keycloaktokenFilterBean; - + @Autowired + private ApplicationProperties applicationProperties; + private static final String[] AUTH_WHITELIST_SWAGGER_UI = { // -- Swagger UI v2 "/v2/api-docs", @@ -68,11 +71,26 @@ public class WebSecurityConfig { // -- Swagger UI v3 (OpenAPI) "/v3/api-docs/**", "/swagger-ui/**" - // other public endpoints of your API may be appended to this array + // other public endpoints of your API may be appended to this array }; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + + List securedEndpointMatchers; + + if (applicationProperties.isAuthEnabled()) { + logger.trace("Authentication is ENABLED. Collecting secured endpoints."); + securedEndpointMatchers = Arrays.asList( + new AntPathRequestMatcher("/api/v1/mappingAdministration/reloadTypes", "GET"), + new AntPathRequestMatcher("/api/v1/mappingAdministration", "PUT"), + new AntPathRequestMatcher("/api/v1/mappingAdministration", "POST") + ); + } else { + logger.trace("Authentication is DISABLED. Not securing endpoints."); + securedEndpointMatchers = Arrays.asList(); + } + HttpSecurity httpSecurity = http.authorizeHttpRequests( authorize -> authorize. requestMatchers(HttpMethod.OPTIONS).permitAll(). @@ -80,11 +98,10 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { InfoEndpoint.class, HealthEndpoint.class )).permitAll(). - requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyRole("ANONYMOUS", "ADMIN", "ACTUATOR", "SERVICE_WRITE"). - // requestMatchers(new AntPathRequestMatcher("/oaipmh")).permitAll(). + requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyRole("ANONYMOUS", "ADMINISTRATOR", "ACTUATOR", "SERVICE_WRITE"). requestMatchers(new AntPathRequestMatcher("/static/**")).permitAll(). requestMatchers(new AntPathRequestMatcher("/error")).permitAll(). - //requestMatchers(new AntPathRequestMatcher("/api/v1/")).permitAll(). + requestMatchers(securedEndpointMatchers.toArray(AntPathRequestMatcher[]::new)).hasRole(applicationProperties.getMappingAdminRole()). //endpoint filters only active if auth is enabled requestMatchers(AUTH_WHITELIST_SWAGGER_UI).permitAll(). anyRequest().authenticated() ). @@ -95,10 +112,22 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { logger.info("CSRF disabled!"); httpSecurity = httpSecurity.csrf(csrf -> csrf.disable()); - logger.info("Authentication is DISABLED. Adding 'NoAuthenticationFilter' to authentication chain."); - AuthenticationManager defaultAuthenticationManager = http.getSharedObject(AuthenticationManager.class); - httpSecurity = httpSecurity.addFilterAfter(new NoAuthenticationFilter("vkfvoswsohwrxgjaxipuiyyjgubggzdaqrcuupbugxtnalhiegkppdgjgwxsmvdb", defaultAuthenticationManager), BasicAuthenticationFilter.class); - + if (keycloaktokenFilterBean.isPresent()) { + logger.trace("Adding Keycloak filter to filter chain."); + httpSecurity.addFilterAfter(keycloaktokenFilterBean.get(), BasicAuthenticationFilter.class); + } else { + logger.trace("Keycloak not configured. Skip adding keycloak filter to filter chain."); + } + + if (!applicationProperties.isAuthEnabled()) { + logger.info("Adding 'NoAuthenticationFilter' to filter chain."); + AuthenticationManager defaultAuthenticationManager = http.getSharedObject(AuthenticationManager.class); + httpSecurity = httpSecurity.addFilterAfter(new NoAuthenticationFilter("vkfvoswsohwrxgjaxipuiyyjgubggzdaqrcuupbugxtnalhiegkppdgjgwxsmvdb", defaultAuthenticationManager), BasicAuthenticationFilter.class); + } else { + logger.info("Skip adding NoAuthenticationFilter to filter chain."); + } + + logger.trace("Turning off cache control."); httpSecurity.headers(headers -> headers.cacheControl(cache -> cache.disable())); return httpSecurity.build(); @@ -116,30 +145,14 @@ public HttpFirewall allowUrlEncodedSlashHttpFirewall() { return firewall; } - /* @Bean - public FilterRegistrationBean corsFilter() { - final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - CorsConfiguration config = new CorsConfiguration(); - config.addAllowedOrigin("*"); - config.addAllowedHeader("*"); - config.addAllowedMethod("*"); - config.addExposedHeader("Content-Range"); - config.addExposedHeader("ETag"); - - source.registerCorsConfiguration("/**", config); - FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source)); - bean.setOrder(0); - return bean; - }*/ public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); + config.addAllowedOriginPattern(applicationProperties.getAllowedOriginPattern()); + config.setAllowedHeaders(Arrays.asList(applicationProperties.getAllowedHeaders())); + config.setAllowedMethods(Arrays.asList(applicationProperties.getAllowedMethods())); + config.setExposedHeaders(Arrays.asList(applicationProperties.getExposedHeaders())); - config.addAllowedOriginPattern("*"); - config.setAllowedHeaders(Arrays.asList("*")); - config.setAllowedMethods(Arrays.asList("*")); - config.setExposedHeaders(Arrays.asList("*")); - final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java index 47db1c8e..be269fc7 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java @@ -14,8 +14,6 @@ */ package edu.kit.datamanager.mappingservice.plugins; -import com.google.common.collect.ImmutableSet; -import com.google.common.reflect.ClassPath; import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import org.slf4j.Logger; @@ -94,12 +92,6 @@ public Map loadPlugins(File pluginDir, String[] packages LOG.warn("Plugin folder {} is not defined. MappingService will only use plugins in classpath.", pluginDir); } else { pluginJars = pluginDir.listFiles(new JARFileFilter()); - - //removed check as plugins are now also accepted from classpath - /*if (plugJars == null || plugJars.length < 1) { - LOG.warn("Plugin folder " + plugDir + " is empty. Unable to load plugins."); - } else {*/ - // } } if (pluginJars != null && pluginJars.length > 0) { @@ -157,21 +149,6 @@ private List> extractClassesFromJARs(File[] jars, String[] classes.add((Class) res); pluginCnt++; } - - /*ImmutableSet clazzes = ClassPath.from(cl).getTopLevelClassesRecursive(pkg); - for (ClassPath.ClassInfo clazz : clazzes) { - try { - LOG.trace(" - Processing class {}.", clazz.getName()); - Class pl = clazz.load(); - - if (isPluggableClass(pl)) { - classes.add((Class) pl); - pluginCnt++; - } - } catch (ClassCastException ex) { - //failed to load, probably no implementation of IMappingPlugin - } - }*/ } LOG.trace("Found {} plugin classes in classpath.", pluginCnt); } @@ -235,7 +212,6 @@ protected List> findAllClasses(String packageName, ClassLoader loader) for (Resource resource : resources) { Class clazz = loadClass(loader, metadataReaderFactory, resource); if (clazz != null && isPluggableClass(clazz)) { - //System.out.println("CLASS " + clazz); result.add(clazz); } } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java index d7a4d9ca..3bb4681e 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/GemmaPlugin.java @@ -15,6 +15,7 @@ */ package edu.kit.datamanager.mappingservice.plugins.impl; +import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException; import edu.kit.datamanager.mappingservice.plugins.*; import edu.kit.datamanager.mappingservice.util.*; import org.slf4j.Logger; @@ -65,19 +66,19 @@ public MimeType[] outputTypes() { public void setup() { LOGGER.info("Checking and installing dependencies for Gemma: gemma, xmltodict, wget"); try { - //PythonRunnerUtil.runPythonScript("-m", "pip", "install", "xmltodict", "wget"); PythonRunnerUtil.runPythonScript("-m", new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), new LoggerOutputStream(LOGGER, LoggerOutputStream.Level.DEBUG), "pip", "install", "xmltodict", "wget"); gemmaDir = FileUtil.cloneGitRepository(GEMMA_REPOSITORY, GEMMA_BRANCH); initialized = true; } catch (MappingPluginException e) { - LOGGER.error("Failed to setup plugin '" + name() + "' " + version() + ".", e); + throw new PluginInitializationFailedException("Failed to setup plugin '" + name() + "' " + version() + ".", e); + } } @Override public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { if (initialized) { - LOGGER.trace("Run gemma on '{}' with mapping '{}' -> '{}'", inputFile, mappingFile, outputFile); + LOGGER.trace("Running plugin '{}' v{} on '{}' with mapping '{}' -> '{}'", name(), version(), inputFile, mappingFile, outputFile); return PythonRunnerUtil.runPythonScript(gemmaDir + "/mapping_single.py", mappingFile.toString(), inputFile.toString(), outputFile.toString()); } else { LOGGER.error("Plugin '" + name() + "' " + version() + " not initialized. Returning EXECUTION_ERROR."); diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java new file mode 100644 index 00000000..4bec0629 --- /dev/null +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/PythonCheckPlugin.java @@ -0,0 +1,140 @@ +package edu.kit.datamanager.mappingservice.plugins.impl; + +import com.google.common.io.Files; +import edu.kit.datamanager.mappingservice.plugins.*; +import edu.kit.datamanager.mappingservice.util.*; +import java.io.File; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.MimeType; +import org.springframework.util.MimeTypeUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; +import org.apache.commons.io.FileUtils; + +public class PythonCheckPlugin implements IMappingPlugin { + + private static String version; + + private final Logger LOGGER = LoggerFactory.getLogger(PythonCheckPlugin.class); + private final String REPOSITORY = "https://github.com/kit-data-manager/mapping-service"; + private String TAG; + private Path dir; + private String pluginVenv = "venv/PluginVenv"; + private String venvInterpreter; + + public PythonCheckPlugin() { + try { + // Get the context class loader + ClassLoader classLoader = this.getClass().getClassLoader(); + Properties props = new Properties(); + props.load(classLoader.getResourceAsStream("META-INF/build-info.properties")); + + version = props.getProperty("build.version"); + + // TODO: do we need to make sure that the resource path is somehow related to the current plugin to avoid loading the wrong property file in case of identical property names? + /*URL resource = classLoader.getResource("sempluginversion.properties"); + LOGGER.info("Resource file: {}", resource); + if (resource != null) { + // Load the properties file + try (InputStream input = resource.openStream()) { + Properties properties = new Properties(); + properties.load(input); + version = properties.getProperty("version"); + TAG = version; + } + } else { + System.err.println("Properties file not found!"); + version = "unavailable"; + TAG = "unavailable"; + }*/ + if (System.getProperty("os.name").startsWith("Windows")) { + venvInterpreter = pluginVenv + "/Scripts/python.exe"; + } else { + venvInterpreter = pluginVenv + "/bin/python3"; + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public String name() { + return "PythonCheckPlugin"; + } + + @Override + public String description() { + return "This is a sample plugin that can be used to check the python version used by this mapping-service instance."; + } + + @Override + public String version() { + return version; + } + + @Override + public String uri() { + return REPOSITORY; + } + + @Override + public MimeType[] inputTypes() { + return new MimeType[]{MimeTypeUtils.parseMimeType("plain/text")}; //should currently be IMAGE/TIFF + } + + @Override + public MimeType[] outputTypes() { + return new MimeType[]{MimeTypeUtils.parseMimeType("plain/text")}; + } + + @Override + public void setup() { + LOGGER.info("Checking and installing dependencies for the tool: "); + //TODO: test for minimal python version? + try { + //LOGGER.info("Cloning git repository {}, Tag {}", REPOSITORY, TAG); + //dir = FileUtil.cloneGitRepository(REPOSITORY, TAG); + // Install Python dependencies + + Path p = Paths.get("tmp", name(), version()); + if (!p.toFile().exists()) { + FileUtils.forceMkdir(p.toFile()); + } + + + + + + + MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", p.toAbsolutePath().toString() + "/" + pluginVenv); + if (venvState.getState() == MappingPluginState.StateEnum.SUCCESS) { + LOGGER.info("Venv for plugin installed succesfully."); + LOGGER.info("Installing packages"); + ShellRunnerUtil.run(p.toAbsolutePath().toString() + "/" + venvInterpreter, "-m", "pip", "install", "-r", p.toAbsolutePath().toString() + "/" + pluginVenv + "/requirements.dist.txt"); + } else { + LOGGER.error("venv installation was not successful"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException { + long startTime = System.currentTimeMillis(); + LOGGER.trace("Run SEM-Mapping-Tool on '{}' with mapping '{}' -> '{}'", mappingFile, inputFile, outputFile); + MappingPluginState result = ShellRunnerUtil.run(dir + "/" + venvInterpreter, dir + "/plugin_wrapper.py", "sem", "-m", mappingFile.toString(), "-i", inputFile.toString(), "-o", outputFile.toString()); + long endTime = System.currentTimeMillis(); + long totalTime = endTime - startTime; + LOGGER.info("Execution time of mapFile: {} milliseconds", totalTime); + return result; + } +} diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index 4ca65e29..bd478399 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -19,7 +19,6 @@ import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.OutputStream; @@ -39,7 +38,7 @@ public class PythonRunnerUtil { private static final Logger LOGGER = LoggerFactory.getLogger(PythonRunnerUtil.class); - public void init(ApplicationProperties configuration) { + public static void init(ApplicationProperties configuration) { PythonRunnerUtil.configuration = configuration; } @@ -93,10 +92,9 @@ public static MappingPluginState runPythonScript(String script, String... args) */ public static MappingPluginState runPythonScript(String script, OutputStream output, OutputStream error, String... args) throws MappingPluginException { if (configuration == null || configuration.getPythonExecutable() == null) { - return MappingPluginState.UNKNOWN_ERROR(); + throw new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "No Python runtime configured."); } ArrayList command = new ArrayList<>(); - System.out.println("SET TPPY " + configuration.getPythonExecutable()); command.add(configuration.getPythonExecutable().getPath()); command.add(script); if (args != null) { diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java index 5efa8065..b3fc7471 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/ShellRunnerUtil.java @@ -14,6 +14,7 @@ */ package edu.kit.datamanager.mappingservice.util; +import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties; import edu.kit.datamanager.mappingservice.exception.BadExitCodeException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginException; import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; @@ -32,16 +33,18 @@ */ public class ShellRunnerUtil { - /** - * Time in seconds when the script should throw a timeout exception. - */ - public static final int TIMEOUT = 30; + + private static ApplicationProperties configuration; /** * Logger for this class. */ private final static Logger LOGGER = LoggerFactory.getLogger(ShellRunnerUtil.class); + public static void init(ApplicationProperties configuration) { + ShellRunnerUtil.configuration = configuration; + } + /** * This method executes a shell command. * @@ -50,7 +53,7 @@ public class ShellRunnerUtil { * @throws MappingPluginException If an error occurs. */ public static MappingPluginState run(String... command) throws MappingPluginException { - return run(TIMEOUT, command); + return run(configuration.getExecutionTimeout(), command); } /** @@ -77,7 +80,7 @@ public static MappingPluginState run(int timeOutInSeconds, String... command) th * @throws MappingPluginException If an error occurs. */ public static MappingPluginState run(OutputStream output, OutputStream error, String... command) throws MappingPluginException { - return run(output, error, TIMEOUT, command); + return run(output, error, configuration.getExecutionTimeout(), command); } /** @@ -103,7 +106,7 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Error stream is null."); } if (timeOutInSeconds <= 0) { - throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Timeout is null or negative."); + throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "Execution timeout is leq 0."); } if (command == null || command.length == 0) { throw new MappingPluginException(MappingPluginState.INVALID_INPUT(), "No command given."); @@ -133,7 +136,7 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in } if (!p.waitFor(timeOutInSeconds, TimeUnit.SECONDS)) { - throw new TimeoutException("Process did not return within " + TIMEOUT + " seconds."); + throw new TimeoutException("Process did not return within " + timeOutInSeconds + " seconds."); } if (p.exitValue() != 0) { throw new BadExitCodeException(p.exitValue()); @@ -142,7 +145,7 @@ public static MappingPluginState run(OutputStream output, OutputStream error, in LOGGER.error("Failed to run command or to access output/error streams.", ioe); returnValue = MappingPluginState.EXECUTION_ERROR(); } catch (TimeoutException te) { - LOGGER.error("Command did not return in expected timeframe of " + TIMEOUT + " seconds", te); + LOGGER.error("Command did not return in expected timeframe of " + timeOutInSeconds + " seconds", te); returnValue = MappingPluginState.TIMEOUT(); } catch (InterruptedException | ExecutionException e) { LOGGER.error("Command execution has been interrupted.", e); diff --git a/src/main/resources/python/check.py b/src/main/resources/python/check.py new file mode 100644 index 00000000..a41a9716 --- /dev/null +++ b/src/main/resources/python/check.py @@ -0,0 +1,37 @@ +import platform +import json +import socket +import re +import uuid +import json +import psutil +import logging + +#schema = sys.argv[1] +#input_folder = sys.argv[2] +output_folder = sys.argv[3] + +print("\n \n \n MAPPING DOCUMENT: {} \n \n \n".format(manuscript)) + +outpath = os.path.join(output_folder, 'info.json') + +def getSystemInfo(): + try: + info={} + info['platform']=platform.system() + info['platform-release']=platform.release() + info['platform-version']=platform.version() + info['architecture']=platform.machine() + info['hostname']=socket.gethostname() + info['ip-address']=socket.gethostbyname(socket.gethostname()) + info['mac-address']=':'.join(re.findall('..', '%012x' % uuid.getnode())) + info['processor']=platform.processor() + info['ram']=str(round(psutil.virtual_memory().total / (1024.0 **3)))+" GB" + + with open(outpath, 'w', encoding='utf-8') as j: + json.dump(d, j, indent=2, ensure_ascii=False) + except Exception as e: + logging.exception(e) + + +getSystemInfo() \ No newline at end of file diff --git a/src/main/resources/python/requirements.dist.txt b/src/main/resources/python/requirements.dist.txt new file mode 100644 index 00000000..054be194 --- /dev/null +++ b/src/main/resources/python/requirements.dist.txt @@ -0,0 +1,3 @@ +uuid +psutil +logging diff --git a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java index bed7ad3c..f4f15cf0 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java @@ -20,15 +20,12 @@ import edu.kit.datamanager.mappingservice.plugins.MappingPluginState; import edu.kit.datamanager.mappingservice.util.PythonRunnerUtil; import edu.kit.datamanager.mappingservice.util.ShellRunnerUtil; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; -import java.io.OutputStream; import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; @@ -39,20 +36,16 @@ @SpringBootTest @ActiveProfiles("test") public class PythonUtilsTest { - - private static String PYTHON_EXECUTABLE; - + @Autowired private ApplicationProperties applicationProperties; - + public PythonUtilsTest() { } - - /** - */ - @Test - public void testRun_Constructor() { - assertNotNull(new PythonRunnerUtil(applicationProperties)); + + @BeforeEach + public void setUpClass() { + PythonRunnerUtil.init(applicationProperties); } /** @@ -61,16 +54,16 @@ public void testRun_Constructor() { @Test public void testRun_3args_withWrongPython() { System.out.println("testRun_3args_withWrongPython"); - ApplicationProperties props =new ApplicationProperties(); + ApplicationProperties props = new ApplicationProperties(); props.setPythonExecutable(null); - new PythonRunnerUtil(props); + PythonRunnerUtil.init(props); String scriptLocation = ""; String[] arguments = null; try { MappingPluginState result = PythonRunnerUtil.runPythonScript(scriptLocation, arguments); fail("Expected MappingPluginException"); } catch (MappingPluginException e) { - fail("Unexpected MappingPluginException"); + assertEquals(MappingPluginState.StateEnum.UNKNOWN_ERROR, e.getMappingPluginState().getState()); } } @@ -83,28 +76,33 @@ public void testRun_3args_withWrongClass() { String scriptLocation = new File("src/test/resources/python/invalid.py").getAbsolutePath(); String[] arguments = null; try { - PythonRunnerUtil.runPythonScript(scriptLocation, arguments); + MappingPluginState state = PythonRunnerUtil.runPythonScript(scriptLocation, arguments); fail("Expected MappingPluginException"); } catch (MappingPluginException e) { assertEquals(MappingPluginState.StateEnum.BAD_EXIT_CODE, e.getMappingPluginState().getState()); + assertEquals(123, e.getMappingPluginState().getDetails()); } } /** * Test of run method, of class PythonUtils. */ - /*@Test + @Test public void testRun_3args_withTimeout() { System.out.println("testRun_3args_withTimeout"); - String pythonLocation = PYTHON_EXECUTABLE; String scriptLocation = new File("src/test/resources/python/sleep.py").getAbsolutePath(); String[] arguments = null; - int result = PythonRunnerUtil.run(pythonLocation, scriptLocation, 1, arguments); - - result = PythonRunnerUtil.runPythonScript(scriptLocation, arguments); - assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); + ApplicationProperties props = new ApplicationProperties(); + props.setExecutionTimeout(1); + ShellRunnerUtil.init(props); + try { + PythonRunnerUtil.runPythonScript(scriptLocation, arguments); + } catch (MappingPluginException e) { + assertEquals(MappingPluginState.StateEnum.TIMEOUT, e.getMappingPluginState().getState()); + } + + } - }*/ /** * Test of run method, of class PythonUtils. */ @@ -120,18 +118,4 @@ public void testRun_3args_withNoOutputStreams() { assertEquals(MappingPluginState.StateEnum.INVALID_INPUT, e.getMappingPluginState().getState()); } } - - /** - * Test of run method, of class PythonUtils. - */ - /* @Test - public void testRun_3args_withInvalidPython() { - System.out.println("testRun_3args_withInvalidPython"); - String pythonLocation = PYTHON_EXECUTABLE; - String scriptLocation = "/notExistingFile.py"; - String[] arguments = null; - int expResult = PythonUtils.EXECUTION_ERROR; - int result = PythonUtils.run(pythonLocation, scriptLocation, arguments); - assertEquals(Integer.valueOf(expResult), Integer.valueOf(result)); - }*/ } diff --git a/src/test/resources/python/invalid.py b/src/test/resources/python/invalid.py new file mode 100644 index 00000000..1d73fff9 --- /dev/null +++ b/src/test/resources/python/invalid.py @@ -0,0 +1,6 @@ +#!/usr/bin/python + + +print("Exit code incoming...") + +exit(123) \ No newline at end of file diff --git a/src/test/resources/python/printOutput.py b/src/test/resources/python/printOutput.py new file mode 100644 index 00000000..30fb1a63 --- /dev/null +++ b/src/test/resources/python/printOutput.py @@ -0,0 +1,6 @@ +#!/usr/bin/python +import time +import sys + +print ("Hello") +sys.stderr.write("Print to stderr\n") \ No newline at end of file diff --git a/src/test/resources/python/sleep.py b/src/test/resources/python/sleep.py new file mode 100644 index 00000000..cecf0d7b --- /dev/null +++ b/src/test/resources/python/sleep.py @@ -0,0 +1,5 @@ +#!/usr/bin/python +import time + +print ("Sleep for 3 seconds") +time.sleep( 3 ) diff --git a/src/test/resources/test-config/application-test.properties b/src/test/resources/test-config/application-test.properties index 097b2400..b5e143da 100644 --- a/src/test/resources/test-config/application-test.properties +++ b/src/test/resources/test-config/application-test.properties @@ -64,9 +64,12 @@ eureka.client.enabled: false # Mapping-Service specific settings ################################################## # Absolute path to the local python interpreter -mapping-service.pythonExecutable=${pythonExecutable:'file:///usr/bin/python'}# +mapping-service.pythonExecutable=${pythonExecutable:file:///usr/bin/python} # Absolute path to the folder where all plugins are located mapping-service.pluginLocation=file:///tmp/mapping-service/plugins # Absolute path to the local gemma mappings folder mapping-service.mappingSchemasLocation=file:///tmp/mapping-service/schemas +# Folder where job output files for async mapping executions are stored mapping-service.jobOutput=file:///tmp/mapping-service/jobOutput +# Execution timeout for script calls +mapping-service.executionTimeout=30 From 27e518eacb080ea40439065d9a9a89d2dc33c04c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 05:24:27 +0000 Subject: [PATCH 29/80] Update plugin com.gorylenko.gradle-git-properties to v2.5.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7072b520..696aa0e3 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { id 'io.freefair.maven-publish-java' version '8.12.1' id "org.owasp.dependencycheck" version "12.1.0" id 'net.researchgate.release' version '3.1.0' - id "com.gorylenko.gradle-git-properties" version "2.4.2" + id "com.gorylenko.gradle-git-properties" version "2.5.0" id 'io.freefair.lombok' version '8.12.1' id 'java' id 'jacoco' From 6d4292bf2638704d31261636be9d4475d7ce5121 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 08:57:33 +0000 Subject: [PATCH 30/80] Update plugin io.freefair.lombok to v8.12.2.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 790c1e75..5cdd3a7a 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { id "org.owasp.dependencycheck" version "12.1.0" id 'net.researchgate.release' version '3.1.0' id "com.gorylenko.gradle-git-properties" version "2.5.0" - id 'io.freefair.lombok' version '8.12.1' + id 'io.freefair.lombok' version '8.12.2.1' id 'java' id 'jacoco' } From 4af15f629a17b60433e397139d292eeaae50d1fb Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Mon, 10 Mar 2025 15:46:48 +0100 Subject: [PATCH 31/80] Added sample test script, started adding support for optional Python dependency --- .../configuration/ApplicationProperties.java | 1 - .../mappingservice/plugins/PluginLoader.java | 1 + src/main/resources/python/check.py | 36 +++++++------------ .../resources/python/requirements.dist.txt | 3 -- .../python/util/PythonUtilsTest.java | 18 +++++++--- 5 files changed, 28 insertions(+), 31 deletions(-) delete mode 100644 src/main/resources/python/requirements.dist.txt diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java index ddb020bf..f8b6e3e3 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java @@ -42,7 +42,6 @@ public class ApplicationProperties { /** * The absolute path to the python interpreter. */ - @ExecutableFileURL @Value("${mapping-service.pythonExecutable}") private URL pythonExecutable; diff --git a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java index be269fc7..9c4a03f4 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java @@ -106,6 +106,7 @@ public Map loadPlugins(File pluginDir, String[] packages for (IMappingPlugin i : IMappingPluginList) { try { i.setup(); + LOG.trace(" - Adding new plugin {}, v{} to available list", i.name(), i.version()); result.put(i.id(), i); } catch (PluginInitializationFailedException re) { LOG.error("Failed to initialize plugin " + i.name() + ", version " + i.version() + ". Plugin will be ignored.", re); diff --git a/src/main/resources/python/check.py b/src/main/resources/python/check.py index a41a9716..d30747b7 100644 --- a/src/main/resources/python/check.py +++ b/src/main/resources/python/check.py @@ -1,37 +1,27 @@ +import sys import platform +import os import json -import socket -import re -import uuid -import json -import psutil import logging -#schema = sys.argv[1] -#input_folder = sys.argv[2] +# input folder and mapping file are ignored output_folder = sys.argv[3] - -print("\n \n \n MAPPING DOCUMENT: {} \n \n \n".format(manuscript)) - +# output path obtained from mapping service outpath = os.path.join(output_folder, 'info.json') + def getSystemInfo(): try: - info={} - info['platform']=platform.system() - info['platform-release']=platform.release() - info['platform-version']=platform.version() - info['architecture']=platform.machine() - info['hostname']=socket.gethostname() - info['ip-address']=socket.gethostbyname(socket.gethostname()) - info['mac-address']=':'.join(re.findall('..', '%012x' % uuid.getnode())) - info['processor']=platform.processor() - info['ram']=str(round(psutil.virtual_memory().total / (1024.0 **3)))+" GB" - + # Python code execution + info = {'version': sys.version, 'platform-release': platform.release(), 'platform-version': platform.version(), + 'architecture': platform.machine(), 'processor': platform.processor()} + # output writing with open(outpath, 'w', encoding='utf-8') as j: - json.dump(d, j, indent=2, ensure_ascii=False) + json.dump(info, j, indent=2, ensure_ascii=False) except Exception as e: + # exception logging for later checks and exit code != 0 to propagate error and cause logging.exception(e) + exit(1) -getSystemInfo() \ No newline at end of file +getSystemInfo() diff --git a/src/main/resources/python/requirements.dist.txt b/src/main/resources/python/requirements.dist.txt deleted file mode 100644 index 054be194..00000000 --- a/src/main/resources/python/requirements.dist.txt +++ /dev/null @@ -1,3 +0,0 @@ -uuid -psutil -logging diff --git a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java index f4f15cf0..6196ac48 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java @@ -23,12 +23,17 @@ import org.junit.jupiter.api.Test; import java.io.File; +import org.apache.commons.lang3.Range; +import org.hamcrest.CoreMatchers; +import org.hamcrest.core.Is; +import org.junit.Assume; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; +import org.springframework.util.Assert; /** * @@ -36,13 +41,13 @@ @SpringBootTest @ActiveProfiles("test") public class PythonUtilsTest { - + @Autowired private ApplicationProperties applicationProperties; - + public PythonUtilsTest() { } - + @BeforeEach public void setUpClass() { PythonRunnerUtil.init(applicationProperties); @@ -72,6 +77,8 @@ public void testRun_3args_withWrongPython() { */ @Test public void testRun_3args_withWrongClass() { + Assume.assumeThat("Python not configured.", Is.is(applicationProperties.getPythonExecutable() == null)); + System.out.println("testRun_3args_withWrongClass"); String scriptLocation = new File("src/test/resources/python/invalid.py").getAbsolutePath(); String[] arguments = null; @@ -89,6 +96,9 @@ public void testRun_3args_withWrongClass() { */ @Test public void testRun_3args_withTimeout() { + System.out.println("ASSERT " + applicationProperties.getPythonExecutable()); + Assume.assumeThat("Python not configured.", applicationProperties.getPythonExecutable(), CoreMatchers.notNullValue()); + System.out.println("ASSERT TRUE!!!!"); System.out.println("testRun_3args_withTimeout"); String scriptLocation = new File("src/test/resources/python/sleep.py").getAbsolutePath(); String[] arguments = null; @@ -100,7 +110,7 @@ public void testRun_3args_withTimeout() { } catch (MappingPluginException e) { assertEquals(MappingPluginState.StateEnum.TIMEOUT, e.getMappingPluginState().getState()); } - + } /** From b7febcd513c2c47c4d7c07ef54dba7546fb41ac5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 19:50:30 +0000 Subject: [PATCH 32/80] Update dependency python to 3.13 --- .github/workflows/CI.yml | 2 +- .github/workflows/codeql-analysis.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 045dc95b..01a30ed4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -31,7 +31,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.13' - name: Get Python location run: python -c "import os, sys; print(sys.executable)" - name: Update pip diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7bef61a2..ffd14e01 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,7 +41,7 @@ jobs: - name: Set up Python3 uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.13' - name: Set up OpenJDK uses: actions/setup-java@v4 with: @@ -101,7 +101,7 @@ jobs: - name: Set up Python3 uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.13' - name: Set up OpenJDK uses: actions/setup-java@v4 From 8fac387cf253dba324cfa3737fa782baeae249d0 Mon Sep 17 00:00:00 2001 From: Thomas Jejkal Date: Tue, 11 Mar 2025 23:02:25 +0100 Subject: [PATCH 33/80] Finished making Python requirement optional, updated README --- README.md | 69 ++- build.gradle | 2 +- settings/application-default.properties | 2 +- settings/application-docker.properties | 8 +- .../configuration/ApplicationProperties.java | 12 +- .../mappingservice/util/PythonRunnerUtil.java | 2 +- .../python/util/PythonUtilsTest.java | 18 +- .../venv/PluginVenv/Scripts/Activate.ps1 | 405 ++++++++++++++++++ .../venv/PluginVenv/Scripts/activate | 69 +++ .../venv/PluginVenv/Scripts/activate.bat | 34 ++ .../venv/PluginVenv/Scripts/deactivate.bat | 22 + .../venv/PluginVenv/Scripts/pip.exe | Bin 0 -> 106427 bytes .../venv/PluginVenv/Scripts/pip3.10.exe | Bin 0 -> 106427 bytes .../venv/PluginVenv/Scripts/pip3.exe | Bin 0 -> 106427 bytes .../venv/PluginVenv/Scripts/python.exe | Bin 0 -> 242920 bytes .../venv/PluginVenv/Scripts/pythonw.exe | Bin 0 -> 232688 bytes .../1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg | 3 + 17 files changed, 596 insertions(+), 50 deletions(-) create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip.exe create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip3.10.exe create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip3.exe create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/python.exe create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pythonw.exe create mode 100644 tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/pyvenv.cfg diff --git a/README.md b/README.md index aaa9266d..5e55d8a0 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,17 @@ The REST-API is documented at the following link: [http://\:8095 Dependencies that are needed to build and are not being downloaded via gradle: - OpenJDK 17 -- Python 3 -- pip (runtime only) +- (Optional) Python 3 +- (Optional) pip (runtime only) `./gradlew build` ### Python Location -Currently, mapping-service requires Python to be installed in order to build and to run. At runtime, the Python executable is configured in -`application.properties`(see below). For building the mapping-service Python executable is set to `/usr/bin/python3` by default. In case you want to build -the mapping-service on a machine on which the Python installation is located elsewhere, e.g., under Windows, you can provide the Python location -used at compile time externally, i.e.: +The mapping-service supports plugins running Python code. To provide basic testing for this feature, some tests require configured Python in order to be executed. +While at runtime, the Python executable is configured in application.properties, at build time the Python location may differ depending on the build environment. +By default, '/usr/bin/python' is assumed as Python location. If you are using a different Python installation, e.g., under Windows or MacOS, you may either modify +'build.gradle' (look out for pythonExecutable) or you provide the Python executable as command line argument, e.g., ``` .\gradlew "-DpythonExecutable=file:///C:/Python310/python.exe" build @@ -37,52 +37,49 @@ used at compile time externally, i.e.: Before you can start the mapping-service, you first have to create an `application.properties` file in the source folder. As an example you may use `settings/application.default.properties` and modify it according to your needs. Espacially the following properties (at the end of the file) are important: -- `spring.datasource.url=jdbc:h2:file:/tmp/mapping-service/database` -The path points to the location of the database in which your configured mappings are stored. -- `mapping-service.pythonExecutable=${pythonExecutable:'file:///usr/bin/python3'}` \ -If no pythonExecutable is provided externally (see above) the default `/usr/bin/python3` is used. -- `mapping-service.pluginLocation=file:///tmp/mapping-service/plugins` \ -The local folder where available plugins are located. -- `mapping-service.mappingsLocation:file:///tmp/mapping-service/` \ -Enter the location where you want to store your mappings. This folder will be created if it does not exist yet. -In order to provide the mapping-service with mapping functionality, there are already some pre-compiled plugins available under in the `plugins` folder of this repository. -Copy them to your configured `mapping-service.pluginLocation` to make them available to the mapping-service. -The source code of the gemma-plugin can be found [here](https://github.com/maximilianiKIT/gemma-plugin). The plugin shows how to integrate Python mappings easily. +| Property | Description | Default | +|----------|-------------|---------| +| spring.datasource.url | The path points to the location of the database in which your configured mappings are stored. For production use it is not recommended to use the pre-configured H2 database! | jdbc:h2:file:/tmp/mapping-service/database | +| mapping-service.pythonExecutable | The path to your local Python executable. The default uses the pythonExecutable system property provided via -DpythonExecutable= or file:///usr/bin/python3 if no such system property is provided. | ${pythonExecutable:'file:///usr/bin/python3'} | +| mapping-service.pluginLocation | The local folder from where plugins are loaded. The folder will be created on startup if it does not exist. | None | +| mapping-service.mappingSchemasLocation | The local folder where the mapping files are stored. The folder will be created on startup if it does not exist. | None | +| mapping-service.jobOutput | The local folder where asynchronous mapping execution job outputs are stored. The folder will be created on startup if it does not exist. | None | +| mapping-service.packagesToScan | Packages scanned for mapping plugins in addition to plugins located in mapping-service.pluginLocation. Typically, this property has not the be changed. | edu.kit.datamanager.mappingservice.plugins.impl | +| mapping-service.executionTimeout | The timeout in seconds a plugin process, i.e., Python of Shell, may take before it is assumed to be stale. | 30 | -There is also the possibility to add new plugins directly at the source tree and create a pluggable Jar out of them. Therefor, check -`src/main/java/edu/kit/datamanager/mappingservice/plugins/impl`. Just add your new plugin, e.g., based on the `TestPlugin` example. -In order to make the plugin usable by the mapping service, you then have to build a plugin Jar out of it. In order to do that, just call: +## Creating Mapping Plugins -``` -./gradlew buildPluginJar -``` +There are some sample plugins available at 'edu.kit.datamanager.mappingservice.plugins.impl'. You may add your plugins to the same package and they will be available +for your mapping-service instance (as long as you kept 'mapping-service.packagesToScan' unchanged). -This task creates a file `default-plugins-` at `build/libs` which has to be copied to `mapping-service.pluginLocation` to make it available. +Optionally, you may also develop plugins in an own repository. +However, in order to do so you'll have to build the mapping-service once and you should provide 'build/libs/mapping-service--plain.jar' at +as build time dependency to have the mapping plugin interface available. After building and packaging your plugin, you can copy the resulting jar file +to 'mapping-service.pluginLocation' to make the plugin available in your mapping-service instance. -After doing this, the mapping-service is ready for the first start. This can be achieved by executing: -`java -jar build/lib/mapping-service-.jar` +## Starting the Mapping-Service -This assumes, that the command is called from the source folder and that your `application.properties` is located in the same folder. -Otherwise, you may use: +The executable jar of the mapping-service is located at 'build/libs/mapping-service-.jar' You should copy it to some dedicated folder, +place 'application.properties' next to it, adapt it according to your needs, and startt he mapping-service by calling: -`java -jar build/lib/mapping-service-.jar --spring.config.location=/tmp/application.properties` +`java -jar mapping-service-.jar` -Ideally, for production use, you place everything (`mapping-service-.jar`, `application.properties`, `mapping-service.pluginLocation`, `mapping-service.mappingsLocation`, -and `spring.datasource.url`) in a separate folder from where you then call the mapping-service via: +If your 'application.properties' is located in another folder, you may use the following call: -`java -jar mapping-service-.jar` +`java -jar mapping-service-.jar --spring.config.location=/myConfigFolder/application.properties` ## Installation -There are three ways to install metaStore2 as a microservice: +There are three ways to install the mapping-service as a system service: + - [Using](#Installation-via-GitHub-Packages) the image available via [GitHub Packages](https://github.com/orgs/kit-data-manager/packages?repo_name=mapping-service) (***recommended***) - [Building](#Build-docker-container-locally) docker image locally - [Building](#Build-and-run-locally) and running locally ## Installation via GitHub Packages ### Prerequisites -In order to run this microservice via docker you'll need: +In order to run the mapping-service via docker you'll need: * [Docker](https://www.docker.com/) @@ -110,7 +107,7 @@ user@localhost:/home/user/mapping-service$ ``` #### Create image -Now you'll have to create an image containing the microservice. This can be done via a script. +Now you'll have to create an image containing the mapping-service. This can be done via a script. On default the created images will be tagged as follows: *'latest tag'-'actual date(yyyy-mm-dd)'* (e.g.: 1.1.0-2023-06-27) @@ -128,7 +125,7 @@ user@localhost:/home/user/mapping-service$ ``` #### Build docker container -After building image you have to create (and start) a container for executing microservice: +After building image you have to create (and start) a container for executing the mapping-service: ``` # If you want to use a specific image you may list all possible tags first. user@localhost:/home/user/mapping-service$ docker images ghcr.io/kit-data-manager/mapping-service --format {{.Tag}} diff --git a/build.gradle b/build.gradle index 408ef7b7..dbea6ef4 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ repositories { ext { set('snippetsDir', file('build/generated-snippets')) applicationProperties = System.getProperty('applicationProperties', './src/test/resources/test-config/application-test.properties') - pythonExecutable = System.getProperty('pythonExecutable', "file:///opt/homebrew/bin/python3") + pythonExecutable = System.getProperty('pythonExecutable', "file:///usr/bin/python3") userDir = System.getProperty('user.dir') set('springBootVersion', "3.2.1") set('springDocVersion', "2.8.5") diff --git a/settings/application-default.properties b/settings/application-default.properties index 68c9e581..e07f6dea 100644 --- a/settings/application-default.properties +++ b/settings/application-default.properties @@ -63,4 +63,4 @@ mapping-service.authEnabled:false mapping-service.mappingAdminRole:MAPPING_ADMIN repo.security.enable-csrf=false -repo.security.allowedOriginPattern=http://localhost:* \ No newline at end of file +repo.security.allowedOriginPattern=* \ No newline at end of file diff --git a/settings/application-docker.properties b/settings/application-docker.properties index ce36a129..73ca39fa 100644 --- a/settings/application-docker.properties +++ b/settings/application-docker.properties @@ -50,4 +50,10 @@ mapping-service.mappingSchemasLocation=file://INSTALLATION_DIR/mappingSchemas # Folder where job output files for async mapping executions are stored mapping-service.jobOutput=file://INSTALLATION_DIR/jobOutput # Execution timeout for script calls -mapping-service.executionTimeout=30 \ No newline at end of file +mapping-service.executionTimeout=30 + +mapping-service.authEnabled:false +mapping-service.mappingAdminRole:MAPPING_ADMIN + +repo.security.enable-csrf=false +repo.security.allowedOriginPattern=* \ No newline at end of file diff --git a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java index f8b6e3e3..702089a6 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java @@ -17,6 +17,7 @@ import edu.kit.datamanager.annotations.ExecutableFileURL; import edu.kit.datamanager.annotations.LocalFolderURL; +import edu.kit.datamanager.validator.ExecutableFileValidator; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.beans.factory.annotation.Value; @@ -82,7 +83,7 @@ public class ApplicationProperties { private boolean authEnabled; @Value("${mapping-service.mappingAdminRole:MAPPING_ADMIN}") private String mappingAdminRole; - /** + /** * CORS and CSRF properties */ @Value("${repo.security.allowedOriginPattern:*}") @@ -94,4 +95,13 @@ public class ApplicationProperties { @Value("${repo.security.allowedHeaders:*}") private String[] allowedHeaders; + /** + * Check if configured python executable is valid and executable. + * + * @return TRUE if python executable is valid. + */ + public boolean isPythonAvailable() { + return new ExecutableFileValidator().isValid(pythonExecutable, null); + } + } diff --git a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java index bd478399..eb48f921 100644 --- a/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java +++ b/src/main/java/edu/kit/datamanager/mappingservice/util/PythonRunnerUtil.java @@ -91,7 +91,7 @@ public static MappingPluginState runPythonScript(String script, String... args) * @throws MappingPluginException if an error occurs. */ public static MappingPluginState runPythonScript(String script, OutputStream output, OutputStream error, String... args) throws MappingPluginException { - if (configuration == null || configuration.getPythonExecutable() == null) { + if (configuration == null || !configuration.isPythonAvailable()) { throw new MappingPluginException(MappingPluginState.UNKNOWN_ERROR(), "No Python runtime configured."); } ArrayList command = new ArrayList<>(); diff --git a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java index 6196ac48..1a7bd6ce 100644 --- a/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java +++ b/src/test/java/edu/kit/datamanager/mappingservice/python/util/PythonUtilsTest.java @@ -23,9 +23,7 @@ import org.junit.jupiter.api.Test; import java.io.File; -import org.apache.commons.lang3.Range; import org.hamcrest.CoreMatchers; -import org.hamcrest.core.Is; import org.junit.Assume; import static org.junit.jupiter.api.Assertions.*; @@ -33,7 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; -import org.springframework.util.Assert; /** * @@ -53,6 +50,12 @@ public void setUpClass() { PythonRunnerUtil.init(applicationProperties); } + @Test + public void testPythonAvailable() { + Assume.assumeThat("Python not configured.", applicationProperties.isPythonAvailable(), CoreMatchers.is(true)); + assertTrue(applicationProperties.isPythonAvailable()); + } + /** * Test of run method, of class PythonUtils. */ @@ -77,13 +80,12 @@ public void testRun_3args_withWrongPython() { */ @Test public void testRun_3args_withWrongClass() { - Assume.assumeThat("Python not configured.", Is.is(applicationProperties.getPythonExecutable() == null)); - + Assume.assumeThat("Python not configured.", applicationProperties.isPythonAvailable(), CoreMatchers.is(true)); System.out.println("testRun_3args_withWrongClass"); String scriptLocation = new File("src/test/resources/python/invalid.py").getAbsolutePath(); String[] arguments = null; try { - MappingPluginState state = PythonRunnerUtil.runPythonScript(scriptLocation, arguments); + PythonRunnerUtil.runPythonScript(scriptLocation, arguments); fail("Expected MappingPluginException"); } catch (MappingPluginException e) { assertEquals(MappingPluginState.StateEnum.BAD_EXIT_CODE, e.getMappingPluginState().getState()); @@ -96,9 +98,7 @@ public void testRun_3args_withWrongClass() { */ @Test public void testRun_3args_withTimeout() { - System.out.println("ASSERT " + applicationProperties.getPythonExecutable()); - Assume.assumeThat("Python not configured.", applicationProperties.getPythonExecutable(), CoreMatchers.notNullValue()); - System.out.println("ASSERT TRUE!!!!"); + Assume.assumeThat("Python not configured.", applicationProperties.isPythonAvailable(), CoreMatchers.is(true)); System.out.println("testRun_3args_withTimeout"); String scriptLocation = new File("src/test/resources/python/sleep.py").getAbsolutePath(); String[] arguments = null; diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 new file mode 100644 index 00000000..181c1eff --- /dev/null +++ b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/Activate.ps1 @@ -0,0 +1,405 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" + +# SIG # Begin signature block +# MIIc+QYJKoZIhvcNAQcCoIIc6jCCHOYCAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB/jbdIOBl7aFn0 +# IOwX0LZ7IuNFjwXgmb5mWup4AsyxRaCCC38wggUwMIIEGKADAgECAhAECRgbX9W7 +# ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK +# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV +# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBa +# Fw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy +# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD +# ZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3 +# DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/l +# qJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fT +# eyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqH +# CN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+ +# bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLo +# LFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIB +# yTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK +# BggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9v +# Y3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGln +# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHow +# eDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl +# ZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp +# Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwA +# AgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAK +# BghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0j +# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7s +# DVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGS +# dQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6 +# r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo +# +MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qz +# sIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHq +# aGxEMrJmoecYpJpkUe8wggZHMIIFL6ADAgECAhADPtXtoGXRuMkd/PkqbJvYMA0G +# CSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ +# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0 +# IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTgxMjE4MDAwMDAw +# WhcNMjExMjIyMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU5ldyBI +# YW1wc2hpcmUxEjAQBgNVBAcTCVdvbGZlYm9ybzEjMCEGA1UEChMaUHl0aG9uIFNv +# ZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMTGlB5dGhvbiBTb2Z0d2FyZSBGb3Vu +# ZGF0aW9uMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqr2kS7J1uW7o +# JRxlsdrETAjKarfoH5TI8PWST6Yb2xPooP7vHT4iaVXyL5Lze1f53Jw67Sp+u524 +# fJXf30qHViEWxumy2RWG0nciU2d+mMqzjlaAWSZNF0u4RcvyDJokEV0RUOqI5CG5 +# zPI3W9uQ6LiUk3HCYW6kpH177A5T3pw/Po8O8KErJGn1anaqtIICq99ySxrMad/2 +# hPMBRf6Ndah7f7HPn1gkSSTAoejyuqF5h+B0qI4+JK5+VLvz659VTbAWJsYakkxZ +# xVWYpFv4KeQSSwoo0DzMvmERsTzNvVBMWhu9OriJNg+QfFmf96zVTu93cZ+r7xMp +# bXyfIOGKhHMaRuZ8ihuWIx3gI9WHDFX6fBKR8+HlhdkaiBEWIsXRoy+EQUyK7zUs +# +FqOo2sRYttbs8MTF9YDKFZwyPjn9Wn+gLGd5NUEVyNvD9QVGBEtN7vx87bduJUB +# 8F4DylEsMtZTfjw/au6AmOnmneK5UcqSJuwRyZaGNk7y3qj06utx+HTTqHgi975U +# pxfyrwAqkovoZEWBVSpvku8PVhkBXcLmNe6MEHlFiaMoiADAeKmX5RFRkN+VrmYG +# Tg4zajxfdHeIY8TvLf48tTfmnQJd98geJQv/01NUy/FxuwqAuTkaez5Nl1LxP0Cp +# THhghzO4FRD4itT2wqTh4jpojw9QZnsCAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaA +# FFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBT8Kr9+1L6s84KcpM97IgE7 +# uI8H8jAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0f +# BHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl +# ZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEy +# LWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYI +# KwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQB +# MIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj +# ZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t +# L0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB +# /wQCMAAwDQYJKoZIhvcNAQELBQADggEBAEt1oS21X0axiafPjyY+vlYqjWKuUu/Y +# FuYWIEq6iRRaFabNDhj9RBFQF/aJiE5msrQEOfAD6/6gVSH91lZWBqg6NEeG9T9S +# XbiAPvJ9CEWFsdkXUrjbWhvCnuZ7kqUuU5BAumI1QRbpYgZL3UA+iZXkmjbGh1ln +# 8rUhWIxbBYL4Sg2nqpB44p7CUFYkPj/MbwU2gvBV2pXjj5WaskoZtsACMv5g42BN +# oVLoRAi+ev6s07POt+JtHRIm87lTyuc8wh0swTPUwksKbLU1Zdj9CpqtzXnuVE0w +# 50exJvRSK3Vt4g+0vigpI3qPmDdpkf9+4Mvy0XMNcqrthw20R+PkIlMxghDQMIIQ +# zAIBATCBhjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw +# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEy +# IEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBAhADPtXtoGXRuMkd/PkqbJvYMA0G +# CWCGSAFlAwQCAQUAoIGaMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG +# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC4GCisGAQQBgjcCAQwxIDAeoByAGgBQ +# AHkAdABoAG8AbgAgADMALgAxADAALgAwMC8GCSqGSIb3DQEJBDEiBCBSbvNxuLmL +# Fyf70+vzWnE86JSS2JLTJbh9WhRqgW9MeDANBgkqhkiG9w0BAQEFAASCAgCAiz/E +# icJSsvY4x2vZnY3UjThg0S9qs+r104rhPxj39k4Qw7szI4yjQQbb2bvnoJA3LoFo +# RROlFg9dXJ8YWRZRNkla+zHX7bIsWO2aIFCnOCOUFH19ttlrTvnal6uLp7P9+wQs +# rller1aRyNIM47dYn+CGxD4NEJ/NIqhCjuRKl0v1Dkps/2md0YkoEcnRXNb3vq6x +# +2L9x3zAcBmVwVM4SFFZ2ZZQG/aHgihbVoNxxTXhYDcwaL5uRrNelz9KXDn+GYpk +# K7ZUFbmNfgnhieLHqF0hk7wLZtHI1BSmsOAFrkApcuIVLzD8aSgDbAMVZEv3GkTx +# Img7jKusLIITGuUWT8wO1LDUXT54qBkQhue6kJ3rqSa2agtg/OWxtQ9JwGSOiRaW +# wlRJjsihrw8Nx1Kcr5EwruBBLFiF+mv/C5ikLvwES1ZKoLccqCftuEptcbmsyEZS +# ov39SslaIWvqfy7rfz+KFfP9WHJxobV6DY4essDCMNcoYXkRwhbT+rr0ydDH23DS +# 3hbXpCuKsy5IAMB7Xk8/uuXV2The/qKmkkmu0KuFOu2/3oqVOC4a27IjkvBCSRhp +# /yWQSM/JQk+KwQ31XCVHeGWf7kqMgCXwkZfkw/lvusXzMuWZqT6bfZ0eGjqX/6jC +# kNwr4fCZtxx0cFLzmCr6/yClCYoDCfGoc1I+D6GCDX0wgg15BgorBgEEAYI3AwMB +# MYINaTCCDWUGCSqGSIb3DQEHAqCCDVYwgg1SAgEDMQ8wDQYJYIZIAWUDBAIBBQAw +# dwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQC +# AQUABCBEd30afcCyVMH4hw1ZZPb4JotijhQZtXQ42klvgjTVGwIQDDJTIO6lXwNY +# 7qTonYA8LxgPMjAyMTEwMDQxOTExMzFaoIIKNzCCBP4wggPmoAMCAQICEA1CSuC+ +# Ooj/YEAhzhQA8N0wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNV +# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G +# A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQTAe +# Fw0yMTAxMDEwMDAwMDBaFw0zMTAxMDYwMDAwMDBaMEgxCzAJBgNVBAYTAlVTMRcw +# FQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0 +# YW1wIDIwMjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC5mGEZ8WK +# 9Q0IpEXKY2tR1zoRQr0KdXVNlLQMULUmEP4dyG+RawyW5xpcSO9E5b+bYc0VkWJa +# uP9nC5xj/TZqgfop+N0rcIXeAhjzeG28ffnHbQk9vmp2h+mKvfiEXR52yeTGdnY6 +# U9HR01o2j8aj4S8bOrdh1nPsTm0zinxdRS1LsVDmQTo3VobckyON91Al6GTm3dOP +# L1e1hyDrDo4s1SPa9E14RuMDgzEpSlwMMYpKjIjF9zBa+RSvFV9sQ0kJ/SYjU/aN +# Y+gaq1uxHTDCm2mCtNv8VlS8H6GHq756WwogL0sJyZWnjbL61mOLTqVyHO6fegFz +# +BnW/g1JhL0BAgMBAAGjggG4MIIBtDAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/ +# BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDBBBgNVHSAEOjA4MDYGCWCGSAGG +# /WwHATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMw +# HwYDVR0jBBgwFoAU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHQYDVR0OBBYEFDZEho6k +# urBmvrwoLR1ENt3janq8MHEGA1UdHwRqMGgwMqAwoC6GLGh0dHA6Ly9jcmwzLmRp +# Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtdHMuY3JsMDKgMKAuhixodHRwOi8vY3Js +# NC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDCBhQYIKwYBBQUHAQEE +# eTB3MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTwYIKwYB +# BQUHMAKGQ2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJB +# c3N1cmVkSURUaW1lc3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggEBAEgc +# 3LXpmiO85xrnIA6OZ0b9QnJRdAojR6OrktIlxHBZvhSg5SeBpU0UFRkHefDRBMOG +# 2Tu9/kQCZk3taaQP9rhwz2Lo9VFKeHk2eie38+dSn5On7UOee+e03UEiifuHokYD +# Tvz0/rdkd2NfI1Jpg4L6GlPtkMyNoRdzDfTzZTlwS/Oc1np72gy8PTLQG8v1Yfx1 +# CAB2vIEO+MDhXM/EEXLnG2RJ2CKadRVC9S0yOIHa9GCiurRS+1zgYSQlT7LfySmo +# c0NR2r1j1h9bm/cuG08THfdKDXF+l7f0P4TrweOjSaH6zqe/Vs+6WXZhiV9+p7SO +# Z3j5NpjhyyjaW4emii8wggUxMIIEGaADAgECAhAKoSXW1jIbfkHkBdo2l8IVMA0G +# CSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ +# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0 +# IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBaFw0zMTAxMDcxMjAw +# MDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV +# BAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNz +# dXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +# ggEKAoIBAQC90DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQfdD5fU1ofue2oPSN +# s4jkl79jIZCYvxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9lP+Cb6+NGRwYaVX4L +# J37AovWg4N4iPw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3ImgtU46gJcWvgzyIQ +# D3XPcXJOCq3fQDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDqR9mIUF79Zm5WYScp +# iYRR5oLnRlD9lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZchfxFwbvPc3WTe8G +# Qv2iUypPhR3EHTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIByjAdBgNVHQ4EFgQU +# 9LbhIB3+Ka7S5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6ch +# nfNtyA8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0l +# BAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRw +# Oi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRz +# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1Ud +# HwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz +# c3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv +# bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0gBEkwRzA4BgpghkgB +# hv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9D +# UFMwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBxlRLpUYdWac3v3dp8 +# qmN6s3jPBjdAhO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3BTQdaq6Z+CeiZr8J +# qmDfdqQ6kw/4stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy23UC4HLHmNY8ZOUf +# SBAYX4k4YU1iRiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWThZN+tpJn+1Nhiaj1 +# a5bA9FhpDXzIAbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZspe6HUSHkWGCbugwt +# K22ixH67xCUrRwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VWMyIvIjayS6JKldj1 +# po5SMYIChjCCAoICAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD +# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln +# aUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQQIQDUJK4L46iP9g +# QCHOFADw3TANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcN +# AQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIxMTAwNDE5MTEzMVowKwYLKoZIhvcNAQkQ +# AgwxHDAaMBgwFgQU4deCqOGRvu9ryhaRtaq0lKYkm/MwLwYJKoZIhvcNAQkEMSIE +# ILvICiD0Bu7OdD0pC2wAqLO9UGMzUOfGejuSENvWkuXdMDcGCyqGSIb3DQEJEAIv +# MSgwJjAkMCIEILMQkAa8CtmDB5FXKeBEA0Fcg+MpK2FPJpZMjTVx7PWpMA0GCSqG +# SIb3DQEBAQUABIIBAIaCoJWKRd6cHB/KrrlVmBY469068xG7ok+T18bfcLmNrvPF +# 7PGY5a4qcMZj+rBevyfWTrOreNAWyNhnxIT0qYneSTJOMytTPYnJI+GhvGwQjDhC +# Eg/JeLOe9guMq7P/ZNvFur+VoCz6sgR/Q+9IGUhJ/7liABdMwNLK38r5VEaSAnSW +# RetjuSqtMoZc2KtjL/MUY26sUwjsMD0tgt0EOF4nrcv3rWl++TsJUEqYr+aFpNu4 +# eVaTNeS0V7sRGQbWAQohkES879Lpqv7KaEW+h426+cc5el260gynz7vTzUuaamvW +# Nfbvu83P5Tk1nRA1Ds2aSqn/RMu6cNNjD8ntV5o= +# SIG # End signature block diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate new file mode 100644 index 00000000..8b73b92a --- /dev/null +++ b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="E:\Software\NetbeansProjects\mapping-service\tmp\PythonCheckPlugin\1.1.2-SNAPSHOT\venv\PluginVenv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(PluginVenv) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(PluginVenv) " + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat new file mode 100644 index 00000000..9d82899c --- /dev/null +++ b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/activate.bat @@ -0,0 +1,34 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set VIRTUAL_ENV=E:\Software\NetbeansProjects\mapping-service\tmp\PythonCheckPlugin\1.1.2-SNAPSHOT\venv\PluginVenv + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=(PluginVenv) %PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set PATH=%VIRTUAL_ENV%\Scripts;%PATH% +set VIRTUAL_ENV_PROMPT=(PluginVenv) + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat new file mode 100644 index 00000000..62a39a75 --- /dev/null +++ b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/deactivate.bat @@ -0,0 +1,22 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= +set VIRTUAL_ENV_PROMPT= + +:END diff --git a/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip.exe b/tmp/PythonCheckPlugin/1.1.2-SNAPSHOT/venv/PluginVenv/Scripts/pip.exe new file mode 100644 index 0000000000000000000000000000000000000000..01cdf58b3adc8d405715fca33493e17abc4c3280 GIT binary patch literal 106427 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%0DR4z)WQcb>Rku)_txjy8TEHVs#H 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%0DqcKFn%RX-DF>qCHtfd(>0m&Tp(1(DRhHdoti)C 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%0DS07BAj6-njF-qy0mJ8pj3rJ?3!<- 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 z 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