Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ val allModules = mapOf(
Pair("here-naksha-lib-view", Pair(CleanAndTest.KOTLIN, PublishModule.NO)),
Pair("here-naksha-storage-http", Pair(CleanAndTest.KOTLIN, PublishModule.NO)),
Pair("here-naksha-cli", Pair(CleanAndTest.KOTLIN, PublishModule.NO)),
Pair("here-naksha-lib-mom10", Pair(CleanAndTest.KOTLIN, PublishModule.YES)),
)

fun Project.configureVanniktechMavenPublish() {
Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Descriptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ private val Descriptions = mapOf(
"here-naksha-lib-view" to "Naksha library, adding capabilities to combine multiple storages, maps, collections into a single virtual view.",
"here-naksha-storage-http" to "TBD",
"here-naksha-cli" to "The Naksha CLI tool allows users to interact with Naksha storage.",
"here-naksha-lib-mom10" to "Naksha library offering support for MOM 10"
)

fun Project.gatherDescription(): String
Expand Down
84 changes: 84 additions & 0 deletions here-naksha-lib-mom10/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
## lib-mom10 module

The job of this module is to provide Naksha ecosystem with tools needed for correct MOM 10 handling.

Naksha itself relies heavily on `@ns:com:here:mom:meta` and `@ns:com:here:mom:delta` namespaces that
were changed in MOM 10.
There were renamed and slightly reshaped, there are also some properties that are no longer valid in
MOM 10.

Because of the above, Naksha has to:

- **do nothing** if the handled (written or read) feature has version below `10.0.0` - we know that
for "pre-MOM 10" features all of necessary namespaces are in place
- when writing `MOM 10` feature: create and shape missing namespace so that all logic that depends
on them will work as expected
- when reading `MOM 10` feature: return them in the same shape as they were written (== don't
include obsolete namespaces needed by Naksha)

### Checking `modelVersion`

[Mom10Verification](src/jvmMain/java/com/here/naksha/mom10/Mom10Verification.java) is responsible
for
checking whether given feature **has MOM version equal or greater to `10.0.0`**.
This information can be used to determine whether a further processing is required.

### Transforming from and to MOM 10

Transforming **from MOM 10** is assumed to happen only for writes - when a client comes with MOM 10
feature:

- we create outdated namespaces basing on data that is mappable from MOM 10
- we store the feature as it was given by the client with additional namespaces being stored next to
the "new ones" (defined in MOM 10)
- the result is feature in "hybrid state" - containing both new and old namespaces

Transforming **to MOM 10** is assumed to happen only for reads - when a client want to retrieve
previously stored MOM 10 feature (described above):

- we fetch the whole "hybrid feature"
- we drop everything that we added in `from MOM 10` transformation (basically we delete obsolete
namespaces)
- we return feature in the same shape as it was given to Naksha in the writing phase

The class responsible for these operations
is [Mom10Transformation](src/jvmMain/java/com/here/naksha/mom10/Mom10Transformation.java).

#### Populating old delta

| `@ns:com:here:mom:delta` properties supported in Naksha (pre MOM 10) | equivalents in `meta.moderationInfo` (MOM 10+) |
|----------------------------------------------------------------------|------------------------------------------------|
| `originId` | `originId` |
| `parentLink` | `parentLink` |
| `changeState` | `changeState` |
| `reviewState` | `reviewState` |
| `streamId` | not applicable |
| `potentialValue` | not applicable |
| `priorityCategory` | not applicable |
| `dueTS` | not applicable |
| `changeCounter` | not applicable |

Only the properties supported in both old delta NS and new `moderationInfo` will be used for
population of `@ns:com:here:mom:delta` namespace.

Pre MOM 10 delta NS
model: https://docs.in.here.com/static/169823/1467398/html/#com/here/mom/internal/extension/branch/branch.html

MOM 10+ moderation
info: https://here-dev.zoominsoftware.io/docs/bundle/map-object-model-data-specification-10/page/com/here/mom/internal/component/moderation/moderation-information.html

#### Populating old meta

Properties supported by both old `@ns:com:here:mom:meta` NS and MOM 10+ `meta` property

- `sourceId`
- `updatedByUser`
- `lastUpdatedBy`
- `modelVersion`
- `protectionFlags`
- `createdTS `
- `layerId`
- `updatedByApp`
- `lastUpdatedTS`

Only the properties listed above will be populated when creating `@ns:com:here:mom:meta` namespace.
34 changes: 34 additions & 0 deletions here-naksha-lib-mom10/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
plugins {
alias(libs.plugins.kotlin.multiplatform)
}

description = gatherDescription()

kotlin {
jvm {}
sourceSets {
jvmMain {
jvmToolchain(23)
dependencies {
implementation(project(":here-naksha-lib-model"))
implementation(project(":here-naksha-lib-handlers"))
}
}
jvmTest {
dependencies {
implementation(libs.bundles.testing)
}
}
}
}

tasks {
getByName<Jar>("jvmJar") { dependsOn("jvmProcessResources") }
getByName<ProcessResources>("jvmTestProcessResources") { dependsOn("jvmProcessResources") }
getByName<Test>("jvmTest") {
useJUnitPlatform()
maxHeapSize = "6g"
}
}

setOverallCoverage(0.0) // only increasing allowed!
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.mom10;

class DeltaProperties {
private DeltaProperties() {}

/*
Properties that are part of both pre-MOM 10 delta NS and MOM 10+ moderationInfo
pre MOM 10: https://docs.in.here.com/static/169823/1467398/html/#com/here/mom/internal/extension/branch/branch.html
MOM 10+: https://here-dev.zoominsoftware.io/docs/bundle/map-object-model-data-specification-10/page/com/here/mom/internal/component/moderation/moderation-information.html
*/
public static final String ORIGIN_ID = "originId";
public static final String PARENT_LINK = "parentLink";
public static final String CHANGE_STATE = "changeState";
public static final String REVIEW_STATE = "reviewState";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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.mom10;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
* Some of Meta-related properties from MOM 10
*/
public class MetaProperties {

private MetaProperties() {
}

/**
* Renamed in MOM 10 from {@link naksha.model.objects.NakshaProperties#META_KEY}
*/
public static final String META = "meta";

/**
* Source of truth about model version - required since MOM 10.0.0, optional before
*/
public static final String MODEL_VERSION = "modelVersion";

/*
https://docs.in.here.com/static/169823/1467398/html/#com/here/mom/internal/component/meta/metadata.html
*/
private static final Set<String> META_NAMESPACE_PROPERTIES = Set.of(
"createdTS",
"hashPayload",
"lastObservedTS",
"lastReviewedTS",
"lastUpdatedBy",
"lastUpdatedTS",
"layerId",
MODEL_VERSION,
"operation",
"owner",
"protectionFlags",
"sourceId",
"tid",
"updatedByApp",
"updatedByUser");

/**
* Renamed from {@link naksha.model.objects.NakshaProperties#DELTA_KEY} and moved under {@link MetaProperties#META}
*/
public static final String MODERATION_INFO = "moderationInfo";

// https://here-dev.zoominsoftware.io/docs/bundle/map-object-model-data-specification-10/page/com/here/mom/internal/component/meta/metadata.html
private static final Set<String> MOM_10_META_PROPERTIES = Set.of(
"confidence",
"createdTS",
"externalIds",
"keyValues",
"lastUpdatedBy",
"lastUpdatedTS",
"layerId",
MODEL_VERSION, // "modelVersion"
MODERATION_INFO, // "moderationInfo"
"protectionFlags",
"sourceId",
"sourceInfo",
"tags",
"updatedByApp",
"updatedByUser");

static final Set<String> COMMON_META_PROPERTIES;

static {
HashSet<String> metaProperties = new HashSet<>(META_NAMESPACE_PROPERTIES);
metaProperties.retainAll(MOM_10_META_PROPERTIES);
COMMON_META_PROPERTIES = Collections.unmodifiableSet(metaProperties);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* 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.mom10;

import static com.here.naksha.mom10.MetaProperties.COMMON_META_PROPERTIES;
import static com.here.naksha.mom10.MetaProperties.META;
import static com.here.naksha.mom10.MetaProperties.MODERATION_INFO;

import java.util.Map;
import naksha.model.mom.MomDeltaNs;
import naksha.model.mom.MomMetaNs;
import naksha.model.objects.NakshaFeature;
import naksha.model.objects.NakshaProperties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class Mom10Transformation {

private Mom10Transformation() {
}

public static void populatePreMom10Namespaces(@Nullable NakshaFeature feature) {
if (feature == null) {
return;
}

NakshaProperties properties = feature.getProperties();
Map<String, Object> meta = (Map<String, Object>) properties.get(META);
if (meta != null && !meta.isEmpty()) {
MomDeltaNs deltaNs = deltaNs(meta);
properties.setDelta(deltaNs);
MomMetaNs metaNs = metaNs(meta);
properties.setMeta(metaNs);
}
}

private static @NotNull MomMetaNs metaNs(@NotNull Map<String, Object> meta) {
MomMetaNs metaNs = new MomMetaNs();
for (String metaKey : COMMON_META_PROPERTIES) {
Object value = meta.get(metaKey);
if (value != null) {
metaNs.put(metaKey, value);
}
}
return metaNs;
}

private static @Nullable MomDeltaNs deltaNs(@NotNull Map<String, Object> meta) {
Map<String, Object> moderationInfo = (Map<String, Object>) meta.get(MODERATION_INFO);
if (moderationInfo == null) {
return null;
} else {
MomDeltaNs deltaNs = new MomDeltaNs();
String changeState = (String) moderationInfo.get(DeltaProperties.CHANGE_STATE);
if (changeState != null) {
deltaNs.setChangeState(changeState);
}
String reviewState = (String) moderationInfo.get(DeltaProperties.REVIEW_STATE);
if (reviewState != null) {
deltaNs.setReviewState(reviewState);
}
String originId = (String) moderationInfo.get(DeltaProperties.ORIGIN_ID);
if (originId != null) {
deltaNs.setOriginId(originId);
}
String parentLink = (String) moderationInfo.get(DeltaProperties.PARENT_LINK);
if (parentLink != null) {
deltaNs.setParentLink(parentLink);
}
return deltaNs;
}
}

public static void dropPreMom10Namespaces(@Nullable NakshaFeature feature) {
if(feature != null) {
NakshaProperties properties = feature.getProperties();
properties.remove(NakshaProperties.META_KEY);
properties.remove(NakshaProperties.DELTA_KEY);
}
}
}
Loading
Loading