summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checkstyle/pom.xml2
-rwxr-xr-xcps-application/pom.xml2
-rw-r--r--cps-application/src/main/resources/application.yml1
-rw-r--r--cps-bom/pom.xml2
-rwxr-xr-xcps-dependencies/pom.xml2
-rw-r--r--cps-events/pom.xml2
-rw-r--r--cps-ncmp-events/pom.xml2
-rw-r--r--cps-ncmp-rest-stub/pom.xml2
-rw-r--r--cps-ncmp-rest/pom.xml2
-rw-r--r--cps-ncmp-service/pom.xml2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java47
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java13
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java10
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java19
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java9
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java6
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy4
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy35
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy7
-rwxr-xr-xcps-parent/pom.xml2
-rw-r--r--cps-path-parser/pom.xml2
-rwxr-xr-xcps-rest/pom.xml2
-rw-r--r--cps-ri/pom.xml2
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java35
-rw-r--r--cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-forward.sql140
-rw-r--r--cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-rollback.sql8
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsToDataNodePerfSpec.groovy89
-rw-r--r--cps-service/pom.xml2
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java48
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy4
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy75
-rwxr-xr-xdocs/release-notes.rst26
-rw-r--r--jacoco-report/pom.xml2
-rw-r--r--pom.xml2
-rw-r--r--spotbugs/pom.xml2
-rwxr-xr-xversion.properties4
37 files changed, 514 insertions, 102 deletions
diff --git a/checkstyle/pom.xml b/checkstyle/pom.xml
index 9a3896899c..dd308e295a 100644
--- a/checkstyle/pom.xml
+++ b/checkstyle/pom.xml
@@ -26,7 +26,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>checkstyle</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<profiles>
<profile>
diff --git a/cps-application/pom.xml b/cps-application/pom.xml
index 20bfb0dc4d..a4d3cbd438 100755
--- a/cps-application/pom.xml
+++ b/cps-application/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index 8b932f61d5..e3ffd04d7b 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -33,6 +33,7 @@ spring:
application:
name: "cps-application"
jpa:
+ show-sql: false
ddl-auto: create
open-in-view: false
properties:
diff --git a/cps-bom/pom.xml b/cps-bom/pom.xml
index e80e6b4872..004c31e39d 100644
--- a/cps-bom/pom.xml
+++ b/cps-bom/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-bom</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>This artifact contains dependencyManagement declarations of all published CPS components.</description>
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index a3d42ddbd6..e04ff02775 100755
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -27,7 +27,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-dependencies</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}:${project.artifactId}</name>
diff --git a/cps-events/pom.xml b/cps-events/pom.xml
index 39f8e49765..6cbb7ebe72 100644
--- a/cps-events/pom.xml
+++ b/cps-events/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-events/pom.xml b/cps-ncmp-events/pom.xml
index 4658894858..193f5d02ad 100644
--- a/cps-ncmp-events/pom.xml
+++ b/cps-ncmp-events/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest-stub/pom.xml b/cps-ncmp-rest-stub/pom.xml
index 2a4979a331..a1711b5f4d 100644
--- a/cps-ncmp-rest-stub/pom.xml
+++ b/cps-ncmp-rest-stub/pom.xml
@@ -26,7 +26,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml
index a4c44ba769..8473674be6 100644
--- a/cps-ncmp-rest/pom.xml
+++ b/cps-ncmp-rest/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index 6a9d9485c4..0f5a234be0 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
index f8836e6bf8..1674c52fc9 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java
@@ -21,6 +21,7 @@
package org.onap.cps.ncmp.api.impl;
import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
+import static org.onap.cps.spi.FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY;
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCpsPathConditionProperties;
import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateModuleNameConditionProperties;
@@ -68,14 +69,14 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
*/
@Override
public Set<NcmpServiceCmHandle> queryCmHandles(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
return getAllCmHandles();
}
final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
- cmHandleQueryServiceParameters);
+ cmHandleQueryServiceParameters);
return new HashSet<>(combineWithModuleNameQuery(cmHandleQueryServiceParameters, combinedQueryResult).values());
}
@@ -88,17 +89,17 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
*/
@Override
public Set<String> queryCmHandleIds(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
return getAllCmHandleIds();
}
final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
- cmHandleQueryServiceParameters);
+ cmHandleQueryServiceParameters);
final Collection<String> moduleNamesForQuery =
- getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+ getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
if (moduleNamesForQuery.isEmpty()) {
return combinedQueryResult.keySet();
}
@@ -113,10 +114,10 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
}
private Map<String, NcmpServiceCmHandle> combineWithModuleNameQuery(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
- final Map<String, NcmpServiceCmHandle> previousQueryResult) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
+ final Map<String, NcmpServiceCmHandle> previousQueryResult) {
final Collection<String> moduleNamesForQuery =
- getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+ getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
if (moduleNamesForQuery.isEmpty()) {
return previousQueryResult;
}
@@ -138,7 +139,7 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
}
private Map<String, NcmpServiceCmHandle> executeInventoryQueries(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
final Map<String, String> cpsPath = getCpsPath(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
if (!validateCpsPathConditionProperties(cpsPath)) {
return Collections.emptyMap();
@@ -149,13 +150,13 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
} else {
try {
cpsPathQueryResult = cmHandleQueries.queryCmHandleDataNodesByCpsPath(
- cpsPath.get("cpsPath"), INCLUDE_ALL_DESCENDANTS)
- .stream().map(this::createNcmpServiceCmHandle)
- .collect(Collectors.toMap(NcmpServiceCmHandle::getCmHandleId,
- Function.identity()));
+ cpsPath.get("cpsPath"), INCLUDE_ALL_DESCENDANTS)
+ .stream().map(this::createNcmpServiceCmHandle)
+ .collect(Collectors.toMap(NcmpServiceCmHandle::getCmHandleId,
+ Function.identity()));
} catch (final PathParsingException pathParsingException) {
throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
- pathParsingException);
+ pathParsingException);
}
if (cpsPathQueryResult.isEmpty()) {
return Collections.emptyMap();
@@ -163,9 +164,9 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
}
final Map<String, String> publicPropertyQueryPairs =
- getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
+ getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
final Map<String, NcmpServiceCmHandle> propertiesQueryResult = publicPropertyQueryPairs.isEmpty()
- ? NO_QUERY_TO_EXECUTE : cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
+ ? NO_QUERY_TO_EXECUTE : cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
return cmHandleQueries.combineCmHandleQueries(cpsPathQueryResult, propertiesQueryResult);
}
@@ -190,14 +191,14 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
private Map<String, String> getCpsPath(final List<ConditionProperties> conditionProperties) {
final Map<String, String> result = new HashMap<>();
getConditions(conditionProperties, ValidQueryProperties.WITH_CPS_PATH.getQueryProperty()).forEach(
- result::putAll);
+ result::putAll);
return result;
}
private Map<String, String> getPublicPropertyPairs(final List<ConditionProperties> conditionProperties) {
final Map<String, String> result = new HashMap<>();
getConditions(conditionProperties,
- ValidQueryProperties.HAS_ALL_PROPERTIES.getQueryProperty()).forEach(result::putAll);
+ ValidQueryProperties.HAS_ALL_PROPERTIES.getQueryProperty()).forEach(result::putAll);
return result;
}
@@ -213,17 +214,17 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm
private Set<NcmpServiceCmHandle> getAllCmHandles() {
return inventoryPersistence.getDataNode("/dmi-registry")
- .getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
+ .getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
}
private Set<String> getAllCmHandleIds() {
- return inventoryPersistence.getDataNode("/dmi-registry")
- .getChildDataNodes().stream().map(dataNode -> dataNode.getLeaves().get("id").toString())
- .collect(Collectors.toSet());
+ return inventoryPersistence.getDataNode("/dmi-registry", FETCH_DIRECT_CHILDREN_ONLY)
+ .getChildDataNodes().stream().map(dataNode -> dataNode.getLeaves().get("id").toString())
+ .collect(Collectors.toSet());
}
private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
- .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));
+ .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java
index c89388b291..5154be7990 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java
@@ -28,7 +28,6 @@ import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
import org.onap.cps.spi.model.DataNode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -39,11 +38,12 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class SynchronizationCacheConfig {
+ public static final int MODULE_SYNC_STARTED_TTL_SECS = 60;
+ public static final int DATA_SYNC_SEMAPHORE_TTL_SECS = 1800;
+
private static final QueueConfig commonQueueConfig = createQueueConfig();
- private static final MapConfig moduleSyncStartedConfig =
- createMapConfig("moduleSyncStartedConfig", TimeUnit.MINUTES.toSeconds(1));
- private static final MapConfig dataSyncSemaphoresConfig =
- createMapConfig("dataSyncSemaphoresConfig", TimeUnit.MINUTES.toSeconds(30));
+ private static final MapConfig moduleSyncStartedConfig = createMapConfig("moduleSyncStartedConfig");
+ private static final MapConfig dataSyncSemaphoresConfig = createMapConfig("dataSyncSemaphoresConfig");
/**
* Module Sync Distributed Queue Instance.
@@ -102,11 +102,10 @@ public class SynchronizationCacheConfig {
return commonQueueConfig;
}
- private static MapConfig createMapConfig(final String configName, final long timeToLiveSeconds) {
+ private static MapConfig createMapConfig(final String configName) {
final MapConfig mapConfig = new MapConfig(configName);
mapConfig.setBackupCount(3);
mapConfig.setAsyncBackupCount(3);
- mapConfig.setTimeToLiveSeconds((int) timeToLiveSeconds);
return mapConfig;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
index bfc3a9ac06..b29825e7c0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
@@ -23,6 +23,7 @@ package org.onap.cps.ncmp.api.inventory;
import java.util.Collection;
import java.util.Map;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleDefinition;
@@ -114,6 +115,15 @@ public interface InventoryPersistence {
DataNode getDataNode(String xpath);
/**
+ * Get data node via xpath.
+ *
+ * @param xpath xpath
+ * @param fetchDescendantsOption fetch descendants option
+ * @return data node
+ */
+ DataNode getDataNode(String xpath, FetchDescendantsOption fetchDescendantsOption);
+
+ /**
* Get data node of given cm handle.
*
* @param cmHandleId cmHandle ID
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java
index 99edfdb0f1..eed47eddab 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java
@@ -76,18 +76,18 @@ public class InventoryPersistenceImpl implements InventoryPersistence {
@Override
public CompositeState getCmHandleState(final String cmHandleId) {
final DataNode stateAsDataNode = cpsDataService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandleId) + "/state",
- FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
+ String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandleId) + "/state",
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
return new CompositeStateBuilder().fromDataNode(stateAsDataNode).build();
}
@Override
public void saveCmHandleState(final String cmHandleId, final CompositeState compositeState) {
final String cmHandleJsonData = String.format("{\"state\":%s}",
- jsonObjectMapper.asJsonString(compositeState));
+ jsonObjectMapper.asJsonString(compositeState));
cpsDataService.updateDataNodeAndDescendants(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandleId),
- cmHandleJsonData, OffsetDateTime.now());
+ String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandleId),
+ cmHandleJsonData, OffsetDateTime.now());
}
@Override
@@ -153,8 +153,13 @@ public class InventoryPersistenceImpl implements InventoryPersistence {
@Override
public DataNode getDataNode(final String xpath) {
+ return getDataNode(xpath, INCLUDE_ALL_DESCENDANTS);
+ }
+
+ @Override
+ public DataNode getDataNode(final String xpath, final FetchDescendantsOption fetchDescendantsOption) {
return cpsDataPersistenceService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- xpath, INCLUDE_ALL_DESCENDANTS);
+ xpath, fetchDescendantsOption);
}
@Override
@@ -164,7 +169,7 @@ public class InventoryPersistenceImpl implements InventoryPersistence {
@Override
public Collection<Anchor> queryAnchors(final Collection<String> moduleNamesForQuery) {
- return cpsAdminPersistenceService.queryAnchors(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery);
+ return cpsAdminPersistenceService.queryAnchors(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery);
}
@Override
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java
index 9336c3b218..9fa75a0d07 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java
@@ -20,12 +20,14 @@
package org.onap.cps.ncmp.api.inventory.sync;
+import com.hazelcast.map.IMap;
import java.time.OffsetDateTime;
-import java.util.Map;
+import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsDataService;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.SynchronizationCacheConfig;
import org.onap.cps.ncmp.api.inventory.CompositeState;
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState;
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
@@ -46,7 +48,7 @@ public class DataSyncWatchdog {
private final SyncUtils syncUtils;
- private final Map<String, Boolean> dataSyncSemaphores;
+ private final IMap<String, Boolean> dataSyncSemaphores;
/**
* Execute Cm Handle poll which queries the cm handle state in 'READY' and Operational Datastore Sync State in
@@ -92,6 +94,7 @@ public class DataSyncWatchdog {
}
private boolean hasPushedIntoSemaphoreMap(final String cmHandleId) {
- return dataSyncSemaphores.putIfAbsent(cmHandleId, DATA_SYNC_IN_PROGRESS) == null;
+ return dataSyncSemaphores.putIfAbsent(cmHandleId, DATA_SYNC_IN_PROGRESS,
+ SynchronizationCacheConfig.DATA_SYNC_SEMAPHORE_TTL_SECS, TimeUnit.SECONDS) == null;
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
index b96889fc58..f629b71d26 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
@@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.SynchronizationCacheConfig;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.sync.executor.AsyncTaskExecutor;
import org.onap.cps.spi.model.DataNode;
@@ -117,8 +118,9 @@ public class ModuleSyncWatchdog {
log.debug("nextBatchCandidates size : {}", nextBatchCandidates.size());
for (final DataNode batchCandidate : nextBatchCandidates) {
final String cmHandleId = String.valueOf(batchCandidate.getLeaves().get("id"));
- final boolean alreadyAddedToInProgressMap = VALUE_FOR_HAZELCAST_IN_PROGRESS_MAP
- .equals(moduleSyncStartedOnCmHandles.putIfAbsent(cmHandleId, VALUE_FOR_HAZELCAST_IN_PROGRESS_MAP));
+ final boolean alreadyAddedToInProgressMap = VALUE_FOR_HAZELCAST_IN_PROGRESS_MAP.equals(
+ moduleSyncStartedOnCmHandles.putIfAbsent(cmHandleId, VALUE_FOR_HAZELCAST_IN_PROGRESS_MAP,
+ SynchronizationCacheConfig.MODULE_SYNC_STARTED_TTL_SECS, TimeUnit.SECONDS));
if (alreadyAddedToInProgressMap) {
log.debug("module sync for {} already in progress by other instance", cmHandleId);
} else {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
index f76316f9cc..eea53e82d9 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceSpec.groovy
@@ -153,7 +153,9 @@ class NetworkCmProxyCmHandlerQueryServiceSpec extends Specification {
def 'Retrieve cm handles when the query is empty.'() {
given: 'We use an empty query'
def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
- and: 'the inventory persistence returns the dmi registry datanode'
+ and: 'the inventory persistence returns the dmi registry datanode with just ids'
+ inventoryPersistence.getDataNode("/dmi-registry", FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY) >> dmiRegistry
+ and: 'the inventory persistence returns the dmi registry datanode with data'
inventoryPersistence.getDataNode("/dmi-registry") >> dmiRegistry
when: 'the query is executed for both cm handle ids and details'
def returnedCmHandlesJustIds = objectUnderTest.queryCmHandleIds(cmHandleQueryParameters)
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy
index 4cfc02b9e7..c16d6b69b6 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy
@@ -28,6 +28,7 @@ import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
import java.util.concurrent.BlockingQueue
+import java.util.concurrent.TimeUnit
@SpringBootTest
@ContextConfiguration(classes = [SynchronizationCacheConfig])
@@ -40,7 +41,7 @@ class SynchronizationCacheConfigSpec extends Specification {
private IMap<String, Object> moduleSyncStartedOnCmHandles
@Autowired
- private Map<String, Boolean> dataSyncSemaphores
+ private IMap<String, Boolean> dataSyncSemaphores
def 'Embedded (hazelcast) Caches for Module and Data Sync.'() {
expect: 'system is able to create an instance of the Module Sync Work Queue'
@@ -54,4 +55,36 @@ class SynchronizationCacheConfigSpec extends Specification {
and: 'they have the correct names (in any order)'
assert Hazelcast.allHazelcastInstances.name.containsAll('moduleSyncWorkQueue', 'moduleSyncStartedOnCmHandles', 'dataSyncSemaphores' )
}
+
+ def 'Verify configs for Distributed objects'(){
+ given: 'the Module Sync Work Queue config'
+ def queueConfig = Hazelcast.getHazelcastInstanceByName('moduleSyncWorkQueue').config.queueConfigs.get('defaultQueueConfig')
+ and: 'the Module Sync Started Cm Handle Map config'
+ def moduleSyncStartedOnCmHandlesConfig = Hazelcast.getHazelcastInstanceByName('moduleSyncStartedOnCmHandles').config.mapConfigs.get('moduleSyncStartedConfig')
+ and: 'the Data Sync Semaphores Map config'
+ def dataSyncSemaphoresConfig = Hazelcast.getHazelcastInstanceByName('dataSyncSemaphores').config.mapConfigs.get('dataSyncSemaphoresConfig')
+ expect: 'system created instance with correct config of Module Sync Work Queue'
+ assert queueConfig.backupCount == 3
+ assert queueConfig.asyncBackupCount == 3
+ and: 'Module Sync Started Cm Handle Map has the correct settings'
+ assert moduleSyncStartedOnCmHandlesConfig.backupCount == 3
+ assert moduleSyncStartedOnCmHandlesConfig.asyncBackupCount == 3
+ and: 'Data Sync Semaphore Map has the correct settings'
+ assert dataSyncSemaphoresConfig.backupCount == 3
+ assert dataSyncSemaphoresConfig.asyncBackupCount == 3
+ }
+
+ def 'Time to Live Verify for Module Sync and Data Sync Semaphore'() {
+ when: 'the keys are inserted with a TTL'
+ moduleSyncStartedOnCmHandles.put('testKeyModuleSync', 'toBeExpired' as Object, 1000, TimeUnit.MILLISECONDS)
+ dataSyncSemaphores.put('testKeyDataSync', Boolean.TRUE, 1000, TimeUnit.MILLISECONDS)
+ then: 'the entries are present in the map'
+ assert moduleSyncStartedOnCmHandles.get('testKeyModuleSync') != null
+ assert dataSyncSemaphores.get('testKeyDataSync') != null
+ and: 'we wait for the key expiration'
+ sleep(1500)
+ and: 'the keys should be expired as TTL elapsed'
+ assert moduleSyncStartedOnCmHandles.get('testKeyModuleSync') == null
+ assert dataSyncSemaphores.get('testKeyDataSync') == null
+ }
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy
index 605381970d..707f3ea3ea 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdogSpec.groovy
@@ -20,6 +20,7 @@
package org.onap.cps.ncmp.api.inventory.sync
+import com.hazelcast.map.IMap
import org.onap.cps.api.CpsDataService
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
import org.onap.cps.ncmp.api.inventory.CmHandleState
@@ -27,8 +28,6 @@ import org.onap.cps.ncmp.api.inventory.CompositeState
import org.onap.cps.ncmp.api.inventory.InventoryPersistence
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState
import spock.lang.Specification
-import java.util.concurrent.ConcurrentHashMap
-import java.util.concurrent.ConcurrentMap
class DataSyncWatchdogSpec extends Specification {
@@ -38,11 +37,11 @@ class DataSyncWatchdogSpec extends Specification {
def mockSyncUtils = Mock(SyncUtils)
- def stubbedMap = Stub(ConcurrentMap)
+ def mockDataSyncSemaphoreMap = Mock(IMap<String,Boolean>)
def jsonString = '{"stores:bookstore":{"categories":[{"code":"01"}]}}'
- def objectUnderTest = new DataSyncWatchdog(mockInventoryPersistence, mockCpsDataService, mockSyncUtils, stubbedMap as ConcurrentHashMap)
+ def objectUnderTest = new DataSyncWatchdog(mockInventoryPersistence, mockCpsDataService, mockSyncUtils, mockDataSyncSemaphoreMap)
def compositeState = getCompositeState()
diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml
index 8739e2ce3e..a29d624aea 100755
--- a/cps-parent/pom.xml
+++ b/cps-parent/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
diff --git a/cps-path-parser/pom.xml b/cps-path-parser/pom.xml
index ffac3b02a1..dce9ace708 100644
--- a/cps-path-parser/pom.xml
+++ b/cps-path-parser/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml
index 37b3e46247..f42aaaa3b7 100755
--- a/cps-rest/pom.xml
+++ b/cps-rest/pom.xml
@@ -28,7 +28,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 5cdbf90c48..824a8d9710 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -26,7 +26,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
index c13422dc4d..ebc851a443 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
@@ -22,8 +22,6 @@
package org.onap.cps.spi.impl;
-import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
-
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import java.util.ArrayList;
@@ -102,7 +100,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
@Override
public void addMultipleLists(final String dataspaceName, final String anchorName, final String parentNodeXpath,
- final Collection<Collection<DataNode>> newLists) {
+ final Collection<Collection<DataNode>> newLists) {
final Collection<String> failedXpaths = new HashSet<>();
newLists.forEach(newList -> {
try {
@@ -119,7 +117,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private void addNewChildDataNode(final String dataspaceName, final String anchorName,
- final String parentNodeXpath, final DataNode newChild) {
+ final String parentNodeXpath, final DataNode newChild) {
final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
final FragmentEntity newChildAsFragmentEntity =
convertToFragmentWithAllDescendants(parentFragmentEntity.getDataspace(),
@@ -134,7 +132,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private void addChildrenDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath,
- final Collection<DataNode> newChildren) {
+ final Collection<DataNode> newChildren) {
final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
final List<FragmentEntity> fragmentEntities = new ArrayList<>(newChildren.size());
try {
@@ -154,7 +152,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private void retrySavingEachChildIndividually(final String dataspaceName, final String anchorName,
- final String parentNodeXpath, final Collection<DataNode> newChildren) {
+ final String parentNodeXpath,
+ final Collection<DataNode> newChildren) {
final Collection<String> failedXpaths = new HashSet<>();
for (final DataNode newChild : newChildren) {
try {
@@ -191,7 +190,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
* @return a Fragment built from current DataNode
*/
private FragmentEntity convertToFragmentWithAllDescendants(final DataspaceEntity dataspaceEntity,
- final AnchorEntity anchorEntity, final DataNode dataNodeToBeConverted) {
+ final AnchorEntity anchorEntity,
+ final DataNode dataNodeToBeConverted) {
final FragmentEntity parentFragment = toFragmentEntity(dataspaceEntity, anchorEntity, dataNodeToBeConverted);
final Builder<FragmentEntity> childFragmentsImmutableSetBuilder = ImmutableSet.builder();
for (final DataNode childDataNode : dataNodeToBeConverted.getChildDataNodes()) {
@@ -226,7 +226,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
if (isRootXpath(xpath)) {
- return fragmentRepository.findFirstRootByDataspaceAndAnchor(dataspaceEntity, anchorEntity);
+ return fragmentRepository.findFirstRootByDataspaceAndAnchor(
+ dataspaceEntity, anchorEntity);
} else {
final String normalizedXpath;
try {
@@ -235,7 +236,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
throw new CpsPathException(e.getMessage());
}
- return fragmentRepository.getByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, normalizedXpath);
+ return fragmentRepository.getByDataspaceAndAnchorAndXpath(
+ dataspaceEntity, anchorEntity, normalizedXpath);
}
}
@@ -319,10 +321,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
private List<DataNode> getChildDataNodes(final FragmentEntity fragmentEntity,
final FetchDescendantsOption fetchDescendantsOption) {
- if (fetchDescendantsOption == INCLUDE_ALL_DESCENDANTS) {
+ if (fetchDescendantsOption.hasNext()) {
return fragmentEntity.getChildFragments().stream()
- .map(childFragmentEntity -> toDataNode(childFragmentEntity, fetchDescendantsOption))
- .collect(Collectors.toUnmodifiableList());
+ .map(childFragmentEntity -> toDataNode(childFragmentEntity, fetchDescendantsOption.next()))
+ .collect(Collectors.toList());
}
return Collections.emptyList();
}
@@ -355,10 +357,11 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final List<DataNode> dataNodes) {
final Map<DataNode, FragmentEntity> dataNodeFragmentEntityMap = dataNodes.stream()
- .collect(Collectors.toMap(
- dataNode -> dataNode, dataNode -> getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath())));
+ .collect(Collectors.toMap(
+ dataNode -> dataNode,
+ dataNode -> getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath())));
dataNodeFragmentEntityMap.forEach(
- (dataNode, fragmentEntity) -> updateFragmentEntityAndDescendantsWithDataNode(fragmentEntity, dataNode));
+ (dataNode, fragmentEntity) -> updateFragmentEntityAndDescendantsWithDataNode(fragmentEntity, dataNode));
try {
fragmentRepository.saveAll(dataNodeFragmentEntityMap.values());
} catch (final StaleStateException staleStateException) {
@@ -367,7 +370,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private void retryUpdateDataNodesIndividually(final String dataspaceName, final String anchorName,
- final Collection<FragmentEntity> fragmentEntities) {
+ final Collection<FragmentEntity> fragmentEntities) {
final Collection<String> failedXpaths = new HashSet<>();
fragmentEntities.forEach(dataNodeFragment -> {
diff --git a/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-forward.sql b/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-forward.sql
index 64b185f3b2..01d441f460 100644
--- a/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-forward.sql
+++ b/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-forward.sql
@@ -1,3 +1,137 @@
-create view cmHandles as select * from fragment where xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]$';
-insert into fragment(xpath, attributes, anchor_id, parent_id, dataspace_id, schema_node_id) select concat(xpath, '/state'), to_jsonb(concat('{"cm-handle-state": "ADVISED", "last-update-time": "', to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SS.MSTZHTZM'), '"}')::json), anchor_id, id, dataspace_id, schema_node_id from cmHandles;
-drop view cmHandles; \ No newline at end of file
+INSERT INTO
+ fragment(
+ xpath,
+ attributes,
+ anchor_id,
+ parent_id,
+ dataspace_id,
+ schema_node_id
+ )
+SELECT
+ concat(cmHandles.xpath, '/state') AS xpath,
+ to_jsonb(
+ concat(
+ '{"cm-handle-state": "READY", "last-update-time": "',
+ to_char(
+ now(),
+ 'YYYY-MM-DD"T"HH24:MI:SS.MSTZHTZM'
+ ),
+ '", "data-sync-enabled": false}'
+ ) :: json
+ ) AS attributes,
+ cmHandles.anchor_id,
+ cmHandles.id,
+ cmHandles.dataspace_id,
+ cmHandles.schema_node_id
+FROM
+ (
+ SELECT
+ id,
+ xpath,
+ anchor_id,
+ dataspace_id,
+ schema_node_id
+ FROM
+ fragment
+ WHERE
+ xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]$'
+ AND xpath NOT IN (
+ SELECT
+ SUBSTRING(
+ xpath
+ FROM
+ '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]'
+ )
+ FROM
+ fragment
+ WHERE
+ xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state$'
+ )
+ ) AS cmHandles;
+INSERT INTO
+ fragment(
+ xpath,
+ attributes,
+ anchor_id,
+ parent_id,
+ dataspace_id,
+ schema_node_id
+ )
+SELECT
+ concat(cmHandlesStates.xpath, '/datastores'),
+ to_jsonb('{}' :: json),
+ cmHandlesStates.anchor_id,
+ cmHandlesStates.id,
+ cmHandlesStates.dataspace_id,
+ cmHandlesStates.schema_node_id
+FROM
+ (
+ SELECT
+ id,
+ xpath,
+ anchor_id,
+ dataspace_id,
+ schema_node_id
+ FROM
+ fragment
+ WHERE
+ xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state$'
+ AND xpath NOT IN (
+ SELECT
+ SUBSTRING(
+ xpath
+ FROM
+ '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state'
+ )
+ FROM
+ fragment
+ WHERE
+ xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores$'
+ )
+ ) AS cmHandlesStates;
+INSERT INTO
+ fragment(
+ xpath,
+ attributes,
+ anchor_id,
+ parent_id,
+ dataspace_id,
+ schema_node_id
+ )
+SELECT
+ concat(
+ cmHandlesDatastores.xpath,
+ '/operational'
+ ),
+ to_jsonb(
+ concat('{"sync-state": "NONE_REQUESTED"}') :: json
+ ),
+ cmHandlesDatastores.anchor_id,
+ cmHandlesDatastores.id,
+ cmHandlesDatastores.dataspace_id,
+ cmHandlesDatastores.schema_node_id
+FROM
+ (
+ SELECT
+ id,
+ xpath,
+ anchor_id,
+ dataspace_id,
+ schema_node_id
+ FROM
+ fragment
+ WHERE
+ xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores$'
+ AND xpath NOT IN (
+ SELECT
+ SUBSTRING(
+ xpath
+ FROM
+ '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores'
+ )
+ FROM
+ fragment
+ WHERE
+ xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores/operational$'
+ )
+ ) AS cmHandlesDatastores; \ No newline at end of file
diff --git a/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-rollback.sql b/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-rollback.sql
index aaf05a24cb..4b006ef0e2 100644
--- a/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-rollback.sql
+++ b/cps-ri/src/main/resources/changelog/db/changes/16-insert-cm-handle-state-rollback.sql
@@ -1,4 +1,4 @@
-delete from fragment where xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/lock-reason$';
-delete from fragment where xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores/operational$';
-delete from fragment where xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores$';
-delete from fragment where xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state$'; \ No newline at end of file
+DELETE FROM fragment WHERE xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/lock-reason$';
+DELETE FROM fragment WHERE xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores/operational$';
+DELETE FROM fragment WHERE xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state/datastores$';
+DELETE FROM fragment WHERE xpath ~* '^/dmi-registry/cm-handles\[@id=''[\w\-]+''\]/state$'; \ No newline at end of file
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsToDataNodePerfSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsToDataNodePerfSpec.groovy
new file mode 100644
index 0000000000..c36de9aaa1
--- /dev/null
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsToDataNodePerfSpec.groovy
@@ -0,0 +1,89 @@
+/*
+ * ============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.ri.performance
+
+import org.apache.commons.lang3.time.StopWatch
+import org.onap.cps.spi.CpsDataPersistenceService
+import org.onap.cps.spi.impl.CpsPersistenceSpecBase
+import org.onap.cps.spi.model.DataNode
+import org.onap.cps.spi.model.DataNodeBuilder
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.jdbc.Sql
+import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+
+class CpsToDataNodePerfSpec extends CpsPersistenceSpecBase {
+
+ @Autowired
+ CpsDataPersistenceService objectUnderTest
+
+ static final String SET_DATA = '/data/fragment.sql'
+ static final String XPATH_DATA_NODE_WITH_DESCENDANTS = '/parent-1'
+
+ @Sql([CLEAR_DATA, SET_DATA])
+ def 'Get data node by xpath with all descendants with many children'() {
+ given: 'nodes and grandchildren have been persisted'
+ def setupStopWatch = new StopWatch()
+ setupStopWatch.start()
+ createLineage()
+ setupStopWatch.stop()
+ def setupDurationInMillis = setupStopWatch.getTime()
+ when: 'data node is requested with all descendants'
+ def readStopWatch = new StopWatch()
+ readStopWatch.start()
+ def result = objectUnderTest.getDataNode(
+ DATASPACE_NAME, ANCHOR_NAME1, XPATH_DATA_NODE_WITH_DESCENDANTS, INCLUDE_ALL_DESCENDANTS)
+ readStopWatch.stop()
+ def readDurationInMillis = readStopWatch.getTime()
+ then : 'setup duration is under 8 seconds'
+ assert setupDurationInMillis < 8000
+ and: 'read duration is under 3.5 seconds'
+ assert readDurationInMillis < 3500
+ and: 'data node is returned with all the descendants populated'
+ assert countDataNodes(result) == 1533
+ }
+
+ def createLineage() {
+ def numOfChildren = 30
+ def numOfGrandChildren = 50
+ (1..numOfChildren).each {
+ def childName = "perf-test-child-${it}".toString()
+ def newChild = goForthAndMultiply(XPATH_DATA_NODE_WITH_DESCENDANTS, childName, numOfGrandChildren)
+ objectUnderTest.addChildDataNode(DATASPACE_NAME, ANCHOR_NAME1, XPATH_DATA_NODE_WITH_DESCENDANTS, newChild)
+ }
+ }
+
+ def goForthAndMultiply(parentXpath, childName, numOfGrandChildren) {
+ def children = []
+ (1..numOfGrandChildren).each {
+ def child = new DataNodeBuilder().withXpath("${parentXpath}/${childName}/${it}-grand-child").build()
+ children.add(child)
+ }
+ return new DataNodeBuilder().withXpath("${parentXpath}/${childName}").withChildDataNodes(children).build()
+ }
+
+ def countDataNodes(DataNode dataNode) {
+ int nodeCount = 1
+ for (DataNode child : dataNode.childDataNodes) {
+ nodeCount = nodeCount + (countDataNodes(child))
+ }
+ return nodeCount
+ }
+} \ No newline at end of file
diff --git a/cps-service/pom.xml b/cps-service/pom.xml
index 51cf32475c..f47a963154 100644
--- a/cps-service/pom.xml
+++ b/cps-service/pom.xml
@@ -28,7 +28,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java b/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java
index 0c994d8d7b..b80054ac3b 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Pantheon.tech
+ * 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.
@@ -19,7 +20,48 @@
package org.onap.cps.spi;
-public enum FetchDescendantsOption {
- OMIT_DESCENDANTS,
- INCLUDE_ALL_DESCENDANTS
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public class FetchDescendantsOption {
+
+ public static final FetchDescendantsOption FETCH_DIRECT_CHILDREN_ONLY = new FetchDescendantsOption(1);
+ public static final FetchDescendantsOption OMIT_DESCENDANTS = new FetchDescendantsOption(0);
+ public static final FetchDescendantsOption INCLUDE_ALL_DESCENDANTS = new FetchDescendantsOption(-1);
+
+ private final int depth;
+
+ /**
+ * Has next depth.
+ *
+ * @return true if next level of depth is available
+ * @throws IllegalArgumentException when depth less than -1
+ */
+ public boolean hasNext() {
+ validateDepth(depth);
+ return depth > 0 || this.depth == INCLUDE_ALL_DESCENDANTS.depth;
+ }
+
+ /**
+ * Next fetch descendants option.
+ *
+ * @return the next fetch descendants option
+ * @throws IllegalArgumentException when depth less than -1 or 0
+ */
+ public FetchDescendantsOption next() {
+ if (depth == 0) {
+ throw new IllegalArgumentException("Do not use next() method with zero depth");
+ }
+ final FetchDescendantsOption nextDescendantsOption = this.depth == INCLUDE_ALL_DESCENDANTS.depth
+ ? INCLUDE_ALL_DESCENDANTS : new FetchDescendantsOption(depth - 1);
+ validateDepth(nextDescendantsOption.depth);
+ return nextDescendantsOption;
+ }
+
+ private static void validateDepth(final int depth) {
+ if (depth < -1) {
+ throw new IllegalArgumentException("A depth of less than minus one is not allowed");
+ }
+ }
+
}
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 3f28f0ac8d..a53706a06b 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
@@ -188,7 +188,7 @@ class CpsDataServiceImplSpec extends Specification {
expect: 'service returns same data if uses same parameters'
objectUnderTest.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) == dataNode
where: 'all fetch options are supported'
- fetchDescendantsOption << FetchDescendantsOption.values()
+ fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS]
}
def 'Get data node with option invalid #scenario.'() {
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 55a252c27d..b7fec85119 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-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.
@@ -44,7 +44,7 @@ class CpsQueryServiceImplSpec extends Specification {
then: 'the persistence service is called once with the correct parameters'
1 * mockCpsDataPersistenceService.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption)
where: 'all fetch descendants options are supported'
- fetchDescendantsOption << FetchDescendantsOption.values()
+ fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS]
}
def 'Query data nodes by cps path with invalid #scenario.'() {
diff --git a/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy
new file mode 100644
index 0000000000..627383561a
--- /dev/null
+++ b/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy
@@ -0,0 +1,75 @@
+/*
+ * ============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.spi
+
+
+import spock.lang.Specification
+
+class FetchDescendantsOptionSpec extends Specification {
+ def 'Check has next descendant for fetch descendant option: #scenario'() {
+ when: 'fetch descendant option with #depth depth'
+ def fetchDescendantsOption = new FetchDescendantsOption(depth)
+ then: 'next level descendants available: #expectedHasNext'
+ fetchDescendantsOption.hasNext() == expectedHasNext
+ where: 'following parameters are used'
+ scenario | depth || expectedHasNext
+ 'omit descendants' | 0 || false
+ 'first child' | 1 || true
+ 'second child' | 2 || true
+ 'include all descendants' | -1 || true
+ }
+
+ def 'Check has next descendant for fetch descendant option: invalid depth'() {
+ given: 'fetch descendant option with -2 depth'
+ def fetchDescendantsOption = new FetchDescendantsOption(-2)
+ when: 'next level descendants not available'
+ fetchDescendantsOption.hasNext()
+ then: 'exception thrown'
+ thrown IllegalArgumentException
+ }
+
+ def 'Get next descendant for fetch descendant option: #scenario'() {
+ when: 'fetch descendant option with #depth depth'
+ def fetchDescendantsOption = new FetchDescendantsOption(depth)
+ then: 'the next level of depth is as expected'
+ fetchDescendantsOption.next().depth == depth - 1
+ where: 'following parameters are used'
+ scenario | depth
+ 'first child' | 1
+ 'second child' | 2
+ }
+
+ def 'Get next descendant for fetch descendant option: include all descendants'() {
+ when: 'fetch descendant option with -1 depth'
+ def fetchDescendantsOption = new FetchDescendantsOption(-1)
+ then: 'the next level of depth is as expected'
+ fetchDescendantsOption.next().depth == -1
+ }
+
+ def 'Get next descendant for fetch descendant option: omit descendants'() {
+ given: 'fetch descendant option with 0 depth'
+ def fetchDescendantsOption = new FetchDescendantsOption(0)
+ when: 'the next level of depth is not allowed'
+ fetchDescendantsOption.next()
+ then: 'exception thrown'
+ thrown IllegalArgumentException
+ }
+}
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 8c90a1ffc7..aec3f3b1f2 100755
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -12,11 +12,11 @@ CPS Release Notes
:depth: 2
..
-.. ====================
-.. * * * KOHN * * *
-.. ====================
+.. ======================
+.. * * * LONDON * * *
+.. ======================
-Version: 3.1.5 (not yet released)
+Version: 3.2.0 (not yet released)
=================================
Release Data
@@ -26,20 +26,34 @@ Release Data
| **CPS Project** | |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Docker images** | onap/cps-and-ncmp:3.1.5 |
+| **Docker images** | onap/cps-and-ncmp:3.2.0 |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Release designation** | 3.1.5 Kohn |
+| **Release designation** | 3.2.0 London |
| | |
+--------------------------------------+--------------------------------------------------------+
| **Release date** | (not yet released) |
| | |
+--------------------------------------+--------------------------------------------------------+
+Features
+--------
+ - `CPS-1185 <https://jira.onap.org/browse/CPS-1185>`_ Get all dataspaces
+ - `CPS-1186 <https://jira.onap.org/browse/CPS-1186>`_ Get all schema sets for a dataspace
+ - `CPS-1187 <https://jira.onap.org/browse/CPS-1187>`_ Get single dataspace
+ - `CPS-1189 <https://jira.onap.org/browse/CPS-1189>`_ Various create endpoints should return 201 response with empty body
Bug Fixes
---------
- `CPS-1312 <https://jira.onap.org/browse/CPS-1312>`_ CPS(/NCMP) does not have version control
+Known Limitations, Issues and Workarounds
+-----------------------------------------
+
+*System Limitations*
+
+For upgrading, CPS uses Liquibase for database upgrades. CPS currently only supports upgrading from Liquibase changelog 11 to Liquibase changelog 16.
+This is from commit CPS-506: List all known modules and revision to CPS-1312: Default CMHandles to READY during upgrade or from ONAP release Honolulu to London.
+
Version: 3.1.4
==============
diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml
index a78399872c..3e7af63321 100644
--- a/jacoco-report/pom.xml
+++ b/jacoco-report/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index 7ae1542991..2f7c157c1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-aggregator</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cps</name>
diff --git a/spotbugs/pom.xml b/spotbugs/pom.xml
index c04f89f3e9..306bdff392 100644
--- a/spotbugs/pom.xml
+++ b/spotbugs/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>spotbugs</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<properties>
<nexusproxy>https://nexus.onap.org</nexusproxy>
diff --git a/version.properties b/version.properties
index 00839db8e5..0a0cb6c5d7 100755
--- a/version.properties
+++ b/version.properties
@@ -21,8 +21,8 @@
# because they are used in Jenkins, whose plug-in doesn't support this
major=3
-minor=1
-patch=5
+minor=2
+patch=0
base_version=${major}.${minor}.${patch}