From 6c6e49f9e4d274db26a513492a8e897e29667ec0 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 13 Jul 2022 16:16:14 +0200 Subject: [PATCH 1/9] Upgrade to JDK 17, include using TextBlocks Signed-off-by: Dennis Labordus --- .github/workflows/build-project.yml | 4 +- .github/workflows/release-project.yml | 4 +- .github/workflows/sonarcloud-analysis.yml | 4 +- .mvn/wrapper/maven-wrapper.properties | 20 +- app/src/main/docker/Dockerfile-basex.jvm | 2 +- app/src/main/docker/Dockerfile-postgresql.jvm | 2 +- pom.xml | 13 +- .../CompasSclDataBaseXRepository.java | 187 ++++++++++-------- .../CompasSclDataBaseXRepositoryTest.java | 15 +- .../test/resources/simplelogger.properties | 14 ++ .../CompasSclDataPostgreSQLRepository.java | 174 ++++++++-------- ...CompasSclDataPostgreSQLRepositoryTest.java | 6 +- ... AbstractCompasSclDataRepositoryTest.java} | 2 +- 13 files changed, 257 insertions(+), 190 deletions(-) create mode 100644 repository-basex/src/test/resources/simplelogger.properties rename repository/src/test/java/org/lfenergy/compas/scl/data/repository/{AbstractCompasSclDataRepository.java => AbstractCompasSclDataRepositoryTest.java} (99%) diff --git a/.github/workflows/build-project.yml b/.github/workflows/build-project.yml index 311e4881..f9c3d973 100644 --- a/.github/workflows/build-project.yml +++ b/.github/workflows/build-project.yml @@ -37,11 +37,11 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: Set up JDK 1.11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Create custom Maven Settings.xml uses: whelk-io/maven-settings-xml-action@v20 diff --git a/.github/workflows/release-project.yml b/.github/workflows/release-project.yml index 10f153f1..7825637e 100644 --- a/.github/workflows/release-project.yml +++ b/.github/workflows/release-project.yml @@ -42,11 +42,11 @@ jobs: shell: bash # Extra the tagname form the git reference, value of GITHUB_REF will be something like refs/tags/. run: echo "##[set-output name=tagname;]$(echo ${GITHUB_REF##*/})" - - name: Set up JDK 1.11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Create custom Maven Settings.xml uses: whelk-io/maven-settings-xml-action@v20 diff --git a/.github/workflows/sonarcloud-analysis.yml b/.github/workflows/sonarcloud-analysis.yml index 46ad09d2..5e0841d6 100644 --- a/.github/workflows/sonarcloud-analysis.yml +++ b/.github/workflows/sonarcloud-analysis.yml @@ -30,11 +30,11 @@ jobs: with: fetch-depth: 0 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Cache SonarCloud packages uses: actions/cache@v3 with: diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index ffdc10e5..41d82133 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,18 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/app/src/main/docker/Dockerfile-basex.jvm b/app/src/main/docker/Dockerfile-basex.jvm index cf607ded..0e014d4f 100644 --- a/app/src/main/docker/Dockerfile-basex.jvm +++ b/app/src/main/docker/Dockerfile-basex.jvm @@ -23,7 +23,7 @@ ### FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 -ARG JAVA_PACKAGE=java-11-openjdk-headless +ARG JAVA_PACKAGE=java-17-openjdk-headless ARG RUN_JAVA_VERSION=1.3.8 ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' # Install java and the run-java script diff --git a/app/src/main/docker/Dockerfile-postgresql.jvm b/app/src/main/docker/Dockerfile-postgresql.jvm index 7e3a8dbf..2781babf 100644 --- a/app/src/main/docker/Dockerfile-postgresql.jvm +++ b/app/src/main/docker/Dockerfile-postgresql.jvm @@ -23,7 +23,7 @@ ### FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 -ARG JAVA_PACKAGE=java-11-openjdk-headless +ARG JAVA_PACKAGE=java-17-openjdk-headless ARG RUN_JAVA_VERSION=1.3.8 ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' # Install java and the run-java script diff --git a/pom.xml b/pom.xml index 36956906..b1b65d6d 100644 --- a/pom.xml +++ b/pom.xml @@ -15,8 +15,7 @@ SPDX-License-Identifier: Apache-2.0 true - 11 - 11 + 17 UTF-8 UTF-8 @@ -181,11 +180,11 @@ SPDX-License-Identifier: Apache-2.0 maven-jar-plugin 3.2.2 - - - test-jar - - + + + test-jar + + diff --git a/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java b/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java index 5944438d..0649fa48 100644 --- a/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java +++ b/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.UUID; -import static java.lang.String.format; import static org.lfenergy.compas.scl.data.SclDataServiceConstants.*; import static org.lfenergy.compas.scl.data.exception.CompasSclDataServiceErrorCode.BASEX_COMMAND_ERROR_CODE; import static org.lfenergy.compas.scl.data.exception.CompasSclDataServiceErrorCode.BASEX_QUERY_ERROR_CODE; @@ -42,32 +41,30 @@ public class CompasSclDataBaseXRepository implements CompasSclDataRepository { private static final Logger LOGGER = LoggerFactory.getLogger(CompasSclDataBaseXRepository.class); - private static final String DECLARE_SCL_NS_URI = "declare namespace scl=\"" + SCL_NS_URI + "\";\n"; - private static final String DECLARE_COMPAS_NAMESPACE = "declare namespace compas=\"" + COMPAS_EXTENSION_NS_URI + "\";\n"; + private static final String DECLARE_NS_AND_VARS = """ + declare namespace scl = "%s"; + declare namespace compas = "%s"; + + declare variable $compasSclExtensionType := '%s'; + declare variable $compasDataServiceNamespace := '%s'; + """.formatted(SCL_NS_URI, COMPAS_EXTENSION_NS_URI, COMPAS_SCL_EXTENSION_TYPE, SCL_DATA_SERVICE_V1_NS_URI); // This find method always searches for the latest version. // Retrieve all versions using db:list-details function. // Sort the result descending, this way the last version is the first. - private static final String DECLARE_LATEST_VERSION_FUNC = - "declare function local:latest-version($db as xs:string, $id as xs:string)\n" + - " as document-node()? { \n" + - " let $doc :=\n" + - " (for $resource in db:open($db, $id)\n" + - " let $parts := tokenize($resource/scl:SCL/scl:Header/@version, '\\.')\n" + - " let $majorVersion := xs:int($parts[1])\n" + - " let $minorVersion := xs:int($parts[2])\n" + - " let $patchVersion := xs:int($parts[3])\n" + - " order by $majorVersion descending, $minorVersion descending, $patchVersion descending\n" + - " return $resource\n" + - " )[1]\n" + - " return $doc\n" + - "};\n"; - private static final String DECLARE_DB_VARIABLE = "declare variable $db := '%s';\n"; - private static final String DECLARE_ID_VARIABLE = "declare variable $id := '%s';\n"; - private static final String DECLARE_PATH_VARIABLE = "declare variable $path := '%s';\n"; - - private static final String SCL_HEADER_ID_XPATH = "/scl:SCL/scl:Header/@id"; - private static final String SCL_HEADER_VERSION_XPATH = "/scl:SCL/scl:Header/@version"; - private static final String COMPAS_NAME_EXTENSION_XPATH = "/scl:SCL/scl:Private[@type='" + COMPAS_SCL_EXTENSION_TYPE + "']/compas:" + COMPAS_SCL_NAME_EXTENSION; + private static final String DECLARE_LATEST_VERSION_FUNC = """ + declare function local:latest-version($db as xs:string, $id as xs:string) as document-node()? { + let $doc := + (for $resource in db:open($db, $id) + let $parts := tokenize($resource/scl:SCL/scl:Header/@version, '\\.') + let $majorVersion := xs:int($parts[1]) + let $minorVersion := xs:int($parts[2]) + let $patchVersion := xs:int($parts[3]) + order by $majorVersion descending, $minorVersion descending, $patchVersion descending + return $resource + )[1] + return $doc + }; + """; private final BaseXClientFactory baseXClientFactory; private final SclDataModelMarshaller sclDataMarshaller; @@ -80,66 +77,77 @@ public CompasSclDataBaseXRepository(BaseXClientFactory baseXClientFactory, // At startup create all needed databases. Arrays.stream(SclFileType.values()).forEach(type -> executeCommand(client -> { - client.executeXQuery( - format(DECLARE_DB_VARIABLE, type) + - "if (not(db:exists($db)))\n" + - " then db:create($db)"); + client.executeXQuery(""" + declare variable $db := '%s'; + if (not(db:exists($db))) + then + db:create($db) + """.formatted(type)); return true; })); } @Override public List list(SclFileType type) { - return executeQuery(type, DECLARE_SCL_NS_URI + - DECLARE_COMPAS_NAMESPACE + - DECLARE_LATEST_VERSION_FUNC + - format(DECLARE_DB_VARIABLE, type) + - "for $resource in db:open($db)\n" + - " let $id := $resource" + SCL_HEADER_ID_XPATH + "\n" + - " group by $id\n" + - " let $latestScl := local:latest-version($db, $id)\n" + - " let $version := $latestScl" + SCL_HEADER_VERSION_XPATH + "\n" + - " let $name := $latestScl" + COMPAS_NAME_EXTENSION_XPATH + "\n" + - " order by fn:lower-case($name)\n" + - " return '' || $id || '' || $name || '' || $version || ''", + return executeQuery(type, """ + %s + %s + declare variable $db := '%s'; + for $resource in db:open($db) + let $id := $resource/scl:SCL/scl:Header/@id + group by $id + let $latestScl := local:latest-version($db, $id) + let $version := $latestScl/scl:SCL/scl:Header/@version + let $name := $latestScl/scl:SCL/scl:Private[@type=$compasSclExtensionType]/compas:SclName + order by fn:lower-case($name) + return '' + || ' ' || $id || '' + || ' ' || $name || '' + || ' ' || $version || '' + || '' + """.formatted(DECLARE_NS_AND_VARS, DECLARE_LATEST_VERSION_FUNC, type) + , sclDataMarshaller::unmarshalItem); } @Override public List listVersionsByUUID(SclFileType type, UUID id) { - return executeQuery(type, DECLARE_SCL_NS_URI + - DECLARE_COMPAS_NAMESPACE + - format(DECLARE_DB_VARIABLE, type) + - format(DECLARE_ID_VARIABLE, id) + - "for $resource in db:open($db, $id)\n" + - " let $id := $resource" + SCL_HEADER_ID_XPATH + "\n" + - " let $version := $resource" + SCL_HEADER_VERSION_XPATH + "\n" + - " let $name := $resource" + COMPAS_NAME_EXTENSION_XPATH + "\n" + - " let $header := ($resource/scl:SCL/scl:Header/scl:History/scl:Hitem[(not(@revision) or @revision=\"\") and @version=$version])[1]\n" + - " let $parts := tokenize($version, '\\.')\n" + - " let $majorVersion := xs:int($parts[1])\n" + - " let $minorVersion := xs:int($parts[2])\n" + - " let $patchVersion := xs:int($parts[3])\n" + - " order by $majorVersion, $minorVersion, $patchVersion\n" + - " return ''" + - " || ' ' || $id || ''" + - " || ' ' || $name || ''" + - " || ' ' || $version || '' " + - " || ' ' || $header/@who || '' " + - " || ' ' || $header/@when || '' " + - " || ' ' || $header/@what || '' " + - " || '' ", + return executeQuery(type, """ + %s + declare variable $db := '%s'; + declare variable $id := '%s'; + for $resource in db:open($db, $id) + let $version := $resource/scl:SCL/scl:Header/@version + let $name := $resource/scl:SCL/scl:Private[@type=$compasSclExtensionType]/compas:SclName + let $header := ($resource/scl:SCL/scl:Header/scl:History/scl:Hitem[(not(@revision) or @revision="") and @version=$version])[1] + let $parts := tokenize($version, '\\.') + let $majorVersion := xs:int($parts[1]) + let $minorVersion := xs:int($parts[2]) + let $patchVersion := xs:int($parts[3]) + order by $majorVersion, $minorVersion, $patchVersion + return '' + || ' ' || $id || '' + || ' ' || $name || '' + || ' ' || $version || '' + || ' ' || $header/@who || '' + || ' ' || $header/@when || '' + || ' ' || $header/@what || '' + || '' + """.formatted(DECLARE_NS_AND_VARS, type, id), sclDataMarshaller::unmarshalHistoryItem); } @Override public String findByUUID(SclFileType type, UUID id) { // This find method always searches for the latest version and returns this. - var result = executeQuery(type, DECLARE_SCL_NS_URI + - DECLARE_LATEST_VERSION_FUNC + - format(DECLARE_DB_VARIABLE, type) + - format(DECLARE_ID_VARIABLE, id) + - "local:latest-version($db, $id)"); + var result = executeQuery(type, """ + %s + %s + declare variable $db := '%s'; + declare variable $id := '%s'; + local:latest-version($db, $id) + """.formatted(DECLARE_NS_AND_VARS, DECLARE_LATEST_VERSION_FUNC, type, id) + ); if (result.isEmpty()) { var message = String.format("No record found for type '%s' with ID '%s'", type, id); @@ -151,9 +159,12 @@ public String findByUUID(SclFileType type, UUID id) { @Override public String findByUUID(SclFileType type, UUID id, Version version) { // This find method searches for a specific version. - var result = executeQuery(type, format(DECLARE_DB_VARIABLE, type) + - format(DECLARE_PATH_VARIABLE, createDocumentPath(id, version)) + - "db:open($db, $path)"); + var result = executeQuery(type, """ + declare variable $db := '%s'; + declare variable $path := '%s'; + db:open($db, $path) + """.formatted(type, createDocumentPath(id, version)) + ); if (result.isEmpty()) { var message = String.format("No record found for type '%s' with ID '%s' and version '%s'", type, id, version); @@ -171,19 +182,23 @@ public boolean hasDuplicateSclName(SclFileType type, String name) { public SclMetaInfo findMetaInfoByUUID(SclFileType type, UUID id) { // This find method always searches for the latest version. // Extracts the needed information from the document and returns this. - var metaInfo = executeQuery(type, DECLARE_SCL_NS_URI + - DECLARE_COMPAS_NAMESPACE + - DECLARE_LATEST_VERSION_FUNC + - format(DECLARE_DB_VARIABLE, type) + - format(DECLARE_ID_VARIABLE, id) + - "let $resource := local:latest-version($db, $id)" + - "return if ($resource)\n" + - "then (\n" + - " let $id := $resource" + SCL_HEADER_ID_XPATH + "\n" + - " let $version := $resource" + SCL_HEADER_VERSION_XPATH + "\n" + - " let $name := $resource" + COMPAS_NAME_EXTENSION_XPATH + "\n" + - " return '' || $id || '' || $name || '' || $version || ''\n" + - ")\n", + var metaInfo = executeQuery(type, """ + %s + %s + declare variable $db := '%s'; + declare variable $id := '%s'; + let $resource := local:latest-version($db, $id) + return if ($resource) + then ( + let $version := $resource/scl:SCL/scl:Header/@version + let $name := $resource/scl:SCL/scl:Private[@type=$compasSclExtensionType]/compas:SclName + return '' + || ' ' || $id || '' + || ' ' || $name || '' + || ' ' || $version || '' + || '' + ) + """.formatted(DECLARE_NS_AND_VARS, DECLARE_LATEST_VERSION_FUNC, type, id), sclDataMarshaller::unmarshalSclMetaInfo); if (metaInfo.isEmpty()) { @@ -208,7 +223,7 @@ public void create(SclFileType type, UUID id, String name, String scl, Version v @Override public void delete(SclFileType type, UUID id) { executeCommand(client -> { - client.executeXQuery("db:delete('" + type + "', '" + id + "')"); + client.executeXQuery("db:delete('%s', '%s')".formatted(type, id)); return true; }); } @@ -216,7 +231,7 @@ public void delete(SclFileType type, UUID id) { @Override public void delete(SclFileType type, UUID id, Version version) { executeCommand(client -> { - client.executeXQuery("db:delete('" + type + "', '" + createDocumentPath(id, version) + "')"); + client.executeXQuery("db:delete('%s', '%s')".formatted(type, createDocumentPath(id, version))); return true; }); } @@ -255,7 +270,7 @@ private List executeQuery(SclFileType type, String query, ResultRowMapper } private void openDatabase(BaseXClient client, SclFileType type) throws IOException { - client.execute("OPEN " + type); + client.execute("OPEN %s".formatted(type)); } private void closeDatabase(BaseXClient client) throws IOException { diff --git a/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java b/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java index 3c4341f7..51c0b925 100644 --- a/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java +++ b/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java @@ -5,10 +5,11 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.lfenergy.compas.scl.data.basex.client.BaseXClientFactory; import org.lfenergy.compas.scl.data.basex.client.BaseXServerJUnitExtension; -import org.lfenergy.compas.scl.data.repository.AbstractCompasSclDataRepository; +import org.lfenergy.compas.scl.data.repository.AbstractCompasSclDataRepositoryTest; import org.lfenergy.compas.scl.data.repository.CompasSclDataRepository; import org.lfenergy.compas.scl.data.util.SclDataModelMarshaller; import org.lfenergy.compas.scl.extensions.model.SclFileType; @@ -19,10 +20,11 @@ import java.io.IOException; import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.lfenergy.compas.scl.data.basex.client.BaseXServerUtil.createClientFactory; @ExtendWith({MockitoExtension.class, BaseXServerJUnitExtension.class}) -class CompasSclDataBaseXRepositoryTest extends AbstractCompasSclDataRepository { +class CompasSclDataBaseXRepositoryTest extends AbstractCompasSclDataRepositoryTest { private static final Logger LOGGER = LoggerFactory.getLogger(CompasSclDataBaseXRepositoryTest.class); private static BaseXClientFactory factory; @@ -53,4 +55,13 @@ static void beforeAll() { void beforeEach() { repository = new CompasSclDataBaseXRepository(factory, new SclDataModelMarshaller()); } + + /* + * TODO: Method beneath needs to be removed and the one from CompasSclDataPostgreSQLRepositoryTest be used + * when hasDuplicateSclName has been implemented by CompasSclDataBaseXRepository. */ + @Test + void hasDuplicateSclName_WhenUsingSclNameThatHasBeenUsedYet_ThenDuplicateIsFound() { + // Will always return false for now, because there is no correct implementation for BaseX + assertFalse(getRepository().hasDuplicateSclName(TYPE, NAME_1)); + } } \ No newline at end of file diff --git a/repository-basex/src/test/resources/simplelogger.properties b/repository-basex/src/test/resources/simplelogger.properties new file mode 100644 index 00000000..684f66ea --- /dev/null +++ b/repository-basex/src/test/resources/simplelogger.properties @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2022 Alliander N.V. +# +# SPDX-License-Identifier: Apache-2.0 + +# SLF4J's SimpleLogger configuration file +# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err. + +org.slf4j.simpleLogger.showThreadName=true +org.slf4j.simpleLogger.showLogName=true +org.slf4j.simpleLogger.showShortLogName=true +org.slf4j.simpleLogger.showDateTime=true +org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss + +org.slf4j.simpleLogger.defaultLogLevel=debug 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 3a03a7fe..efce9b9c 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 @@ -23,32 +23,6 @@ import static org.lfenergy.compas.scl.data.exception.CompasSclDataServiceErrorCode.*; public class CompasSclDataPostgreSQLRepository implements CompasSclDataRepository { - private static final String SELECT_METADATA_CLAUSE = "select scl_file.id, scl_file.name, scl_file.major_version, scl_file.minor_version, scl_file.patch_version "; - private static final String SELECT_DATA_CLAUSE = "select scl_file.scl_data "; - private static final String SELECT_HEADER_INFO_CLAUSE = - ", (xpath('/scl:Hitem/@who', scl_data.header, ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']]))[1] hitem_who " + - ", (xpath('/scl:Hitem/@when', scl_data.header, ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']]))[1] hitem_when " + - ", (xpath('/scl:Hitem/@what', scl_data.header, ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']]))[1] hitem_what "; - private static final String FROM_CLAUSE = " from scl_file "; - private static final String JOIN_HEADER_CLAUSE = " left outer join (" + - "SELECT id, major_version, minor_version, patch_version," + - " unnest(" + - " xpath('(/scl:SCL/scl:Header//scl:Hitem[(not(@revision) or @revision=\"\") and @version=\"' || major_version || '.' || minor_version || '.' || patch_version || '\"])[1]' " + - " , scl_data::xml " + - " , ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']])) as header " + - " from scl_file) scl_data " + - " on scl_data.id = scl_file.id " + - " and scl_data.major_version = scl_file.major_version " + - " and scl_data.minor_version = scl_file.minor_version " + - " and scl_data.patch_version = scl_file.patch_version "; - private static final String DELETE_FROM_CLAUSE = "delete " + FROM_CLAUSE; - private static final String WHERE_CLAUSE = " where "; - private static final String AND_CLAUSE = " and "; - - private static final String FILTER_ON_TYPE = "scl_file.type = ?"; - private static final String FILTER_ON_ID = "scl_file.id = ?"; - private static final String FILTER_ON_VERSION = "scl_file.major_version = ? and scl_file.minor_version = ? and scl_file.patch_version = ? "; - private static final String ID_FIELD = "id"; private static final String MAJOR_VERSION_FIELD = "major_version"; private static final String MINOR_VERSION_FIELD = "minor_version"; @@ -67,31 +41,33 @@ public CompasSclDataPostgreSQLRepository(DataSource dataSource) { @Override public List list(SclFileType type) { - var sql = SELECT_METADATA_CLAUSE - + FROM_CLAUSE - + WHERE_CLAUSE + FILTER_ON_TYPE - + " and (scl_file.id, scl_file.major_version, scl_file.minor_version, scl_file.patch_version) in (" - // Last select the maximum patch version with the major/minor version per id. - + " select id, major_version, minor_version, max(patch_version)" - + " from scl_file patch_scl" - + " where patch_scl.type = scl_file.type" - + " and (id, major_version, minor_version) in (" - // Next select the maximum minor version with the major version per id. - + " select id, major_version, max(minor_version)" - + " from scl_file minor_scl" - + " where minor_scl.type = scl_file.type" - + " and (id, major_version) in (" - // First select the maximum major version per id. - + " select id, max(major_version)" - + " from scl_file major_scl" - + " where major_scl.type = scl_file.type" - + " group by id" - + " )" - + " group by id, major_version" - + " )" - + " group by id, major_version, minor_version" - + " )" - + " order by scl_file.name, scl_file.major_version, scl_file.minor_version, scl_file.patch_version"; + var sql = """ + select scl_file.id, scl_file.name, scl_file.major_version, scl_file.minor_version, scl_file.patch_version + from scl_file + where scl_file.type = ? + and (scl_file.id, scl_file.major_version, scl_file.minor_version, scl_file.patch_version) in ( + -- Last select the maximum patch version with the major/minor version per id. + select id, major_version, minor_version, max(patch_version) + from scl_file patch_scl + where patch_scl.type = scl_file.type + and (id, major_version, minor_version) in ( + -- Next select the maximum minor version with the major version per id. + select id, major_version, max(minor_version) + from scl_file minor_scl + where minor_scl.type = scl_file.type + and (id, major_version) in ( + -- First select the maximum major version per id. + select id, max(major_version) + from scl_file major_scl + where major_scl.type = scl_file.type + group by id + ) + group by id, major_version + ) + group by id, major_version, minor_version + ) + order by scl_file.name, scl_file.major_version, scl_file.minor_version, scl_file.patch_version + """; var items = new ArrayList(); try (var connection = dataSource.getConnection(); @@ -113,13 +89,30 @@ public List list(SclFileType type) { @Override public List listVersionsByUUID(SclFileType type, UUID id) { - var sql = SELECT_METADATA_CLAUSE - + SELECT_HEADER_INFO_CLAUSE - + FROM_CLAUSE - + JOIN_HEADER_CLAUSE - + WHERE_CLAUSE + FILTER_ON_ID - + AND_CLAUSE + FILTER_ON_TYPE - + " order by scl_file.major_version, scl_file.minor_version, scl_file.patch_version"; + var sql = """ + select scl_file.id, scl_file.name + , scl_file.major_version, scl_file.minor_version, scl_file.patch_version + , (xpath('/scl:Hitem/@who', scl_data.header, ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']]))[1] hitem_who + , (xpath('/scl:Hitem/@when', scl_data.header, ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']]))[1] hitem_when + , (xpath('/scl:Hitem/@what', scl_data.header, ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']]))[1] hitem_what + from scl_file + left outer join ( + select id, major_version, minor_version, patch_version, + unnest( + xpath( '(/scl:SCL/scl:Header//scl:Hitem[(not(@revision) or @revision="") and @version="' || major_version || '.' || minor_version || '.' || patch_version || '"])[1]' + , scl_data::xml + , ARRAY[ARRAY['scl', 'http://www.iec.ch/61850/2003/SCL']])) as header + from scl_file) scl_data + on scl_data.id = scl_file.id + and scl_data.major_version = scl_file.major_version + and scl_data.minor_version = scl_file.minor_version + and scl_data.patch_version = scl_file.patch_version + where scl_file.id = ? + and scl_file.type = ? + order by scl_file.major_version + , scl_file.minor_version + , scl_file.patch_version + """; var items = new ArrayList(); try (var connection = dataSource.getConnection(); @@ -153,11 +146,15 @@ public String findByUUID(SclFileType type, UUID id) { @Override public String findByUUID(SclFileType type, UUID id, Version version) { - var sql = SELECT_DATA_CLAUSE - + FROM_CLAUSE - + WHERE_CLAUSE + FILTER_ON_ID - + AND_CLAUSE + FILTER_ON_TYPE - + AND_CLAUSE + FILTER_ON_VERSION; + var sql = """ + select scl_file.scl_data + from scl_file + where scl_file.id = ? + and scl_file.type = ? + and scl_file.major_version = ? + and scl_file.minor_version = ? + and scl_file.patch_version = ? + """; try (var connection = dataSource.getConnection(); var stmt = connection.prepareStatement(sql)) { @@ -181,10 +178,15 @@ public String findByUUID(SclFileType type, UUID id, Version version) { @Override public boolean hasDuplicateSclName(SclFileType type, String name) { - var sql = "SELECT DISTINCT ON (scl_file.id) * " - + FROM_CLAUSE - + "WHERE scl_file.type = ? " - + "ORDER BY scl_file.id, scl_file.major_version desc, scl_file.minor_version desc, scl_file.patch_version desc"; + var sql = """ + select distinct on (scl_file.id) * + from scl_file + where scl_file.type = ? + order by scl_file.id + , scl_file.major_version desc + , scl_file.minor_version desc + , scl_file.patch_version desc + """; try (var connection = dataSource.getConnection(); var stmt = connection.prepareStatement(sql)) { @@ -204,11 +206,13 @@ public boolean hasDuplicateSclName(SclFileType type, String name) { @Override public SclMetaInfo findMetaInfoByUUID(SclFileType type, UUID id) { - var sql = SELECT_METADATA_CLAUSE - + FROM_CLAUSE - + WHERE_CLAUSE + FILTER_ON_ID - + AND_CLAUSE + FILTER_ON_TYPE - + " order by scl_file.major_version desc, scl_file.minor_version desc, scl_file.patch_version desc"; + var sql = """ + select scl_file.id, scl_file.name, scl_file.major_version, scl_file.minor_version, scl_file.patch_version + from scl_file + where scl_file.id = ? + and scl_file.type = ? + order by scl_file.major_version desc, scl_file.minor_version desc, scl_file.patch_version desc + """; try (var connection = dataSource.getConnection(); var stmt = connection.prepareStatement(sql)) { @@ -232,8 +236,10 @@ public SclMetaInfo findMetaInfoByUUID(SclFileType type, UUID id) { @Override public void create(SclFileType type, UUID id, String name, String scl, Version version, String who) { - var sql = "insert into scl_file(id, major_version, minor_version, patch_version, type, name, created_by, scl_data)" - + " values (?, ?, ?, ?, ?, ?, ?, ?)"; + var sql = """ + insert into scl_file(id, major_version, minor_version, patch_version, type, name, created_by, scl_data) + values (?, ?, ?, ?, ?, ?, ?, ?) + """; try (var connection = dataSource.getConnection(); var stmt = connection.prepareStatement(sql)) { @@ -253,9 +259,11 @@ public void create(SclFileType type, UUID id, String name, String scl, Version v @Override public void delete(SclFileType type, UUID id) { - var sql = DELETE_FROM_CLAUSE - + WHERE_CLAUSE + FILTER_ON_ID - + AND_CLAUSE + FILTER_ON_TYPE; + var sql = """ + delete from scl_file + where scl_file.id = ? + and scl_file.type = ? + """; try (var connection = dataSource.getConnection(); var stmt = connection.prepareStatement(sql)) { @@ -269,10 +277,14 @@ public void delete(SclFileType type, UUID id) { @Override public void delete(SclFileType type, UUID id, Version version) { - var sql = DELETE_FROM_CLAUSE - + WHERE_CLAUSE + FILTER_ON_ID - + AND_CLAUSE + FILTER_ON_TYPE - + AND_CLAUSE + FILTER_ON_VERSION; + var sql = """ + delete from scl_file + where scl_file.id = ? + and scl_file.type = ? + and scl_file.major_version = ? + and scl_file.minor_version = ? + and scl_file.patch_version = ? + """; try (var connection = dataSource.getConnection(); var stmt = connection.prepareStatement(sql)) { 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 6964072a..1395a7f3 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 @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.lfenergy.compas.scl.data.model.Version; -import org.lfenergy.compas.scl.data.repository.AbstractCompasSclDataRepository; +import org.lfenergy.compas.scl.data.repository.AbstractCompasSclDataRepositoryTest; import org.lfenergy.compas.scl.data.repository.CompasSclDataRepository; import org.mockito.junit.jupiter.MockitoExtension; @@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @ExtendWith({MockitoExtension.class, PostgreSQLServerJUnitExtension.class}) -class CompasSclDataPostgreSQLRepositoryTest extends AbstractCompasSclDataRepository { +class CompasSclDataPostgreSQLRepositoryTest extends AbstractCompasSclDataRepositoryTest { private CompasSclDataPostgreSQLRepository repository; @Override @@ -30,7 +30,7 @@ void beforeEach() { } /* - * TODO: Method beneath needs to be moved to AbstractCompasSclDataRepository + * TODO: Method beneath needs to be moved to AbstractCompasSclDataRepositoryTest * when hasDuplicateSclName has been implemented by CompasSclDataBaseXRepository. */ @Test void hasDuplicateSclName_WhenUsingSclNameThatHasBeenUsedYet_ThenDuplicateIsFound() { diff --git a/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepository.java b/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java similarity index 99% rename from repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepository.java rename to repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java index 9d0eda3c..8d1da6c7 100644 --- a/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepository.java +++ b/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java @@ -19,7 +19,7 @@ import static org.lfenergy.compas.scl.data.exception.CompasSclDataServiceErrorCode.HEADER_NOT_FOUND_ERROR_CODE; import static org.lfenergy.compas.scl.data.exception.CompasSclDataServiceErrorCode.NO_DATA_FOUND_ERROR_CODE; -public abstract class AbstractCompasSclDataRepository { +public abstract class AbstractCompasSclDataRepositoryTest { protected static final SclFileType TYPE = SclFileType.SCD; protected static final String NAME_1 = "SCL-NAME1"; protected static final String NAME_2 = "SCL-NAME2"; From ee98e0e88db4d0eb6b9f11c44909d205bd1f9916 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Wed, 13 Jul 2022 16:36:37 +0200 Subject: [PATCH 2/9] Upgrade to JDK 17, include using TextBlocks Signed-off-by: Dennis Labordus --- .../data/basex/repository/CompasSclDataBaseXRepositoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java b/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java index 51c0b925..c9e82dd1 100644 --- a/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java +++ b/repository-basex/src/test/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepositoryTest.java @@ -64,4 +64,4 @@ void hasDuplicateSclName_WhenUsingSclNameThatHasBeenUsedYet_ThenDuplicateIsFound // Will always return false for now, because there is no correct implementation for BaseX assertFalse(getRepository().hasDuplicateSclName(TYPE, NAME_1)); } -} \ No newline at end of file +} From bf3b0ac749e3da9075b47b83697fe774eff524a8 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 14 Jul 2022 07:59:12 +0200 Subject: [PATCH 3/9] Fixed Sonar issues. Signed-off-by: Dennis Labordus --- .../data/rest/v1/CompasCommonResource.java | 3 +- .../CompasSclDataBaseXRepository.java | 13 +++---- .../AbstractCompasSclDataRepositoryTest.java | 34 +++++++++++-------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasCommonResource.java b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasCommonResource.java index e26f86f4..79c5d6ef 100644 --- a/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasCommonResource.java +++ b/app/src/main/java/org/lfenergy/compas/scl/data/rest/v1/CompasCommonResource.java @@ -22,7 +22,6 @@ import javax.ws.rs.core.MediaType; import java.util.Arrays; import java.util.Comparator; -import java.util.stream.Collectors; import static org.lfenergy.compas.scl.data.rest.Constants.READ_ROLE; @@ -54,7 +53,7 @@ public TypeListResponse list(@HeaderParam("Authorization") String authHeader) { .filter(sclFileType -> roles.contains(sclFileType.name() + "_" + READ_ROLE)) .map(sclFileType -> new Type(sclFileType.name(), sclFileType.getDescription())) .sorted(Comparator.comparing(Type::getDescription)) - .collect(Collectors.toList())); + .toList()); return response; } diff --git a/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java b/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java index 0649fa48..2b650e05 100644 --- a/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java +++ b/repository-basex/src/main/java/org/lfenergy/compas/scl/data/basex/repository/CompasSclDataBaseXRepository.java @@ -74,15 +74,16 @@ public CompasSclDataBaseXRepository(BaseXClientFactory baseXClientFactory, this.baseXClientFactory = baseXClientFactory; this.sclDataMarshaller = sclDataMarshaller; + var command = """ + declare variable $db := '%s'; + if (not(db:exists($db))) + then + db:create($db) + """; // At startup create all needed databases. Arrays.stream(SclFileType.values()).forEach(type -> executeCommand(client -> { - client.executeXQuery(""" - declare variable $db := '%s'; - if (not(db:exists($db))) - then - db:create($db) - """.formatted(type)); + client.executeXQuery(command.formatted(type)); return true; })); } diff --git a/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java b/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java index 8d1da6c7..9ddb6bb6 100644 --- a/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java +++ b/repository/src/test/java/org/lfenergy/compas/scl/data/repository/AbstractCompasSclDataRepositoryTest.java @@ -135,8 +135,9 @@ void listVersionsByUUID_WhenTwoVersionsOfARecordAdded_ThenAllRecordAreFound() { void findByUUID_WhenCalledWithUnknownUUID_ThenExceptionIsThrown() { var uuid = UUID.randomUUID(); + var repository = getRepository(); var exception = assertThrows(CompasNoDataFoundException.class, () -> { - getRepository().findByUUID(TYPE, uuid); + repository.findByUUID(TYPE, uuid); }); assertEquals(NO_DATA_FOUND_ERROR_CODE, exception.getErrorCode()); } @@ -163,11 +164,13 @@ void findByUUIDWithVersion_WhenCalledWithUnknownVersion_ThenExceptionIsThrown() var version = new Version(1, 0, 0); var uuid = UUID.randomUUID(); var scl = readSCL(uuid, version, NAME_1); - getRepository().create(TYPE, uuid, NAME_1, scl, version, WHO); + + var repository = getRepository(); + repository.create(TYPE, uuid, NAME_1, scl, version, WHO); var unknownVersion = new Version(1, 1, 1); var exception = assertThrows(CompasNoDataFoundException.class, () -> { - getRepository().findByUUID(TYPE, uuid, unknownVersion); + repository.findByUUID(TYPE, uuid, unknownVersion); }); assertEquals(NO_DATA_FOUND_ERROR_CODE, exception.getErrorCode()); } @@ -221,8 +224,9 @@ void findMetaInfoByUUID_WhenTwoVersionsOfARecordAdded_ThenLastRecordIsFound() { void findMetaInfoByUUID_WhenCalledWithUnknownUUID_ThenExceptionIsThrown() { var uuid = UUID.randomUUID(); + var repository = getRepository(); var exception = assertThrows(CompasNoDataFoundException.class, () -> { - getRepository().findMetaInfoByUUID(TYPE, uuid); + repository.findMetaInfoByUUID(TYPE, uuid); }); assertEquals(NO_DATA_FOUND_ERROR_CODE, exception.getErrorCode()); } @@ -283,14 +287,15 @@ void createAndDelete_WhenSclAddedAndDelete_ThenScLStoredAndRemoved() { var uuid = UUID.randomUUID(); var scl = readSCL(uuid, version, NAME_1); - getRepository().create(TYPE, uuid, NAME_1, scl, version, WHO); - var foundScl = getRepository().findByUUID(TYPE, uuid); + var repository = getRepository(); + repository.create(TYPE, uuid, NAME_1, scl, version, WHO); + var foundScl = repository.findByUUID(TYPE, uuid); assertNotNull(foundScl); assertEquals(getIdFromHeader(scl), getIdFromHeader(foundScl)); - getRepository().delete(TYPE, uuid, version); + repository.delete(TYPE, uuid, version); var exception = assertThrows(CompasNoDataFoundException.class, () -> { - getRepository().findByUUID(TYPE, uuid); + repository.findByUUID(TYPE, uuid); }); assertEquals(NO_DATA_FOUND_ERROR_CODE, exception.getErrorCode()); } @@ -301,22 +306,23 @@ void createAndDeleteAll_WhenSclAddedAndDelete_ThenScLStoredAndRemoved() { var uuid = UUID.randomUUID(); var scl = readSCL(uuid, version, NAME_1); - getRepository().create(TYPE, uuid, NAME_1, scl, version, WHO); - var foundScl = getRepository().findByUUID(TYPE, uuid); + var repository = getRepository(); + repository.create(TYPE, uuid, NAME_1, scl, version, WHO); + var foundScl = repository.findByUUID(TYPE, uuid); assertNotNull(foundScl); assertEquals(getIdFromHeader(scl), getIdFromHeader(foundScl)); assertEquals(getVersionFromHeader(scl), getVersionFromHeader(foundScl)); version = version.getNextVersion(ChangeSetType.MAJOR); - getRepository().create(TYPE, uuid, NAME_1, scl, version, WHO); - foundScl = getRepository().findByUUID(TYPE, uuid); + repository.create(TYPE, uuid, NAME_1, scl, version, WHO); + foundScl = repository.findByUUID(TYPE, uuid); assertNotNull(foundScl); assertEquals(getIdFromHeader(scl), getIdFromHeader(foundScl)); assertEquals(getVersionFromHeader(scl), getVersionFromHeader(foundScl)); - getRepository().delete(TYPE, uuid); + repository.delete(TYPE, uuid); var exception = assertThrows(CompasNoDataFoundException.class, () -> { - getRepository().findByUUID(TYPE, uuid); + repository.findByUUID(TYPE, uuid); }); assertEquals(NO_DATA_FOUND_ERROR_CODE, exception.getErrorCode()); } From b23c87159a5cd0cc96dc310b2a7c99956f36cbe7 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Thu, 14 Jul 2022 08:53:35 +0200 Subject: [PATCH 4/9] Updated readme for development. Signed-off-by: Dennis Labordus --- doc/basex.md | 22 ++++++++++++++++++++++ doc/postgresql.md | 25 ++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/doc/basex.md b/doc/basex.md index 9858ecd3..9d7b8e10 100644 --- a/doc/basex.md +++ b/doc/basex.md @@ -37,6 +37,28 @@ docker run --rm --name compas_basex \ > **Note:** Replace with a directory on your local machine, for instance "~/basex". > All data will be stored in this directory under "data". This way data isn't lost after stopping the docker container. +### Application depends on a running KeyCloak instance + +Beside a BaseX Database there is also a KeyCloak instance need to be running on port 8089 by default. +See [README.md](../README.md#security) for default values, if custom keycloak is used. + +There is a preconfigured keycloak instance available in +the [CoMPAS Deployment Repository](https://github.com/com-pas/compas-deployment). This repository can be cloned and +when going to this directory the following command can be executed to create a local Docker Image with configuration. + +```shell +cd /compas/keycloak +docker build -t compas_keycloak . +``` + +There is now a Docker Image `compas_keycloak` created that can be started using the following command + +```shell +docker run --rm --name compas_keycloak \ + -p 8089:8080 + -d compas_keycloak:latest +``` + ### Building the application You can run the following command to build the BaseX version of the application. diff --git a/doc/postgresql.md b/doc/postgresql.md index e29a817a..b065d17c 100644 --- a/doc/postgresql.md +++ b/doc/postgresql.md @@ -56,7 +56,30 @@ docker run --rm --name compas_postgresql \ ``` > **Note:** Replace with a directory on your local machine, for instance "~/postgres". -> All data will be stored in this directory under "compas". This way data isn't lost after stopping the docker container. +> All data will be stored in this directory under "compas". This way data isn't lost after stopping the docker +> container. + +### Application depends on a running KeyCloak instance + +Beside a PostgreSQL Database there is also a KeyCloak instance need to be running on port 8089 by default. +See [README.md](../README.md#security) for default values, if custom keycloak is used. + +There is a preconfigured keycloak instance available in +the [CoMPAS Deployment Repository](https://github.com/com-pas/compas-deployment). This repository can be cloned and +when going to this directory the following command can be executed to create a local Docker Image with configuration. + +```shell +cd /compas/keycloak +docker build -t compas_keycloak . +``` + +There is now a Docker Image `compas_keycloak` created that can be started using the following command + +```shell +docker run --rm --name compas_keycloak \ + -p 8089:8080 + -d compas_keycloak:latest +``` ### Building the application From 823a1b6dbab89354d5dcc1d6f3a1ae7f56f27580 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 19 Jul 2022 09:41:54 +0200 Subject: [PATCH 5/9] Updated documentation for development. Signed-off-by: Dennis Labordus --- README.md | 7 ++-- doc/basex.md | 60 +++++++++++++++++++++------------- doc/compas-scl-data-service.md | 8 ++++- doc/postgresql.md | 60 +++++++++++++++++++++------------- 4 files changed, 87 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index bdd298ea..7a2caa06 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ SPDX-License-Identifier: Apache-2.0 [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5925/badge)](https://bestpractices.coreinfrastructure.org/projects/5925) [![Slack](https://raw.githubusercontent.com/com-pas/compas-architecture/master/public/LFEnergy-slack.svg)](http://lfenergy.slack.com/) -# compas-scl-data-service +# CoMPAS SCL Data Service Service to store and retrieve the SCL XML to a database. @@ -21,8 +21,9 @@ to [documentation](doc/compas-scl-data-service.md). There are currently two database implementations available. -- For more information about the BaseX Implementation go to [BaseX](doc/basex.md). (Profile activated by default.) -- For more information about the PostgreSQL Implementation go to [PostgreSQL](doc/postgresql.md). +- For more development information about the BaseX Implementation go to [BaseX](doc/basex.md). (Profile activated by + default.) +- For more development information about the PostgreSQL Implementation go to [PostgreSQL](doc/postgresql.md). > **Note:** When switching between implementation it's a good practise to first execute a maven clean to remove > old dependencies from the target directory in the app module. diff --git a/doc/basex.md b/doc/basex.md index 9d7b8e10..d60aa557 100644 --- a/doc/basex.md +++ b/doc/basex.md @@ -19,7 +19,31 @@ Below environment variable(s) can be used to configure the connection to BaseX, ## Development -### Application depends on a running BaseX instance +### Building the application + +You can use Maven to build the application and see if all tests are working using: + +```shell script +./mvnw clean verify +``` + +This should normally be enough to also run the application, but there were cases that we need to build using: + +```shell script +./mvnw clean install +``` + +This to make the local modules available for the app module to run the application. + +### Running the application in dev mode + +You can run your application in dev mode that enables live coding using: + +```shell script +./mvnw -DskipTests=true -Dquarkus.profile=dev-basex package io.quarkus:quarkus-maven-plugin::dev +``` + +#### Application depends on a running BaseX instance Check [basexhttp on DockerHub](https://hub.docker.com/r/basex/basexhttp) for a running BaseX docker container. This is needed when running the SCL Data Service locally. Not needed to run the tests. @@ -37,7 +61,7 @@ docker run --rm --name compas_basex \ > **Note:** Replace with a directory on your local machine, for instance "~/basex". > All data will be stored in this directory under "data". This way data isn't lost after stopping the docker container. -### Application depends on a running KeyCloak instance +#### Application depends on a running KeyCloak instance Beside a BaseX Database there is also a KeyCloak instance need to be running on port 8089 by default. See [README.md](../README.md#security) for default values, if custom keycloak is used. @@ -59,34 +83,26 @@ docker run --rm --name compas_keycloak \ -d compas_keycloak:latest ``` -### Building the application +### Creating a Docker image with native executable -You can run the following command to build the BaseX version of the application. +The releases created in the repository will create a docker image with a native executable. If you're running a Linux +system it's possible to create and run the executable locally. You can create a Docker image with native executable +using: ```shell script -./mvnw clean verify +./mvnw package -Pnative-image ``` -### Running the application in dev mode - -You can run your application in dev mode that enables live coding using: - -```shell script -./mvnw -DskipTests=true -Dquarkus.profile=dev-basex package io.quarkus:quarkus-maven-plugin::dev -``` +You can then execute your native executable with: `./app/target/basex-quarkus-app/app-local-SNAPSHOT-runner` -### Creating a native executable +### Creating a Docker image with JVM executable -You can create a native executable using: +There is also a profile to create a Docker Image which runs the application using a JVM. You can create a Docker Image +with JVM executable using: ```shell script -./mvnw -P native package +./mvnw package -Pjvm-image ``` -This will run the native executable build in a container. In the native profile the property -"quarkus.native.container-build" is set to 'true'. - -You can then execute your native executable with: `./app/target/basex-quarkus-app/app-local-SNAPSHOT-runner` - -If you want to learn more about building native executables, please see https://quarkus.io/guides/maven-tooling.html -and https://quarkus.io/guides/writing-native-applications-tips. +The JVM Image can also (temporary) be created by the release action if there are problems creating or running the +native executable. diff --git a/doc/compas-scl-data-service.md b/doc/compas-scl-data-service.md index aa8df86c..a7986bcd 100644 --- a/doc/compas-scl-data-service.md +++ b/doc/compas-scl-data-service.md @@ -66,4 +66,10 @@ There a some BaseX specific choices made in storing the SCL. ### PostgreSQL -TODO \ No newline at end of file +There a some PostgreSQL choices made in storing the SCL. + +- For the PostgreSQL version we use FlyWay to maintain the database schema. All SCL XML Files are stored in a table + called `scl_file`. +- For every new version of an SCL XML File a new record is created. +- The full XML is stored in a text field `scl_data`. +- We can use the XPath function of PostgreSQL to retrieve extra info from the XML. diff --git a/doc/postgresql.md b/doc/postgresql.md index b065d17c..f7c590cd 100644 --- a/doc/postgresql.md +++ b/doc/postgresql.md @@ -40,7 +40,31 @@ Table: scl_file ## Development -### Application depends on a running PostgreSQL instance +### Building the application + +You can use Maven to build the application and see if all tests are working using: + +```shell script +./mvnw clean verify +``` + +This should normally be enough to also run the application, but there were cases that we need to build using: + +```shell script +./mvnw clean install +``` + +This to make the local modules available for the app module to run the application. + +### Running the application in dev mode + +You can run your application in dev mode that enables live coding using: + +```shell script +./mvnw -DskipTests=true -Dquarkus.profile=dev-postgresql package io.quarkus:quarkus-maven-plugin::dev +``` + +#### Application depends on a running PostgreSQL instance Check [PostgreSQL on DockerHub](https://hub.docker.com/_/postgres?tab=description) for a running PostgreSQL docker container. Use the following command to start the docker container. @@ -59,7 +83,7 @@ docker run --rm --name compas_postgresql \ > All data will be stored in this directory under "compas". This way data isn't lost after stopping the docker > container. -### Application depends on a running KeyCloak instance +#### Application depends on a running KeyCloak instance Beside a PostgreSQL Database there is also a KeyCloak instance need to be running on port 8089 by default. See [README.md](../README.md#security) for default values, if custom keycloak is used. @@ -81,34 +105,26 @@ docker run --rm --name compas_keycloak \ -d compas_keycloak:latest ``` -### Building the application +### Creating a Docker image with native executable -You can run the following command to build the PostgreSQL version of the application. +The releases created in the repository will create a docker image with a native executable. If you're running a Linux +system it's possible to create and run the executable locally. You can create a Docker image with native executable +using: ```shell script -./mvnw clean verify +./mvnw package -Pnative-image ``` -### Running the application in dev mode - -You can run your application in dev mode that enables live coding using: - -```shell script -./mvnw -DskipTests=true -Dquarkus.profile=dev-postgresql package io.quarkus:quarkus-maven-plugin::dev -``` +You can then execute your native executable with: `./app/target/postgresql-quarkus-app/app-local-SNAPSHOT-runner` -### Creating a native executable +### Creating a Docker image with JVM executable -You can create a native executable using: +There is also a profile to create a Docker Image which runs the application using a JVM. You can create a Docker Image +with JVM executable using: ```shell script -./mvnw -P native package +./mvnw package -Pjvm-image ``` -This will run the native executable build in a container. In the native profile the property -"quarkus.native.container-build" is set to 'true'. - -You can then execute your native executable with: `./app/target/postgresql-quarkus-app/app-local-SNAPSHOT-runner` - -If you want to learn more about building native executables, please see https://quarkus.io/guides/maven-tooling.html -and https://quarkus.io/guides/writing-native-applications-tips. +The JVM Image can also (temporary) be created by the release action if there are problems creating or running the +native executable. From 0929d52b7d8bf147128f349f509a02d68acc3304 Mon Sep 17 00:00:00 2001 From: Dennis Labordus Date: Tue, 19 Jul 2022 09:44:30 +0200 Subject: [PATCH 6/9] Updated documentation for development. Signed-off-by: Dennis Labordus --- doc/compas-scl-data-service.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/compas-scl-data-service.md b/doc/compas-scl-data-service.md index a7986bcd..760246ac 100644 --- a/doc/compas-scl-data-service.md +++ b/doc/compas-scl-data-service.md @@ -68,8 +68,8 @@ There a some BaseX specific choices made in storing the SCL. There a some PostgreSQL choices made in storing the SCL. -- For the PostgreSQL version we use FlyWay to maintain the database schema. All SCL XML Files are stored in a table - called `scl_file`. +- For the PostgreSQL version we use FlyWay to maintain the database schema. +- All SCL XML Files are stored in a table called `scl_file`. - For every new version of an SCL XML File a new record is created. - The full XML is stored in a text field `scl_data`. - We can use the XPath function of PostgreSQL to retrieve extra info from the XML. From 01b90787e931d0dc8b3fd6f8fbf48fd7fba50ab0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Jul 2022 11:26:52 +0000 Subject: [PATCH 7/9] Bump quarkus.platform.version from 2.10.2.Final to 2.10.3.Final Bumps `quarkus.platform.version` from 2.10.2.Final to 2.10.3.Final. Updates `quarkus-universe-bom` from 2.10.2.Final to 2.10.3.Final - [Release notes](https://github.com/quarkusio/quarkus-platform/releases) - [Commits](https://github.com/quarkusio/quarkus-platform/compare/2.10.2.Final...2.10.3.Final) Updates `quarkus-maven-plugin` from 2.10.2.Final to 2.10.3.Final --- updated-dependencies: - dependency-name: io.quarkus:quarkus-universe-bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.quarkus:quarkus-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1b65d6d..061a5382 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ SPDX-License-Identifier: Apache-2.0 0.9.1 - 2.10.2.Final + 2.10.3.Final 2.3.6 3.0 1.7.36 From 9b45f7a23f54adef1c3f16e05185ea412c52f652 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Aug 2022 05:49:49 +0000 Subject: [PATCH 8/9] Bump quarkus.platform.version from 2.10.3.Final to 2.11.1.Final Bumps `quarkus.platform.version` from 2.10.3.Final to 2.11.1.Final. Updates `quarkus-universe-bom` from 2.10.3.Final to 2.11.1.Final - [Release notes](https://github.com/quarkusio/quarkus-platform/releases) - [Commits](https://github.com/quarkusio/quarkus-platform/compare/2.10.3.Final...2.11.1.Final) Updates `quarkus-maven-plugin` from 2.10.3.Final to 2.11.1.Final --- updated-dependencies: - dependency-name: io.quarkus:quarkus-universe-bom dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.quarkus:quarkus-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: Dennis Labordus --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 061a5382..235bfe96 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ SPDX-License-Identifier: Apache-2.0 0.9.1 - 2.10.3.Final + 2.11.1.Final 2.3.6 3.0 1.7.36 From 4ae3f5507b4b608b89af471b3d69bc1d10dc0c16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Aug 2022 11:20:25 +0000 Subject: [PATCH 9/9] Bump quarkus.platform.version from 2.11.1.Final to 2.11.2.Final Bumps `quarkus.platform.version` from 2.11.1.Final to 2.11.2.Final. Updates `quarkus-universe-bom` from 2.11.1.Final to 2.11.2.Final - [Release notes](https://github.com/quarkusio/quarkus-platform/releases) - [Commits](https://github.com/quarkusio/quarkus-platform/compare/2.11.1.Final...2.11.2.Final) Updates `quarkus-maven-plugin` from 2.11.1.Final to 2.11.2.Final --- updated-dependencies: - dependency-name: io.quarkus:quarkus-universe-bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.quarkus:quarkus-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: Dennis Labordus --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 235bfe96..4ec7a604 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ SPDX-License-Identifier: Apache-2.0 0.9.1 - 2.11.1.Final + 2.11.2.Final 2.3.6 3.0 1.7.36