diff --git a/.github/workflows/reusable-build-and-publish-v3s.yml b/.github/workflows/reusable-build-and-publish-v3s.yml index 0ca2b426a..df93cf626 100644 --- a/.github/workflows/reusable-build-and-publish-v3s.yml +++ b/.github/workflows/reusable-build-and-publish-v3s.yml @@ -55,7 +55,7 @@ jobs: # run: gradle shadowJar jacocoTestReport jacocoTestCoverageVerification shell: bash run: | - array=( here-naksha-lib-model here-naksha-lib-base here-naksha-lib-core here-naksha-lib-psql here-naksha-lib-view here-naksha-storage-http here-naksha-lib-diff here-naksha-lib-handlers here-naksha-lib-hub here-naksha-handler-activitylog) + array=( here-naksha-lib-model here-naksha-lib-base here-naksha-lib-core here-naksha-lib-psql here-naksha-lib-view here-naksha-storage-http here-naksha-lib-diff here-naksha-lib-handlers here-naksha-lib-hub here-naksha-handler-activitylog here-naksha-lib-ext-manager ) for item in ${array[@]}; do gradle -x jsNodeTest :$item:build :$item:jacocoTestReport :$item:jacocoTestCoverageVerification done diff --git a/here-naksha-lib-core/build.gradle.kts b/here-naksha-lib-core/build.gradle.kts index f6bb4d82a..76d4d0b1f 100644 --- a/here-naksha-lib-core/build.gradle.kts +++ b/here-naksha-lib-core/build.gradle.kts @@ -3,6 +3,7 @@ description = "Naksha Core Library" plugins { id("naksha.java") id("naksha.publish") + kotlin("jvm") } java { @@ -25,4 +26,7 @@ dependencies { testImplementation(Lib.mockito) testImplementation(Lib.json_assert) } -setOverallCoverage(0.0) // only increasing allowed! \ No newline at end of file +setOverallCoverage(0.0) // only increasing allowed! +kotlin { + jvmToolchain(11) +} \ No newline at end of file diff --git a/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/models/ExtensionConfig.java b/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/models/ExtensionConfig.java deleted file mode 100644 index 36c38e25e..000000000 --- a/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/models/ExtensionConfig.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2017-2024 HERE Europe B.V. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * License-Filename: LICENSE - */ -package com.here.naksha.lib.core.models; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.here.naksha.lib.core.models.features.Extension; -import java.util.List; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -@JsonTypeName -public class ExtensionConfig { - - public static final String EXPIRY = "expiry"; - public static final String EXTENSIONS = "extensions"; - public static final String WHITELIST_DELEGATE_CLASSES = "whitelistDelegateClasses"; - public static final String ENV_NAME = "env"; - - @JsonProperty(EXPIRY) - long expiry; - - @JsonProperty(EXTENSIONS) - List extensions; - - @JsonProperty(WHITELIST_DELEGATE_CLASSES) - List whitelistDelegateClasses; - - @JsonProperty(ENV_NAME) - String env; - - @JsonCreator - public ExtensionConfig( - @JsonProperty(EXPIRY) @NotNull Long expiry, - @JsonProperty(EXTENSIONS) @Nullable List extensions, - @JsonProperty(WHITELIST_DELEGATE_CLASSES) @Nullable List whitelistDelegateClasses, - @JsonProperty(ENV_NAME) @NotNull String env) { - this.expiry = expiry; - this.extensions = extensions; - this.whitelistDelegateClasses = whitelistDelegateClasses; - this.env = env; - } - - public long getExpiry() { - return expiry; - } - - public List getExtensions() { - return extensions; - } - - public List getWhilelistDelegateClass() { - return whitelistDelegateClasses; - } - - public String getEnv() { - return env; - } -} diff --git a/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/models/features/Extension.java b/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/models/features/Extension.java deleted file mode 100644 index 34115ff7c..000000000 --- a/here-naksha-lib-core/src/main/java/com/here/naksha/lib/core/models/features/Extension.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2017-2024 HERE Europe B.V. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * License-Filename: LICENSE - */ -package com.here.naksha.lib.core.models.features; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeName; -import naksha.model.NakshaVersion; -import naksha.model.objects.NakshaFeature; -import org.jetbrains.annotations.ApiStatus.AvailableSince; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * An extension is an administrative feature that allows to run proprietary code, outside the Naksha-Hub using proprietary libraries. - */ -@AvailableSince(NakshaVersion.v2_0_3) -@JsonTypeName -public class Extension extends NakshaFeature { - public static final String ID = "id"; - public static final String URL = "url"; - public static final String VERSION = "version"; - public static final String INIT_CLASS_NAME = "initClassName"; - - @JsonProperty(URL) - String url; - - @JsonProperty(VERSION) - String version; - - @JsonProperty(INIT_CLASS_NAME) - String initClassName; - - /** - * Create an extension. - * - * @param id Unique identifier of extension. - * @param url source url of given extension. - * @param version version of extension. - * @param initClassName Extension initialisation class. - */ - @AvailableSince(NakshaVersion.v2_0_3) - @JsonCreator - public Extension( - @JsonProperty(ID) @NotNull String id, - @JsonProperty(URL) @NotNull String url, - @JsonProperty(VERSION) @NotNull String version, - @JsonProperty(INIT_CLASS_NAME) @Nullable String initClassName) { - super(id); - this.url = url; - this.version = version; - this.initClassName = initClassName; - } - - public String getUrl() { - return url; - } - - public String getVersion() { - return version; - } - - public String getInitClassName() { - return initClassName; - } -} diff --git a/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/ExtensionConfig.kt b/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/ExtensionConfig.kt new file mode 100644 index 000000000..b98b4d4e8 --- /dev/null +++ b/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/ExtensionConfig.kt @@ -0,0 +1,31 @@ +package com.here.naksha.lib.core.models + +import com.here.naksha.lib.core.models.features.Extension +import naksha.base.AnyObject +import naksha.base.NotNullProperty +import naksha.base.NullableProperty +import naksha.base.StringList + +class ExtensionConfig() : AnyObject() { + companion object { + private val EXTENSIONS_NULL = NullableProperty(ExtensionList::class) + private val WHITELIST_DELEGATE_CLASSES_NULL = NullableProperty(StringList::class) + private val LONG = NotNullProperty(Long::class) + private val STRING = NotNullProperty(String::class) + } + + var expiry by LONG + var extensions by EXTENSIONS_NULL + var whitelistDelegateClasses by WHITELIST_DELEGATE_CLASSES_NULL + var env by STRING + + constructor(expiry: Long, + extensions: List, + whitelistDelegateClasses: List, + env: String) : this() { + this.expiry = expiry + this.extensions = ExtensionList.fromList(extensions) + this.whitelistDelegateClasses = StringList.fromList(whitelistDelegateClasses) + this.env = env + } +} \ No newline at end of file diff --git a/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/ExtensionList.kt b/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/ExtensionList.kt new file mode 100644 index 000000000..a705ef563 --- /dev/null +++ b/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/ExtensionList.kt @@ -0,0 +1,12 @@ +package com.here.naksha.lib.core.models + +import com.here.naksha.lib.core.models.features.Extension +import naksha.base.ListProxy + +class ExtensionList: ListProxy(Extension::class) { + companion object ExtensionList_C { + @JvmStatic + fun fromList(extensions: List): ExtensionList = + ExtensionList().apply { addAll(extensions) } + } +} \ No newline at end of file diff --git a/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/features/Extension.kt b/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/features/Extension.kt new file mode 100644 index 000000000..4ed40acf4 --- /dev/null +++ b/here-naksha-lib-core/src/main/kotlin/com/here/naksha/lib/core/models/features/Extension.kt @@ -0,0 +1,30 @@ +package com.here.naksha.lib.core.models.features + +import naksha.base.NotNullProperty +import naksha.base.NullableProperty +import naksha.model.objects.NakshaFeature + +class Extension() : NakshaFeature() { + companion object { + private val STRING_NULL = NullableProperty(String::class) + private val STRING = NotNullProperty(String::class) + } + + var url by STRING + + var version by STRING + + var initClassName by STRING_NULL + + constructor( + id: String, + url: String, + version: String, + initClassName: String? + ) : this() { + this.id = id + this.url = url + this.version = version + this.initClassName = initClassName + } +} \ No newline at end of file diff --git a/here-naksha-lib-ext-manager/build.gradle.kts b/here-naksha-lib-ext-manager/build.gradle.kts index b7fc8b71d..dcfe7e111 100644 --- a/here-naksha-lib-ext-manager/build.gradle.kts +++ b/here-naksha-lib-ext-manager/build.gradle.kts @@ -10,5 +10,6 @@ dependencies { implementation(Lib.jcl_slf4j) implementation(Lib.cytodynamics) testImplementation(Lib.mockito) + testImplementation(project(":here-naksha-lib-core")) } setOverallCoverage(0.0) // only increasing allowed! \ No newline at end of file diff --git a/here-naksha-lib-ext-manager/src/main/java/com/here/naksha/lib/extmanager/ExtensionCache.java b/here-naksha-lib-ext-manager/src/main/java/com/here/naksha/lib/extmanager/ExtensionCache.java index ec1fdc17b..9cef139c8 100644 --- a/here-naksha-lib-ext-manager/src/main/java/com/here/naksha/lib/extmanager/ExtensionCache.java +++ b/here-naksha-lib-ext-manager/src/main/java/com/here/naksha/lib/extmanager/ExtensionCache.java @@ -103,7 +103,7 @@ private void publishIntoCache(KVPair result, ExtensionConfig ex final File jarFile = result.getValue(); ClassLoader loader; try { - loader = ClassLoaderHelper.getClassLoader(jarFile, extensionConfig.getWhilelistDelegateClass()); + loader = ClassLoaderHelper.getClassLoader(jarFile, extensionConfig.getWhitelistDelegateClasses()); } catch (Exception e) { logger.error("Failed to load extension jar " + extension.getId(), e); return; diff --git a/here-naksha-lib-ext-manager/src/test/java/com/here/naksha/lib/extmanager/BaseSetup.java b/here-naksha-lib-ext-manager/src/test/java/com/here/naksha/lib/extmanager/BaseSetup.java index f997e0f67..9ac22b887 100644 --- a/here-naksha-lib-ext-manager/src/test/java/com/here/naksha/lib/extmanager/BaseSetup.java +++ b/here-naksha-lib-ext-manager/src/test/java/com/here/naksha/lib/extmanager/BaseSetup.java @@ -1,9 +1,13 @@ package com.here.naksha.lib.extmanager; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import com.here.naksha.lib.core.models.ExtensionConfig; +import com.here.naksha.lib.core.models.ExtensionList; import com.here.naksha.lib.core.models.features.Extension; +import naksha.base.FromJsonOptions; +import naksha.base.JvmBoxingUtil; +import naksha.base.JvmListProxy; +import naksha.base.Platform; + import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -20,8 +24,7 @@ public ExtensionConfig getExtensionConfig() { List list; try { String data = Files.readAllLines(file).stream().collect(Collectors.joining()); - list = new ObjectMapper().readValue(data, new TypeReference<>() { - }); + list = JvmBoxingUtil.box(Platform.fromJSON(data, FromJsonOptions.DEFAULT), ExtensionList.class); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/here-naksha-lib-ext-manager/src/test/resources/test-config.json b/here-naksha-lib-ext-manager/src/test/resources/test-config.json deleted file mode 100644 index 21045fa9b..000000000 --- a/here-naksha-lib-ext-manager/src/test/resources/test-config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "id": "test-config", - "type": "Config", - - "httpPort": 8080, - "env": "local", - "jwtName": "jwt", - "maintenanceInitialDelayInMins": 60, - "maintenanceIntervalInMins": 720, - "maintenancePoolCoreSize": 5, - "maintenancePoolMaxSize": 20, - "storageParams": { - "pg_hint_plan": false, - "pg_stat_statements": false - } -} \ No newline at end of file diff --git a/here-naksha-lib-hub/src/main/java/com/here/naksha/lib/hub/NakshaHub.java b/here-naksha-lib-hub/src/main/java/com/here/naksha/lib/hub/NakshaHub.java index 724b5a794..8de61adb7 100644 --- a/here-naksha-lib-hub/src/main/java/com/here/naksha/lib/hub/NakshaHub.java +++ b/here-naksha-lib-hub/src/main/java/com/here/naksha/lib/hub/NakshaHub.java @@ -49,6 +49,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; + +import naksha.base.FromJsonOptions; +import naksha.base.JvmBoxingUtil; +import naksha.base.Platform; import naksha.model.IReadSession; import naksha.model.IStorage; import naksha.model.IWriteSession; @@ -404,7 +408,7 @@ private List loadExtensionConfigFromS3(String extensionRootPath) { } Extension extension; try { - extension = new ObjectMapper().readValue(exJson, Extension.class); + extension = JvmBoxingUtil.box(Platform.fromJSON(exJson, FromJsonOptions.DEFAULT), Extension.class); extList.add(extension); } catch (Exception e) { logger.error("Failed to convert extension meta data to Extension object. {} ", exJson, e);