aboutsummaryrefslogtreecommitdiffstats
path: root/cps-service/src
diff options
context:
space:
mode:
Diffstat (limited to 'cps-service/src')
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java33
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsDataService.java27
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java33
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java32
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java31
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsDeltaServiceImpl.java5
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java20
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheConfig.java45
-rw-r--r--cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheEntry.java44
-rw-r--r--cps-service/src/main/java/org/onap/cps/cache/HazelcastCacheConfig.java104
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/utils/CpsValidator.java (renamed from cps-service/src/main/java/org/onap/cps/spi/utils/CpsValidator.java)2
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java47
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java16
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/DeltaReport.java4
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/DeltaReportBuilder.java8
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java92
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java10
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy37
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy94
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDeltaServiceImplSpec.groovy14
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy38
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy2
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy4
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy3
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheConfigSpec.groovy80
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheEntrySpec.groovy40
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/cache/HazelcastCacheConfigSpec.groovy76
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/spi/model/DeltaReportBuilderSpec.groovy10
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy67
-rw-r--r--cps-service/src/test/resources/application.yml10
35 files changed, 346 insertions, 692 deletions
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java b/cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java
index a247150c15..fcb969ba30 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,6 +37,15 @@ public interface CpsAnchorService {
void createAnchor(String dataspaceName, String schemaSetName, String anchorName);
/**
+ * Get an anchor in the given dataspace using the anchor name.
+ *
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @return an anchor
+ */
+ Anchor getAnchor(String dataspaceName, String anchorName);
+
+ /**
* Read all anchors in the given dataspace.
*
* @param dataspaceName dataspace name
@@ -45,13 +54,22 @@ public interface CpsAnchorService {
Collection<Anchor> getAnchors(String dataspaceName);
/**
+ * Read all anchors in the given dataspace with the anchor names.
+ *
+ * @param dataspaceName dataspace name
+ * @param anchorNames anchor names
+ * @return a collection of anchors
+ */
+ Collection<Anchor> getAnchors(String dataspaceName, Collection<String> anchorNames);
+
+ /**
* Read all anchors associated with the given schema-set in the given dataspace.
*
* @param dataspaceName dataspace name
* @param schemaSetName schema-set name
* @return a collection of anchors
*/
- Collection<Anchor> getAnchors(String dataspaceName, String schemaSetName);
+ Collection<Anchor> getAnchorsBySchemaSetName(String dataspaceName, String schemaSetName);
/**
* Read all anchors associated with the given schema-sets in the given dataspace.
@@ -60,16 +78,7 @@ public interface CpsAnchorService {
* @param schemaSetNames schema-set names
* @return a collection of anchors
*/
- Collection<Anchor> getAnchors(String dataspaceName, Collection<String> schemaSetNames);
-
- /**
- * Get an anchor in the given dataspace using the anchor name.
- *
- * @param dataspaceName dataspace name
- * @param anchorName anchor name
- * @return an anchor
- */
- Anchor getAnchor(String dataspaceName, String anchorName);
+ Collection<Anchor> getAnchorsBySchemaSetNames(String dataspaceName, Collection<String> schemaSetNames);
/**
* Delete anchor by name in given dataspace.
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
index f396b49e6b..68e1880d77 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
@@ -55,7 +55,7 @@ public interface CpsDataService {
* @param anchorName anchor name
* @param nodeData node data
* @param observedTimestamp observedTimestamp
- * @param contentType node data content type
+ * @param contentType JSON/XML content type
*/
void saveData(String dataspaceName, String anchorName, String nodeData, OffsetDateTime observedTimestamp,
ContentType contentType);
@@ -80,7 +80,7 @@ public interface CpsDataService {
* @param parentNodeXpath parent node xpath
* @param nodeData node data
* @param observedTimestamp observedTimestamp
- * @param contentType node data content type
+ * @param contentType JSON/XML content type
*
*/
void saveData(String dataspaceName, String anchorName, String parentNodeXpath, String nodeData,
@@ -93,11 +93,12 @@ public interface CpsDataService {
* @param dataspaceName dataspace name
* @param anchorName anchor name
* @param parentNodeXpath parent node xpath
- * @param jsonData json data representing list element(s)
+ * @param nodeData node data representing list element(s)
* @param observedTimestamp observedTimestamp
+ * @param contentType JSON/XML content type
*/
- void saveListElements(String dataspaceName, String anchorName, String parentNodeXpath, String jsonData,
- OffsetDateTime observedTimestamp);
+ void saveListElements(String dataspaceName, String anchorName, String parentNodeXpath, String nodeData,
+ OffsetDateTime observedTimestamp, ContentType contentType);
/**
* Retrieves all the datanodes by XPath for given dataspace and anchor.
@@ -134,7 +135,7 @@ public interface CpsDataService {
* @param parentNodeXpath xpath to parent node
* @param nodeData node data
* @param observedTimestamp observedTimestamp
- * @param contentType node data content type
+ * @param contentType JSON/XML content type
*/
void updateNodeLeaves(String dataspaceName, String anchorName, String parentNodeXpath, String nodeData,
OffsetDateTime observedTimestamp, ContentType contentType);
@@ -145,22 +146,24 @@ public interface CpsDataService {
* @param dataspaceName dataspace name
* @param anchorName anchor name
* @param parentNodeXpath xpath to parent node
- * @param jsonData json data
+ * @param nodeData node data
* @param observedTimestamp observedTimestamp
+ * @param contentType JSON/XML content type
*/
- void updateDataNodeAndDescendants(String dataspaceName, String anchorName, String parentNodeXpath, String jsonData,
- OffsetDateTime observedTimestamp);
+ void updateDataNodeAndDescendants(String dataspaceName, String anchorName, String parentNodeXpath, String nodeData,
+ OffsetDateTime observedTimestamp, ContentType contentType);
/**
* Replaces multiple existing data nodes' content including descendants in a batch operation.
*
* @param dataspaceName dataspace name
* @param anchorName anchor name
- * @param nodesJsonData map of xpath and node JSON data
+ * @param nodeDataPerXPath map of xpath and node JSON/XML data
* @param observedTimestamp observedTimestamp
+ * @param contentType JSON/XML content type
*/
- void updateDataNodesAndDescendants(String dataspaceName, String anchorName, Map<String, String> nodesJsonData,
- OffsetDateTime observedTimestamp);
+ void updateDataNodesAndDescendants(String dataspaceName, String anchorName, Map<String, String> nodeDataPerXPath,
+ OffsetDateTime observedTimestamp, ContentType contentType);
/**
* Replaces list content by removing all existing elements and inserting the given new elements as json
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
index bdd361458e..931209c998 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
@@ -155,4 +155,37 @@ public interface CpsModuleService {
Collection<ModuleReference> identifyNewModuleReferences(
Collection<ModuleReference> moduleReferencesToCheck);
+ /**
+ * Retrieves module references based on the provided dataspace name, anchor name and attribute filters
+ * for both parent and child fragments.
+
+ * This method constructs and executes a SQL query to find module references from a database, using
+ * the specified `dataspaceName`, `anchorName` and two sets of attribute filters: one for parent fragments
+ * and one for child fragments. The method applies these filters to identify the appropriate fragments
+ * and schema sets, and then retrieves the corresponding module references.
+
+ * The SQL query is dynamically built based on the provided attribute filters:
+ * - The `parentAttributes` map is used to filter the parent fragments. The entries in this map are
+ * converted into a WHERE clause for the parent fragments.
+ * - The `childAttributes` map is used to filter the child fragments. This is applied to the child fragments
+ * after filtering the parent fragments.
+ *
+ * @param dataspaceName the name of the dataspace to filter on. It is used to locate the relevant dataspace
+ * in the database.
+ * @param anchorName the name of the anchor to filter on. It is used to locate the relevant anchor within
+ * the dataspace.
+ * @param parentAttributes a map of attributes to filter parent fragments. Each entry in this map represents
+ * an attribute key-value pair used in the WHERE clause for parent fragments.
+ * @param childAttributes a map of attributes to filter child fragments. Each entry in this map represents
+ * an attribute key-value pair used in the WHERE clause for child fragments.
+ * @return a collection of {@link ModuleReference} objects that match the given criteria. Each
+ * {@code ModuleReference} contains information about a module's name and revision.
+ * @implNote The method assumes that both `parentAttributes` and `childAttributes` maps contain at least
+ * one entry. The first entry from `parentAttributes` is used to filter parent fragments,
+ * and the first entry from `childAttributes` is used to filter child fragments.
+ */
+ Collection<ModuleReference> getModuleReferencesByAttribute(final String dataspaceName, final String anchorName,
+ final Map<String, String> parentAttributes,
+ final Map<String, String> childAttributes);
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java
index aa9c45d09a..5ca0fe63d4 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,10 +23,10 @@ package org.onap.cps.api.impl;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsAnchorService;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.model.Anchor;
-import org.onap.cps.spi.utils.CpsValidator;
import org.springframework.stereotype.Service;
@Service
@@ -44,28 +44,36 @@ public class CpsAnchorServiceImpl implements CpsAnchorService {
}
@Override
+ public Anchor getAnchor(final String dataspaceName, final String anchorName) {
+ cpsValidator.validateNameCharacters(dataspaceName, anchorName);
+ return cpsAdminPersistenceService.getAnchor(dataspaceName, anchorName);
+ }
+
+ @Override
public Collection<Anchor> getAnchors(final String dataspaceName) {
cpsValidator.validateNameCharacters(dataspaceName);
return cpsAdminPersistenceService.getAnchors(dataspaceName);
}
@Override
- public Collection<Anchor> getAnchors(final String dataspaceName, final String schemaSetName) {
- cpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
- return cpsAdminPersistenceService.getAnchors(dataspaceName, schemaSetName);
+ public Collection<Anchor> getAnchors(final String dataspaceName, final Collection<String> anchorNames) {
+ cpsValidator.validateNameCharacters(dataspaceName);
+ cpsValidator.validateNameCharacters(anchorNames);
+ return cpsAdminPersistenceService.getAnchors(dataspaceName, anchorNames);
}
@Override
- public Collection<Anchor> getAnchors(final String dataspaceName, final Collection<String> schemaSetNames) {
- cpsValidator.validateNameCharacters(dataspaceName);
- cpsValidator.validateNameCharacters(schemaSetNames);
- return cpsAdminPersistenceService.getAnchors(dataspaceName, schemaSetNames);
+ public Collection<Anchor> getAnchorsBySchemaSetName(final String dataspaceName, final String schemaSetName) {
+ cpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
+ return cpsAdminPersistenceService.getAnchorsBySchemaSetName(dataspaceName, schemaSetName);
}
@Override
- public Anchor getAnchor(final String dataspaceName, final String anchorName) {
- cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- return cpsAdminPersistenceService.getAnchor(dataspaceName, anchorName);
+ public Collection<Anchor> getAnchorsBySchemaSetNames(final String dataspaceName,
+ final Collection<String> schemaSetNames) {
+ cpsValidator.validateNameCharacters(dataspaceName);
+ cpsValidator.validateNameCharacters(schemaSetNames);
+ return cpsAdminPersistenceService.getAnchorsBySchemaSetNames(dataspaceName, schemaSetNames);
}
@Override
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
index 5a48428772..eed4f09bf0 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
@@ -42,6 +42,7 @@ import org.onap.cps.api.CpsDeltaService;
import org.onap.cps.cpspath.parser.CpsPathUtil;
import org.onap.cps.events.CpsDataUpdateEventsService;
import org.onap.cps.events.model.Data.Operation;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataValidationException;
@@ -49,7 +50,6 @@ import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.DataNodeBuilder;
import org.onap.cps.spi.model.DeltaReport;
-import org.onap.cps.spi.utils.CpsValidator;
import org.onap.cps.utils.ContentType;
import org.onap.cps.utils.DataMapUtils;
import org.onap.cps.utils.JsonObjectMapper;
@@ -119,12 +119,13 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
@Timed(value = "cps.data.service.list.element.save",
description = "Time taken to save list elements")
- public void saveListElements(final String dataspaceName, final String anchorName, final String parentNodeXpath,
- final String jsonData, final OffsetDateTime observedTimestamp) {
+ public void saveListElements(final String dataspaceName, final String anchorName,
+ final String parentNodeXpath, final String nodeData,
+ final OffsetDateTime observedTimestamp, final ContentType contentType) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> listElementDataNodeCollection =
- buildDataNodesWithParentNodeXpath(anchor, parentNodeXpath, jsonData, ContentType.JSON);
+ buildDataNodesWithParentNodeXpath(anchor, parentNodeXpath, nodeData, contentType);
if (isRootNodeXpath(parentNodeXpath)) {
cpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName, listElementDataNodeCollection);
} else {
@@ -251,12 +252,12 @@ public class CpsDataServiceImpl implements CpsDataService {
@Timed(value = "cps.data.service.datanode.descendants.update",
description = "Time taken to update a data node and descendants")
public void updateDataNodeAndDescendants(final String dataspaceName, final String anchorName,
- final String parentNodeXpath, final String jsonData,
- final OffsetDateTime observedTimestamp) {
+ final String parentNodeXpath, final String nodeData,
+ final OffsetDateTime observedTimestamp, final ContentType contentType) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodes =
- buildDataNodesWithParentNodeXpath(anchor, parentNodeXpath, jsonData, ContentType.JSON);
+ buildDataNodesWithParentNodeXpath(anchor, parentNodeXpath, nodeData, contentType);
cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, dataNodes);
sendDataUpdatedEvent(anchor, parentNodeXpath, Operation.UPDATE, observedTimestamp);
}
@@ -265,13 +266,13 @@ public class CpsDataServiceImpl implements CpsDataService {
@Timed(value = "cps.data.service.datanode.descendants.batch.update",
description = "Time taken to update a batch of data nodes and descendants")
public void updateDataNodesAndDescendants(final String dataspaceName, final String anchorName,
- final Map<String, String> nodesJsonData,
- final OffsetDateTime observedTimestamp) {
+ final Map<String, String> nodeDataPerXPath,
+ final OffsetDateTime observedTimestamp, final ContentType contentType) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
- final Collection<DataNode> dataNodes = buildDataNodesWithParentNodeXpath(anchor, nodesJsonData);
+ final Collection<DataNode> dataNodes = buildDataNodesWithParentNodeXpath(anchor, nodeDataPerXPath, contentType);
cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, dataNodes);
- nodesJsonData.keySet().forEach(nodeXpath ->
+ nodeDataPerXPath.keySet().forEach(nodeXpath ->
sendDataUpdatedEvent(anchor, nodeXpath, Operation.UPDATE, observedTimestamp));
}
@@ -399,8 +400,7 @@ public class CpsDataServiceImpl implements CpsDataService {
private List<Map<String, Object>> prefixResolver(final Anchor anchor, final Collection<DataNode> dataNodes) {
final List<Map<String, Object>> prefixToDataNodes = new ArrayList<>(dataNodes.size());
for (final DataNode dataNode: dataNodes) {
- final String prefix = prefixResolver
- .getPrefix(anchor.getDataspaceName(), anchor.getName(), dataNode.getXpath());
+ final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath());
final Map<String, Object> prefixToDataNode = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix);
prefixToDataNodes.add(prefixToDataNode);
}
@@ -408,11 +408,12 @@ public class CpsDataServiceImpl implements CpsDataService {
}
private Collection<DataNode> buildDataNodesWithParentNodeXpath(final Anchor anchor,
- final Map<String, String> nodesJsonData) {
+ final Map<String, String> nodesJsonData,
+ final ContentType contentType) {
final Collection<DataNode> dataNodes = new ArrayList<>();
for (final Map.Entry<String, String> nodeJsonData : nodesJsonData.entrySet()) {
dataNodes.addAll(buildDataNodesWithParentNodeXpath(anchor, nodeJsonData.getKey(),
- nodeJsonData.getValue(), ContentType.JSON));
+ nodeJsonData.getValue(), contentType));
}
return dataNodes;
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java
index a7f5da4874..6bccf2a865 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java
@@ -26,9 +26,9 @@ package org.onap.cps.api.impl;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsDataspaceService;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.model.Dataspace;
-import org.onap.cps.spi.utils.CpsValidator;
import org.springframework.stereotype.Service;
@Service
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDeltaServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDeltaServiceImpl.java
index 2f99dbf7bb..7819568ae1 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDeltaServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDeltaServiceImpl.java
@@ -20,7 +20,6 @@
package org.onap.cps.api.impl;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
@@ -179,7 +178,7 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
final List<DeltaReport> updatedDeltaReportEntries) {
for (final Map.Entry<Map<String, Serializable>, Map<String, Serializable>> entry:
updatedLeavesAsSourceDataToTargetData.entrySet()) {
- final DeltaReport updatedDataForDeltaReport = new DeltaReportBuilder().actionUpdate()
+ final DeltaReport updatedDataForDeltaReport = new DeltaReportBuilder().actionReplace()
.withXpath(xpath).withSourceData(entry.getKey()).withTargetData(entry.getValue()).build();
updatedDeltaReportEntries.add(updatedDataForDeltaReport);
}
@@ -195,7 +194,7 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
for (final Map.Entry<String, DataNode> entry: xpathToAddedNodes.entrySet()) {
final String xpath = entry.getKey();
final DataNode dataNode = entry.getValue();
- final DeltaReport addedDataForDeltaReport = new DeltaReportBuilder().actionAdd().withXpath(xpath)
+ final DeltaReport addedDataForDeltaReport = new DeltaReportBuilder().actionCreate().withXpath(xpath)
.withTargetData(dataNode.getLeaves()).build();
addedDeltaReportEntries.add(addedDataForDeltaReport);
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
index 14b949e5ae..a600b22b61 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
@@ -30,6 +30,7 @@ import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsModuleService;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CascadeDeleteAllowed;
import org.onap.cps.spi.CpsModulePersistenceService;
import org.onap.cps.spi.exceptions.SchemaSetInUseException;
@@ -37,7 +38,6 @@ import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.model.ModuleDefinition;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.spi.model.SchemaSet;
-import org.onap.cps.spi.utils.CpsValidator;
import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder;
import org.onap.cps.yang.YangTextSchemaSourceSet;
import org.springframework.stereotype.Service;
@@ -97,7 +97,7 @@ public class CpsModuleServiceImpl implements CpsModuleService {
public void deleteSchemaSet(final String dataspaceName, final String schemaSetName,
final CascadeDeleteAllowed cascadeDeleteAllowed) {
cpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
- final Collection<Anchor> anchors = cpsAnchorService.getAnchors(dataspaceName, schemaSetName);
+ final Collection<Anchor> anchors = cpsAnchorService.getAnchorsBySchemaSetName(dataspaceName, schemaSetName);
if (!anchors.isEmpty() && isCascadeDeleteProhibited(cascadeDeleteAllowed)) {
throw new SchemaSetInUseException(dataspaceName, schemaSetName);
}
@@ -114,8 +114,9 @@ public class CpsModuleServiceImpl implements CpsModuleService {
public void deleteSchemaSetsWithCascade(final String dataspaceName, final Collection<String> schemaSetNames) {
cpsValidator.validateNameCharacters(dataspaceName);
cpsValidator.validateNameCharacters(schemaSetNames);
- final Collection<String> anchorNames = cpsAnchorService.getAnchors(dataspaceName, schemaSetNames)
- .stream().map(Anchor::getName).collect(Collectors.toSet());
+ final Collection<String> anchorNames =
+ cpsAnchorService.getAnchorsBySchemaSetNames(dataspaceName, schemaSetNames)
+ .stream().map(Anchor::getName).collect(Collectors.toSet());
cpsAnchorService.deleteAnchors(dataspaceName, anchorNames);
cpsModulePersistenceService.deleteSchemaSets(dataspaceName, schemaSetNames);
cpsModulePersistenceService.deleteUnusedYangResourceModules();
@@ -170,6 +171,17 @@ public class CpsModuleServiceImpl implements CpsModuleService {
return cpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck);
}
+ @Timed(value = "cps.module.service.module.reference.query",
+ description = "Time taken to query list of module references")
+ @Override
+ public Collection<ModuleReference> getModuleReferencesByAttribute(final String dataspaceName,
+ final String anchorName,
+ final Map<String, String> parentAttributes,
+ final Map<String, String> childAttributes) {
+ return cpsModulePersistenceService.getModuleReferencesByAttribute(dataspaceName, anchorName, parentAttributes,
+ childAttributes);
+ }
+
private boolean isCascadeDeleteProhibited(final CascadeDeleteAllowed cascadeDeleteAllowed) {
return CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED == cascadeDeleteAllowed;
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java
index 1d7a7ceeb0..d1c98986e6 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java
@@ -25,11 +25,11 @@ import io.micrometer.core.annotation.Timed;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsQueryService;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.PaginationOption;
import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.spi.utils.CpsValidator;
import org.springframework.stereotype.Service;
@Service
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java b/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java
index 4fdae5a307..8b85dfca32 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java
@@ -27,8 +27,8 @@ import io.micrometer.core.instrument.Metrics;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.RequiredArgsConstructor;
+import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsModulePersistenceService;
-import org.onap.cps.spi.utils.CpsValidator;
import org.onap.cps.yang.YangTextSchemaSourceSet;
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder;
import org.springframework.cache.annotation.CacheConfig;
diff --git a/cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheConfig.java b/cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheConfig.java
deleted file mode 100644
index efe19c6cb7..0000000000
--- a/cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheConfig.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ============LICENSE_START========================================================
- * Copyright (C) 2022-2023 Nordix Foundation
- * ================================================================================
- * 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_END=========================================================
- */
-
-package org.onap.cps.cache;
-
-import com.hazelcast.config.MapConfig;
-import com.hazelcast.map.IMap;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Core infrastructure of the hazelcast distributed cache for anchor data config use cases.
- */
-@Configuration
-public class AnchorDataCacheConfig extends HazelcastCacheConfig {
-
- private static final MapConfig anchorDataCacheMapConfig = createMapConfig("anchorDataCacheMapConfig");
-
- /**
- * Distributed instance of anchor data cache that contains module prefix by anchor name as properties.
- *
- * @return configured map of anchor data cache
- */
- @Bean
- public IMap<String, AnchorDataCacheEntry> anchorDataCache() {
- return createHazelcastInstance("hazelCastInstanceCpsCore", anchorDataCacheMapConfig).getMap("anchorDataCache");
- }
-}
diff --git a/cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheEntry.java b/cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheEntry.java
deleted file mode 100644
index 41adbdd5dc..0000000000
--- a/cps-service/src/main/java/org/onap/cps/cache/AnchorDataCacheEntry.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ============LICENSE_START========================================================
- * Copyright (C) 2022 Nordix Foundation
- * ================================================================================
- * 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_END=========================================================
- */
-
-package org.onap.cps.cache;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-public class AnchorDataCacheEntry implements Serializable {
-
- private static final long serialVersionUID = 2111243947810370698L;
-
- private Map<String, Serializable> properties = new HashMap<>();
-
- public Object getProperty(final String propertyName) {
- return properties.get(propertyName);
- }
-
- public void setProperty(final String propertyName, final Serializable value) {
- properties.put(propertyName, value);
- }
-
- public boolean hasProperty(final String propertyName) {
- return properties.containsKey(propertyName);
- }
-}
diff --git a/cps-service/src/main/java/org/onap/cps/cache/HazelcastCacheConfig.java b/cps-service/src/main/java/org/onap/cps/cache/HazelcastCacheConfig.java
deleted file mode 100644
index 418de9b17a..0000000000
--- a/cps-service/src/main/java/org/onap/cps/cache/HazelcastCacheConfig.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ============LICENSE_START========================================================
- * Copyright (C) 2023-2024 Nordix Foundation
- * ================================================================================
- * 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_END=========================================================
- */
-
-package org.onap.cps.cache;
-
-import com.hazelcast.config.Config;
-import com.hazelcast.config.MapConfig;
-import com.hazelcast.config.NamedConfig;
-import com.hazelcast.config.QueueConfig;
-import com.hazelcast.config.RestEndpointGroup;
-import com.hazelcast.config.SetConfig;
-import com.hazelcast.core.Hazelcast;
-import com.hazelcast.core.HazelcastInstance;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-
-/**
- * Core infrastructure of the hazelcast distributed cache.
- */
-@Slf4j
-public class HazelcastCacheConfig {
-
- @Value("${hazelcast.cluster-name}")
- protected String clusterName;
-
- @Value("${hazelcast.mode.kubernetes.enabled}")
- protected boolean cacheKubernetesEnabled;
-
- @Value("${hazelcast.mode.kubernetes.service-name}")
- protected String cacheKubernetesServiceName;
-
- protected HazelcastInstance createHazelcastInstance(final String hazelcastInstanceName,
- final NamedConfig namedConfig) {
- return Hazelcast.newHazelcastInstance(initializeConfig(hazelcastInstanceName, namedConfig));
- }
-
- private Config initializeConfig(final String instanceName, final NamedConfig namedConfig) {
- final Config config = new Config(instanceName);
- if (namedConfig instanceof MapConfig) {
- config.addMapConfig((MapConfig) namedConfig);
- }
- if (namedConfig instanceof QueueConfig) {
- config.addQueueConfig((QueueConfig) namedConfig);
- }
- if (namedConfig instanceof SetConfig) {
- config.addSetConfig((SetConfig) namedConfig);
- }
-
- config.setClusterName(clusterName);
- config.setClassLoader(org.onap.cps.spi.model.Dataspace.class.getClassLoader());
- exposeClusterInformation(config);
- updateDiscoveryMode(config);
- return config;
- }
-
- protected static MapConfig createMapConfig(final String configName) {
- final MapConfig mapConfig = new MapConfig(configName);
- mapConfig.setBackupCount(1);
- return mapConfig;
- }
-
- protected static QueueConfig createQueueConfig(final String configName) {
- final QueueConfig commonQueueConfig = new QueueConfig(configName);
- commonQueueConfig.setBackupCount(1);
- return commonQueueConfig;
- }
-
- protected static SetConfig createSetConfig(final String configName) {
- final SetConfig commonSetConfig = new SetConfig(configName);
- commonSetConfig.setBackupCount(1);
- return commonSetConfig;
- }
-
- protected void updateDiscoveryMode(final Config config) {
- if (cacheKubernetesEnabled) {
- log.info("Enabling kubernetes mode with service-name : {}", cacheKubernetesServiceName);
- config.getNetworkConfig().getJoin().getKubernetesConfig().setEnabled(true)
- .setProperty("service-name", cacheKubernetesServiceName);
- }
- }
-
- protected void exposeClusterInformation(final Config config) {
- config.getNetworkConfig().getRestApiConfig().setEnabled(true)
- .enableGroups(RestEndpointGroup.HEALTH_CHECK, RestEndpointGroup.CLUSTER_READ);
- }
-
-}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/utils/CpsValidator.java b/cps-service/src/main/java/org/onap/cps/impl/utils/CpsValidator.java
index ceb75c09b2..fd677eb2d2 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/utils/CpsValidator.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/utils/CpsValidator.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.spi.utils;
+package org.onap.cps.impl.utils;
import org.onap.cps.spi.PaginationOption;
diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
index 2b21619cb7..25830a55de 100755
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2022 Nordix Foundation.
+ * Copyright (C) 2020-2024 Nordix Foundation.
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2022 TechMahindra Ltd.
@@ -73,30 +73,48 @@ public interface CpsAdminPersistenceService {
void createAnchor(String dataspaceName, String schemaSetName, String anchorName);
/**
- * Read all anchors associated with the given schema-set in the given dataspace.
+ * Get an anchor in the given dataspace using the anchor name.
+ *
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @return an anchor
+ */
+ Anchor getAnchor(String dataspaceName, String anchorName);
+
+ /**
+ * Read all anchors in the given a dataspace.
*
* @param dataspaceName dataspace name
- * @param schemaSetName schema-set name
* @return a collection of anchors
*/
- Collection<Anchor> getAnchors(String dataspaceName, String schemaSetName);
+ Collection<Anchor> getAnchors(String dataspaceName);
/**
- * Read all anchors associated with multiple schema-sets in the given dataspace.
+ * Read all anchors in the given dataspace with the anchor names.
*
- * @param dataspaceName dataspace name
- * @param schemaSetNames schema-set names
+ * @param dataspaceName dataspace name
+ * @param anchorNames anchor names
* @return a collection of anchors
*/
- Collection<Anchor> getAnchors(String dataspaceName, Collection<String> schemaSetNames);
+ Collection<Anchor> getAnchors(String dataspaceName, Collection<String> anchorNames);
/**
- * Read all anchors in the given a dataspace.
+ * Read all anchors associated with the given schema-set in the given dataspace.
*
* @param dataspaceName dataspace name
+ * @param schemaSetName schema-set name
* @return a collection of anchors
*/
- Collection<Anchor> getAnchors(String dataspaceName);
+ Collection<Anchor> getAnchorsBySchemaSetName(String dataspaceName, String schemaSetName);
+
+ /**
+ * Read all anchors associated with multiple schema-sets in the given dataspace.
+ *
+ * @param dataspaceName dataspace name
+ * @param schemaSetNames schema-set names
+ * @return a collection of anchors
+ */
+ Collection<Anchor> getAnchorsBySchemaSetNames(String dataspaceName, Collection<String> schemaSetNames);
/**
* Query anchor names for the given module names in the provided dataspace.
@@ -110,15 +128,6 @@ public interface CpsAdminPersistenceService {
Collection<String> queryAnchorNames(String dataspaceName, Collection<String> moduleNames);
/**
- * Get an anchor in the given dataspace using the anchor name.
- *
- * @param dataspaceName dataspace name
- * @param anchorName anchor name
- * @return an anchor
- */
- Anchor getAnchor(String dataspaceName, String anchorName);
-
- /**
* Delete anchor by name in given dataspace.
*
* @param dataspaceName dataspace name
diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
index eeaaa47991..793f38e4bc 100755
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
@@ -153,4 +153,20 @@ public interface CpsModulePersistenceService {
Collection<ModuleReference> identifyNewModuleReferences(
Collection<ModuleReference> moduleReferencesToCheck);
+ /**
+ * Retrieves module references based on the specified dataspace, anchor, and attribute filters.
+
+ * Constructs and executes a SQL query to find module references by applying filters for parent and child fragments.
+ * Uses `parentAttributes` for filtering parent fragments and `childAttributes` for filtering child fragments.
+ *
+ * @param dataspaceName the name of the dataspace to filter on.
+ * @param anchorName the name of the anchor to filter on.
+ * @param parentAttributes a map of attributes for filtering parent fragments.
+ * @param childAttributes a map of attributes for filtering child fragments.
+ * @return a collection of {@link ModuleReference} objects matching the criteria.
+ */
+ Collection<ModuleReference> getModuleReferencesByAttribute(final String dataspaceName, final String anchorName,
+ final Map<String, String> parentAttributes,
+ final Map<String, String> childAttributes);
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReport.java b/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReport.java
index 34715e70b9..c6270a41d2 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReport.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReport.java
@@ -32,9 +32,9 @@ import lombok.Setter;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DeltaReport {
- public static final String ADD_ACTION = "add";
+ public static final String CREATE_ACTION = "create";
public static final String REMOVE_ACTION = "remove";
- public static final String UPDATE_ACTION = "update";
+ public static final String REPLACE_ACTION = "replace";
DeltaReport() {}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReportBuilder.java b/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReportBuilder.java
index 1e151eeb2d..a7e7aae215 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReportBuilder.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/DeltaReportBuilder.java
@@ -48,8 +48,8 @@ public class DeltaReportBuilder {
return this;
}
- public DeltaReportBuilder actionAdd() {
- this.action = DeltaReport.ADD_ACTION;
+ public DeltaReportBuilder actionCreate() {
+ this.action = DeltaReport.CREATE_ACTION;
return this;
}
@@ -58,8 +58,8 @@ public class DeltaReportBuilder {
return this;
}
- public DeltaReportBuilder actionUpdate() {
- this.action = DeltaReport.UPDATE_ACTION;
+ public DeltaReportBuilder actionReplace() {
+ this.action = DeltaReport.REPLACE_ACTION;
return this;
}
diff --git a/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java b/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java
index 35dc7347b2..c3097cc552 100644
--- a/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java
+++ b/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation.
+ * Copyright (C) 2022-2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,53 +20,25 @@
package org.onap.cps.utils;
-import com.hazelcast.map.IMap;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.impl.YangTextSchemaSourceSetCache;
-import org.onap.cps.cache.AnchorDataCacheEntry;
import org.onap.cps.cpspath.parser.CpsPathPrefixType;
import org.onap.cps.cpspath.parser.CpsPathQuery;
import org.onap.cps.cpspath.parser.CpsPathUtil;
import org.onap.cps.spi.model.Anchor;
import org.onap.cps.yang.YangTextSchemaSourceSet;
-import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class PrefixResolver {
- private static final long ANCHOR_DATA_CACHE_TTL_SECS = TimeUnit.HOURS.toSeconds(1);
-
- private static final String CACHE_ENTRY_PROPERTY_NAME = "prefixPerContainerName";
-
- private final CpsAnchorService cpsAnchorService;
-
private final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache;
- private final IMap<String, AnchorDataCacheEntry> anchorDataCache;
-
- /**
- * Get the module prefix for the given xpath for a dataspace and anchor name.
- *
- * @param dataspaceName the name of the dataspace
- * @param anchorName the name of the anchor the xpath belongs to
- * @param xpath the xpath to prefix a prefix for
- * @return the prefix of the module the top level element of given xpath
- */
- public String getPrefix(final String dataspaceName, final String anchorName, final String xpath) {
- final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
- return getPrefix(anchor, xpath);
- }
-
/**
* Get the module prefix for the given xpath under the given anchor.
*
@@ -75,57 +47,25 @@ public class PrefixResolver {
* @return the prefix of the module the top level element of given xpath
*/
public String getPrefix(final Anchor anchor, final String xpath) {
- final Map<String, String> prefixPerContainerName = getPrefixPerContainerName(anchor);
- return getPrefixForTopContainer(prefixPerContainerName, xpath);
- }
-
- private Map<String, String> getPrefixPerContainerName(final Anchor anchor) {
- if (anchorDataCache.containsKey(anchor.getName())) {
- final AnchorDataCacheEntry anchorDataCacheEntry = anchorDataCache.get(anchor.getName());
- if (anchorDataCacheEntry.hasProperty(CACHE_ENTRY_PROPERTY_NAME)) {
- return (Map) anchorDataCacheEntry.getProperty(CACHE_ENTRY_PROPERTY_NAME);
- }
- }
- return createAndCachePrefixPerContainerNameMap(anchor);
- }
-
- private String getPrefixForTopContainer(final Map<String, String> prefixPerContainerName,
- final String xpath) {
final CpsPathQuery cpsPathQuery = CpsPathUtil.getCpsPathQuery(xpath);
- if (cpsPathQuery.getCpsPathPrefixType() == CpsPathPrefixType.ABSOLUTE) {
- final String topLevelContainerName = cpsPathQuery.getContainerNames().get(0);
- if (prefixPerContainerName.containsKey(topLevelContainerName)) {
- return prefixPerContainerName.get(topLevelContainerName);
- }
+ if (cpsPathQuery.getCpsPathPrefixType() != CpsPathPrefixType.ABSOLUTE) {
+ return "";
}
- return "";
- }
+ final String topLevelContainerName = cpsPathQuery.getContainerNames().get(0);
- private Map<String, String> createAndCachePrefixPerContainerNameMap(final Anchor anchor) {
final YangTextSchemaSourceSet yangTextSchemaSourceSet =
- yangTextSchemaSourceSetCache.get(anchor.getDataspaceName(), anchor.getSchemaSetName());
+ yangTextSchemaSourceSetCache.get(anchor.getDataspaceName(), anchor.getSchemaSetName());
final SchemaContext schemaContext = yangTextSchemaSourceSet.getSchemaContext();
- final Map<QNameModule, String> prefixPerQNameModule = new HashMap<>(schemaContext.getModules().size());
- for (final Module module : schemaContext.getModules()) {
- prefixPerQNameModule.put(module.getQNameModule(), module.getPrefix());
- }
- final HashMap<String, String> prefixPerContainerName = new HashMap<>();
- for (final DataSchemaNode dataSchemaNode : schemaContext.getChildNodes()) {
- if (dataSchemaNode instanceof DataNodeContainer) {
- final String containerName = dataSchemaNode.getQName().getLocalName();
- final String prefix = prefixPerQNameModule.get(dataSchemaNode.getQName().getModule());
- prefixPerContainerName.put(containerName, prefix);
- }
- }
- cachePrefixPerContainerNameMap(anchor.getName(), prefixPerContainerName);
- return prefixPerContainerName;
- }
- private void cachePrefixPerContainerNameMap(final String anchorName,
- final Serializable prefixPerContainerName) {
- final AnchorDataCacheEntry anchorDataCacheEntry = new AnchorDataCacheEntry();
- anchorDataCacheEntry.setProperty(CACHE_ENTRY_PROPERTY_NAME, prefixPerContainerName);
- anchorDataCache.put(anchorName, anchorDataCacheEntry, ANCHOR_DATA_CACHE_TTL_SECS, TimeUnit.SECONDS);
+ return schemaContext.getChildNodes().stream()
+ .filter(DataNodeContainer.class::isInstance)
+ .map(SchemaNode::getQName)
+ .filter(qname -> qname.getLocalName().equals(topLevelContainerName))
+ .findFirst()
+ .map(QName::getModule)
+ .flatMap(schemaContext::findModule)
+ .map(Module::getPrefix)
+ .orElse("");
}
}
diff --git a/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java b/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java
index 5cadd29368..597164598a 100644
--- a/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java
+++ b/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java
@@ -120,13 +120,9 @@ public class YangParserHelper {
try (jsonParserStream) {
jsonParserStream.parse(jsonReader);
- } catch (final IOException | JsonSyntaxException exception) {
+ } catch (final IOException | JsonSyntaxException | IllegalStateException | IllegalArgumentException exception) {
throw new DataValidationException(
- "Failed to parse json data: " + jsonData, exception.getMessage(), exception);
- } catch (final IllegalStateException | IllegalArgumentException exception) {
- throw new DataValidationException(
- "Failed to parse json data. Unsupported xpath or json data:" + jsonData, exception
- .getMessage(), exception);
+ "Data Validation Failed", "Failed to parse json data. " + exception.getMessage(), exception);
}
return dataContainerNodeBuilder.build();
}
@@ -168,7 +164,7 @@ public class YangParserHelper {
} catch (final XMLStreamException | URISyntaxException | IOException | SAXException | NullPointerException
| ParserConfigurationException | TransformerException exception) {
throw new DataValidationException(
- "Failed to parse xml data: " + xmlData, exception.getMessage(), exception);
+ "Data Validation Failed", "Failed to parse xml data: " + exception.getMessage(), exception);
}
final DataContainerChild dataContainerChild =
(DataContainerChild) getFirstChildXmlRoot(normalizedNodeResult.getResult());
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy
index c7865386bc..ccf943a470 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +20,11 @@
package org.onap.cps.api.impl
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.exceptions.ModuleNamesNotFoundException
import org.onap.cps.spi.model.Anchor
-import org.onap.cps.spi.utils.CpsValidator
import spock.lang.Specification
class CpsAnchorServiceImplSpec extends Specification {
@@ -59,9 +59,9 @@ class CpsAnchorServiceImplSpec extends Specification {
def 'Retrieve all anchors for schema-set.'() {
given: 'that anchor is associated with the dataspace and schemaset'
def anchors = [new Anchor()]
- mockCpsAdminPersistenceService.getAnchors('someDataspace', 'someSchemaSet') >> anchors
+ mockCpsAdminPersistenceService.getAnchorsBySchemaSetName('someDataspace', 'someSchemaSet') >> anchors
when: 'get anchors is called for a dataspace name and schema set name'
- def result = objectUnderTest.getAnchors('someDataspace', 'someSchemaSet')
+ def result = objectUnderTest.getAnchorsBySchemaSetName('someDataspace', 'someSchemaSet')
then: 'the collection provided by persistence service is returned as result'
result == anchors
and: 'the CpsValidator is called on the dataspaceName, schemaSetName'
@@ -71,9 +71,9 @@ class CpsAnchorServiceImplSpec extends Specification {
def 'Retrieve all anchors for multiple schema-sets.'() {
given: 'that anchor is associated with the dataspace and schemasets'
def anchors = [new Anchor(), new Anchor()]
- mockCpsAdminPersistenceService.getAnchors('someDataspace', _ as Collection<String>) >> anchors
+ mockCpsAdminPersistenceService.getAnchorsBySchemaSetNames('someDataspace', _ as Collection<String>) >> anchors
when: 'get anchors is called for a dataspace name and schema set names'
- def result = objectUnderTest.getAnchors('someDataspace', ['schemaSet1', 'schemaSet2'])
+ def result = objectUnderTest.getAnchorsBySchemaSetNames('someDataspace', ['schemaSet1', 'schemaSet2'])
then: 'the collection provided by persistence service is returned as result'
result == anchors
and: 'the CpsValidator is called on the dataspace name and schema-set names'
@@ -93,6 +93,21 @@ class CpsAnchorServiceImplSpec extends Specification {
1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someAnchor')
}
+ def 'Retrieve multiple anchors for dataspace and provided anchor names.'() {
+ given: 'multiple anchors names to get'
+ def anchorNames = ['anchor1', 'anchor2']
+ and: 'that anchors are associated with the dataspace and anchor names'
+ def anchors = [new Anchor(), new Anchor()]
+ mockCpsAdminPersistenceService.getAnchors('someDataspace', anchorNames) >> anchors
+ when: 'get anchors is called for a dataspace name and anchor names'
+ def result = objectUnderTest.getAnchors('someDataspace', anchorNames)
+ then: 'the collection provided by persistence service is returned as result'
+ result == anchors
+ and: 'the CpsValidator is called on the dataspace name and anchor names'
+ 1 * mockCpsValidator.validateNameCharacters('someDataspace')
+ 1 * mockCpsValidator.validateNameCharacters(anchorNames)
+ }
+
def 'Delete anchor.'() {
when: 'delete anchor is invoked'
objectUnderTest.deleteAnchor('someDataspace','someAnchor')
@@ -105,15 +120,17 @@ class CpsAnchorServiceImplSpec extends Specification {
}
def 'Delete multiple anchors.'() {
+ given: 'multiple anchors to delete'
+ def anchorNames = ['anchor1', 'anchor2']
when: 'delete anchors is invoked'
- objectUnderTest.deleteAnchors('someDataspace', ['anchor1', 'anchor2'])
+ objectUnderTest.deleteAnchors('someDataspace', anchorNames)
then: 'delete data nodes is invoked on the data service with expected parameters'
- 1 * mockCpsDataPersistenceService.deleteDataNodes('someDataspace', _ as Collection<String>)
+ 1 * mockCpsDataPersistenceService.deleteDataNodes('someDataspace', anchorNames)
and: 'the persistence service method is invoked with same parameters to delete anchor'
- 1 * mockCpsAdminPersistenceService.deleteAnchors('someDataspace',_ as Collection<String>)
+ 1 * mockCpsAdminPersistenceService.deleteAnchors('someDataspace', anchorNames)
and: 'the CpsValidator is called on the dataspace name and anchor names'
1 * mockCpsValidator.validateNameCharacters('someDataspace')
- 1 * mockCpsValidator.validateNameCharacters(_)
+ 1 * mockCpsValidator.validateNameCharacters(anchorNames)
}
def 'Query all anchor identifiers for a dataspace and module names.'() {
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index edf25715b3..9846b30158 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -23,14 +23,15 @@
package org.onap.cps.api.impl
-import com.fasterxml.jackson.databind.ObjectMapper
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.core.read.ListAppender
+import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDeltaService
import org.onap.cps.events.CpsDataUpdateEventsService
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.ConcurrencyException
@@ -40,12 +41,11 @@ import org.onap.cps.spi.exceptions.SessionManagerException
import org.onap.cps.spi.exceptions.SessionTimeoutException
import org.onap.cps.spi.model.Anchor
import org.onap.cps.spi.model.DataNodeBuilder
-import org.onap.cps.spi.utils.CpsValidator
import org.onap.cps.utils.ContentType
-import org.onap.cps.utils.YangParser
-import org.onap.cps.utils.YangParserHelper
import org.onap.cps.utils.JsonObjectMapper
import org.onap.cps.utils.PrefixResolver
+import org.onap.cps.utils.YangParser
+import org.onap.cps.utils.YangParserHelper
import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder
import org.onap.cps.yang.YangTextSchemaSourceSet
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
@@ -53,8 +53,11 @@ import org.slf4j.LoggerFactory
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import spock.lang.Shared
import spock.lang.Specification
+
import java.time.OffsetDateTime
+import static org.onap.cps.events.model.Data.Operation.DELETE
+
class CpsDataServiceImplSpec extends Specification {
def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
def mockCpsAnchorService = Mock(CpsAnchorService)
@@ -130,8 +133,8 @@ class CpsDataServiceImplSpec extends Specification {
where: 'given parameters'
scenario | invalidData | contentType || expectedMessage
'no data nodes' | '{}' | ContentType.JSON || 'No data nodes'
- 'invalid json' | '{invalid json' | ContentType.JSON || 'Failed to parse json data'
- 'invalid xml' | '<invalid xml' | ContentType.XML || 'Failed to parse xml data'
+ 'invalid json' | '{invalid json' | ContentType.JSON || 'Data Validation Failed'
+ 'invalid xml' | '<invalid xml' | ContentType.XML || 'Data Validation Failed'
}
def 'Saving list element data fragment under Root node.'() {
@@ -139,7 +142,7 @@ class CpsDataServiceImplSpec extends Specification {
setupSchemaSetMocks('bookstore.yang')
when: 'save data method is invoked with list element json data'
def jsonData = '{"bookstore-address":[{"bookstore-name":"Easons","address":"Dublin,Ireland","postal-code":"D02HA21"}]}'
- objectUnderTest.saveListElements(dataspaceName, anchorName, '/', jsonData, observedTimestamp)
+ objectUnderTest.saveListElements(dataspaceName, anchorName, '/', jsonData, observedTimestamp, ContentType.JSON)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName,
{ dataNodeCollection ->
@@ -167,12 +170,11 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
}
- def 'Saving list element data fragment under existing node.'() {
+ def 'Saving list element data fragment under existing JSON/XML node.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
- when: 'save data method is invoked with list element json data'
- def jsonData = '{"branch": [{"name": "A"}, {"name": "B"}]}'
- objectUnderTest.saveListElements(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
+ when: 'save data method is invoked with list element data'
+ objectUnderTest.saveListElements(dataspaceName, anchorName, '/test-tree', data, observedTimestamp, contentType)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.addListElements(dataspaceName, anchorName, '/test-tree',
{ dataNodeCollection ->
@@ -185,16 +187,23 @@ class CpsDataServiceImplSpec extends Specification {
)
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
+ where:
+ data | contentType
+ '{"branch": [{"name": "A"}, {"name": "B"}]}' | ContentType.JSON
+ '<test-tree xmlns="org:onap:cps:test:test-tree"><branch><name>A</name></branch><branch><name>B</name></branch></test-tree>' | ContentType.XML
}
- def 'Saving empty list element data fragment.'() {
+ def 'Saving empty list element data fragment for JSON/XML data.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'save data method is invoked with an empty list'
- def jsonData = '{"branch": []}'
- objectUnderTest.saveListElements(dataspaceName, anchorName, '/test-tree', jsonData, observedTimestamp)
+ objectUnderTest.saveListElements(dataspaceName, anchorName, '/test-tree', data, observedTimestamp, contentType)
then: 'invalid data exception is thrown'
thrown(DataValidationException)
+ where:
+ data | contentType
+ '{"branch": []}' | ContentType.JSON
+ '<test-tree><branch></branch></test-tree>' | ContentType.XML
}
def 'Get all data nodes #scenario.'() {
@@ -360,11 +369,11 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
}
- def 'Replace data node using singular data node: #scenario.'() {
+ def 'Replace data node using singular JSON data node: #scenario.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'replace data method is invoked with json data #jsonData and parent node xpath #parentNodeXpath'
- objectUnderTest.updateDataNodeAndDescendants(dataspaceName, anchorName, parentNodeXpath, jsonData, observedTimestamp)
+ objectUnderTest.updateDataNodeAndDescendants(dataspaceName, anchorName, parentNodeXpath, jsonData, observedTimestamp, ContentType.JSON)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == expectedNodeXpath})
@@ -377,30 +386,63 @@ class CpsDataServiceImplSpec extends Specification {
'json list' | '/test-tree' | '{"branch": [{"name":"Name1"}, {"name":"Name2"}]}' || ["/test-tree/branch[@name='Name1']", "/test-tree/branch[@name='Name2']"]
}
- def 'Replace data node using multiple data nodes: #scenario.'() {
+ def 'Replace data node using singular XML data node: #scenario.'() {
+ given: 'schema set for given anchor and dataspace references test-tree model'
+ setupSchemaSetMocks('test-tree.yang')
+ when: 'replace data method is invoked with XML data #xmlData and parent node xpath #parentNodeXpath'
+ objectUnderTest.updateDataNodeAndDescendants(dataspaceName, anchorName, parentNodeXpath, xmlData, observedTimestamp, ContentType.XML)
+ then: 'the persistence service method is invoked with correct parameters'
+ 1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName,
+ { dataNode -> dataNode.xpath == expectedNodeXpath })
+ and: 'the CpsValidator is called on the dataspaceName and AnchorName'
+ 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
+ where: 'following parameters were used'
+ scenario | parentNodeXpath | xmlData || expectedNodeXpath
+ 'level 2 node' | '/test-tree' | '<branch><name>Name</name></branch>' || ['/test-tree/branch[@name=\'Name\']']
+ 'xml list' | '/test-tree' | '<test-tree xmlns="org:onap:cps:test:test-tree"><branch><name>Name1</name></branch>' + '<branch><name>Name2</name></branch></test-tree>' || ["/test-tree/branch[@name='Name1']", "/test-tree/branch[@name='Name2']"]
+ }
+
+ def 'Replace data node using multiple JSON data nodes: #scenario.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
when: 'replace data method is invoked with a map of xpaths and json data'
- objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, nodesJsonData, observedTimestamp)
+ objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, nodeDataPerXPath, observedTimestamp, ContentType.JSON)
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == expectedNodeXpath})
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
where: 'following parameters were used'
- scenario | nodesJsonData || expectedNodeXpath
+ scenario | nodeDataPerXPath || expectedNodeXpath
'top level node' | ['/' : '{"test-tree": {"branch": []}}', '/test-tree' : '{"branch": [{"name":"Name"}]}'] || ["/test-tree", "/test-tree/branch[@name='Name']"]
'level 2 node' | ['/test-tree' : '{"branch": [{"name":"Name"}]}', '/test-tree/branch[@name=\'Name\']':'{"nest":{"name":"nestName"}}'] || ["/test-tree/branch[@name='Name']", "/test-tree/branch[@name='Name']/nest"]
'json list' | ['/test-tree' : '{"branch": [{"name":"Name1"}, {"name":"Name2"}]}'] || ["/test-tree/branch[@name='Name1']", "/test-tree/branch[@name='Name2']"]
}
+ def 'Replace data node using multiple XML data nodes: #scenario.'() {
+ given: 'schema set for given anchor and dataspace references test-tree model'
+ setupSchemaSetMocks('test-tree.yang')
+ when: 'replace data method is invoked with a map of xpaths and XML data'
+ objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, nodeXmlDataPerXPath, observedTimestamp, ContentType.XML)
+ then: 'the persistence service method is invoked with correct parameters'
+ 1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName,
+ { dataNode -> dataNode.xpath == expectedNodeXpath })
+ and: 'the CpsValidator is called on the dataspaceName and AnchorName'
+ 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
+ where: 'following parameters were used'
+ scenario | nodeXmlDataPerXPath || expectedNodeXpath
+ 'top level node' | ['/test-tree': '<branch><name>Name</name></branch>'] || ["/test-tree/branch[@name='Name']"]
+ 'level 2 node' | ['/test-tree': '<branch><name>Name</name></branch>', '/test-tree/branch[@name=\'Name\']': '<nest><name>nestName</name></nest>'] || ["/test-tree/branch[@name='Name']", "/test-tree/branch[@name='Name']/nest"]
+ 'xml list' | ['/test-tree': '<test-tree xmlns="org:onap:cps:test:test-tree"><branch><name>Name1</name></branch>' + '<branch><name>Name2</name></branch></test-tree>'] || ["/test-tree/branch[@name='Name1']", "/test-tree/branch[@name='Name2']"]
+ }
+
def 'Replace data node with concurrency exception in persistence layer.'() {
given: 'the persistence layer throws an concurrency exception'
def originalException = new ConcurrencyException('message', 'details')
mockCpsDataPersistenceService.updateDataNodesAndDescendants(*_) >> { throw originalException }
setupSchemaSetMocks('test-tree.yang')
when: 'attempt to replace data node'
- objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, ['/' : '{"test-tree": {}}'] , observedTimestamp)
+ objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, ['/' : '{"test-tree": {}}'] , observedTimestamp, ContentType.JSON)
then: 'the same exception is thrown up'
def thrownUp = thrown(ConcurrencyException)
assert thrownUp == originalException
@@ -489,15 +531,19 @@ class CpsDataServiceImplSpec extends Specification {
def 'Delete all data nodes for given dataspace and multiple anchors.'() {
given: 'schema set for given anchors and dataspace references test tree model'
setupSchemaSetMocks('test-tree.yang')
- mockCpsAnchorService.getAnchors(dataspaceName, ['anchor1', 'anchor2']) >>
- [new Anchor(name: 'anchor1', dataspaceName: dataspaceName),
- new Anchor(name: 'anchor2', dataspaceName: dataspaceName)]
+ def anchor1 = new Anchor(name: 'anchor1', dataspaceName: dataspaceName)
+ def anchor2 = new Anchor(name: 'anchor2', dataspaceName: dataspaceName)
+ mockCpsAnchorService.getAnchors(dataspaceName, ['anchor1', 'anchor2']) >> [anchor1, anchor2]
when: 'delete data node method is invoked with correct parameters'
objectUnderTest.deleteDataNodes(dataspaceName, ['anchor1', 'anchor2'], observedTimestamp)
then: 'the CpsValidator is called on the dataspace name and the anchor names'
- 2 * mockCpsValidator.validateNameCharacters(_)
+ 1 * mockCpsValidator.validateNameCharacters(dataspaceName)
+ 1 * mockCpsValidator.validateNameCharacters(['anchor1', 'anchor2'])
and: 'the persistence service method is invoked with the correct parameters'
1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, _ as Collection<String>)
+ and: 'a data update event is sent for each anchor'
+ 1 * mockDataUpdateEventsService.publishCpsDataUpdateEvent(anchor1, '/', DELETE, observedTimestamp)
+ 1 * mockDataUpdateEventsService.publishCpsDataUpdateEvent(anchor2, '/', DELETE, observedTimestamp)
}
def 'Start session.'() {
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy
index 8e17594bd1..ac7d4c0aa7 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy
@@ -20,9 +20,9 @@
package org.onap.cps.api.impl
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.spi.model.Dataspace
-import org.onap.cps.spi.utils.CpsValidator
import spock.lang.Specification
class CpsDataspaceServiceImplSpec extends Specification {
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDeltaServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDeltaServiceImplSpec.groovy
index 42d75f3eab..f12afe61ec 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDeltaServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDeltaServiceImplSpec.groovy
@@ -51,8 +51,8 @@ class CpsDeltaServiceImplSpec extends Specification{
def 'Get delta between data nodes for ADDED data'() {
when: 'attempt to get delta between 2 data nodes'
def result = objectUnderTest.getDeltaReports([], targetDataNodeWithLeafData)
- then: 'the delta report contains expected "add" action'
- assert result[0].action.equals('add')
+ then: 'the delta report contains expected "create" action'
+ assert result[0].action.equals('create')
and: 'the delta report contains expected xpath'
assert result[0].xpath == '/parent'
and: 'the delta report contains no source data'
@@ -68,12 +68,12 @@ class CpsDeltaServiceImplSpec extends Specification{
when: 'attempt to get delta between 2 data nodes'
def result = objectUnderTest.getDeltaReports(sourceDataNode, targetDataNode)
then: 'the delta report contains expected details for parent node'
- assert result[0].action.equals('update')
+ assert result[0].action.equals('replace')
assert result[0].xpath == '/parent'
assert result[0].sourceData == ['parent-leaf': 'parent-payload']
assert result[0].targetData == ['parent-leaf': 'parent-payload-updated']
and: 'the delta report contains expected details for child node'
- assert result[1].action.equals('update')
+ assert result[1].action.equals('replace')
assert result[1].xpath == '/parent/child'
assert result[1].sourceData == ['child-leaf': 'child-payload']
assert result[1].targetData == ['child-leaf': 'child-payload-updated']
@@ -82,8 +82,8 @@ class CpsDeltaServiceImplSpec extends Specification{
def 'Delta report between leaves, #scenario'() {
when: 'attempt to get delta between 2 data nodes'
def result = objectUnderTest.getDeltaReports(sourceDataNode, targetDataNode)
- then: 'the delta report contains expected "update" action'
- assert result[0].action.equals('update')
+ then: 'the delta report contains expected "replace" action'
+ assert result[0].action.equals('replace')
and: 'the delta report contains expected xpath'
assert result[0].xpath == '/parent'
and: 'the delta report contains expected source and target data'
@@ -100,7 +100,7 @@ class CpsDeltaServiceImplSpec extends Specification{
def 'Get delta between data nodes for updated data, where source and target data nodes have no leaves '() {
when: 'attempt to get delta between 2 data nodes'
def result = objectUnderTest.getDeltaReports(sourceDataNodeWithoutLeafData, targetDataNodeWithoutLeafData)
- then: 'the delta report contains "update" action with right data'
+ then: 'the delta report is empty'
assert result.isEmpty()
}
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
index 0bad0de6ac..1831506563 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
@@ -23,19 +23,15 @@
package org.onap.cps.api.impl
-import org.onap.cps.api.CpsAnchorService
-
-import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
-import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
-
import org.onap.cps.TestUtils
+import org.onap.cps.api.CpsAnchorService
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.exceptions.DuplicatedYangResourceException
import org.onap.cps.spi.exceptions.ModelValidationException
import org.onap.cps.spi.exceptions.SchemaSetInUseException
-import org.onap.cps.spi.model.ModuleDefinition
-import org.onap.cps.spi.utils.CpsValidator
import org.onap.cps.spi.model.Anchor
+import org.onap.cps.spi.model.ModuleDefinition
import org.onap.cps.spi.model.ModuleReference
import org.onap.cps.spi.model.SchemaSet
import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder
@@ -43,6 +39,9 @@ import org.onap.cps.yang.YangTextSchemaSourceSet
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
import spock.lang.Specification
+import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
+import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
+
class CpsModuleServiceImplSpec extends Specification {
def mockCpsModulePersistenceService = Mock(CpsModulePersistenceService)
@@ -134,7 +133,7 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete schema-set when cascade is allowed.'() {
given: '#numberOfAnchors anchors are associated with schemaset'
def associatedAnchors = createAnchors(numberOfAnchors)
- mockCpsAnchorService.getAnchors('my-dataspace', 'my-schemaset') >> associatedAnchors
+ mockCpsAnchorService.getAnchorsBySchemaSetName('my-dataspace', 'my-schemaset') >> associatedAnchors
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_ALLOWED)
then: 'anchor deletion is called #numberOfAnchors times'
@@ -153,7 +152,7 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete schema-set when cascade is prohibited.'() {
given: 'no anchors are associated with schemaset'
- mockCpsAnchorService.getAnchors('my-dataspace', 'my-schemaset') >> Collections.emptyList()
+ mockCpsAnchorService.getAnchorsBySchemaSetName('my-dataspace', 'my-schemaset') >> Collections.emptyList()
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_PROHIBITED)
then: 'no anchors are deleted'
@@ -170,7 +169,7 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete schema-set when cascade is prohibited and schema-set has anchors.'() {
given: '2 anchors are associated with schemaset'
- mockCpsAnchorService.getAnchors('my-dataspace', 'my-schemaset') >> createAnchors(2)
+ mockCpsAnchorService.getAnchorsBySchemaSetName('my-dataspace', 'my-schemaset') >> createAnchors(2)
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_PROHIBITED)
then: 'Schema-Set in Use exception is thrown'
@@ -179,7 +178,7 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete multiple schema-sets when cascade is allowed.'() {
given: '#numberOfAnchors anchors are associated with each schemaset'
- mockCpsAnchorService.getAnchors('my-dataspace', ['my-schemaset1', 'my-schemaset2']) >> createAnchors(numberOfAnchors * 2)
+ mockCpsAnchorService.getAnchorsBySchemaSetNames('my-dataspace', ['my-schemaset1', 'my-schemaset2']) >> createAnchors(numberOfAnchors * 2)
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSetsWithCascade('my-dataspace', ['my-schemaset1', 'my-schemaset2'])
then: 'anchor deletion is called #numberOfAnchors times'
@@ -238,6 +237,23 @@ class CpsModuleServiceImplSpec extends Specification {
1 * mockCpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck)
}
+ def 'Get module references when queried by attributes'() {
+ given: 'a valid dataspace name and anchor name'
+ def dataspaceName = 'someDataspace'
+ def anchorName = 'someAnchor'
+ and: 'a set of parent attributes and child attributes used for filtering'
+ def parentAttributes = ['some-property-key1': 'some-property-val1']
+ def childAttributes = ['some-property-key2': 'some-property-val2']
+ and: 'a list of expected module references returned by the persistence service'
+ def expectedModuleReferences = [new ModuleReference(moduleName: 'some-name', revision: 'some-revision')]
+ mockCpsModulePersistenceService.getModuleReferencesByAttribute(dataspaceName, anchorName, parentAttributes, childAttributes) >> expectedModuleReferences
+ when: 'the method is invoked to retrieve module references by attributes'
+ def actualModuleReferences = objectUnderTest.getModuleReferencesByAttribute(dataspaceName, anchorName, parentAttributes, childAttributes)
+ then: 'the retrieved module references should match the expected module references'
+ assert actualModuleReferences == expectedModuleReferences
+ }
+
+
def 'Getting module definitions with module name'() {
given: 'module persistence service returns module definitions for module name'
def moduleDefinitionsFromPersistenceService = [ new ModuleDefinition('name', 'revision', 'content' ) ]
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
index 1ad5017919..3b10669ddb 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
@@ -21,10 +21,10 @@
package org.onap.cps.api.impl
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.PaginationOption
-import org.onap.cps.spi.utils.CpsValidator
import spock.lang.Specification
class CpsQueryServiceImplSpec extends Specification {
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
index 9e55e8f10a..05c8983fc2 100755
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
@@ -28,13 +28,13 @@ import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDeltaService
import org.onap.cps.events.CpsDataUpdateEventsService
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.model.Anchor
-import org.onap.cps.spi.utils.CpsValidator
+import org.onap.cps.utils.ContentType
import org.onap.cps.utils.JsonObjectMapper
import org.onap.cps.utils.PrefixResolver
-import org.onap.cps.utils.ContentType
import org.onap.cps.utils.YangParser
import org.onap.cps.utils.YangParserHelper
import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy
index a9f50ee5b0..189e28521b 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/YangTextSchemaSourceSetCacheSpec.groovy
@@ -22,6 +22,7 @@
package org.onap.cps.api.impl
import org.onap.cps.TestUtils
+import org.onap.cps.impl.utils.CpsValidator
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.yang.YangTextSchemaSourceSet
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
@@ -34,8 +35,6 @@ import org.springframework.cache.annotation.EnableCaching
import org.springframework.cache.caffeine.CaffeineCacheManager
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
-import org.onap.cps.spi.utils.CpsValidator
-
@SpringBootTest
@EnableCaching
diff --git a/cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheConfigSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheConfigSpec.groovy
deleted file mode 100644
index 010308c42f..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheConfigSpec.groovy
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
- * ================================================================================
- * 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_END=========================================================
- */
-
-package org.onap.cps.cache
-
-import com.hazelcast.config.Config
-import com.hazelcast.core.Hazelcast
-import com.hazelcast.map.IMap
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.test.context.ContextConfiguration
-import spock.lang.Specification
-
-@SpringBootTest
-@ContextConfiguration(classes = [AnchorDataCacheConfig])
-class AnchorDataCacheConfigSpec extends Specification {
-
- @Autowired
- private IMap<String, AnchorDataCacheEntry> anchorDataCache
-
- def 'Embedded (hazelcast) cache for Anchor Data.'() {
- expect: 'system is able to create an instance of the Anchor data cache'
- assert null != anchorDataCache
- and: 'there is at least 1 instance'
- assert Hazelcast.allHazelcastInstances.size() > 0
- and: 'anchorDataCache is present'
- assert Hazelcast.allHazelcastInstances.name.contains('hazelCastInstanceCpsCore')
- }
-
- def 'Verify configs for Distributed Caches'(){
- given: 'the Anchor Data Cache config'
- def anchorDataCacheConfig = Hazelcast.getHazelcastInstanceByName('hazelCastInstanceCpsCore').config
- def anchorDataCacheMapConfig = anchorDataCacheConfig.mapConfigs.get('anchorDataCacheMapConfig')
- expect: 'system created instance with correct config'
- assert anchorDataCacheConfig.clusterName == 'cps-and-ncmp-test-caches'
- assert anchorDataCacheMapConfig.backupCount == 1
- assert anchorDataCacheMapConfig.asyncBackupCount == 0
- }
-
- def 'Verify deployment network configs for Distributed Caches'() {
- given: 'the Anchor Data Cache config'
- def anchorDataCacheNetworkConfig = Hazelcast.getHazelcastInstanceByName('hazelCastInstanceCpsCore').config.networkConfig
- expect: 'system created instance with correct config'
- assert anchorDataCacheNetworkConfig.join.autoDetectionConfig.enabled
- assert !anchorDataCacheNetworkConfig.join.kubernetesConfig.enabled
- }
-
- def 'Verify network config'() {
- given: 'Synchronization config object and test configuration'
- def objectUnderTest = new AnchorDataCacheConfig()
- def testConfig = new Config()
- when: 'kubernetes properties are enabled'
- objectUnderTest.cacheKubernetesEnabled = true
- objectUnderTest.cacheKubernetesServiceName = 'test-service-name'
- and: 'method called to update the discovery mode'
- objectUnderTest.updateDiscoveryMode(testConfig)
- then: 'applied properties are reflected'
- assert testConfig.networkConfig.join.kubernetesConfig.enabled
- assert testConfig.networkConfig.join.kubernetesConfig.properties.get('service-name') == 'test-service-name'
-
- }
-
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheEntrySpec.groovy b/cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheEntrySpec.groovy
deleted file mode 100644
index f38b45d17c..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/cache/AnchorDataCacheEntrySpec.groovy
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
- * ================================================================================
- * 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_END=========================================================
- */
-
-package org.onap.cps.cache
-
-
-import spock.lang.Specification
-
-class AnchorDataCacheEntrySpec extends Specification {
-
- def objectUnderTest = new AnchorDataCacheEntry()
-
- def 'Anchor Data Cache Properties Management.'() {
- when: 'a property named "sample" is added to the cache'
- objectUnderTest.setProperty('sample', 123)
- then: 'the cache has that property'
- assert objectUnderTest.hasProperty('sample')
- and: 'the value is correct'
- assert objectUnderTest.getProperty('sample') == 123
- and: 'the cache does not have an an object called "something else"'
- assert objectUnderTest.hasProperty('something else') == false
- }
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/cache/HazelcastCacheConfigSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/cache/HazelcastCacheConfigSpec.groovy
deleted file mode 100644
index 022cd74ea6..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/cache/HazelcastCacheConfigSpec.groovy
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
- * ================================================================================
- * 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_END=========================================================
- */
-
-package org.onap.cps.cache
-
-import com.hazelcast.config.Config
-import com.hazelcast.config.RestEndpointGroup
-import spock.lang.Specification
-
-class HazelcastCacheConfigSpec extends Specification {
-
- def objectUnderTest = new HazelcastCacheConfig()
-
- def 'Create Hazelcast instance with a #scenario'() {
- given: 'a cluster name'
- objectUnderTest.clusterName = 'my cluster'
- when: 'an hazelcast instance is created (name has to be unique)'
- def result = objectUnderTest.createHazelcastInstance(scenario, config)
- then: 'the instance is created and has the correct name'
- assert result.name == scenario
- and: 'if applicable it has a map config with the expected name'
- if (expectMapConfig) {
- assert result.config.mapConfigs.values()[0].name == 'my map config'
- } else {
- assert result.config.mapConfigs.isEmpty()
- }
- and: 'if applicable it has a queue config with the expected name'
- if (expectQueueConfig) {
- assert result.config.queueConfigs.values()[0].name == 'my queue config'
- } else {
- assert result.config.queueConfigs.isEmpty()
- }
- and: 'if applicable it has a set config with the expected name'
- if (expectSetConfig) {
- assert result.config.setConfigs.values()[0].name == 'my set config'
- } else {
- assert result.config.setConfigs.isEmpty()
- }
- where: 'the following configs are used'
- scenario | config || expectMapConfig | expectQueueConfig | expectSetConfig
- 'Map Config' | HazelcastCacheConfig.createMapConfig('my map config') || true | false | false
- 'Queue Config' | HazelcastCacheConfig.createQueueConfig('my queue config') || false | true | false
- 'Set Config' | HazelcastCacheConfig.createSetConfig('my set config') || false | false | true
- }
-
- def 'Verify Hazelcast Cluster Information'() {
- given: 'a test configuration'
- def testConfig = new Config()
- when: 'cluster information is exposed'
- objectUnderTest.exposeClusterInformation(testConfig)
- then: 'REST api configs are enabled'
- assert testConfig.networkConfig.restApiConfig.enabled
- and: 'only health check and cluster read are enabled'
- def enabledGroups = testConfig.networkConfig.restApiConfig.enabledGroups
- assert enabledGroups.size() == 2
- assert enabledGroups.containsAll([RestEndpointGroup.CLUSTER_READ, RestEndpointGroup.HEALTH_CHECK])
- }
-
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/spi/model/DeltaReportBuilderSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/spi/model/DeltaReportBuilderSpec.groovy
index e19d120421..00b5499c2f 100644
--- a/cps-service/src/test/groovy/org/onap/cps/spi/model/DeltaReportBuilderSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/spi/model/DeltaReportBuilderSpec.groovy
@@ -24,20 +24,20 @@ import spock.lang.Specification
class DeltaReportBuilderSpec extends Specification{
- def 'Generating delta report with for add action'() {
+ def 'Generating delta report for "create" action'() {
when: 'delta report is generated'
def result = new DeltaReportBuilder()
- .actionAdd()
+ .actionCreate()
.withXpath('/xpath')
.withTargetData(['data':'leaf-data'])
.build()
- then: 'the delta report contains the "add" action with expected target data'
- assert result.action == 'add'
+ then: 'the delta report contains the "create" action with expected target data'
+ assert result.action == 'create'
assert result.xpath == '/xpath'
assert result.targetData == ['data': 'leaf-data']
}
- def 'Generating delta report with attributes for remove action'() {
+ def 'Generating delta report with attributes for "remove" action'() {
when: 'delta report is generated'
def result = new DeltaReportBuilder()
.actionRemove()
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy
index 8cbd493550..09d45b92c0 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy
@@ -42,7 +42,7 @@ class JsonObjectMapperSpec extends Specification {
def contentMap = new JsonSlurper().parseText(new String(content))
and: 'the parsed content is as expected'
assert contentMap.'test:bookstore'.'bookstore-name' == 'Chapters/Easons'
- where: 'the following data stores are used'
+ where: 'the following content types are used'
type << ['String', 'bytes']
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy
index b975de6555..13b042f1ae 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2021-2024 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021-2022 Bell Canada.
* ================================================================================
@@ -22,11 +22,8 @@
package org.onap.cps.utils
-import com.hazelcast.map.IMap
import org.onap.cps.TestUtils
-import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.impl.YangTextSchemaSourceSetCache
-import org.onap.cps.cache.AnchorDataCacheEntry
import org.onap.cps.spi.model.Anchor
import org.onap.cps.yang.YangTextSchemaSourceSet
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
@@ -34,13 +31,9 @@ import spock.lang.Specification
class PrefixResolverSpec extends Specification {
- def mockCpsAnchorService = Mock(CpsAnchorService)
-
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
- def mockAnchorDataCache = Mock(IMap<String, AnchorDataCacheEntry>)
-
- def objectUnderTest = new PrefixResolver(mockCpsAnchorService, mockYangTextSchemaSourceSetCache, mockAnchorDataCache)
+ def objectUnderTest = new PrefixResolver(mockYangTextSchemaSourceSetCache)
def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
@@ -48,29 +41,16 @@ class PrefixResolverSpec extends Specification {
def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
- def setup() {
- given: 'an anchor for the test-tree model'
- def anchor = new Anchor(dataspaceName: 'testDataspace', name: 'testAnchor')
- and: 'the system can get this anchor'
- mockCpsAnchorService.getAnchor('testDataspace', 'testAnchor') >> anchor
- and: 'the schema source cache contains the schema context for the test-tree module'
- mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
- }
+ def anchor = new Anchor(dataspaceName: 'testDataspace', name: 'testAnchor')
def 'get xpath prefix using node schema context'() {
+ given: 'the schema source cache contains the schema context for the test-tree module'
+ mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
+ mockYangTextSchemaSourceSetCache.get(*_) >> mockYangTextSchemaSourceSet
when: 'the prefix of the yang module is retrieved'
- def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', xpath)
+ def result = objectUnderTest.getPrefix(anchor, xpath)
then: 'the expected prefix is returned'
result == expectedPrefix
- and: 'the cache is updated for the given anchor with a map of prefixes per top level container (just one one this case)'
- 1 * mockAnchorDataCache.put('testAnchor',_ , _ ,_) >> { args -> {
- def prefixPerContainerName = args[1].getProperty("prefixPerContainerName")
- assert prefixPerContainerName.size() == 1
- assert prefixPerContainerName.get('test-tree') == 'tree'
- }
- }
- and: 'schema source cache is used (i.e. need to build schema context)'
- 1 * mockYangTextSchemaSourceSetCache.get(*_) >> mockYangTextSchemaSourceSet
where: 'the following scenarios are applied'
xpath || expectedPrefix
'/test-tree' || 'tree'
@@ -82,37 +62,4 @@ class PrefixResolverSpec extends Specification {
'/not-defined' || ''
}
- def 'get prefix with populated anchor data cache with #scenario cache entry'() {
- given: 'anchor data cache is populated for the anchor with a prefix for top level container named #cachedTopLevelContainerName'
- def anchorDataCacheEntry = new AnchorDataCacheEntry()
- def prefixPerContainerName = [(cachedTopLevelContainerName): 'cachedPrefix']
- anchorDataCacheEntry.setProperty('prefixPerContainerName',prefixPerContainerName)
- mockAnchorDataCache.containsKey('testAnchor') >> true
- mockAnchorDataCache.get('testAnchor') >> anchorDataCacheEntry
- when: 'the prefix of the yang module is retrieved'
- def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', '/test-tree')
- then: 'the expected prefix is returned'
- result == expectedPrefix
- and: 'schema source cache is not used (i.e. no need to build schema context)'
- 0 * mockYangTextSchemaSourceSetCache.get(*_)
- where: 'the following scenarios are applied'
- scenario | cachedTopLevelContainerName || expectedPrefix
- 'matching' | 'test-tree' || 'cachedPrefix'
- 'non-matching' | 'other' || ''
- }
-
- def 'get prefix with other (non relevant) data in anchor data cache'() {
- given: 'anchor data cache is populated with non relevant other property'
- def anchorDataCacheEntry = new AnchorDataCacheEntry()
- anchorDataCacheEntry.setProperty('something else', 'does not matter')
- mockAnchorDataCache.containsKey('testAnchor') >> true
- mockAnchorDataCache.get('testAnchor') >> anchorDataCacheEntry
- when: 'the prefix of the yang module is retrieved'
- def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', '/test-tree')
- then: 'the expected prefix is returned'
- result == 'tree'
- and: 'schema source cache is used (i.e. need to build schema context)'
- 1 * mockYangTextSchemaSourceSetCache.get(*_) >> mockYangTextSchemaSourceSet
- }
-
}
diff --git a/cps-service/src/test/resources/application.yml b/cps-service/src/test/resources/application.yml
index b666885f22..be71d37d2a 100644
--- a/cps-service/src/test/resources/application.yml
+++ b/cps-service/src/test/resources/application.yml
@@ -1,6 +1,6 @@
# ============LICENSE_START=======================================================
# Copyright (c) 2021 Bell Canada.
-# Modification Copyright (C) 2022 Nordix Foundation.
+# Modification Copyright (C) 2022-2024 Nordix Foundation.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -41,11 +41,3 @@ spring:
logging:
level:
org.apache.kafka: ERROR
-
-# Custom Hazelcast Config.
-hazelcast:
- cluster-name: "cps-and-ncmp-test-caches"
- mode:
- kubernetes:
- enabled: false
- service-name: "cps-and-ncmp-service"