diff --git a/.github/workflows/automate-projects.yml b/.github/workflows/automate-projects.yml index ec3166d7..c907722c 100644 --- a/.github/workflows/automate-projects.yml +++ b/.github/workflows/automate-projects.yml @@ -14,14 +14,14 @@ jobs: steps: - name: add-new-issues-to-organization-based-project-column if: github.event_name == 'issues' && github.event.action == 'opened' - uses: alex-page/github-project-automation-plus@v0.8.2 + uses: alex-page/github-project-automation-plus@v0.8.3 with: project: CoMPAS Issues Overview Board column: To do repo-token: ${{ secrets.ORG_GITHUB_ACTION_SECRET }} - name: add-new-pull-request-to-organization-based-project-column if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.action == 'opened' - uses: alex-page/github-project-automation-plus@v0.8.2 + uses: alex-page/github-project-automation-plus@v0.8.3 with: project: CoMPAS Pull Request Overview Board column: To do diff --git a/app/src/main/docker/Dockerfile-basex.jvm b/app/src/main/docker/Dockerfile-basex.jvm index e4aade5f..66d7ce10 100644 --- a/app/src/main/docker/Dockerfile-basex.jvm +++ b/app/src/main/docker/Dockerfile-basex.jvm @@ -21,7 +21,7 @@ # docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/app-jvm # ### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-923 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-1085 ARG JAVA_PACKAGE=java-17-openjdk-headless ARG RUN_JAVA_VERSION=1.3.8 diff --git a/app/src/main/docker/Dockerfile-basex.native b/app/src/main/docker/Dockerfile-basex.native index 14b0b3ec..7cf1b486 100644 --- a/app/src/main/docker/Dockerfile-basex.native +++ b/app/src/main/docker/Dockerfile-basex.native @@ -14,7 +14,7 @@ # docker run -i --rm -p 8080:8080 quarkus/app # ### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-923 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-1085 WORKDIR /work/ RUN chown 1001 /work \ && chmod "g+rwX" /work \ diff --git a/app/src/main/docker/Dockerfile-postgresql.jvm b/app/src/main/docker/Dockerfile-postgresql.jvm index f37f05fa..80ad6494 100644 --- a/app/src/main/docker/Dockerfile-postgresql.jvm +++ b/app/src/main/docker/Dockerfile-postgresql.jvm @@ -21,7 +21,7 @@ # docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/app-jvm # ### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-923 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-1085 ARG JAVA_PACKAGE=java-17-openjdk-headless ARG RUN_JAVA_VERSION=1.3.8 diff --git a/app/src/main/docker/Dockerfile-postgresql.native b/app/src/main/docker/Dockerfile-postgresql.native index 1065b351..d33b2a19 100644 --- a/app/src/main/docker/Dockerfile-postgresql.native +++ b/app/src/main/docker/Dockerfile-postgresql.native @@ -14,7 +14,7 @@ # docker run -i --rm -p 8080:8080 quarkus/app # ### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-923 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7-1085 WORKDIR /work/ RUN chown 1001 /work \ && chmod "g+rwX" /work \ diff --git a/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResource.java b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResource.java index f6ce9f30..5bad7160 100644 --- a/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResource.java +++ b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResource.java @@ -143,4 +143,17 @@ public Uni deleteVersion(@PathParam(TYPE_PATH_PARAM) SclFileType type, compasSclDataService.delete(type, id, version); return Uni.createFrom().nullItem(); } + + @POST + @Path("/checkname") + @Consumes(MediaType.APPLICATION_XML) + @Produces(MediaType.APPLICATION_XML) + public Uni checkDuplicateName(@PathParam(TYPE_PATH_PARAM) SclFileType type, + @Valid DuplicateNameCheckRequest request) { + LOGGER.info("Checking for duplicate SCL File name."); + + var response = new DuplicateNameCheckResponse(); + response.setDuplicate(compasSclDataService.hasDuplicateSclName(type, request.getName())); + return Uni.createFrom().item(response); + } } diff --git a/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckRequest.java b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckRequest.java new file mode 100644 index 00000000..32827e8e --- /dev/null +++ b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckRequest.java @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2022 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.scl.data.rest.v1.model; + +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.lfenergy.compas.core.commons.constraint.FilenameValid; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import static org.lfenergy.compas.scl.data.SclDataServiceConstants.SCL_DATA_SERVICE_V1_NS_URI; + +@Schema(description = "Request to check for duplicate names.") +@XmlRootElement(name = "DuplicateNameCheckRequest", namespace = SCL_DATA_SERVICE_V1_NS_URI) +@XmlAccessorType(XmlAccessType.FIELD) +public class DuplicateNameCheckRequest { + @FilenameValid + @Schema(description = "The name that will be stored as Private Element and can later be used to determine the filename.", + example = "STATION-0012312") + @XmlElement(name = "Name", namespace = SCL_DATA_SERVICE_V1_NS_URI, required = true) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckResponse.java b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckResponse.java new file mode 100644 index 00000000..0cb1ba22 --- /dev/null +++ b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckResponse.java @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2022 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.scl.data.rest.v1.model; + +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import static org.lfenergy.compas.scl.data.SclDataServiceConstants.SCL_DATA_SERVICE_V1_NS_URI; + +@Schema(description = "Response from duplicate name check in the database.") +@XmlRootElement(name = "DuplicateNameCheckResponse", namespace = SCL_DATA_SERVICE_V1_NS_URI) +@XmlAccessorType(XmlAccessType.FIELD) +public class DuplicateNameCheckResponse { + @Schema(description = "Boolean result for duplicate name check.") + @XmlElement(name = "Duplicate", namespace = SCL_DATA_SERVICE_V1_NS_URI) + private boolean duplicate; + + public boolean isDuplicate() { + return duplicate; + } + + public void setDuplicate(boolean duplicate) { + this.duplicate = duplicate; + } +} diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties index 07b1add8..88e84e90 100644 --- a/app/src/main/resources/application.properties +++ b/app/src/main/resources/application.properties @@ -60,6 +60,11 @@ quarkus.http.auth.permission.SSD_DELETE_DELETE.paths=/compas-scl-data-service/sc quarkus.http.auth.permission.SSD_DELETE_DELETE.policy=SSD_DELETE quarkus.http.auth.permission.SSD_DELETE_DELETE.methods=DELETE +quarkus.http.auth.policy.SSD_CHECK_NAME.roles-allowed=SSD_READ +quarkus.http.auth.permission.SSD_CHECK_NAME.paths=/compas-scl-data-service/scl/v1/SSD/checkname +quarkus.http.auth.permission.SSD_CHECK_NAME.policy=SSD_READ +quarkus.http.auth.permission.SSD_CHECK_NAME.methods=POST + quarkus.http.auth.permission.SSD_READ_GET_WS.paths=/compas-scl-data-service/scl-ws/v1/SSD/get quarkus.http.auth.permission.SSD_READ_GET_WS.policy=SSD_READ quarkus.http.auth.permission.SSD_READ_GET_VERSION_WS.paths=/compas-scl-data-service/scl-ws/v1/SSD/get-version @@ -137,7 +142,6 @@ quarkus.http.auth.policy.SCD_DELETE.roles-allowed=SCD_DELETE quarkus.http.auth.permission.SCD_DELETE_DELETE.paths=/compas-scl-data-service/scl/v1/SCD/* quarkus.http.auth.permission.SCD_DELETE_DELETE.policy=SCD_DELETE quarkus.http.auth.permission.SCD_DELETE_DELETE.methods=DELETE - quarkus.http.auth.permission.SCD_READ_GET_WS.paths=/compas-scl-data-service/scl-ws/v1/SCD/get quarkus.http.auth.permission.SCD_READ_GET_WS.policy=SCD_READ quarkus.http.auth.permission.SCD_READ_GET_VERSION_WS.paths=/compas-scl-data-service/scl-ws/v1/SCD/get-version @@ -147,6 +151,11 @@ quarkus.http.auth.permission.SCD_CREATE_POST_WS.policy=SCD_CREATE quarkus.http.auth.permission.SCD_UPDATE_PUT_WS.paths=/compas-scl-data-service/scl-ws/v1/SCD/update quarkus.http.auth.permission.SCD_UPDATE_PUT_WS.policy=SCD_UPDATE +quarkus.http.auth.policy.SCD_CHECK_NAME.roles-allowed=SCD_READ +quarkus.http.auth.permission.SCD_CHECK_NAME.paths=/compas-scl-data-service/scl/v1/SCD/checkname +quarkus.http.auth.permission.SCD_CHECK_NAME.policy=SCD_READ +quarkus.http.auth.permission.SCD_CHECK_NAME.methods=POST + quarkus.http.auth.policy.CID_READ.roles-allowed=CID_READ quarkus.http.auth.permission.CID_READ_GET.paths=/compas-scl-data-service/scl/v1/CID/* quarkus.http.auth.permission.CID_READ_GET.policy=CID_READ @@ -249,4 +258,4 @@ quarkus.http.auth.permission.STD_READ_GET_VERSION_WS.policy=STD_READ quarkus.http.auth.permission.STD_CREATE_POST_WS.paths=/compas-scl-data-service/scl-ws/v1/STD/create quarkus.http.auth.permission.STD_CREATE_POST_WS.policy=STD_CREATE quarkus.http.auth.permission.STD_UPDATE_PUT_WS.paths=/compas-scl-data-service/scl-ws/v1/STD/update -quarkus.http.auth.permission.STD_UPDATE_PUT_WS.policy=STD_UPDATE +quarkus.http.auth.permission.STD_UPDATE_PUT_WS.policy=STD_UPDATE \ No newline at end of file diff --git a/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResourceAsEditorTest.java b/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResourceAsEditorTest.java index 34dc5252..cfb1265c 100644 --- a/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResourceAsEditorTest.java +++ b/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/CompasSclDataResourceAsEditorTest.java @@ -16,6 +16,7 @@ import org.lfenergy.compas.scl.data.model.Item; import org.lfenergy.compas.scl.data.model.Version; import org.lfenergy.compas.scl.data.rest.v1.model.CreateRequest; +import org.lfenergy.compas.scl.data.rest.v1.model.DuplicateNameCheckRequest; import org.lfenergy.compas.scl.data.rest.v1.model.UpdateRequest; import org.lfenergy.compas.scl.data.service.CompasSclDataService; import org.lfenergy.compas.scl.extensions.model.SclFileType; @@ -27,7 +28,7 @@ import static io.restassured.RestAssured.given; import static io.restassured.path.xml.config.XmlPathConfig.xmlPathConfig; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import static org.lfenergy.compas.scl.data.SclDataServiceConstants.SCL_NS_URI; import static org.lfenergy.compas.scl.data.rest.Constants.*; import static org.mockito.Mockito.*; @@ -267,6 +268,54 @@ void deleteVersion_WhenCalled_ThenServiceCalled() { verify(compasSclDataService).delete(type, uuid, version); } + @Test + void checkNameForDuplication_WhenCalled_WithDuplicateName_ThenServiceCalled() { + var type = SclFileType.SCD; + var name = "STATION-0012312"; + + when(compasSclDataService.hasDuplicateSclName(type, name)).thenReturn(true); + + var request = new DuplicateNameCheckRequest(); + request.setName(name); + + var response = given() + .pathParam(TYPE_PATH_PARAM, type) + .contentType(ContentType.XML) + .body(request) + .when().post("/checkname") + .then() + .statusCode(200) + .extract() + .response(); + + verify(compasSclDataService).hasDuplicateSclName(type, name); + assertTrue(response.xmlPath().getBoolean("DuplicateNameCheckResponse.Duplicate")); + } + + @Test + void checkNameForDuplication_WhenCalled_WithUniqueName_ThenServiceCalled() { + var type = SclFileType.SCD; + var name = "STATION-0012312"; + + when(compasSclDataService.hasDuplicateSclName(type, name)).thenReturn(false); + + var request = new DuplicateNameCheckRequest(); + request.setName(name); + + var response = given() + .pathParam(TYPE_PATH_PARAM, type) + .contentType(ContentType.XML) + .body(request) + .when().post("/checkname") + .then() + .statusCode(200) + .extract() + .response(); + + verify(compasSclDataService).hasDuplicateSclName(type, name); + assertFalse(response.xmlPath().getBoolean("DuplicateNameCheckResponse.Duplicate")); + } + private String readSCL() throws IOException { try (var inputStream = getClass().getResourceAsStream("/scl/icd_import_ied_test.scd")) { assert inputStream != null; diff --git a/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckRequestTest.java b/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckRequestTest.java new file mode 100644 index 00000000..e037f693 --- /dev/null +++ b/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckRequestTest.java @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2022 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.scl.data.rest.v1.model; + +class DuplicateNameCheckRequestTest extends AbstractPojoTester { + @Override + protected Class getClassToBeTested() { + return DuplicateNameCheckRequest.class; + } +} \ No newline at end of file diff --git a/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckResponseTest.java b/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckResponseTest.java new file mode 100644 index 00000000..6c5d8075 --- /dev/null +++ b/app/src/test/java/org/lfenergy/compas/scl/data/rest/v1/model/DuplicateNameCheckResponseTest.java @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2022 Alliander N.V. +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.scl.data.rest.v1.model; + +class DuplicateNameCheckResponseTest extends AbstractPojoTester{ + + @Override + protected Class getClassToBeTested() { + return DuplicateNameCheckResponse.class; + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index b4b80c87..eb6ad634 100644 --- a/pom.xml +++ b/pom.xml @@ -20,15 +20,15 @@ SPDX-License-Identifier: Apache-2.0 UTF-8 3.10.1 - 3.0.0-M7 + 3.0.0-M9 3.2.0 0.12.0 + 2.16.3.Final - 2.14.1.Final - 2.3.7 + 2.3.8 3.1 - 2.19.0 + 2.20.0 0.9.1 @@ -278,7 +278,7 @@ SPDX-License-Identifier: Apache-2.0 org.apache.maven.plugins maven-javadoc-plugin - 3.4.1 + 3.5.0 attach-javadocs diff --git a/repository-postgresql/src/main/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepository.java b/repository-postgresql/src/main/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepository.java index 46394e23..bf1a937f 100644 --- a/repository-postgresql/src/main/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepository.java +++ b/repository-postgresql/src/main/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepository.java @@ -191,7 +191,7 @@ public String findByUUID(SclFileType type, UUID id, Version version) { @Transactional(SUPPORTS) public boolean hasDuplicateSclName(SclFileType type, String name) { var sql = """ - select distinct on (scl_file.id) * + select distinct on (scl_file.id) scl_file.name from scl_file where scl_file.type = ? order by scl_file.id diff --git a/repository-postgresql/src/test/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepositoryTest.java b/repository-postgresql/src/test/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepositoryTest.java index 6f4c54e1..4fafb2d4 100644 --- a/repository-postgresql/src/test/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepositoryTest.java +++ b/repository-postgresql/src/test/java/org/lfenergy/compas/scl/data/repository/postgresql/CompasSclDataPostgreSQLRepositoryTest.java @@ -29,9 +29,6 @@ void beforeEach() { repository = new CompasSclDataPostgreSQLRepository(PostgreSQLServerJUnitExtension.getDataSource()); } - /* - * TODO: Method beneath needs to be moved to AbstractCompasSclDataRepositoryTest - * when hasDuplicateSclName has been implemented by CompasSclDataBaseXRepository. */ @Test void hasDuplicateSclName_WhenUsingSclNameThatHasBeenUsedYet_ThenDuplicateIsFound() { var expectedVersion = new Version(1, 0, 0); diff --git a/service/src/main/java/org/lfenergy/compas/scl/data/service/CompasSclDataService.java b/service/src/main/java/org/lfenergy/compas/scl/data/service/CompasSclDataService.java index fbae11dd..b0f5bfd7 100644 --- a/service/src/main/java/org/lfenergy/compas/scl/data/service/CompasSclDataService.java +++ b/service/src/main/java/org/lfenergy/compas/scl/data/service/CompasSclDataService.java @@ -122,7 +122,7 @@ public String create(SclFileType type, String name, String who, String comment, throw new CompasException(NO_SCL_ELEMENT_FOUND_ERROR_CODE, "No valid SCL found in the passed SCL Data."); } - if (repository.hasDuplicateSclName(type, name)) { + if (hasDuplicateSclName(type, name)) { throw new CompasException(DUPLICATE_SCL_NAME_ERROR_CODE, "Given name of SCL File already used."); } @@ -147,6 +147,10 @@ public String create(SclFileType type, String name, String who, String comment, return newSclData; } + public boolean hasDuplicateSclName(SclFileType type, String name){ + return repository.hasDuplicateSclName(type, name); + } + /** * Create a new version of a specific SCL XML File. The content will be the passed SCL XML File. * The UUID and new version (depending on the passed ChangeSetType) are set and