aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cps-application/pom.xml4
-rw-r--r--cps-application/src/main/java/org/onap/cps/Application.java2
-rw-r--r--cps-application/src/main/java/org/onap/cps/config/MicroMeterConfig.java39
-rw-r--r--cps-application/src/main/resources/application.yml2
-rw-r--r--cps-application/src/test/groovy/org/onap/cps/config/MicroMeterConfigSpec.groovy15
-rw-r--r--cps-application/src/test/java/org/onap/cps/architecture/ArchitectureTestBase.java1
-rw-r--r--cps-dependencies/pom.xml7
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java3
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java19
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java9
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java64
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponseSpec.groovy11
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilderSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy69
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy49
-rw-r--r--cps-rest/docs/openapi/cpsAdmin.yml22
-rw-r--r--cps-rest/docs/openapi/openapi.yml5
-rw-r--r--cps-rest/pom.xml4
-rwxr-xr-xcps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java16
-rwxr-xr-xcps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy65
-rwxr-xr-xcps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy4
-rw-r--r--cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy2
-rw-r--r--cps-ri/pom.xml4
-rw-r--r--cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java2
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/ri/CpsModulePersistenceServiceImpl.java29
-rw-r--r--cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java6
-rw-r--r--cps-ri/src/main/java/org/onap/cps/ri/utils/CpsValidatorImpl.java2
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/ri/CpsDataPersistenceServiceImplSpec.groovy2
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/ri/CpsModulePersistenceServiceConcurrencySpec.groovy145
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java7
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/model/DataNode.java7
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/model/DeltaReport.java7
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/CpsAnchorServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/CpsDataServiceImpl.java3
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/CpsDataspaceServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java1
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/CpsModuleServiceImpl.java7
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/CpsQueryServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/DataNodeBuilder.java (renamed from cps-service/src/main/java/org/onap/cps/api/model/DataNodeBuilder.java)3
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/DeltaReportBuilder.java (renamed from cps-service/src/main/java/org/onap/cps/api/model/DeltaReportBuilder.java)3
-rw-r--r--cps-service/src/main/java/org/onap/cps/impl/YangTextSchemaSourceSetCache.java2
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java6
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java (renamed from cps-service/src/main/java/org/onap/cps/impl/utils/CpsValidator.java)2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/CpsAnchorServiceImplSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/CpsDataServiceImplSpec.groovy3
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/CpsDataspaceServiceImplSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/CpsModuleServiceImplSpec.groovy10
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/CpsQueryServiceImplSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/DataNodeBuilderSpec.groovy (renamed from cps-service/src/test/groovy/org/onap/cps/api/model/DataNodeBuilderSpec.groovy)3
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/DeltaReportBuilderSpec.groovy (renamed from cps-service/src/test/groovy/org/onap/cps/api/model/DeltaReportBuilderSpec.groovy)2
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/impl/E2ENetworkSliceSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/impl/YangTextSchemaSourceSetCacheSpec.groovy2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy2
-rw-r--r--docker-compose/config/grafana/inventory-dashboard.json (renamed from docker-compose/config/grafana/lcm-state-dashboard.json)240
-rw-r--r--docker-compose/docker-compose.yml7
-rw-r--r--docs/admin-guide.rst51
-rw-r--r--docs/api/swagger/cps/openapi.yaml59
-rw-r--r--docs/cm-handle-lcm-events.rst12
-rw-r--r--docs/cps-events.rst6
-rw-r--r--docs/cps-ncmp-message-status-codes.rst10
-rw-r--r--docs/cps-scheduled-processes.rst20
-rw-r--r--docs/deployment.rst128
-rw-r--r--docs/modeling.rst22
-rw-r--r--docs/ncmp-data-operation.rst8
-rw-r--r--docs/overview.rst6
-rw-r--r--docs/policy-executor.rst16
-rw-r--r--docs/release-notes.rst111
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy12
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/AnchorServiceIntegrationSpec.groovy12
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/DataspaceServiceIntegrationSpec.groovy4
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy6
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpdateSpec.groovy6
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy1
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy87
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy4
-rw-r--r--k6-tests/ncmp/common/utils.js4
85 files changed, 727 insertions, 821 deletions
diff --git a/cps-application/pom.xml b/cps-application/pom.xml
index 5ac2202e85..1a46b5fa8a 100644
--- a/cps-application/pom.xml
+++ b/cps-application/pom.xml
@@ -78,6 +78,10 @@
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
+ <groupId>io.github.mweirauch</groupId>
+ <artifactId>micrometer-jvm-extras</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
diff --git a/cps-application/src/main/java/org/onap/cps/Application.java b/cps-application/src/main/java/org/onap/cps/Application.java
index 053139fcc8..62103bf368 100644
--- a/cps-application/src/main/java/org/onap/cps/Application.java
+++ b/cps-application/src/main/java/org/onap/cps/Application.java
@@ -22,9 +22,7 @@ package org.onap.cps;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.retry.annotation.EnableRetry;
-@EnableRetry
@SpringBootApplication
public class Application {
public static void main(final String[] args) {
diff --git a/cps-application/src/main/java/org/onap/cps/config/MicroMeterConfig.java b/cps-application/src/main/java/org/onap/cps/config/MicroMeterConfig.java
index de981164f5..b85f391b8e 100644
--- a/cps-application/src/main/java/org/onap/cps/config/MicroMeterConfig.java
+++ b/cps-application/src/main/java/org/onap/cps/config/MicroMeterConfig.java
@@ -21,10 +21,14 @@
package org.onap.cps.config;
import com.hazelcast.map.IMap;
+import io.github.mweirauch.micrometer.jvm.extras.ProcessMemoryMetrics;
+import io.github.mweirauch.micrometer.jvm.extras.ProcessThreadMetrics;
import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.binder.MeterBinder;
import lombok.RequiredArgsConstructor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -41,6 +45,18 @@ public class MicroMeterConfig {
return new TimedAspect(meterRegistry);
}
+ @Bean
+ @ConditionalOnProperty("cps.monitoring.micrometer-jvm-extras")
+ public MeterBinder processMemoryMetrics() {
+ return new ProcessMemoryMetrics();
+ }
+
+ @Bean
+ @ConditionalOnProperty("cps.monitoring.micrometer-jvm-extras")
+ public MeterBinder processThreadMetrics() {
+ return new ProcessThreadMetrics();
+ }
+
/**
* Register gauge metric for cm handles with state 'advised'.
*
@@ -52,7 +68,7 @@ public class MicroMeterConfig {
return Gauge.builder(CM_HANDLE_STATE_GAUGE, cmHandlesByState,
value -> cmHandlesByState.get("advisedCmHandlesCount"))
.tag(STATE_TAG, "ADVISED")
- .description("Current number of cmhandles in advised state")
+ .description("Current number of cm handles in advised state")
.register(meterRegistry);
}
@@ -67,7 +83,7 @@ public class MicroMeterConfig {
return Gauge.builder(CM_HANDLE_STATE_GAUGE, cmHandlesByState,
value -> cmHandlesByState.get("readyCmHandlesCount"))
.tag(STATE_TAG, "READY")
- .description("Current number of cmhandles in ready state")
+ .description("Current number of cm handles in ready state")
.register(meterRegistry);
}
@@ -82,7 +98,7 @@ public class MicroMeterConfig {
return Gauge.builder(CM_HANDLE_STATE_GAUGE, cmHandlesByState,
value -> cmHandlesByState.get("lockedCmHandlesCount"))
.tag(STATE_TAG, "LOCKED")
- .description("Current number of cmhandles in locked state")
+ .description("Current number of cm handles in locked state")
.register(meterRegistry);
}
@@ -97,7 +113,22 @@ public class MicroMeterConfig {
return Gauge.builder(CM_HANDLE_STATE_GAUGE, cmHandlesByState,
value -> cmHandlesByState.get("deletingCmHandlesCount"))
.tag(STATE_TAG, "DELETING")
- .description("Current number of cmhandles in deleting state")
+ .description("Current number of cm handles in deleting state")
+ .register(meterRegistry);
+ }
+
+ /**
+ * Register gauge metric for cm handles with state 'deleted'.
+ *
+ * @param meterRegistry meter registry
+ * @return cm handle state gauge
+ */
+ @Bean
+ public Gauge deletedCmHandles(final MeterRegistry meterRegistry) {
+ return Gauge.builder(CM_HANDLE_STATE_GAUGE, cmHandlesByState,
+ value -> cmHandlesByState.get("deletedCmHandlesCount"))
+ .tag(STATE_TAG, "DELETED")
+ .description("Number of cm handles that have been deleted since the application started")
.register(meterRegistry);
}
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index 0b5d59ecc9..6b9c694cf2 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -152,6 +152,8 @@ security:
password: ${CPS_PASSWORD:cpsr0cks!}
cps:
+ monitoring:
+ micrometer-jvm-extras: false
tracing:
sampler:
jaeger_remote:
diff --git a/cps-application/src/test/groovy/org/onap/cps/config/MicroMeterConfigSpec.groovy b/cps-application/src/test/groovy/org/onap/cps/config/MicroMeterConfigSpec.groovy
index da3afc6f2c..b9302ccd72 100644
--- a/cps-application/src/test/groovy/org/onap/cps/config/MicroMeterConfigSpec.groovy
+++ b/cps-application/src/test/groovy/org/onap/cps/config/MicroMeterConfigSpec.groovy
@@ -31,10 +31,17 @@ class MicroMeterConfigSpec extends Specification {
def simpleMeterRegistry = new SimpleMeterRegistry()
def 'Creating a timed aspect.'() {
- expect: ' a timed aspect can be created'
+ expect: 'a timed aspect can be created'
assert objectUnderTest.timedAspect(simpleMeterRegistry) != null
}
+ def 'Creating JVM process metrics.'() {
+ expect: 'process memory metrics can be created'
+ assert objectUnderTest.processMemoryMetrics() != null
+ and: 'process thread metrics can be created'
+ assert objectUnderTest.processThreadMetrics() != null
+ }
+
def 'Creating gauges for cm handle states.'() {
given: 'cache returns value for each state'
cmHandlesByState.get(_) >> 1
@@ -43,10 +50,10 @@ class MicroMeterConfigSpec extends Specification {
objectUnderTest.readyCmHandles(simpleMeterRegistry)
objectUnderTest.lockedCmHandles(simpleMeterRegistry)
objectUnderTest.deletingCmHandles(simpleMeterRegistry)
+ objectUnderTest.deletedCmHandles(simpleMeterRegistry)
then: 'each state has the correct value when queried'
- def states = ["ADVISED", "READY", "LOCKED", "DELETING"]
- states.each { state ->
- def gaugeValue = simpleMeterRegistry.get("cmHandlesByState").tag("state",state).gauge().value()
+ ['ADVISED', 'READY', 'LOCKED', 'DELETING', 'DELETED'].each { state ->
+ def gaugeValue = simpleMeterRegistry.get('cmHandlesByState').tag('state',state).gauge().value()
assert gaugeValue == 1
}
}
diff --git a/cps-application/src/test/java/org/onap/cps/architecture/ArchitectureTestBase.java b/cps-application/src/test/java/org/onap/cps/architecture/ArchitectureTestBase.java
index 1d39060024..c1d65758c7 100644
--- a/cps-application/src/test/java/org/onap/cps/architecture/ArchitectureTestBase.java
+++ b/cps-application/src/test/java/org/onap/cps/architecture/ArchitectureTestBase.java
@@ -36,6 +36,7 @@ public class ArchitectureTestBase {
"lombok..",
"org.apache..",
"org.mapstruct..",
+ "org.opendaylight..",
"org.slf4j..",
"org.springframework..",
"reactor.."
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index 5783ef7fcd..62fa154611 100644
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -146,7 +146,7 @@
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
- <version>5.3.7</version>
+ <version>5.5.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
@@ -173,6 +173,11 @@
<scope>import</scope>
</dependency>
<dependency>
+ <groupId>io.github.mweirauch</groupId>
+ <artifactId>micrometer-jvm-extras</artifactId>
+ <version>0.2.2</version>
+ </dependency>
+ <dependency>
<groupId>io.gsonfire</groupId>
<artifactId>gson-fire</artifactId>
<version>1.9.0</version>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java
index 75007e2e35..5a6e1ce269 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START========================================================
- * Copyright (C) 2023-2024 Nordix Foundation
+ * Copyright (C) 2023-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -130,6 +130,10 @@ public class HazelcastCacheConfig {
}
}
+ /*Note: Need to keep this for the meantime as Hazelcast community version 5.5 has marked RestApiConfig
+ for removal in future version and we have clients relying on these endpoints.
+ https://lf-onap.atlassian.net/browse/CPS-2599 created to address the issue. */
+ @SuppressWarnings("squid:S5738")
protected void exposeClusterInformation(final Config config) {
config.getNetworkConfig().getRestApiConfig().setEnabled(true)
.enableGroups(RestEndpointGroup.HEALTH_CHECK, RestEndpointGroup.CLUSTER_READ);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java
index 59d0f9704e..ae913ddfe7 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java
@@ -38,7 +38,6 @@ import org.onap.cps.api.CpsQueryService;
import org.onap.cps.api.model.DataNode;
import org.onap.cps.api.parameters.FetchDescendantsOption;
import org.onap.cps.cpspath.parser.CpsPathUtil;
-import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState;
import org.onap.cps.ncmp.api.inventory.models.CmHandleState;
import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
@@ -46,6 +45,7 @@ import org.onap.cps.ncmp.impl.inventory.models.ModelledDmiServiceLeaves;
import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelCacheConfig;
import org.onap.cps.ncmp.impl.utils.YangDataConverter;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
index e7fd247a08..75c52f3c60 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
@@ -23,7 +23,6 @@
package org.onap.cps.ncmp.impl.inventory;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_READY;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST;
@@ -347,7 +346,7 @@ public class CmHandleRegistrationService {
final Collection<String> rejectedCmHandleIds = alternateIdChecker
.getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated, AlternateIdChecker.Operation.CREATE);
cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(
- rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED));
+ rejectedCmHandleIds, CM_HANDLE_ALREADY_EXIST));
return rejectedCmHandleIds;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java
index b7a13d9989..3415793478 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2024 Nordix Foundation
+ * Copyright (C) 2022-2025 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* Modifications Copyright (C) 2024 TechMahindra Ltd.
* ================================================================================
@@ -22,8 +22,8 @@
package org.onap.cps.ncmp.impl.inventory;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST;
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID;
import static org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationServicePropertyHandler.PropertyType.DMI_PROPERTY;
import static org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationServicePropertyHandler.PropertyType.PUBLIC_PROPERTY;
@@ -49,7 +49,7 @@ import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.exceptions.DataNodeNotFoundException;
import org.onap.cps.api.exceptions.DataValidationException;
import org.onap.cps.api.model.DataNode;
-import org.onap.cps.api.model.DataNodeBuilder;
+import org.onap.cps.impl.DataNodeBuilder;
import org.onap.cps.ncmp.api.inventory.models.CmHandleRegistrationResponse;
import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
@@ -81,7 +81,7 @@ public class CmHandleRegistrationServicePropertyHandler {
final Collection<String> rejectedCmHandleIds = alternateIdChecker
.getIdsOfCmHandlesWithRejectedAlternateId(updatedNcmpServiceCmHandles, AlternateIdChecker.Operation.UPDATE);
final List<CmHandleRegistrationResponse> failureResponses =
- CmHandleRegistrationResponse.createFailureResponses(rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED);
+ CmHandleRegistrationResponse.createFailureResponses(rejectedCmHandleIds, CM_HANDLE_ALREADY_EXIST);
final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(failureResponses);
for (final NcmpServiceCmHandle updatedNcmpServiceCmHandle : updatedNcmpServiceCmHandles) {
final String cmHandleId = updatedNcmpServiceCmHandle.getCmHandleId();
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java
index e7ec9cd13c..e145c62921 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java
@@ -45,13 +45,13 @@ import org.onap.cps.api.model.DataNode;
import org.onap.cps.api.model.ModuleDefinition;
import org.onap.cps.api.model.ModuleReference;
import org.onap.cps.api.parameters.FetchDescendantsOption;
-import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException;
import org.onap.cps.ncmp.api.inventory.models.CompositeState;
import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.utils.ContentType;
+import org.onap.cps.utils.CpsValidator;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Component;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
index 1e24671f8d..2cc4375447 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
+ * Copyright (C) 2021-2025 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -61,13 +61,14 @@ public class DmiModelOperations {
* Retrieves module references.
*
* @param yangModelCmHandle the yang model cm handle
+ * @param targetModuleSetTag module set tag to send to dmi
* @return module references
*/
@Timed(value = "cps.ncmp.inventory.module.references.from.dmi",
description = "Time taken to get all module references for a cm handle from dmi")
- public List<ModuleReference> getModuleReferences(final YangModelCmHandle yangModelCmHandle) {
- final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
- .moduleSetTag(yangModelCmHandle.getModuleSetTag()).build();
+ public List<ModuleReference> getModuleReferences(final YangModelCmHandle yangModelCmHandle,
+ final String targetModuleSetTag) {
+ final DmiRequestBody dmiRequestBody = DmiRequestBody.builder().moduleSetTag(targetModuleSetTag).build();
dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
final ResponseEntity<Object> dmiFetchModulesResponseEntity = getResourceFromDmiWithJsonData(
yangModelCmHandle.resolveDmiServiceName(MODEL),
@@ -79,18 +80,20 @@ public class DmiModelOperations {
* Retrieve yang resources from dmi for any modules that CPS-NCMP hasn't cached before.
*
* @param yangModelCmHandle the yangModelCmHandle
+ * @param targetModuleSetTag module set tag to send to dmi
* @param newModuleReferences the unknown module references
* @return yang resources as map of module name to yang(re)source
*/
@Timed(value = "cps.ncmp.inventory.yang.resources.from.dmi",
description = "Time taken to get list of yang resources from dmi")
public Map<String, String> getNewYangResourcesFromDmi(final YangModelCmHandle yangModelCmHandle,
+ final String targetModuleSetTag,
final Collection<ModuleReference> newModuleReferences) {
if (newModuleReferences.isEmpty()) {
return Collections.emptyMap();
}
final String jsonWithDataAndDmiProperties = getRequestBodyToFetchYangResources(newModuleReferences,
- yangModelCmHandle.getDmiProperties(), yangModelCmHandle.getModuleSetTag());
+ yangModelCmHandle.getDmiProperties(), targetModuleSetTag);
final ResponseEntity<Object> responseEntity = getResourceFromDmiWithJsonData(
yangModelCmHandle.resolveDmiServiceName(MODEL),
jsonWithDataAndDmiProperties,
@@ -123,13 +126,13 @@ public class DmiModelOperations {
private static String getRequestBodyToFetchYangResources(final Collection<ModuleReference> newModuleReferences,
final List<YangModelCmHandle.Property> dmiProperties,
- final String moduleSetTag) {
+ final String targetModuleSetTag) {
final JsonArray moduleReferencesAsJson = getModuleReferencesAsJson(newModuleReferences);
final JsonObject data = new JsonObject();
data.add("modules", moduleReferencesAsJson);
final JsonObject jsonRequestObject = new JsonObject();
- if (!moduleSetTag.isEmpty()) {
- jsonRequestObject.addProperty("moduleSetTag", moduleSetTag);
+ if (!targetModuleSetTag.isEmpty()) {
+ jsonRequestObject.addProperty("moduleSetTag", targetModuleSetTag);
}
jsonRequestObject.add("data", data);
jsonRequestObject.add("cmHandleProperties", toJsonObject(dmiProperties));
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java
index e9f3d9b475..80e41652ee 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2024 Nordix Foundation
+ * Copyright (C) 2022-2025 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -189,7 +189,12 @@ public class ModuleOperationsUtils {
.getLockReasonCategory()));
}
- public static String getTargetModuleSetTagFromLockReason(final CompositeState.LockReason lockReason) {
+ public static String getTargetModuleSetTagForUpgrade(final YangModelCmHandle yangModelCmHandle) {
+ final CompositeState.LockReason lockReason = yangModelCmHandle.getCompositeState().getLockReason();
+ return getTargetModuleSetTagFromLockReason(lockReason);
+ }
+
+ private static String getTargetModuleSetTagFromLockReason(final CompositeState.LockReason lockReason) {
return getLockedCompositeStateDetails(lockReason).getOrDefault(MODULE_SET_TAG_KEY, "");
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
index 9534cf35b1..f929d6708c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
@@ -36,7 +36,6 @@ import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
import org.onap.cps.api.exceptions.AlreadyDefinedException;
-import org.onap.cps.api.exceptions.DuplicatedYangResourceException;
import org.onap.cps.api.model.ModuleReference;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.utils.ContentType;
@@ -67,10 +66,15 @@ public class ModuleSyncService {
*/
public void syncAndCreateSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) {
final String cmHandleId = yangModelCmHandle.getId();
- final String moduleSetTag = yangModelCmHandle.getModuleSetTag();
- final String schemaSetName = getSchemaSetName(cmHandleId, moduleSetTag);
- syncAndCreateSchemaSet(yangModelCmHandle, schemaSetName);
- cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName, cmHandleId);
+ final String targetModuleSetTag = yangModelCmHandle.getModuleSetTag();
+ final String schemaSetName = getSchemaSetNameForModuleSetTag(cmHandleId, targetModuleSetTag);
+ syncAndCreateSchemaSet(yangModelCmHandle, schemaSetName, targetModuleSetTag);
+ try {
+ cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName, cmHandleId);
+ } catch (final AlreadyDefinedException alreadyDefinedException) {
+ log.warn("Ignoring (Anchor) already exists exception for {}. Exception details: {}", cmHandleId,
+ alreadyDefinedException.getDetails());
+ }
}
/**
@@ -81,39 +85,40 @@ public class ModuleSyncService {
public void syncAndUpgradeSchemaSet(final YangModelCmHandle yangModelCmHandle) {
final String cmHandleId = yangModelCmHandle.getId();
final String sourceModuleSetTag = yangModelCmHandle.getModuleSetTag();
- final String targetModuleSetTag = ModuleOperationsUtils.getTargetModuleSetTagFromLockReason(
- yangModelCmHandle.getCompositeState().getLockReason());
+ final String targetModuleSetTag = ModuleOperationsUtils.getTargetModuleSetTagForUpgrade(yangModelCmHandle);
+ final String schemaSetName = getSchemaSetNameForModuleSetTag(cmHandleId, targetModuleSetTag);
if (sourceModuleSetTag.isEmpty() && targetModuleSetTag.isEmpty()) {
- final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle);
+ final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle, targetModuleSetTag);
cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
- cmHandleId, moduleDelta.newModuleNameToContentMap, moduleDelta.allModuleReferences);
+ schemaSetName, moduleDelta.newModuleNameToContentMap, moduleDelta.allModuleReferences);
} else {
- final String targetSchemaSetName = getSchemaSetName(cmHandleId, targetModuleSetTag);
- syncAndCreateSchemaSet(yangModelCmHandle, targetSchemaSetName);
- cpsAnchorService.updateAnchorSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
- targetSchemaSetName);
+ syncAndCreateSchemaSet(yangModelCmHandle, schemaSetName, targetModuleSetTag);
+ cpsAnchorService.updateAnchorSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, schemaSetName);
setCmHandleModuleSetTag(yangModelCmHandle, targetModuleSetTag);
log.info("Upgrading schema set for CM handle ID: {}, Source Tag: {}, Target Tag: {}",
cmHandleId, sourceModuleSetTag, targetModuleSetTag);
}
}
- private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle, final String schemaSetName) {
+ private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle,
+ final String schemaSetName,
+ final String targetModuleSetTag) {
if (isNewSchemaSet(schemaSetName)) {
- final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle);
+ final String cmHandleId = yangModelCmHandle.getId();
+ final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle, targetModuleSetTag);
try {
- log.info("Creating Schema Set {} for CM Handle {}", schemaSetName, yangModelCmHandle.getId());
+ log.info("Creating Schema Set {} for CM Handle {}", schemaSetName, cmHandleId);
cpsModuleService.createSchemaSetFromModules(
- NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
- schemaSetName,
- moduleDelta.newModuleNameToContentMap,
- moduleDelta.allModuleReferences
+ NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+ schemaSetName,
+ moduleDelta.newModuleNameToContentMap,
+ moduleDelta.allModuleReferences
);
- log.info("Successfully created Schema Set {} for CM Handle {}",
- schemaSetName, yangModelCmHandle.getId());
- } catch (final AlreadyDefinedException | DuplicatedYangResourceException exception) {
- log.warn("Schema Set {} already exists, no need to (re)create it for {}",
- schemaSetName, yangModelCmHandle.getId());
+ log.info("Successfully created Schema Set {} for CM Handle {}", schemaSetName,
+ yangModelCmHandle.getId());
+ } catch (final AlreadyDefinedException alreadyDefinedException) {
+ log.warn("Ignoring (Schema Set) already exists exception for {}. Exception details: {}", cmHandleId,
+ alreadyDefinedException.getDetails());
}
}
}
@@ -122,13 +127,14 @@ public class ModuleSyncService {
return !cpsModuleService.schemaSetExists(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName);
}
- private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle) {
+ private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle,
+ final String targetModuleSetTag) {
final Collection<ModuleReference> allModuleReferences =
- dmiModelOperations.getModuleReferences(yangModelCmHandle);
+ dmiModelOperations.getModuleReferences(yangModelCmHandle, targetModuleSetTag);
final Collection<ModuleReference> newModuleReferences =
cpsModuleService.identifyNewModuleReferences(allModuleReferences);
final Map<String, String> newYangResources = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
- newModuleReferences);
+ targetModuleSetTag, newModuleReferences);
log.debug("Module delta calculated for CM handle ID: {}. All references: {}. New modules: {}",
yangModelCmHandle.getId(), allModuleReferences, newYangResources.keySet());
return new ModuleDelta(allModuleReferences, newYangResources);
@@ -141,7 +147,7 @@ public class ModuleSyncService {
jsonForUpdate, OffsetDateTime.now(), ContentType.JSON);
}
- private static String getSchemaSetName(final String cmHandleId, final String moduleSetTag) {
+ private static String getSchemaSetNameForModuleSetTag(final String cmHandleId, final String moduleSetTag) {
return moduleSetTag.isEmpty() ? cmHandleId : moduleSetTag;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
index 40404b719a..f039cf3c02 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
@@ -114,7 +114,7 @@ public class ModuleSyncTasks {
compositeState.setLockReason(null);
return CmHandleState.READY;
} catch (final Exception e) {
- log.warn("Processing of {} failed,reason : {}.", yangModelCmHandle.getId(), e.getMessage());
+ log.warn("Processing of {} failed, reason: {}.", yangModelCmHandle.getId(), e.getMessage());
final LockReasonCategory lockReasonCategory = inUpgrade
? LockReasonCategory.MODULE_UPGRADE_FAILED
: LockReasonCategory.MODULE_SYNC_FAILED;
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponseSpec.groovy
index 055a6e7448..c49af0f01b 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponseSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CmHandleRegistrationResponseSpec.groovy
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Bell Canada
- * Modifications Copyright (C) 2023-2024 Nordix Foundation
+ * Modifications Copyright (C) 2023-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@ import spock.lang.Specification
import java.util.stream.Collectors
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED
import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST
import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR
@@ -89,14 +88,14 @@ class CmHandleRegistrationResponseSpec extends Specification {
}
def 'Failed cm-handle registration based on cm handle id and registration error'() {
- when: 'the failure response is created with "alternate id already associated" error code for 1 cm handle'
+ when: 'the failure response is created with "cm-handle already exists" error code for 1 cm handle'
def cmHandleRegistrationResponses =
- CmHandleRegistrationResponse.createFailureResponses(['ch 1'], ALTERNATE_ID_ALREADY_ASSOCIATED)
+ CmHandleRegistrationResponse.createFailureResponses(['ch 1'], CM_HANDLE_ALREADY_EXIST)
then: 'the response with expected values'
assert cmHandleRegistrationResponses[0].cmHandle == 'ch 1'
assert cmHandleRegistrationResponses[0].status == Status.FAILURE
- assert cmHandleRegistrationResponses[0].ncmpResponseStatus == ALTERNATE_ID_ALREADY_ASSOCIATED
- assert cmHandleRegistrationResponses[0].errorText == 'alternate id already associated'
+ assert cmHandleRegistrationResponses[0].ncmpResponseStatus == CM_HANDLE_ALREADY_EXIST
+ assert cmHandleRegistrationResponses[0].errorText == 'cm-handle already exists'
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilderSpec.groovy
index 4d42e62025..8b04568239 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilderSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/models/CompositeStateBuilderSpec.groovy
@@ -24,7 +24,7 @@ package org.onap.cps.ncmp.api.inventory.models
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState
import org.onap.cps.api.model.DataNode
-import org.onap.cps.api.model.DataNodeBuilder
+import org.onap.cps.impl.DataNodeBuilder
import spock.lang.Specification
import java.time.OffsetDateTime
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy
index 811e4ea526..1cbdc7beca 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy
@@ -26,7 +26,7 @@ import com.hazelcast.core.Hazelcast
import com.hazelcast.instance.impl.HazelcastInstanceFactory
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsQueryService
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState
import org.onap.cps.ncmp.api.inventory.models.TrustLevel
import org.onap.cps.ncmp.api.inventory.models.CmHandleState
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy
index b600d02be5..70bd418026 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy
@@ -32,7 +32,7 @@ import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
import org.onap.cps.api.exceptions.DataNodeNotFoundException
import org.onap.cps.api.exceptions.DataValidationException
import org.onap.cps.api.model.DataNode
-import org.onap.cps.api.model.DataNodeBuilder
+import org.onap.cps.impl.DataNodeBuilder
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.JsonObjectMapper
import org.slf4j.LoggerFactory
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy
index d8d92e99f5..0ed9dd8aae 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy
@@ -35,7 +35,7 @@ import org.onap.cps.api.model.DataNode
import org.onap.cps.api.model.ModuleDefinition
import org.onap.cps.api.model.ModuleReference
import org.onap.cps.api.parameters.FetchDescendantsOption
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException
import org.onap.cps.ncmp.api.inventory.models.CompositeState
import org.onap.cps.ncmp.api.inventory.models.CmHandleState
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy
index 714555958a..302e43f170 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
+ * Copyright (C) 2021-2025 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,14 +21,11 @@
package org.onap.cps.ncmp.impl.inventory.sync
-import com.fasterxml.jackson.core.JsonProcessingException
-import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.impl.dmi.DmiOperationsBaseSpec
import org.onap.cps.ncmp.impl.dmi.DmiProperties
import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import org.onap.cps.api.model.ModuleReference
import org.onap.cps.utils.JsonObjectMapper
-import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpStatus
@@ -40,9 +37,12 @@ import static org.onap.cps.ncmp.api.data.models.OperationType.READ
import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL
@SpringBootTest
-@ContextConfiguration(classes = [DmiProperties, DmiModelOperations])
+@ContextConfiguration(classes = [DmiProperties, DmiModelOperations, JsonObjectMapper])
class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
+ def NO_AUTH_HEADER = null
+ def NO_MODULE_SET_TAG = ''
+
def expectedModulesUrlTemplateWithVariables = new UrlTemplateParameters('myServiceName/dmi/v1/ch/{cmHandleId}/modules', ['cmHandleId': cmHandleId])
def expectedModuleResourcesUrlTemplateWithVariables = new UrlTemplateParameters('myServiceName/dmi/v1/ch/{cmHandleId}/moduleResources', ['cmHandleId': cmHandleId])
@@ -52,11 +52,6 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
@Autowired
DmiModelOperations objectUnderTest
- @SpringBean
- JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
-
- def NO_AUTH_HEADER = null
-
def 'Retrieving module references.'() {
given: 'a cm handle'
mockYangModelCmHandleRetrieval([])
@@ -65,7 +60,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
def responseFromDmi = new ResponseEntity([schemas: moduleReferencesAsLisOfMaps], HttpStatus.OK)
mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, expectedModulesUrlTemplateWithVariables, '{"cmHandleProperties":{},"moduleSetTag":""}', READ, NO_AUTH_HEADER) >> responseFromDmi
when: 'get module references is called'
- def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
+ def result = objectUnderTest.getModuleReferences(yangModelCmHandle, NO_MODULE_SET_TAG)
then: 'the result consists of expected module references'
assert result == [new ModuleReference(moduleName: 'mod1', revision: 'A'), new ModuleReference(moduleName: 'mod2', revision: 'X')]
}
@@ -78,7 +73,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
def responseFromDmi = new ResponseEntity(bodyAsMap, HttpStatus.NO_CONTENT)
mockDmiRestClient.synchronousPostOperationWithJsonData(*_) >> responseFromDmi
when: 'get module references is called'
- def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
+ def result = objectUnderTest.getModuleReferences(yangModelCmHandle, NO_MODULE_SET_TAG)
then: 'the result is empty'
assert result == []
where: 'the DMI response body has the following content'
@@ -97,7 +92,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, expectedModulesUrlTemplateWithVariables,
'{"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + ',"moduleSetTag":""}', READ, NO_AUTH_HEADER) >> responseFromDmi
when: 'a get module references is called'
- def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
+ def result = objectUnderTest.getModuleReferences(yangModelCmHandle, NO_MODULE_SET_TAG)
then: 'the result is the response from DMI service'
assert result == []
where: 'the following DMI properties are used'
@@ -116,7 +111,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, expectedModuleResourcesUrlTemplateWithVariables,
'{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":{}}', READ, NO_AUTH_HEADER) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, NO_MODULE_SET_TAG, newModuleReferences)
then: 'the result has the 2 expected yang (re)sources (order is not guaranteed)'
assert result.size() == 2
assert result.get('mod1') == 'some yang source'
@@ -131,7 +126,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
def responseFromDmi = new ResponseEntity(responseFromDmiBody, HttpStatus.NO_CONTENT)
mockDmiRestClient.synchronousPostOperationWithJsonData(*_) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, NO_MODULE_SET_TAG, newModuleReferences)
then: 'the result is empty'
assert result == [:]
where: 'the DMI response body has the following content'
@@ -149,7 +144,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
'{"data":{"modules":[{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}]},"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}',
READ, NO_AUTH_HEADER) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, NO_MODULE_SET_TAG, newModuleReferences)
then: 'the result is the response from DMI service'
assert result == [mod1:'some yang source']
where: 'the following DMI properties are used'
@@ -166,7 +161,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, expectedModuleResourcesUrlTemplateWithVariables,
'{' + expectedModuleSetTagInRequest + '"data":{"modules":[{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}]},"cmHandleProperties":{}}', READ, NO_AUTH_HEADER) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, moduleSetTag, newModuleReferences)
then: 'the result is the response from DMI service'
assert result == [mod1:'some yang source']
where: 'the following Module Set Tags are used'
@@ -180,7 +175,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
given: 'a cm handle'
mockYangModelCmHandleRetrieval([])
when: 'a get new yang resources from DMI is called with no module references'
- def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, [])
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, NO_MODULE_SET_TAG, [])
then: 'no resources are returned'
assert result == [:]
and: 'no request is sent to DMI'
@@ -191,21 +186,35 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
given: 'a cm handle'
mockYangModelCmHandleRetrieval(null)
when: 'a get new yang resources from DMI is called'
- objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, [new ModuleReference('mod1', 'A')])
+ objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, NO_MODULE_SET_TAG, [new ModuleReference('mod1', 'A')])
then: 'a null pointer is thrown (we might need to address this later)'
thrown(NullPointerException)
}
- def 'Retrieving module references with Json processing exception.'() {
- given: 'a cm handle'
- mockYangModelCmHandleRetrieval([])
- and: 'a Json processing exception occurs'
- spiedJsonObjectMapper.asJsonString(_) >> {throw (new JsonProcessingException('parsing error'))}
- when: 'a DMI operation is executed'
- objectUnderTest.getModuleReferences(yangModelCmHandle)
- then: 'an ncmp exception is thrown'
- def exceptionThrown = thrown(JsonProcessingException)
- and: 'the message indicates a parsing error'
- exceptionThrown.message.toLowerCase().contains('parsing error')
+ def 'Retrieving module references forwards the new module set tag to DMI during CM-handle upgrade.'() {
+ given: 'a cm handle with an existing module set tag'
+ mockYangModelCmHandleRetrieval([], 'OLD-TAG')
+ when: 'get module references is called'
+ objectUnderTest.getModuleReferences(yangModelCmHandle, 'NEW-TAG')
+ then: 'a request was sent to DMI with the NEW module set tag in the body'
+ 1 * mockDmiRestClient.synchronousPostOperationWithJsonData(*_) >> { args ->
+ def requestBodyAsJson = args[2] as String
+ assert requestBodyAsJson.contains('"moduleSetTag":"NEW-TAG"')
+ return new ResponseEntity([schemas: [[moduleName: 'mod1', revision: 'A'], [moduleName: 'mod2', revision: 'X']]], HttpStatus.OK)
+ }
+ }
+
+ def 'Retrieving yang resources forwards the new module set tag to DMI during CM-handle upgrade.'() {
+ given: 'a cm handle with an existing module set tag'
+ mockYangModelCmHandleRetrieval([], 'OLD-TAG')
+ when: 'get new yang resources from DMI service'
+ objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, 'NEW-TAG', newModuleReferences)
+ then: 'a request was sent to DMI with the NEW module set tag in the body'
+ 1 * mockDmiRestClient.synchronousPostOperationWithJsonData(*_) >> { args ->
+ def requestBodyAsJson = args[2] as String
+ assert requestBodyAsJson.contains('"moduleSetTag":"NEW-TAG"')
+ return new ResponseEntity([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source'],
+ [moduleName: 'mod2', revision: 'X', yangSource: 'other yang source']], HttpStatus.OK)
+ }
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy
index f8adfe5578..b4837f7bab 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy
@@ -39,6 +39,8 @@ import static org.onap.cps.ncmp.api.inventory.models.LockReasonCategory.MODULE_U
class ModuleSyncServiceSpec extends Specification {
+ def NO_MODULE_SET_TAG = ''
+
def mockCpsModuleService = Mock(CpsModuleService)
def mockDmiModelOperations = Mock(DmiModelOperations)
def mockCpsAnchorService = Mock(CpsAnchorService)
@@ -53,9 +55,9 @@ class ModuleSyncServiceSpec extends Specification {
def yangModelCmHandle = createAdvisedCmHandle(moduleSetTag)
and: 'DMI operations returns some module references'
def moduleReferences = [ new ModuleReference('module1','1'), new ModuleReference('module2','2') ]
- mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
+ mockDmiModelOperations.getModuleReferences(yangModelCmHandle, moduleSetTag) >> moduleReferences
and: 'DMI-Plugin returns resource(s) for "new" module(s)'
- mockDmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, identifiedNewModuleReferences) >> newModuleNameContentToMap
+ mockDmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, moduleSetTag, identifiedNewModuleReferences) >> newModuleNameContentToMap
and: 'the module service identifies #identifiedNewModuleReferences.size() new modules'
mockCpsModuleService.identifyNewModuleReferences(moduleReferences) >> identifiedNewModuleReferences
when: 'module sync is triggered'
@@ -90,20 +92,45 @@ class ModuleSyncServiceSpec extends Specification {
'without' | ''
}
- def 'Attempt Sync models for a cm handle with existing schema set (#exception).'() {
+ def 'Sync models for a cm handle with already defined exception upon schema set creation.'() {
given: 'a cm handle to be synced'
def yangModelCmHandle = createAdvisedCmHandle('existing tag')
and: 'dmi returns no new yang resources'
mockDmiModelOperations.getNewYangResourcesFromDmi(*_) >> [:]
and: 'already defined exception occurs when creating schema (existing)'
- mockCpsModuleService.createSchemaSetFromModules(*_) >> { throw exception }
+ mockCpsModuleService.createSchemaSetFromModules(*_) >> { throw AlreadyDefinedException.forSchemaSet('', '', null) }
when: 'module sync is triggered'
objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
- then: 'no exception is thrown up'
+ then: 'the exception is ignored'
noExceptionThrown()
- where: 'following exceptions occur'
- exception << [ AlreadyDefinedException.forSchemaSet('', '', null),
- new DuplicatedYangResourceException('', '', null) ]
+ }
+
+ def 'Sync models for a cm handle with already defined exception upon anchor set creation.'() {
+ given: 'a cm handle to be synced'
+ def yangModelCmHandle = createAdvisedCmHandle('existing tag')
+ and: 'dmi returns no new yang resources'
+ mockDmiModelOperations.getNewYangResourcesFromDmi(*_) >> [:]
+ and: 'already defined exception occurs when creating schema (existing)'
+ mockCpsAnchorService.createAnchor(*_) >> { throw AlreadyDefinedException.forAnchor('', '', null) }
+ when: 'module sync is triggered'
+ objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
+ then: 'the exception is ignored'
+ noExceptionThrown()
+ }
+
+ def 'Attempt Sync models for a cm handle with duplicate yang resources exception).'() {
+ given: 'a cm handle to be synced'
+ def yangModelCmHandle = createAdvisedCmHandle('existing tag')
+ and: 'dmi returns no new yang resources'
+ mockDmiModelOperations.getNewYangResourcesFromDmi(*_) >> [:]
+ and: 'duplicate yang resource exception occurs when creating schema'
+ def originalException = new DuplicatedYangResourceException('', '', null)
+ mockCpsModuleService.createSchemaSetFromModules(*_) >> { throw originalException }
+ when: 'module sync is triggered'
+ objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
+ then: 'same exception is thrown up'
+ def thrownException = thrown(Exception)
+ assert thrownException == originalException
}
def 'Model upgrade without using Module Set Tags (legacy) where the modules are in database.'() {
@@ -115,8 +142,8 @@ class ModuleSyncServiceSpec extends Specification {
def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '', '', ncmpServiceCmHandle,'', '', '')
and: 'DMI operations returns some module references for upgraded cm handle'
def moduleReferences = [ new ModuleReference('module1','1') ]
- mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
- mockDmiModelOperations.getNewYangResourcesFromDmi(_, []) >> [:]
+ mockDmiModelOperations.getModuleReferences(yangModelCmHandle, NO_MODULE_SET_TAG) >> moduleReferences
+ mockDmiModelOperations.getNewYangResourcesFromDmi(_, NO_MODULE_SET_TAG, []) >> [:]
and: 'none of these module references are new (all already known to the system)'
mockCpsModuleService.identifyNewModuleReferences(_) >> []
when: 'module sync is triggered'
@@ -138,7 +165,7 @@ class ModuleSyncServiceSpec extends Specification {
mockCpsModuleService.schemaSetExists(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, tagTo) >> schemaExists
and: 'DMI operations returns some module references for upgraded cm handle'
def moduleReferences = [ new ModuleReference('module1','1') ]
- expectedCallsToDmi * mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
+ expectedCallsToDmi * mockDmiModelOperations.getModuleReferences(yangModelCmHandle, tagTo) >> moduleReferences
and: 'dmi returns no new yang resources'
mockDmiModelOperations.getNewYangResourcesFromDmi(*_) >> [:]
and: 'none of these module references are new (all already known to the system)'
diff --git a/cps-rest/docs/openapi/cpsAdmin.yml b/cps-rest/docs/openapi/cpsAdmin.yml
index f394270dd5..6cfffa48f3 100644
--- a/cps-rest/docs/openapi/cpsAdmin.yml
+++ b/cps-rest/docs/openapi/cpsAdmin.yml
@@ -1,6 +1,6 @@
# ============LICENSE_START=======================================================
# Copyright (c) 2021 Bell Canada.
-# Modifications Copyright (C) 2021-2022 Nordix Foundation
+# Modifications Copyright (C) 2021-2025 Nordix Foundation
# Modifications Copyright (C) 2022 TechMahindra Ltd.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -230,3 +230,23 @@ adminDataspace:
$ref: 'components.yml#/components/responses/Forbidden'
'500':
$ref: 'components.yml#/components/responses/InternalServerError'
+
+adminCleanDataspace:
+ post:
+ description: Clean the dataspace (remove orphaned schema sets and modules)
+ tags:
+ - cps-admin
+ summary: Clean the dataspace
+ operationId: cleanDataspace
+ parameters:
+ - $ref: 'components.yml#/components/parameters/apiVersionInPath'
+ - $ref: 'components.yml#/components/parameters/dataspaceNameInPath'
+ responses:
+ '204':
+ $ref: 'components.yml#/components/responses/NoContent'
+ '400':
+ $ref: 'components.yml#/components/responses/BadRequest'
+ '403':
+ $ref: 'components.yml#/components/responses/Forbidden'
+ '500':
+ $ref: 'components.yml#/components/responses/InternalServerError'
diff --git a/cps-rest/docs/openapi/openapi.yml b/cps-rest/docs/openapi/openapi.yml
index f4eab61875..c85bf7cac7 100644
--- a/cps-rest/docs/openapi/openapi.yml
+++ b/cps-rest/docs/openapi/openapi.yml
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (C) 2021-2024 Nordix Foundation
+# Copyright (C) 2021-2025 Nordix Foundation
# Modifications Copyright (C) 2021 Pantheon.tech
# Modifications Copyright (C) 2021 Bell Canada.
# Modifications Copyright (C) 2022-2024 TechMahindra Ltd.
@@ -61,6 +61,9 @@ paths:
/{apiVersion}/admin/dataspaces/{dataspace-name}:
$ref: 'cpsAdmin.yml#/adminDataspace'
+ /{apiVersion}/admin/dataspaces/{dataspace-name}/actions/clean:
+ $ref: 'cpsAdmin.yml#/adminCleanDataspace'
+
/v1/dataspaces/{dataspace-name}/anchors:
$ref: 'cpsAdminV1Deprecated.yml#/anchorsByDataspace'
diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml
index b04daf03bd..f72cef9f28 100644
--- a/cps-rest/pom.xml
+++ b/cps-rest/pom.xml
@@ -62,10 +62,6 @@
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
- <groupId>org.springframework.retry</groupId>
- <artifactId>spring-retry</artifactId>
- </dependency>
- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
index 675c0eaec4..4c6bd6cdc5 100755
--- a/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2020-2025 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2022 TechMahindra Ltd.
@@ -176,6 +176,20 @@ public class AdminRestController implements CpsAdminApi {
}
/**
+ * Clean the given dataspace of any orphaned (module) data.
+ *
+ * @param apiVersion api version
+ * @param dataspaceName dataspace name
+ *
+ * @return a {@Link ResponseEntity} of {@link HttpStatus} NO_CONTENT
+ */
+ @Override
+ public ResponseEntity<Void> cleanDataspace(final String apiVersion, final String dataspaceName) {
+ cpsModuleService.deleteAllUnusedYangModuleData(dataspaceName);
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ /**
* Create a new anchor.
*
* @param dataspaceName dataspace name
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
index 2335a5e770..0d189783fd 100755
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2020-2021 Pantheon.tech
* Modifications Copyright (C) 2020-2021 Bell Canada.
- * Modifications Copyright (C) 2021-2022 Nordix Foundation
+ * Modifications Copyright (C) 2021-2025 Nordix Foundation
* Modifications Copyright (C) 2022 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,15 +23,8 @@
package org.onap.cps.rest.controller
-import org.onap.cps.api.CpsAnchorService
-
-import static org.onap.cps.api.parameters.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
-
import org.mapstruct.factory.Mappers
+import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDataspaceService
import org.onap.cps.api.CpsModuleService
import org.onap.cps.api.exceptions.AlreadyDefinedException
@@ -51,6 +44,12 @@ import org.springframework.util.LinkedMultiValueMap
import org.springframework.util.MultiValueMap
import spock.lang.Specification
+import static org.onap.cps.api.parameters.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
+
@WebMvcTest(AdminRestController)
class AdminRestControllerSpec extends Specification {
@@ -79,7 +78,7 @@ class AdminRestControllerSpec extends Specification {
def dataspace = new Dataspace(name: dataspaceName)
def 'Create new dataspace with #scenario.'() {
- when: 'post is invoked'
+ when: 'post is invoked on endpoint for creating a dataspace'
def response =
mvc.perform(
post("/cps/api/${apiVersion}/dataspaces")
@@ -97,7 +96,7 @@ class AdminRestControllerSpec extends Specification {
}
def 'Create dataspace over existing with same name.'() {
- given: 'an endpoint'
+ given: 'the endpoint to create a dataspace'
def createDataspaceEndpoint = "$basePath/v1/dataspaces"
and: 'the service method throws an exception indicating the dataspace is already defined'
def thrownException = new AlreadyDefinedException(dataspaceName, new RuntimeException())
@@ -115,7 +114,7 @@ class AdminRestControllerSpec extends Specification {
def 'Get a dataspace.'() {
given: 'service method returns a dataspace'
mockCpsDataspaceService.getDataspace(dataspaceName) >> dataspace
- and: 'an endpoint'
+ and: 'the endpoint for getting a dataspace by name'
def getDataspaceEndpoint = "$basePath/v1/admin/dataspaces/$dataspaceName"
when: 'get dataspace API is invoked'
def response = mvc.perform(get(getDataspaceEndpoint)).andReturn().response
@@ -124,6 +123,17 @@ class AdminRestControllerSpec extends Specification {
response.getContentAsString().contains(dataspaceName)
}
+ def 'Clean a dataspace.'() {
+ given: 'service method returns a dataspace'
+ mockCpsDataspaceService.getDataspace(dataspaceName) >> dataspace
+ and: 'the endpoint for cleaning a dataspace'
+ def postCleanDataspaceEndpoint = "$basePath/v1/admin/dataspaces/$dataspaceName/actions/clean"
+ when: 'post is invoked on the clean dataspace endpoint'
+ def response = mvc.perform(post(postCleanDataspaceEndpoint)).andReturn().response
+ then: 'no content is returned'
+ response.status == HttpStatus.NO_CONTENT.value()
+ }
+
def 'Get all dataspaces.'() {
given: 'service method returns all dataspace'
mockCpsDataspaceService.getAllDataspaces() >> [dataspace, new Dataspace(name: "dataspace-test2")]
@@ -173,8 +183,7 @@ class AdminRestControllerSpec extends Specification {
.param('schema-set-name', schemaSetName))
.andReturn().response
then: 'associated service method is invoked with expected parameters'
- 1 * mockCpsModuleService.createSchemaSet(dataspaceName, schemaSetName, _) >>
- { args -> yangResourceMapCapture = args[2] }
+ 1 * mockCpsModuleService.createSchemaSet(dataspaceName, schemaSetName, _) >> { args -> yangResourceMapCapture = args[2] }
yangResourceMapCapture['assembly.yang'] == "fake assembly content 1\n"
yangResourceMapCapture['component.yang'] == "fake component content 1\n"
and: 'response code indicates success'
@@ -208,7 +217,7 @@ class AdminRestControllerSpec extends Specification {
}
def 'Create schema set from zip archive having #caseDescriptor.'() {
- given: 'an endpoint'
+ given: 'the endpoint to create a schema set'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets"
when: 'zip archive having #caseDescriptor is uploaded with create schema set request'
def response =
@@ -228,7 +237,7 @@ class AdminRestControllerSpec extends Specification {
def 'Create schema set from file with unsupported filename extension.'() {
given: 'file with unsupported filename extension (.doc)'
def multipartFile = createMultipartFile("filename.doc", "content")
- and: 'an endpoint'
+ and: 'the endpoint to create a schema set'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets"
when: 'file uploaded with schema set create request'
def response =
@@ -242,7 +251,7 @@ class AdminRestControllerSpec extends Specification {
}
def 'Create schema set from #fileType file with IOException occurrence on processing.'() {
- given: 'an endpoint'
+ given: 'the endpoint to create a schema set'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets"
when: 'file uploaded with schema set create request'
def multipartFile = createMultipartFileForIOException(fileType)
@@ -259,7 +268,7 @@ class AdminRestControllerSpec extends Specification {
}
def 'Delete schema set.'() {
- given: 'an endpoint'
+ given: 'the endpoint for deleting a schema set'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets/$schemaSetName"
when: 'delete schema set endpoint is invoked'
def response = mvc.perform(delete(schemaSetEndpoint)).andReturn().response
@@ -274,7 +283,7 @@ class AdminRestControllerSpec extends Specification {
def thrownException = new SchemaSetInUseException(dataspaceName, schemaSetName)
mockCpsModuleService.deleteSchemaSet(dataspaceName, schemaSetName, CASCADE_DELETE_PROHIBITED) >>
{ throw thrownException }
- and: 'an endpoint'
+ and: 'the endpoint for deleting a schema set'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets/$schemaSetName"
when: 'delete schema set endpoint is invoked'
def response = mvc.perform(delete(schemaSetEndpoint)).andReturn().response
@@ -286,7 +295,7 @@ class AdminRestControllerSpec extends Specification {
given: 'service method returns a new schema set'
mockCpsModuleService.getSchemaSet(dataspaceName, schemaSetName) >>
new SchemaSet(name: schemaSetName, dataspaceName: dataspaceName)
- and: 'an endpoint'
+ and: 'the endpoint for getting a schema set'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets/$schemaSetName"
when: 'get schema set API is invoked'
def response = mvc.perform(get(schemaSetEndpoint)).andReturn().response
@@ -300,7 +309,7 @@ class AdminRestControllerSpec extends Specification {
mockCpsModuleService.getSchemaSets(dataspaceName) >>
[new SchemaSet(name: schemaSetName, dataspaceName: dataspaceName),
new SchemaSet(name: "test-schemaset", dataspaceName: dataspaceName)]
- and: 'an endpoint'
+ and: 'the endpoint for getting all schema sets'
def schemaSetEndpoint = "$basePath/v1/dataspaces/$dataspaceName/schema-sets"
when: 'get schema sets API is invoked'
def response = mvc.perform(get(schemaSetEndpoint)).andReturn().response
@@ -315,7 +324,7 @@ class AdminRestControllerSpec extends Specification {
def requestParams = new LinkedMultiValueMap<>()
requestParams.add('schema-set-name', schemaSetName)
requestParams.add('anchor-name', anchorName)
- when: 'post is invoked'
+ when: 'post is invoked on the create anchors endpoint'
def response =
mvc.perform(
post("/cps/api/${apiVersion}/dataspaces/my_dataspace/anchors")
@@ -332,10 +341,10 @@ class AdminRestControllerSpec extends Specification {
'V2 API' | 'v2' || ''
}
- def 'Get existing anchor.'() {
- given: 'service method returns a list of anchors'
+ def 'Get existing anchors.'() {
+ given: 'service method returns a list of (one) anchors'
mockCpsAnchorService.getAnchors(dataspaceName) >> [anchor]
- and: 'an endpoint'
+ and: 'the endpoint for getting all anchors'
def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors"
when: 'get all anchors API is invoked'
def response = mvc.perform(get(anchorEndpoint)).andReturn().response
@@ -348,7 +357,7 @@ class AdminRestControllerSpec extends Specification {
given: 'service method returns an anchor'
mockCpsAnchorService.getAnchor(dataspaceName, anchorName) >>
new Anchor(name: anchorName, dataspaceName: dataspaceName, schemaSetName: schemaSetName)
- and: 'an endpoint'
+ and: 'the endpoint for getting an anchor'
def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors/$anchorName"
when: 'get anchor API is invoked'
def response = mvc.perform(get(anchorEndpoint)).andReturn().response
@@ -361,7 +370,7 @@ class AdminRestControllerSpec extends Specification {
}
def 'Delete anchor.'() {
- given: 'an endpoint'
+ given: 'the endpoint for deleting an anchor'
def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors/$anchorName"
when: 'delete method is invoked on anchor endpoint'
def response = mvc.perform(delete(anchorEndpoint)).andReturn().response
@@ -372,7 +381,7 @@ class AdminRestControllerSpec extends Specification {
}
def 'Delete dataspace.'() {
- given: 'an endpoint'
+ given: 'the endpoint for deleting a dataspace'
def dataspaceEndpoint = "$basePath/v1/dataspaces"
when: 'delete dataspace endpoint is invoked'
def response = mvc.perform(delete(dataspaceEndpoint)
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
index ca89fafe83..f2f962422f 100755
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
@@ -30,8 +30,8 @@ import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.parameters.FetchDescendantsOption
import org.onap.cps.api.model.DataNode
-import org.onap.cps.api.model.DataNodeBuilder
-import org.onap.cps.api.model.DeltaReportBuilder
+import org.onap.cps.impl.DataNodeBuilder
+import org.onap.cps.impl.DeltaReportBuilder
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.DateTimeUtility
import org.onap.cps.utils.JsonObjectMapper
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy
index f29654c99f..2b5c471287 100644
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy
@@ -27,7 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsQueryService
import org.onap.cps.api.parameters.PaginationOption
-import org.onap.cps.api.model.DataNodeBuilder
+import org.onap.cps.impl.DataNodeBuilder
import org.onap.cps.utils.JsonObjectMapper
import org.onap.cps.utils.PrefixResolver
import org.spockframework.spring.SpringBean
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 2492cb837e..f065421ec9 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -56,10 +56,6 @@
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
- <groupId>org.springframework.retry</groupId>
- <artifactId>spring-retry</artifactId>
- </dependency>
- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
diff --git a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
index c43c8e2999..52fd7f2be1 100644
--- a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
@@ -50,12 +50,12 @@ import org.onap.cps.api.exceptions.CpsPathException;
import org.onap.cps.api.exceptions.DataNodeNotFoundException;
import org.onap.cps.api.exceptions.DataNodeNotFoundExceptionBatch;
import org.onap.cps.api.model.DataNode;
-import org.onap.cps.api.model.DataNodeBuilder;
import org.onap.cps.api.parameters.FetchDescendantsOption;
import org.onap.cps.api.parameters.PaginationOption;
import org.onap.cps.cpspath.parser.CpsPathQuery;
import org.onap.cps.cpspath.parser.CpsPathUtil;
import org.onap.cps.cpspath.parser.PathParsingException;
+import org.onap.cps.impl.DataNodeBuilder;
import org.onap.cps.ri.models.AnchorEntity;
import org.onap.cps.ri.models.DataspaceEntity;
import org.onap.cps.ri.models.FragmentEntity;
diff --git a/cps-ri/src/main/java/org/onap/cps/ri/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/CpsModulePersistenceServiceImpl.java
index cf9fb021a6..aaf6165471 100755
--- a/cps-ri/src/main/java/org/onap/cps/ri/CpsModulePersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/ri/CpsModulePersistenceServiceImpl.java
@@ -70,10 +70,6 @@ import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.annotation.Backoff;
-import org.springframework.retry.annotation.Retryable;
-import org.springframework.retry.support.RetrySynchronizationManager;
import org.springframework.stereotype.Component;
@Slf4j
@@ -154,10 +150,6 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Override
@Transactional
- // A retry is made to store the schema set if it fails because of duplicated yang resource exception that
- // can occur in case of specific concurrent requests.
- @Retryable(retryFor = DuplicatedYangResourceException.class, maxAttempts = 5, backoff =
- @Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2))
public void storeSchemaSet(final String dataspaceName, final String schemaSetName,
final Map<String, String> moduleReferenceNameToContentMap) {
final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
@@ -189,12 +181,8 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Override
@Transactional
- // A retry is made to store the schema set if it fails because of duplicated yang resource exception that
- // can occur in case of specific concurrent requests.
- @Retryable(retryFor = DuplicatedYangResourceException.class, maxAttempts = 5, backoff =
- @Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2))
@Timed(value = "cps.module.persistence.schemaset.store",
- description = "Time taken to store a schemaset (list of module references")
+ description = "Time taken to store a schemaset (list of module references)")
public void storeSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
final Map<String, String> newModuleNameToContentMap,
final Collection<ModuleReference> allModuleReferences) {
@@ -237,8 +225,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Override
@Transactional
- public void deleteAllUnusedYangModuleData() {
- schemaSetRepository.deleteOrphanedSchemaSets();
+ public void deleteAllUnusedYangModuleData(final String dataspaceName) {
+ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+ schemaSetRepository.deleteOrphanedSchemaSets(dataspaceEntity.getId());
yangResourceRepository.deleteOrphanedYangResources();
}
@@ -278,18 +267,10 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
yangResourceRepository.saveAll(newYangResourceEntities);
} catch (final DataIntegrityViolationException dataIntegrityViolationException) {
// Throw a CPS duplicated Yang resource exception if the cause of the error is a yang checksum
- // database constraint violation.
- // If it is not, then throw the original exception
+ // database constraint violation. If it is not, then throw the original exception
final Optional<DuplicatedYangResourceException> convertedException =
convertToDuplicatedYangResourceException(
dataIntegrityViolationException, newYangResourceEntities);
- convertedException.ifPresent(
- e -> {
- final RetryContext retryContext = RetrySynchronizationManager.getContext();
- int retryCount = retryContext == null ? 0 : retryContext.getRetryCount();
- log.warn("Cannot persist duplicated yang resource. System will attempt this method "
- + "up to 5 times. Current retry count : {}", ++retryCount, e);
- });
throw convertedException.isPresent() ? convertedException.get() : dataIntegrityViolationException;
}
}
diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java
index b8dd7b755c..fdd72624ba 100644
--- a/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java
@@ -83,8 +83,8 @@ public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Inte
*/
@Modifying
@Query(value = """
- DELETE FROM schema_set WHERE NOT EXISTS
- (SELECT 1 FROM anchor WHERE anchor.schema_set_id = schema_set.id)
+ DELETE FROM schema_set WHERE schema_set.dataspace_id = :dataspaceId AND
+ NOT EXISTS (SELECT 1 FROM anchor WHERE anchor.schema_set_id = schema_set.id)
""", nativeQuery = true)
- void deleteOrphanedSchemaSets();
+ void deleteOrphanedSchemaSets(@Param("dataspaceId") final int dataspaceId);
}
diff --git a/cps-ri/src/main/java/org/onap/cps/ri/utils/CpsValidatorImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/utils/CpsValidatorImpl.java
index fa9feee1e7..9e89c8aed9 100644
--- a/cps-ri/src/main/java/org/onap/cps/ri/utils/CpsValidatorImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/ri/utils/CpsValidatorImpl.java
@@ -27,7 +27,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.exceptions.DataValidationException;
import org.onap.cps.api.parameters.PaginationOption;
-import org.onap.cps.impl.utils.CpsValidator;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.stereotype.Component;
@Slf4j
diff --git a/cps-ri/src/test/groovy/org/onap/cps/ri/CpsDataPersistenceServiceImplSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/ri/CpsDataPersistenceServiceImplSpec.groovy
index c818f3ba1f..e927922acf 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/ri/CpsDataPersistenceServiceImplSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/ri/CpsDataPersistenceServiceImplSpec.groovy
@@ -33,7 +33,7 @@ import org.onap.cps.api.parameters.FetchDescendantsOption
import org.onap.cps.api.exceptions.ConcurrencyException
import org.onap.cps.api.exceptions.DataValidationException
import org.onap.cps.api.model.DataNode
-import org.onap.cps.api.model.DataNodeBuilder
+import org.onap.cps.impl.DataNodeBuilder
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.dao.DataIntegrityViolationException
import spock.lang.Specification
diff --git a/cps-ri/src/test/groovy/org/onap/cps/ri/CpsModulePersistenceServiceConcurrencySpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/ri/CpsModulePersistenceServiceConcurrencySpec.groovy
deleted file mode 100644
index 28a615b0e8..0000000000
--- a/cps-ri/src/test/groovy/org/onap/cps/ri/CpsModulePersistenceServiceConcurrencySpec.groovy
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2022 Bell Canada.
- * Modifications Copyright (C) 2021-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.ri
-
-import org.hibernate.exception.ConstraintViolationException
-import org.onap.cps.ri.models.DataspaceEntity
-import org.onap.cps.ri.models.SchemaSetEntity
-import org.onap.cps.ri.repository.DataspaceRepository
-import org.onap.cps.ri.repository.ModuleReferenceRepository
-import org.onap.cps.ri.repository.SchemaSetRepository
-import org.onap.cps.ri.repository.YangResourceRepository
-import org.onap.cps.spi.CpsAdminPersistenceService
-import org.onap.cps.spi.CpsModulePersistenceService
-import org.onap.cps.api.exceptions.DuplicatedYangResourceException
-import org.onap.cps.api.model.ModuleReference
-import org.spockframework.spring.SpringBean
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.dao.DataIntegrityViolationException
-import org.springframework.retry.annotation.EnableRetry
-import spock.lang.Specification
-
-import java.sql.SQLException
-
-@SpringBootTest(classes=[CpsModulePersistenceServiceImpl])
-@EnableRetry
-class CpsModulePersistenceServiceConcurrencySpec extends Specification {
-
- @Autowired
- CpsModulePersistenceService objectUnderTest
-
- @SpringBean
- DataspaceRepository dataspaceRepository = Mock()
-
- @SpringBean
- YangResourceRepository yangResourceRepository = Mock()
-
- @SpringBean
- SchemaSetRepository schemaSetRepository = Mock()
-
- @SpringBean
- CpsAdminPersistenceService cpsAdminPersistenceService = Mock()
-
- @SpringBean
- ModuleReferenceRepository moduleReferenceRepository = Mock()
-
- def NEW_RESOURCE_NAME = 'some new resource'
- def NEW_RESOURCE_CONTENT = 'module stores {\n' +
- ' yang-version 1.1;\n' +
- ' namespace "org:onap:ccsdk:sample";\n' +
- '}'
-
- def newYangResourcesNameToContentMap = [(NEW_RESOURCE_NAME):NEW_RESOURCE_CONTENT]
-
- def yangResourceChecksum = 'b13faef573ed1374139d02c40d8ce09c80ea1dc70e63e464c1ed61568d48d539'
-
- def yangResourceChecksumDbConstraint = 'yang_resource_checksum_key'
-
- def sqlExceptionMessage = String.format('(checksum)=(%s)', yangResourceChecksum)
-
- def checksumIntegrityException = new DataIntegrityViolationException("checksum integrity exception",
- new ConstraintViolationException('', new SQLException(sqlExceptionMessage), yangResourceChecksumDbConstraint))
-
- def 'Store new schema set, maximum retries.'() {
- given: 'no pre-existing schemaset in database'
- dataspaceRepository.getByName(_) >> new DataspaceEntity()
- yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
- when: 'a new schemaset is stored'
- objectUnderTest.storeSchemaSet('some dataspace', 'some new schema set', newYangResourcesNameToContentMap)
- then: 'a duplicated yang resource exception is thrown '
- thrown(DuplicatedYangResourceException)
- and: 'the system will attempt to save the data 5 times (because checksum integrity exception is thrown each time)'
- 5 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
- }
-
- def 'Store new schema set, succeed on third attempt.'() {
- given: 'no pre-existing schemaset in database'
- dataspaceRepository.getByName(_) >> new DataspaceEntity()
- yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
- when: 'a new schemaset is stored'
- objectUnderTest.storeSchemaSet('some dataspace', 'some new schema set', newYangResourcesNameToContentMap)
- then: 'no exception is thrown '
- noExceptionThrown()
- and: 'the system will attempt to save the data 2 times with checksum integrity exception but then succeed'
- 2 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
- 1 * yangResourceRepository.saveAll(_) >> []
- }
-
- def 'Store schema set using modules, maximum retries.'() {
- given: 'map of new modules, a list of existing modules, module reference'
- def mapOfNewModules = [newModule1: 'module newmodule { yang-version 1.1; revision "2021-10-12" { } }']
- def moduleReferenceForExistingModule = new ModuleReference("test","2021-10-12")
- def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule]
- and: 'no pre-existing schemaset in database'
- dataspaceRepository.getByName(_) >> new DataspaceEntity()
- yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
- when: 'a new schemaset is stored from a module'
- objectUnderTest.storeSchemaSetFromModules('some dataspace', 'some new schema set' , mapOfNewModules, listOfExistingModulesModuleReference)
- then: 'a duplicated yang resource exception is thrown '
- thrown(DuplicatedYangResourceException)
- and: 'the system will attempt to save the data 5 times (because checksum integrity exception is thrown each time)'
- 5 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
- }
-
- def 'Store schema set using modules, succeed on third attempt.'() {
- given: 'map of new modules, a list of existing modules, module reference'
- def mapOfNewModules = [newModule1: 'module newmodule { yang-version 1.1; revision "2021-10-12" { } }']
- def moduleReferenceForExistingModule = new ModuleReference("test","2021-10-12")
- def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule]
- and: 'no pre-existing schemaset in database'
- def dataspaceEntity = new DataspaceEntity()
- dataspaceRepository.getByName(_) >> new DataspaceEntity()
- yangResourceRepository.findAllByChecksumIn(_) >> Collections.emptyList()
- yangResourceRepository.getResourceIdsByModuleReferences(_) >> []
- and: 'can retrieve schemaset details after storing it'
- def schemaSetEntity = new SchemaSetEntity()
- schemaSetRepository.getByDataspaceAndName(dataspaceEntity, 'new schema set') >> schemaSetEntity
- when: 'a new schemaset is stored from a module'
- objectUnderTest.storeSchemaSetFromModules('some dataspace', 'new schema set' , mapOfNewModules, listOfExistingModulesModuleReference)
- then: 'no exception is thrown '
- noExceptionThrown()
- and: 'the system will attempt to save the data 2 times with checksum integrity exception but then succeed'
- 2 * yangResourceRepository.saveAll(_) >> { throw checksumIntegrityException }
- 1 * yangResourceRepository.saveAll(_) >> []
- }
-
-}
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 81b6439efc..c6b8c60ab9 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
@@ -164,8 +164,11 @@ public interface CpsModuleService {
Collection<ModuleReference> identifyNewModuleReferences(Collection<ModuleReference> moduleReferencesToCheck);
/**
- * Remove any Yang Resource Modules and Schema Sets from the DB that are no longer referenced by any anchor.
+ * Remove any Yang Resource Modules and Schema Sets from the given dataspace that are no longer referenced
+ * by any anchor.
+ *
+ * @param dataspaceName dataspace name
*/
- void deleteAllUnusedYangModuleData();
+ void deleteAllUnusedYangModuleData(String dataspaceName);
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/model/DataNode.java b/cps-service/src/main/java/org/onap/cps/api/model/DataNode.java
index be80b636ad..6597aa3908 100644
--- a/cps-service/src/main/java/org/onap/cps/api/model/DataNode.java
+++ b/cps-service/src/main/java/org/onap/cps/api/model/DataNode.java
@@ -26,20 +26,19 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
-import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
-@Setter(AccessLevel.PROTECTED)
+@Setter
@Getter
@EqualsAndHashCode
+@NoArgsConstructor
public class DataNode implements Serializable {
private static final long serialVersionUID = 1482619410918597467L;
- DataNode() {}
-
private String dataspace;
private String schemaSetName;
private String anchorName;
diff --git a/cps-service/src/main/java/org/onap/cps/api/model/DeltaReport.java b/cps-service/src/main/java/org/onap/cps/api/model/DeltaReport.java
index df642628d0..761c6ad01d 100644
--- a/cps-service/src/main/java/org/onap/cps/api/model/DeltaReport.java
+++ b/cps-service/src/main/java/org/onap/cps/api/model/DeltaReport.java
@@ -23,21 +23,20 @@ package org.onap.cps.api.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.io.Serializable;
import java.util.Map;
-import lombok.AccessLevel;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
-@Setter(AccessLevel.PROTECTED)
+@Setter
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
+@NoArgsConstructor
public class DeltaReport {
public static final String CREATE_ACTION = "create";
public static final String REMOVE_ACTION = "remove";
public static final String REPLACE_ACTION = "replace";
- DeltaReport() {}
-
private String action;
private String xpath;
private Map<String, Serializable> sourceData;
diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsAnchorServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsAnchorServiceImpl.java
index fb22311128..f18ae74c73 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/CpsAnchorServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/CpsAnchorServiceImpl.java
@@ -24,9 +24,9 @@ import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.model.Anchor;
-import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.CpsDataPersistenceService;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.stereotype.Service;
@Service
diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsDataServiceImpl.java
index f2513173a6..71e6f79bb7 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/CpsDataServiceImpl.java
@@ -42,15 +42,14 @@ import org.onap.cps.api.CpsDeltaService;
import org.onap.cps.api.exceptions.DataValidationException;
import org.onap.cps.api.model.Anchor;
import org.onap.cps.api.model.DataNode;
-import org.onap.cps.api.model.DataNodeBuilder;
import org.onap.cps.api.model.DeltaReport;
import org.onap.cps.api.parameters.FetchDescendantsOption;
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.utils.ContentType;
+import org.onap.cps.utils.CpsValidator;
import org.onap.cps.utils.DataMapUtils;
import org.onap.cps.utils.JsonObjectMapper;
import org.onap.cps.utils.PrefixResolver;
diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsDataspaceServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsDataspaceServiceImpl.java
index 15caa2276d..1a85147b64 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/CpsDataspaceServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/CpsDataspaceServiceImpl.java
@@ -27,8 +27,8 @@ import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsDataspaceService;
import org.onap.cps.api.model.Dataspace;
-import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsAdminPersistenceService;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.stereotype.Service;
@Service
diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java
index 7a9d142506..d532001aec 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java
@@ -32,7 +32,6 @@ import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsDeltaService;
import org.onap.cps.api.model.DataNode;
import org.onap.cps.api.model.DeltaReport;
-import org.onap.cps.api.model.DeltaReportBuilder;
import org.springframework.stereotype.Service;
@Slf4j
diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsModuleServiceImpl.java
index 7622ba5fe2..b16abcc31f 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/CpsModuleServiceImpl.java
@@ -36,8 +36,8 @@ import org.onap.cps.api.model.ModuleDefinition;
import org.onap.cps.api.model.ModuleReference;
import org.onap.cps.api.model.SchemaSet;
import org.onap.cps.api.parameters.CascadeDeleteAllowed;
-import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsModulePersistenceService;
+import org.onap.cps.utils.CpsValidator;
import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder;
import org.onap.cps.yang.YangTextSchemaSourceSet;
import org.springframework.stereotype.Service;
@@ -175,8 +175,9 @@ public class CpsModuleServiceImpl implements CpsModuleService {
}
@Override
- public void deleteAllUnusedYangModuleData() {
- cpsModulePersistenceService.deleteAllUnusedYangModuleData();
+ public void deleteAllUnusedYangModuleData(final String dataspaceName) {
+ cpsValidator.validateNameCharacters(dataspaceName);
+ cpsModulePersistenceService.deleteAllUnusedYangModuleData(dataspaceName);
}
private boolean isCascadeDeleteProhibited(final CascadeDeleteAllowed cascadeDeleteAllowed) {
diff --git a/cps-service/src/main/java/org/onap/cps/impl/CpsQueryServiceImpl.java b/cps-service/src/main/java/org/onap/cps/impl/CpsQueryServiceImpl.java
index e534e0aea1..2687d8faee 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/CpsQueryServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/CpsQueryServiceImpl.java
@@ -29,8 +29,8 @@ import org.onap.cps.api.CpsQueryService;
import org.onap.cps.api.model.DataNode;
import org.onap.cps.api.parameters.FetchDescendantsOption;
import org.onap.cps.api.parameters.PaginationOption;
-import org.onap.cps.impl.utils.CpsValidator;
import org.onap.cps.spi.CpsDataPersistenceService;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.stereotype.Service;
@Service
diff --git a/cps-service/src/main/java/org/onap/cps/api/model/DataNodeBuilder.java b/cps-service/src/main/java/org/onap/cps/impl/DataNodeBuilder.java
index d509f53525..a78f3d9826 100644
--- a/cps-service/src/main/java/org/onap/cps/api/model/DataNodeBuilder.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/DataNodeBuilder.java
@@ -20,7 +20,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.api.model;
+package org.onap.cps.impl;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -33,6 +33,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.exceptions.DataValidationException;
+import org.onap.cps.api.model.DataNode;
import org.onap.cps.utils.YangUtils;
import org.opendaylight.yangtools.yang.common.Ordering;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
diff --git a/cps-service/src/main/java/org/onap/cps/api/model/DeltaReportBuilder.java b/cps-service/src/main/java/org/onap/cps/impl/DeltaReportBuilder.java
index a8e922f3df..fdc2e939d6 100644
--- a/cps-service/src/main/java/org/onap/cps/api/model/DeltaReportBuilder.java
+++ b/cps-service/src/main/java/org/onap/cps/impl/DeltaReportBuilder.java
@@ -18,11 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.api.model;
+package org.onap.cps.impl;
import java.io.Serializable;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.api.model.DeltaReport;
@Slf4j
public class DeltaReportBuilder {
diff --git a/cps-service/src/main/java/org/onap/cps/impl/YangTextSchemaSourceSetCache.java b/cps-service/src/main/java/org/onap/cps/impl/YangTextSchemaSourceSetCache.java
index 688669c941..e7e7b1c5ce 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/YangTextSchemaSourceSetCache.java
+++ b/cps-service/src/main/java/org/onap/cps/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.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/spi/CpsModulePersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
index b1f8aad88f..86ad50252d 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
@@ -146,9 +146,11 @@ public interface CpsModulePersistenceService {
String moduleName, String moduleRevision);
/**
- * Remove any unused Yang Resource Modules and Schema Sets.
+ * Remove any unused Yang Resource Modules and Schema Sets from the given dataspace.
+ *
+ * @param dataspaceName dataspace name
*/
- void deleteAllUnusedYangModuleData();
+ void deleteAllUnusedYangModuleData(String dataspaceName);
/**
* Identify new module references from those returned by a node compared to what is in CPS already.
diff --git a/cps-service/src/main/java/org/onap/cps/impl/utils/CpsValidator.java b/cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java
index 75bcf126a4..93f51ee58d 100644
--- a/cps-service/src/main/java/org/onap/cps/impl/utils/CpsValidator.java
+++ b/cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.impl.utils;
+package org.onap.cps.utils;
import org.onap.cps.api.parameters.PaginationOption;
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/CpsAnchorServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/CpsAnchorServiceImplSpec.groovy
index 22f5c9f83e..d78c8bb47f 100644
--- a/cps-service/src/test/groovy/org/onap/cps/impl/CpsAnchorServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/CpsAnchorServiceImplSpec.groovy
@@ -21,7 +21,7 @@
package org.onap.cps.impl
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.api.exceptions.ModuleNamesNotFoundException
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataServiceImplSpec.groovy
index 3ea859ae6d..34d2b7564a 100644
--- a/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataServiceImplSpec.groovy
@@ -31,7 +31,7 @@ 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.utils.CpsValidator
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.api.parameters.FetchDescendantsOption
import org.onap.cps.api.exceptions.ConcurrencyException
@@ -40,7 +40,6 @@ import org.onap.cps.api.exceptions.DataValidationException
import org.onap.cps.api.exceptions.SessionManagerException
import org.onap.cps.api.exceptions.SessionTimeoutException
import org.onap.cps.api.model.Anchor
-import org.onap.cps.api.model.DataNodeBuilder
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.JsonObjectMapper
import org.onap.cps.utils.PrefixResolver
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataspaceServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataspaceServiceImplSpec.groovy
index 468fe76d41..97f6fba4d3 100644
--- a/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataspaceServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/CpsDataspaceServiceImplSpec.groovy
@@ -21,7 +21,7 @@
package org.onap.cps.impl
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.api.model.Dataspace
import spock.lang.Specification
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/CpsModuleServiceImplSpec.groovy
index ce871621e5..041ce605c4 100644
--- a/cps-service/src/test/groovy/org/onap/cps/impl/CpsModuleServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/CpsModuleServiceImplSpec.groovy
@@ -25,7 +25,7 @@ package org.onap.cps.impl
import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAnchorService
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.api.exceptions.DuplicatedYangResourceException
import org.onap.cps.api.exceptions.ModelValidationException
@@ -252,11 +252,11 @@ class CpsModuleServiceImplSpec extends Specification {
1 * mockCpsValidator.validateNameCharacters('some-dataspace-name', 'some-anchor-name')
}
- def 'Delete all unused yang module data.'() {
+ def 'Delete unused yang module data for a dataspace.'() {
when: 'deleting unused yang module data'
- objectUnderTest.deleteAllUnusedYangModuleData()
- then: 'it is delegated to the module persistence service'
- 1 * mockCpsModulePersistenceService.deleteAllUnusedYangModuleData()
+ objectUnderTest.deleteAllUnusedYangModuleData('some-dataspace-name')
+ then: 'it is delegated to the module persistence service with the correct parameters'
+ 1 * mockCpsModulePersistenceService.deleteAllUnusedYangModuleData('some-dataspace-name')
}
def 'Schema set exists.'() {
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/CpsQueryServiceImplSpec.groovy
index 80db83b27a..237e4e4592 100644
--- a/cps-service/src/test/groovy/org/onap/cps/impl/CpsQueryServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/CpsQueryServiceImplSpec.groovy
@@ -22,7 +22,7 @@
package org.onap.cps.impl
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.api.parameters.FetchDescendantsOption
import org.onap.cps.api.parameters.PaginationOption
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/model/DataNodeBuilderSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/DataNodeBuilderSpec.groovy
index 24c78864a5..1597d45761 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/model/DataNodeBuilderSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/DataNodeBuilderSpec.groovy
@@ -19,10 +19,11 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.api.model
+package org.onap.cps.impl
import org.onap.cps.TestUtils
import org.onap.cps.api.exceptions.DataValidationException
+import org.onap.cps.api.model.DataNode
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.DataMapUtils
import org.onap.cps.utils.YangParserHelper
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/model/DeltaReportBuilderSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/DeltaReportBuilderSpec.groovy
index 94e3ed5c26..2decefff21 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/model/DeltaReportBuilderSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/DeltaReportBuilderSpec.groovy
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.api.model
+package org.onap.cps.impl
import spock.lang.Specification
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/E2ENetworkSliceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/E2ENetworkSliceSpec.groovy
index 4ab71f7228..8171209947 100755
--- a/cps-service/src/test/groovy/org/onap/cps/impl/E2ENetworkSliceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/E2ENetworkSliceSpec.groovy
@@ -28,7 +28,7 @@ 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.utils.CpsValidator
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.api.model.Anchor
diff --git a/cps-service/src/test/groovy/org/onap/cps/impl/YangTextSchemaSourceSetCacheSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/impl/YangTextSchemaSourceSetCacheSpec.groovy
index fe49d04f3c..6694e7712f 100644
--- a/cps-service/src/test/groovy/org/onap/cps/impl/YangTextSchemaSourceSetCacheSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/impl/YangTextSchemaSourceSetCacheSpec.groovy
@@ -22,7 +22,7 @@
package org.onap.cps.impl
import org.onap.cps.TestUtils
-import org.onap.cps.impl.utils.CpsValidator
+import org.onap.cps.utils.CpsValidator
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.yang.YangTextSchemaSourceSet
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy
index bb0f5b0911..6ff41c128f 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy
@@ -22,7 +22,7 @@
package org.onap.cps.utils
-import org.onap.cps.api.model.DataNodeBuilder
+import org.onap.cps.impl.DataNodeBuilder
import spock.lang.Specification
class DataMapUtilsSpec extends Specification {
diff --git a/docker-compose/config/grafana/lcm-state-dashboard.json b/docker-compose/config/grafana/inventory-dashboard.json
index 5339b038d7..f6a7e8cbb2 100644
--- a/docker-compose/config/grafana/lcm-state-dashboard.json
+++ b/docker-compose/config/grafana/inventory-dashboard.json
@@ -18,7 +18,7 @@
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
- "id": 2,
+ "id": 12,
"links": [],
"panels": [
{
@@ -100,7 +100,7 @@
"sort": "none"
}
},
- "pluginVersion": "11.4.0",
+ "pluginVersion": "11.3.1",
"targets": [
{
"disableTextWrap": false,
@@ -179,111 +179,11 @@
},
"gridPos": {
"h": 8,
- "w": 12,
+ "w": 24,
"x": 0,
"y": 9
},
- "id": 1,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "pluginVersion": "11.4.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "disableTextWrap": false,
- "editorMode": "builder",
- "expr": "cmHandlesByState{state=\"ADVISED\", instance=\"$Instance\", job=\"$Job\"}",
- "fullMetaSearch": false,
- "includeNullMetadata": true,
- "legendFormat": "__auto",
- "range": true,
- "refId": "A",
- "useBackend": false
- }
- ],
- "title": "ADVISED",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "barWidthFactor": 0.6,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- }
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 9
- },
- "id": 3,
+ "id": 6,
"options": {
"legend": {
"calcs": [],
@@ -296,12 +196,12 @@
"sort": "none"
}
},
- "pluginVersion": "11.4.0",
+ "pluginVersion": "11.3.1",
"targets": [
{
"disableTextWrap": false,
"editorMode": "builder",
- "expr": "cmHandlesByState{state=\"READY\", instance=\"$Instance\", job=\"$Job\"}",
+ "expr": "http_server_requests_seconds_count{instance=\"$Instance\", job=\"$Job\", status=~\"201|200\", uri=\"/ncmpInventory/v1/ch\"}",
"fullMetaSearch": false,
"includeNullMetadata": true,
"legendFormat": "__auto",
@@ -310,7 +210,7 @@
"useBackend": false
}
],
- "title": "READY",
+ "title": "Inventory API calls by URI and STATUS",
"type": "timeseries"
},
{
@@ -375,107 +275,11 @@
},
"gridPos": {
"h": 8,
- "w": 12,
+ "w": 24,
"x": 0,
"y": 17
},
- "id": 2,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "mode": "single",
- "sort": "none"
- }
- },
- "pluginVersion": "11.4.0",
- "targets": [
- {
- "disableTextWrap": false,
- "editorMode": "builder",
- "expr": "cmHandlesByState{state=\"LOCKED\", instance=\"$Instance\", job=\"$Job\"}",
- "fullMetaSearch": false,
- "includeNullMetadata": true,
- "legendFormat": "__auto",
- "range": true,
- "refId": "A",
- "useBackend": false
- }
- ],
- "title": "LOCKED",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "barWidthFactor": 0.6,
- "drawStyle": "line",
- "fillOpacity": 0,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "auto",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- }
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 17
- },
- "id": 4,
+ "id": 7,
"options": {
"legend": {
"calcs": [],
@@ -488,12 +292,12 @@
"sort": "none"
}
},
- "pluginVersion": "11.4.0",
+ "pluginVersion": "11.3.1",
"targets": [
{
"disableTextWrap": false,
"editorMode": "builder",
- "expr": "cmHandlesByState{state=\"DELETING\", instance=\"$Instance\", job=\"$Job\"}",
+ "expr": "sum({error=\"OutOfMemoryError\", instance=\"$Instance\", job=\"$Job\"})",
"fullMetaSearch": false,
"includeNullMetadata": true,
"legendFormat": "__auto",
@@ -502,19 +306,23 @@
"useBackend": false
}
],
- "title": "DELETING",
+ "title": "Out of Memory Errors",
"type": "timeseries"
}
],
"preload": false,
"schemaVersion": 40,
- "tags": [],
+ "tags": [
+ "CPS",
+ "NCMP",
+ "k6"
+ ],
"templating": {
"list": [
{
"current": {
- "text": "172.17.0.1:8799",
- "value": "172.17.0.1:8799"
+ "text": "129.192.80.24:9998",
+ "value": "129.192.80.24:9998"
},
"definition": "label_values(instance)",
"label": "Instance",
@@ -531,8 +339,8 @@
},
{
"current": {
- "text": "cps-and-ncmp-endurance",
- "value": "cps-and-ncmp-endurance"
+ "text": "cps-and-ncmp-kpi",
+ "value": "cps-and-ncmp-kpi"
},
"definition": "label_values(job)",
"label": "job",
@@ -555,8 +363,8 @@
},
"timepicker": {},
"timezone": "browser",
- "title": "LCM State",
- "uid": "ae9zcowku03k0d",
- "version": 1,
+ "title": "Inventory REST Interfaces",
+ "uid": "beao8xrt6qjnkc",
+ "version": 7,
"weekStart": ""
} \ No newline at end of file
diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml
index c9df8b9889..0828d6f3a9 100644
--- a/docker-compose/docker-compose.yml
+++ b/docker-compose/docker-compose.yml
@@ -68,7 +68,8 @@ services:
ONAP_OTEL_EXPORTER_ENDPOINT: http://jaeger-service:4317
POLICY_SERVICE_ENABLED: 'false'
POLICY_SERVICE_DEFAULT_DECISION: 'deny from env'
- JAVA_TOOL_OPTIONS: "-XX:InitialRAMPercentage=75.0 -XX:MaxRAMPercentage=75.0"
+ CPS_MONITORING_MICROMETER_JVM_EXTRAS: 'true'
+ JAVA_TOOL_OPTIONS: "-XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=70.0"
### DEBUG: Uncomment next line to enable java debugging
### JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
restart: unless-stopped
@@ -80,7 +81,7 @@ services:
resources:
limits:
cpus: '3'
- memory: 2G
+ memory: 3G
nginx:
container_name: ${NGINX_CONTAINER_NAME:-nginx-loadbalancer}
@@ -199,7 +200,7 @@ services:
volumes:
- ./config/grafana/provisioning/:/etc/grafana/provisioning/
- ./config/grafana/jvm-micrometer-dashboard.json:/var/lib/grafana/dashboards/jvm-micrometer-dashboard.json
- - ./config/grafana/lcm-state-dashboard.json:/var/lib/grafana/dashboards/lcm-state-dashboard.json
+ - ./config/grafana/inventory-dashboard.json:/var/lib/grafana/dashboards/inventory-dashboard.json
- grafana:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
diff --git a/docs/admin-guide.rst b/docs/admin-guide.rst
index 4a40f9b29c..156a5df832 100644
--- a/docs/admin-guide.rst
+++ b/docs/admin-guide.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2021-2022 Nordix Foundation
+.. Copyright (C) 2021-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _adminGuide:
@@ -12,6 +12,40 @@ CPS Admin Guide
.. toctree::
:maxdepth: 1
+Regular Maintenance
+===================
+This section details tasks that an administrator of the CPS application should execute on regular basis
+to ensure optimum working of CPS.
+
+Dataspace Clean Up
+------------------
+Certain data in the CPS database might not be explicitly removed after it is no longer required ('orphaned data').
+For example, schema sets and their associated unique module resources no longer used by any anchor because of model upgrades.
+This data would unnecessarily take up space and could eventually affect the performance of the DB if it is not deleted.
+How often this needs to be done depends on how often schema sets are being deprecated.
+Typically once per month should suffice.
+
+To remove orphaned data in a given dataspace use the following post request:
+
+.. code::
+
+ http://<cps-component-service-name>:<cps-port>/v2/admin/dataspaces/<dataspace-name>/actions/clean
+
+for example
+
+.. code-block:: bash
+
+ curl --location --request POST 'http://cps:8080/admin/datsaspaces/bookstore/actions/clean' \
+ --header 'Content-Type: application/json; charset=utf-8'
+
+ Response : HTTP Status 204
+
+For more details refer to the CPS-Core API: :doc:`design`.
+
+.. note::
+ NCMP has no specific maintenance tasks but it will also build up orphaned data when CM Handles get updated and or deleted.
+ To delete this data execute the above procedure for the dataspace named 'NFP-Operational'.
+
Logging Configuration
=====================
@@ -192,8 +226,20 @@ Prometheus Metrics can be checked at the following endpoint
http://<cps-component-service-name>:8080/actuator/prometheus
+Heap Dump and Thread Dump
+-------------------------
+
+On demand heap dump and thread dump generation using the below endpoints.
+
+.. code::
+
+ http://<cps-component-service-name>:8080/actuator/heapdump
+ http://<cps-component-service-name>:8080/actuator/threaddump
+
Hazelcast
---------
+.. note::
+ The below endpoints will be removed from hazelcast community version in the future release.
Hazelcast cluster state and health check can be seen using the below endpoints
@@ -210,9 +256,8 @@ Naming Validation
As part of the Kohn 3.1.0 release, CPS has added validation to the names of the following components:
- Dataspace names
- - Schema Set names
- Anchor names
- - Cm-Handle identifiers
+ - CM Handle identifiers
The following characters along with spaces are no longer valid for naming of these components.
diff --git a/docs/api/swagger/cps/openapi.yaml b/docs/api/swagger/cps/openapi.yaml
index c84609b638..f6baadc8ea 100644
--- a/docs/api/swagger/cps/openapi.yaml
+++ b/docs/api/swagger/cps/openapi.yaml
@@ -330,6 +330,65 @@ paths:
summary: Get a dataspace
tags:
- cps-admin
+ /{apiVersion}/admin/dataspaces/{dataspace-name}/actions/clean:
+ post:
+ description: Clean the dataspace (remove orphaned schema sets and modules)
+ operationId: cleanDataspace
+ parameters:
+ - description: apiVersion
+ in: path
+ name: apiVersion
+ required: true
+ schema:
+ default: v2
+ enum:
+ - v1
+ - v2
+ type: string
+ - description: dataspace-name
+ in: path
+ name: dataspace-name
+ required: true
+ schema:
+ example: my-dataspace
+ type: string
+ responses:
+ "204":
+ content: {}
+ description: No Content
+ "400":
+ content:
+ application/json:
+ example:
+ status: 400
+ message: Bad Request
+ details: The provided request is not valid
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Bad Request
+ "403":
+ content:
+ application/json:
+ example:
+ status: 403
+ message: Request Forbidden
+ details: This request is forbidden
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Forbidden
+ "500":
+ content:
+ application/json:
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Internal Server Error
+ summary: Clean the dataspace
+ tags:
+ - cps-admin
/v1/dataspaces/{dataspace-name}/anchors:
post:
deprecated: true
diff --git a/docs/cm-handle-lcm-events.rst b/docs/cm-handle-lcm-events.rst
index 8446834c31..38339e206a 100644
--- a/docs/cm-handle-lcm-events.rst
+++ b/docs/cm-handle-lcm-events.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2023 Nordix Foundation
+.. Copyright (C) 2023-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _cmHandleLcmEvents:
@@ -15,7 +15,7 @@ CM Handle Lifecycle Management (LCM) Events
Introduction
============
-LCM events for CM Handles are published when a CM Handle is created, deleted or another change in the cm handle state occurs.
+LCM events for CM Handles are published when a CM Handle is created, deleted or another change in the CM Handle state occurs.
**3 possible event types:**
@@ -55,7 +55,7 @@ Event payload varies based on the type of event.
**CREATE**
-Event payload for this event contains the properties of the new cm handle created.
+Event payload for this event contains the properties of the new CM Handle created.
*Create event payload prototype*
@@ -77,7 +77,7 @@ Event payload for this event contains the properties of the new cm handle create
**UPDATE**
-Event payload for this event contains the difference in state and properties of the cm handle.
+Event payload for this event contains the difference in state and properties of the CM Handle.
*Update event payload prototype*
@@ -106,7 +106,7 @@ Event payload for this event contains the difference in state and properties of
**DELETE**
-Event payload for this event contains the identifier of the deleted cm handle.
+Event payload for this event contains the identifier of the deleted CM Handle.
*Delete event payload prototype*
@@ -114,4 +114,4 @@ Event payload for this event contains the identifier of the deleted cm handle.
"event": {
"cmHandleId" : "cmhandle-001",
- } \ No newline at end of file
+ }
diff --git a/docs/cps-events.rst b/docs/cps-events.rst
index 47aa73f12e..1097af9a12 100644
--- a/docs/cps-events.rst
+++ b/docs/cps-events.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2022-2023 Nordix Foundation
+.. Copyright (C) 2022-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _cpsEvents:
@@ -16,9 +16,9 @@ CPS Events
cm-notification-subscriptions.rst
.. note::
- Legacy async response on a client supplied topic for single cm handle data request are no longer supported. Click link below for the legacy specification.
+ Legacy async response on a client supplied topic for single CM Handle data request are no longer supported. Click link below for the legacy specification.
.. toctree::
:maxdepth: 0
- ncmp-async-events.rst \ No newline at end of file
+ ncmp-async-events.rst
diff --git a/docs/cps-ncmp-message-status-codes.rst b/docs/cps-ncmp-message-status-codes.rst
index e0a3f0308b..799838ae44 100644
--- a/docs/cps-ncmp-message-status-codes.rst
+++ b/docs/cps-ncmp-message-status-codes.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2023-2024 Nordix Foundation
+.. Copyright (C) 2023-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _dataOperationMessageStatusCodes:
@@ -16,9 +16,9 @@ CPS-NCMP Message Status Codes
+-----------------+------------------------------------------------------+-----------------------------------+
| 1 | ACCEPTED | CM Data Notification Subscription |
+-----------------+------------------------------------------------------+-----------------------------------+
- | 100 | cm handle id(s) is(are) not found | All features |
+ | 100 | CM Handle id(s) is(are) not found | All features |
+-----------------+------------------------------------------------------+-----------------------------------+
- | 101 | cm handle(s) not ready | Data Operation |
+ | 101 | CM Handle(s) not ready | Data Operation |
+-----------------+------------------------------------------------------+-----------------------------------+
| 102 | dmi plugin service is not responding | Data Operation |
+-----------------+------------------------------------------------------+-----------------------------------+
@@ -30,9 +30,9 @@ CPS-NCMP Message Status Codes
+-----------------+------------------------------------------------------+-----------------------------------+
| 108 | Unknown error | All features |
+-----------------+------------------------------------------------------+-----------------------------------+
- | 109 | cm-handle already exists | Inventory |
+ | 109 | CM Handle already exists | Inventory |
+-----------------+------------------------------------------------------+-----------------------------------+
- | 110 | cm-handle has an invalid character(s) in id | Inventory |
+ | 110 | CM Handle has an invalid character(s) in id | Inventory |
+-----------------+------------------------------------------------------+-----------------------------------+
| 111 | alternate id already associated | Inventory |
+-----------------+------------------------------------------------------+-----------------------------------+
diff --git a/docs/cps-scheduled-processes.rst b/docs/cps-scheduled-processes.rst
index c204e6ca0a..9af9a81c0c 100644
--- a/docs/cps-scheduled-processes.rst
+++ b/docs/cps-scheduled-processes.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2022 Nordix Foundation
+.. Copyright (C) 2022-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
@@ -21,17 +21,17 @@ The following section is a list of the current scheduled processes running withi
Module Sync
-----------
The module sync is a user :ref:`configurable timed process<additional-cps-ncmp-customizations>`,
-which is set to search for CM-Handles within CPS with an *'ADVISED'* state.
-Once the CM-Handle is processed by the module sync, the CM-Handle state is then set to *'READY'*, if the process completes successfully.
-If for any reason the module sync fails, the CM-Handle state will then be set to *'LOCKED'*,
+which is set to search for CM Handles within CPS with an *'ADVISED'* state.
+Once the CM Handle is processed by the module sync, the CM Handle state is then set to *'READY'*, if the process completes successfully.
+If for any reason the module sync fails, the CM Handle state will then be set to *'LOCKED'*,
and the reason for the lock will also be stored within CPS.
-CM-Handles in the *'LOCKED'* state will be retried when the system has availability. CM-Handles in a *'LOCKED'*
-state are processed by the retry mechanism, by setting CM-Handle state back to *'ADVISED'* so the next sync cycle will process those again.
+CM Handles in the *'LOCKED'* state will be retried when the system has availability. CM Handles in a *'LOCKED'*
+state are processed by the retry mechanism, by setting CM Handle state back to *'ADVISED'* so the next sync cycle will process those again.
Data Sync
---------
The data sync is a user :ref:`configurable timed process<additional-cps-ncmp-customizations>`,
-which is set to search for CM-Handles with a sync state of *'UNSYNCHRONIZED'*.
-Once the CM-Handle(s) with a sync state of *'UNSYNCHRONIZED'* is processed by the data sync,
-the CM-Handle sync state is then set to *'SYNCHRONIZED'*, if the process completes successfully.
-If the data sync fails, the CM-Handle sync state will remain as *'UNSYNCHRONIZED'*, and will be re-attempted.
+which is set to search for CM Handles with a sync state of *'UNSYNCHRONIZED'*.
+Once the CM Handle(s) with a sync state of *'UNSYNCHRONIZED'* is processed by the data sync,
+the CM Handle sync state is then set to *'SYNCHRONIZED'*, if the process completes successfully.
+If the data sync fails, the CM Handle sync state will remain as *'UNSYNCHRONIZED'*, and will be re-attempted.
diff --git a/docs/deployment.rst b/docs/deployment.rst
index 940bc50923..2af0dd0cd5 100644
--- a/docs/deployment.rst
+++ b/docs/deployment.rst
@@ -191,21 +191,16 @@ Any spring supported property can be configured by providing in ``config.additio
| Property | Description | Default Value |
+===========================================+=========================================================================================================+===============================+
| config.appUserName | User name used by cps-core service to configure the authentication for REST API it exposes. | ``cpsuser`` |
-| | | |
| | This is the user name to be used by cps-core REST clients to authenticate themselves. | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.appUserPassword | Password used by cps-core service to configure the authentication for REST API it exposes. | Not defined |
-| | | |
| | If not defined, the password is generated when deploying the application. | |
-| | | |
| | See also :ref:`cps_common_credentials_retrieval`. | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| postgres.config.pgUserName | Internal user name used by cps-core to connect to its own database. | ``cps`` |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| postgres.config.pgUserPassword | Internal password used by cps-core to connect to its own database. | Not defined |
-| | | |
| | If not defined, the password is generated when deploying the application. | |
-| | | |
| | See also :ref:`cps_common_credentials_retrieval`. | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| postgres.config.pgDatabase | Database name used by cps-core | ``cpsdb`` |
@@ -225,28 +220,24 @@ Any spring supported property can be configured by providing in ``config.additio
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.eventPublisher. | Kafka security protocol. | ``SASL_PLAINTEXT`` |
| spring.kafka.security.protocol | Some possible values are: | |
-| | | |
| | * ``PLAINTEXT`` | |
| | * ``SASL_PLAINTEXT``, for authentication | |
| | * ``SASL_SSL``, for authentication and encryption | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.eventPublisher. | Kafka security SASL mechanism. Required for SASL_PLAINTEXT and SASL_SSL protocols. | Not defined |
| spring.kafka.properties. | Some possible values are: | |
-| sasl.mechanism | | |
-| | * ``PLAIN``, for PLAINTEXT | |
+| sasl.mechanism | * ``PLAIN``, for PLAINTEXT | |
| | * ``SCRAM-SHA-512``, for SSL | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.eventPublisher. | Kafka security SASL JAAS configuration. Required for SASL_PLAINTEXT and SASL_SSL protocols. | Not defined |
| spring.kafka.properties. | Some possible values are: | |
-| sasl.jaas.config | | |
-| | * ``org.apache.kafka.common.security.plain.PlainLoginModule required username="..." password="...";``, | |
-| | for PLAINTEXT | |
+| sasl.jaas.config | * ``org.apache.kafka.common.security.plain.PlainLoginModule required username="..." password="...";``, | |
+| | for PLAINTEXT | |
| | * ``org.apache.kafka.common.security.scram.ScramLoginModule required username="..." password="...";``, | |
-| | for SSL | |
+| | for SSL | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.eventPublisher. | Kafka security SASL SSL store type. Required for SASL_SSL protocol. | Not defined |
| spring.kafka.ssl.trust-store-type | Some possible values are: | |
-| | | |
| | * ``JKS`` | |
+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.eventPublisher. | Kafka security SASL SSL store file location. Required for SASL_SSL protocol. | Not defined |
@@ -293,35 +284,84 @@ Any spring supported property can be configured by providing in ``config.additio
Additional CPS-NCMP Customizations
==================================
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.dmiPluginUserName | User name used by cps-core to authenticate themselves for using ncmp-dmi-plugin service. | ``dmiuser`` |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.dmiPluginUserPassword | Internal password used by cps-core to connect to ncmp-dmi-plugin service. | Not defined |
-| | | |
-| | If not defined, the password is generated when deploying the application. | |
-| | | |
-| | See also :ref:`cps_common_credentials_retrieval`. | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.ncmp.timers | Specifies the delay in milliseconds in which the module sync watch dog will wake again after finishing. | ``5000`` |
-| .advised-modules-sync.sleep-time-ms | | |
-| | | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.ncmp.timers | Specifies the delay in milliseconds in which the data sync watch dog will wake again after finishing. | ``30000`` |
-| .cm-handle-data-sync.sleep-time-ms | | |
-| | | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.additional.ncmp.dmi.httpclient | Specifies the maximum time in seconds, to wait for establishing a connection for the HTTP Client. | ``30`` |
-| .connectionTimeoutInSeconds | | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.additional.ncmp.dmi.httpclient | Specifies the maximum number of connections allowed per route in the HTTP client. | ``50`` |
-| .maximumConnectionsPerRoute | | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.additional.ncmp.dmi.httpclient | Specifies the maximum total number of connections that can be held by the HTTP client. | ``100`` |
-| .maximumConnectionsTotal | | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.additional.ncmp.dmi.httpclient | Specifies the duration in seconds for the threshold, after which idle connections will be evicted | ``5`` |
-| .idleConnectionEvictionThresholdInSeconds | from the connection pool by the HTTP client. | |
-+-------------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
+
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| Property | Description | Default Value |
++=================================================+=======================================================================================+=================================+
+| config.dmiPluginUserName | User name used by cps-core to authenticate themselves for using ncmp-dmi-plugin | ``dmiuser`` |
+| | service. | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.dmiPluginUserPassword | Internal password used by cps-core to connect to ncmp-dmi-plugin service. | Not defined |
+| | If not defined, the password is generated when deploying the application. | |
+| | See also :ref:`cps_common_credentials_retrieval`. | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.ncmp.timers | Specifies the delay in milliseconds in which the module sync watch dog will wake again| ``5000`` |
+| .advised-modules-sync.sleep-time-ms | after finishing. | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.ncmp.timers | Specifies the delay in milliseconds in which the data sync watch dog will wake again | ``30000`` |
+| .cm-handle-data-sync.sleep-time-ms | after finishing. | |
+| | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Maximum size (in MB) of the in-memory buffer for HTTP response data. | ``16`` |
+| .[app] | | |
+| .httpclient | | |
+| .[services] | | |
+| .maximumInMemorySizeInMegabytes | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Maximum number of simultaneous connections allowed in the connection pool. | ``100`` |
+| .[app] | | |
+| .httpclient | | |
+| .[services] | | |
+| .maximumConnectionsTotal | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Maximum number of pending requests when the connection pool is full. | ``50`` |
+| .[app] | | |
+| .httpclient | | |
+| .[services] | | |
+| .pendingAcquireMaxCount | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Specifies the maximum time in seconds, to wait for establishing a connection for the | ``30`` |
+| .[app] | HTTP Client. | |
+| .httpclient | | |
+| .[services] | | |
+| .connectionTimeoutInSeconds | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Timeout (in seconds) for reading data from the server after the connection is | ``30`` |
+| .[app] | established. | |
+| .httpclient | | |
+| .[services] | | |
+| .readTimeoutInSeconds | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Timeout (in seconds) for writing data to the server. | ``30`` |
+| .[app] | | |
+| .httpclient | | |
+| .[services] | | |
+| .writeTimeoutInSeconds | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp | Total timeout (in seconds) for receiving a complete response, including all processing| ``60`` |
+| .[app] | stages. | |
+| .httpclient | | |
+| .[services] | | |
+| .responseTimeoutInSeconds | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp.policy-executor | Enables or disables the policy-executor feature. | ``false`` |
+| .enabled | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp.policy-executor | The default (fallback) decision in case a problem with the external service occurs. | ``allow`` |
+| .defaultDecision | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp.policy-executor | The server address for the external policy executor service. | ``http://policy-executor-stub`` |
+| .server.address | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+| config.additional.ncmp.policy-executor | The port used for the external policy executor service. | ``8093`` |
+| .server.port | | |
++-------------------------------------------------+---------------------------------------------------------------------------------------+---------------------------------+
+
+.. note::
+
+ - [app] : can be 'policy-executor' or 'dmi'.
+ - [services] 'all-services' for 'policy-executor'.
+ - [services] 'data-services' and 'model-services' for 'dmi'.
CPS-Core Docker Installation
============================
@@ -342,13 +382,13 @@ Below are the list of distributed datastructures that we have.
+--------------+------------------------------------+-----------------------------------------------------------+
| Component | Data Structure Name | Use |
+==============+====================================+===========================================================+
-| cps-ncmp | moduleSyncStartedOnCmHandles | Watchdog process to register cm handles. |
+| cps-ncmp | moduleSyncStartedOnCmHandles | Watchdog process to register CM Handles. |
+--------------+------------------------------------+-----------------------------------------------------------+
| cps-ncmp | dataSyncSemaphores | Watchdog process to sync data from the nodes. |
+--------------+------------------------------------+-----------------------------------------------------------+
| cps-ncmp | moduleSyncWorkQueue | Queue used internally for workers to pick the task. |
+--------------+------------------------------------+-----------------------------------------------------------+
-| cps-ncmp | trustLevelPerCmHandle | Stores the trust level per cm handle id |
+| cps-ncmp | trustLevelPerCmHandle | Stores the trust level per CM Handle id |
+--------------+------------------------------------+-----------------------------------------------------------+
| cps-ncmp | trustLevelPerDmiPlugin | Stores the trust level for the dmi-plugins. |
+--------------+------------------------------------+-----------------------------------------------------------+
diff --git a/docs/modeling.rst b/docs/modeling.rst
index 7ebf6fecd5..65e4aa97ca 100644
--- a/docs/modeling.rst
+++ b/docs/modeling.rst
@@ -1,7 +1,7 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
.. Copyright (C) 2021 Pantheon.tech
-.. Modifications Copyright (C) 2021-2023 Nordix Foundation
+.. Modifications Copyright (C) 2021-2025 Nordix Foundation
.. _modeling:
.. toctree::
@@ -89,31 +89,31 @@ Note: Although additional-properties are present in the model of the dmi-registr
Basic Concepts
--------------
-- **CM-Handle** represents an instance a modeled Network Function(node) in ONAP.
+- **CM Handle** represents an instance a modeled Network Function(node) in ONAP.
These are stored as Anchors within CPS-Core.
- - **CM-Handle States** are used to represent the potential states in which a CM-Handle can transition between.
+ - **CM Handle States** are used to represent the potential states in which a CM Handle can transition between.
- The 5 possible CM-Handle states are: ADVISED, READY, LOCKED, DELETING, DELETED
+ The 5 possible CM Handle states are: ADVISED, READY, LOCKED, DELETING, DELETED
- **ADVISED** indicates that a CM-Handle has been registered successfully, and is waiting for the module synchronization process to sync the CM-Handle.
+ **ADVISED** indicates that a CM Handle has been registered successfully, and is waiting for the module synchronization process to sync the CM Handle.
- **READY** indicates that the CM-Handle has been synced successfully.
+ **READY** indicates that the CM Handle has been synced successfully.
- **LOCKED** indicates that the CM-Handle has not synced successfully. A retry mechanism within CPS will set the state back to ADVISED after a set time.
+ **LOCKED** indicates that the CM Handle has not synced successfully. A retry mechanism within CPS will set the state back to ADVISED after a set time.
- **DELETING** indicates that the CM-Handle is currently being deleted.
+ **DELETING** indicates that the CM Handle is currently being deleted.
- **DELETED** indicates that the CM-Handle has been deleted successfully.
+ **DELETED** indicates that the CM Handle has been deleted successfully.
- - **Data-sync state** is the state of the data synchronization process of the CM-Handle
+ - **Data-sync state** is the state of the data synchronization process of the CM Handle
There are 3 possibles states: NONE_REQUESTED, UNSYNCHRONIZED, SYNCHRONIZED
**NONE_REQUESTED** indicates that the data sync is not requested by the user
- **UNSYNCHRONIZED** indicates the cm-handle is waiting for the data sync watchdog operation to carry out the sync process
+ **UNSYNCHRONIZED** indicates the CM Handle is waiting for the data sync watchdog operation to carry out the sync process
**SYNCHRONIZED** indicates the watchdog process has finished the data synchronization successfully
diff --git a/docs/ncmp-data-operation.rst b/docs/ncmp-data-operation.rst
index 10c3bfaca5..e0b7bb88cd 100644
--- a/docs/ncmp-data-operation.rst
+++ b/docs/ncmp-data-operation.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2023-2024 Nordix Foundation
+.. Copyright (C) 2023-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _cmHandleDataOperation:
@@ -15,7 +15,7 @@ Data Operations Endpoint
Introduction
============
-For all data operations on cm handle(s), we have a post endpoint:
+For all data operations on CM Handle(s), we have a post endpoint:
- /ncmp/v1/data?topic={client-topic-name} forward request to it's dmi plugin service.
@@ -50,7 +50,7 @@ This endpoint executes data operation for given array of operations:
| | | implementation. For ONAP DMI Plugin it will be RESTConf paths but it can|
| | | really be anything. |
+--------------------------+-------------+-------------------------------------------------------------------------+
- | targetIds | Yes | List of cm handle references |
+ | targetIds | Yes | List of CM Handle references |
+--------------------------+-------------+-------------------------------------------------------------------------+
The status codes used in the events resulting from these operations are defined here:
@@ -156,4 +156,4 @@ DMI Service 2 (POST) : `http://{dmi-host-name}:{dmi-port}/dmi/v1/data?topic=my-t
Above examples are for illustration purposes only. Please refer to link below for latest schema.
-:download:`Data operation event schema <schemas/data-operation-event-schema-1.0.0.json>` \ No newline at end of file
+:download:`Data operation event schema <schemas/data-operation-event-schema-1.0.0.json>`
diff --git a/docs/overview.rst b/docs/overview.rst
index 19ab8b4847..bc99214e2e 100644
--- a/docs/overview.rst
+++ b/docs/overview.rst
@@ -1,6 +1,8 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2021 Pantheon.tech, Nordix Foundation
+.. Copyright (C) 2021 Pantheon.tech
+.. Modifications Copyright (C) 2021-2025 Nordix Foundation
+
.. _overview:
CPS Overview
@@ -45,7 +47,7 @@ even though CPS-Core could be deployed without the NCMP extension.
NCMP-DMI-Plugin
---------------
-The Data-Model-Inventory (DMI) Plugin is a rest interface used to synchronize CM-Handles data between CPS and DMI through the DMI-Plugin.
+The Data-Model-Inventory (DMI) Plugin is a rest interface used to synchronize CM Handles data between CPS and DMI through the DMI-Plugin.
This is built previously from the CPS-NF-Proxy component.
CPS Project
diff --git a/docs/policy-executor.rst b/docs/policy-executor.rst
index b934a579b1..712b4fcf38 100644
--- a/docs/policy-executor.rst
+++ b/docs/policy-executor.rst
@@ -1,11 +1,10 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2024 Nordix Foundation
+.. Copyright (C) 2024-2025 Nordix Foundation
-.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
+.. DO NOT CHANGE THIS LABEL - EVEN THOUGH IT GIVES A WARNING
.. _policy_executor:
-
Policy Executor
###############
@@ -15,7 +14,16 @@ Policy Executor
Introduction
============
-Work In Progress: This feature is not yet completed and does not affect current NCMP functionality.
+The Policy Executor feature can be used to connect an external system to make decisions on CM write operation.
+When the feature is enabled, NCMP will first call the configured external system and depending on the response, return an error or continue.
+The details of the interface can be found in the ':ref:`policy_executor_consumed_apis`' section.
+
+This feature is available on 'legacy data interface' for operation on a single cm handle: "/v1/ch/{cm-handle}/data/ds/{datastore-name}" and only applies to "ncmp-datastore:passthrough-running".
+
+By default, the feature is not enabled. This is controlled by 'config.additional.ncmp.policy-executor.enabled' and other deployment parameters in the same group to enable it. See :ref:`additional-cps-ncmp-customizations`
+
+.. DO NOT CHANGE THIS LABEL - EVEN THOUGH IT GIVES A WARNING
+.. _policy_executor_consumed_apis:
Consumed APIs
-------------
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 9c825e4d35..1f37612570 100644
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2021-2024 Nordix Foundation
+.. Copyright (C) 2021-2025 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _release_notes:
@@ -40,6 +40,7 @@ Bug Fixes
Features
--------
+ - `CPS-2249 <https://lf-onap.atlassian.net/browse/CPS-2249>`_ NCMP to support Conflict Handling.
.. ====================
@@ -68,21 +69,19 @@ Release Data
Bug Fixes
---------
-3.5.5
- `CPS-2509 <https://lf-onap.atlassian.net/browse/CPS-2509>`_ Fix module endpoints using alternate identifier.
- `CPS-2517 <https://lf-onap.atlassian.net/browse/CPS-2517>`_ Make Content-Type header default to JSON for CPS APIs.
- - `CPS-2530 <https://lf-onap.atlassian.net/browse/CPS-2530>`_ NCMP Modules API giving empty response on READY cm handles if two sub systems discovered in parallel.
+ - `CPS-2530 <https://lf-onap.atlassian.net/browse/CPS-2530>`_ NCMP Modules API giving empty response on READY CM Handles if two sub systems discovered in parallel.
Features
--------
-3.5.5
- `CPS-2009 <https://lf-onap.atlassian.net/browse/CPS-2009>`_ Update legacy NCMP APIs interfaces to support alternate id.
- `CPS-2082 <https://lf-onap.atlassian.net/browse/CPS-2082>`_ Support XML content type to data node APIs in cps-core.
- `CPS-2433 <https://lf-onap.atlassian.net/browse/CPS-2433>`_ Remove traces of unmaintained CPS-TBDMT repository.
- `CPS-2436 <https://lf-onap.atlassian.net/browse/CPS-2436>`_ CM Avc Event to publish source key to target key while forwarding.
- `CPS-2445 <https://lf-onap.atlassian.net/browse/CPS-2445>`_ Expose CPS and NCMP version information using git plugin.
- `CPS-2451 <https://lf-onap.atlassian.net/browse/CPS-2451>`_ Removing oparent from CPS-NCMP and ONAP DMI Plugin repository.
- - `CPS-2478 <https://lf-onap.atlassian.net/browse/CPS-2478>`_ Optimized Cm Handle Registration and De-Registration use case.
+ - `CPS-2478 <https://lf-onap.atlassian.net/browse/CPS-2478>`_ Optimized CM Handle Registration and De-Registration use case.
- `CPS-2507 <https://lf-onap.atlassian.net/browse/CPS-2507>`_ Upgrade liquibase to 4.30.0 version.
Performance
@@ -111,12 +110,10 @@ Release Data
Bug Fixes
---------
-3.5.4
- `CPS-2403 <https://lf-onap.atlassian.net/browse/CPS-2403>`_ Improve lock handling and queue management during CM-handle Module Sync.
Features
--------
-3.5.4
- `CPS-2408 <https://lf-onap.atlassian.net/browse/CPS-2408>`_ One Hazelcast instance per JVM to manage the distributed data structures.
Version: 3.5.3
@@ -141,7 +138,6 @@ Release Data
Bug Fixes
---------
-3.5.3
- `CPS-2353 <https://lf-onap.atlassian.net/browse/CPS-2353>`_ Slow cmHandle registration when we use moduleSetTag, alternateId and dataProducerIdentifier
- `CPS-2395 <https://lf-onap.atlassian.net/browse/CPS-2395>`_ Retry mechanism (with back off algorithm) is removed with more frequent watchdog poll
- `CPS-2409 <https://lf-onap.atlassian.net/browse/CPS-2409>`_ Return NONE for get effective trust level api if the trust level caches empty (restart case)
@@ -150,9 +146,6 @@ Bug Fixes
Features
--------
-3.5.3
- - `CPS-2247 <https://lf-onap.atlassian.net/browse/CPS-2247>`_ Policy Executor: Invoke Policy Executor and handle 'deny' response
- - `CPS-2412 <https://lf-onap.atlassian.net/browse/CPS-2412>`_ Policy Executor: handle errors
- `CPS-2417 <https://lf-onap.atlassian.net/browse/CPS-2417>`_ Remove Hazelcast cache for prefix resolver
@@ -178,14 +171,12 @@ Release Data
Bug Fixes
---------
-3.5.2
- `CPS-2306 <https://lf-onap.atlassian.net/browse/CPS-2306>`_ Update response message for data validation failure and make it consistent across APIs
- `CPS-2319 <https://lf-onap.atlassian.net/browse/CPS-2319>`_ Fix "Create a node" and "Add List Elements" APIs response code
- `CPS-2372 <https://lf-onap.atlassian.net/browse/CPS-2372>`_ Blank alternate ID overwrites existing one
Features
--------
-3.5.2
- `CPS-1812 <https://lf-onap.atlassian.net/browse/CPS-1812>`_ CM Data Subscriptions ( Create, Delete and Merging ) with positive scenarios
- `CPS-2326 <https://lf-onap.atlassian.net/browse/CPS-2326>`_ Uplift liquibase-core dependency to 4.28.0
- `CPS-2353 <https://lf-onap.atlassian.net/browse/CPS-2353>`_ Improve registration performance with moduleSetTag
@@ -213,14 +204,12 @@ Release Data
Bug Fixes
---------
-3.5.1
- `CPS-2302 <https://lf-onap.atlassian.net/browse/CPS-2302>`_ Fix handling of special characters in moduleSetTag.
Features
--------
-3.5.1
- `CPS-2121 <https://lf-onap.atlassian.net/browse/CPS-2121>`_ Enabled http client prometheus metrics and manage high cardinality using URL template.
- - `CPS-2289 <https://lf-onap.atlassian.net/browse/CPS-2289>`_ Support for CPS Path Query in NCMP Inventory Cm Handle Search.
+ - `CPS-2289 <https://lf-onap.atlassian.net/browse/CPS-2289>`_ Support for CPS Path Query in NCMP Inventory CM Handle Search.
Version: 3.5.0
==============
@@ -242,13 +231,8 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.5.0
-
Features
--------
-3.5.0
- `CPS-989 <https://lf-onap.atlassian.net/browse/CPS-989>`_ Replace RestTemplate with WebClient.
- `CPS-2172 <https://lf-onap.atlassian.net/browse/CPS-2172>`_ Support for OpenTelemetry Tracing.
@@ -278,12 +262,10 @@ Release Data
Bug Fixes
---------
-3.4.9
- `CPS-2211 <https://lf-onap.atlassian.net/browse/CPS-2211>`_ Toggle switch to disable CPS Core change events if not used by application. Set CPS_CHANGE_EVENT_NOTIFICATIONS_ENABLED environment variable for the same.
Features
--------
-3.4.9
- `CPS-1836 <https://lf-onap.atlassian.net/browse/CPS-1836>`_ Delta between anchor and JSON payload.
Version: 3.4.8
@@ -308,15 +290,11 @@ Release Data
Bug Fixes
---------
-3.4.8
- `CPS-2186 <https://lf-onap.atlassian.net/browse/CPS-2186>`_ Report async task failures to client topic during data operations request
- `CPS-2190 <https://lf-onap.atlassian.net/browse/CPS-2190>`_ Improve performance of NCMP module searches
- `CPS-2194 <https://lf-onap.atlassian.net/browse/CPS-2194>`_ Added defaults for CPS and DMI username and password
- `CPS-2204 <https://lf-onap.atlassian.net/browse/CPS-2204>`_ Added error handling for yang module upgrade operation
-Features
---------
-
Version: 3.4.7
==============
@@ -339,12 +317,10 @@ Release Data
Bug Fixes
---------
-3.4.7
- `CPS-2150 <https://lf-onap.atlassian.net/browse/CPS-2150>`_ Fix for Async task execution failed by TimeoutException.
Features
--------
-3.4.7
- `CPS-2061 <https://lf-onap.atlassian.net/browse/CPS-2061>`_ Liquibase Steps Condensing and Cleanup.
- `CPS-2101 <https://lf-onap.atlassian.net/browse/CPS-2101>`_ Uplift Spring Boot to 3.2.4 version.
@@ -370,7 +346,6 @@ Release Data
Bug Fixes
---------
-3.4.6
- `CPS-2126 <https://lf-onap.atlassian.net/browse/CPS-2126>`_ Passing HTTP Authorization Bearer Token to DMI Plugins.
@@ -406,10 +381,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.4.5
-
Features
--------
@@ -438,7 +409,6 @@ Release Data
Bug Fixes
---------
-3.4.4
- `CPS-2027 <https://lf-onap.atlassian.net/browse/CPS-2027>`_ Upgrade Yang modules using module set tag functionalities fix
Features
@@ -469,7 +439,6 @@ Release Data
Bug Fixes
---------
-3.4.3
- `CPS-2000 <https://lf-onap.atlassian.net/browse/CPS-2000>`_ Fix for Schema object cache not being distributed.
- `CPS-2027 <https://lf-onap.atlassian.net/browse/CPS-2027>`_ Fixes for upgrade yang modules using module set tag.
- `CPS-2070 <https://lf-onap.atlassian.net/browse/CPS-2070>`_ Add retry interval for Kafka consumer.
@@ -506,11 +475,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.4.2
-
-
Features
--------
- `CPS-1638 <https://lf-onap.atlassian.net/browse/CPS-1638>`_ Introduce trust level for CM handle.
@@ -530,7 +494,7 @@ Known Limitations, Issues and Workarounds
For upgrading, CPS uses Liquibase for database upgrades. In order to enable Hibernate write batching
(`CPS-1795 <https://lf-onap.atlassian.net/browse/CPS-1795>`_), a change to the database entity ID generation is required.
As such, *this release does not fully support In-Service Software Upgrade* - CPS will not store new DataNodes and
-NCMP will not register new CM-handles during an upgrade with old and new versions of CPS running concurrently.
+NCMP will not register new CM Handles during an upgrade with old and new versions of CPS running concurrently.
Other operations (read, update, delete) are not impacted.
@@ -556,7 +520,6 @@ Release Data
Bug Fixes
---------
-3.4.1
- `CPS-1979 <https://lf-onap.atlassian.net/browse/CPS-1979>`_ Bug fix for Invalid topic name suffix.
Features
@@ -594,7 +557,6 @@ Release Data
Bug Fixes
---------
-3.4.0
- `CPS-1956 <https://lf-onap.atlassian.net/browse/CPS-1956>`_ Bug fix for No yang resources stored during cmhandle discovery.
.. ========================
@@ -623,13 +585,9 @@ Release Data
Bug Fixes
---------
-3.3.9
- `CPS-1923 <https://lf-onap.atlassian.net/browse/CPS-1923>`_ CPS and NCMP changed management endpoint and port from /manage to /actuator and port same as cps application port.
- `CPS-1933 <https://lf-onap.atlassian.net/browse/CPS-1933>`_ Setting up the class loader explicitly in hazelcast config.
-Features
---------
-
Version: 3.3.8
==============
@@ -650,10 +608,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.3.8
-
Features
--------
- `CPS-1888 <https://lf-onap.atlassian.net/browse/CPS-1888>`_ Uplift Spring Boot to 3.1.2.
@@ -680,7 +634,6 @@ Release Data
Bug Fixes
---------
-3.3.7
- `CPS-1866 <https://lf-onap.atlassian.net/browse/CPS-1866>`_ Fix ClassDefNotFoundError in opendaylight Yang parser
Features
@@ -713,7 +666,6 @@ Release Data
Bug Fixes
---------
-3.3.6
- `CPS-1841 <https://lf-onap.atlassian.net/browse/CPS-1841>`_ Update of top-level data node fails with exception
- `CPS-1842 <https://lf-onap.atlassian.net/browse/CPS-1842>`_ Replace event-id with correlation-id for data read operation cloud event
@@ -743,10 +695,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.3.5
-
Features
--------
- `CPS-1760 <https://lf-onap.atlassian.net/browse/CPS-1760>`_ Improve handling of special characters in Cps Paths
@@ -771,10 +719,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.3.4
-
Features
--------
- `CPS-1767 <https://lf-onap.atlassian.net/browse/CPS-1767>`_ Upgrade CPS to java 17
@@ -799,13 +743,9 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.3.3
-
Features
--------
- - `CPS-1515 <https://lf-onap.atlassian.net/browse/CPS-1515>`_ Support Multiple CM-Handles for NCMP Get Operation
+ - `CPS-1515 <https://lf-onap.atlassian.net/browse/CPS-1515>`_ Support Multiple CM Handles for NCMP Get Operation
- `CPS-1675 <https://lf-onap.atlassian.net/browse/CPS-1675>`_ Persistence write performance improvement(s)
- `CPS-1745 <https://lf-onap.atlassian.net/browse/CPS-1745>`_ Upgrade to Openapi 3.0.3
@@ -831,7 +771,6 @@ Release Data
Bug Fixes
---------
-3.3.2
- `CPS-1716 <https://lf-onap.atlassian.net/browse/CPS-1716>`_ NCMP: Java Heap OutOfMemory errors and slow registration in case of 20k cmhandles
Features
@@ -862,11 +801,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.3.1
- - None
-
Features
--------
- `CPS-1272 <https://lf-onap.atlassian.net/browse/CPS-1272>`_ Add Contains operation to CPS Path
@@ -895,11 +829,6 @@ Release Data
| | |
+--------------------------------------+--------------------------------------------------------+
-Bug Fixes
----------
-3.3.0
- - None
-
Features
--------
- `CPS-1215 <https://lf-onap.atlassian.net/browse/CPS-1215>`_ Add OR operation for CPS Path
@@ -931,7 +860,6 @@ Release Data
Bug Fixes
---------
-3.2.6
- `CPS-1526 <https://lf-onap.atlassian.net/browse/CPS-1526>`_ Fix response message for PATCH operation
- `CPS-1563 <https://lf-onap.atlassian.net/browse/CPS-1563>`_ Fix 500 response error on id-searches with empty parameters
@@ -961,13 +889,8 @@ Release Data
Bug Fixes
---------
-3.2.5
- `CPS-1537 <https://lf-onap.atlassian.net/browse/CPS-1537>`_ Introduce control switch for model loader functionality.
-Features
---------
- - None
-
Version: 3.2.4
==============
@@ -1265,7 +1188,7 @@ Features
- `CPS-869 <https://lf-onap.atlassian.net/browse/CPS-869>`_ Apply Standardized logging fields to adhere to ONAP Best practice REQ-1072
- `CPS-870 <https://lf-onap.atlassian.net/browse/CPS-870>`_ Align CPS-Core output with SDN-C output (add module name)
- `CPS-875 <https://lf-onap.atlassian.net/browse/CPS-875>`_ CM Handle State: Watchdog-process that syncs 'ADVISED' CM Handles
- - `CPS-877 <https://lf-onap.atlassian.net/browse/CPS-877>`_ CM Handle State: Exclude any CM-Handles from queries/operations that are not in state 'READY'
+ - `CPS-877 <https://lf-onap.atlassian.net/browse/CPS-877>`_ CM Handle State: Exclude any CM Handles from queries/operations that are not in state 'READY'
- `CPS-899 <https://lf-onap.atlassian.net/browse/CPS-899>`_ Start and stop sessions on Java API
- `CPS-909 <https://lf-onap.atlassian.net/browse/CPS-909>`_ Separate NCMP endpoint for ch/{cm-handle}/properties and ch/{cm-handle}/state
- `CPS-917 <https://lf-onap.atlassian.net/browse/CPS-917>`_ Structured Errors response for passthrough use-cases in NCMP
@@ -1278,7 +1201,7 @@ Features
- `CPS-1099 <https://lf-onap.atlassian.net/browse/CPS-1099>`_ Expose simplified 'external' lock reason enum state over REST interface
- `CPS-1101 <https://lf-onap.atlassian.net/browse/CPS-1101>`_ Introducing the DELETING and DELETED Cmhandle State
- `CPS-1102 <https://lf-onap.atlassian.net/browse/CPS-1102>`_ Register the Cmhandle Sends Advised State notification.
- - `CPS-1133 <https://lf-onap.atlassian.net/browse/CPS-1133>`_ Enable/Disable Data Sync for Cm Handle
+ - `CPS-1133 <https://lf-onap.atlassian.net/browse/CPS-1133>`_ Enable/Disable Data Sync for CM Handle
- `CPS-1136 <https://lf-onap.atlassian.net/browse/CPS-1136>`_ DMI Audit Support (get all CM Handles for a registered DMI)
@@ -1379,27 +1302,27 @@ Features
- `CPS-559 <https://lf-onap.atlassian.net/browse/CPS-559>`_ Define response objects (schemas) in cps-ncmp
- `CPS-636 <https://lf-onap.atlassian.net/browse/CPS-636>`_ Update operation for datastore pass through running
- `CPS-638 <https://lf-onap.atlassian.net/browse/CPS-638>`_ Delete operation for datastore pass through running
- - `CPS-677 <https://lf-onap.atlassian.net/browse/CPS-677>`_ Support 'public' Cm Handle Properties
- - `CPS-741 <https://lf-onap.atlassian.net/browse/CPS-741>`_ Re sync after removing cm handles
+ - `CPS-677 <https://lf-onap.atlassian.net/browse/CPS-677>`_ Support 'public' CM Handle Properties
+ - `CPS-741 <https://lf-onap.atlassian.net/browse/CPS-741>`_ Re sync after removing CM Handles
- `CPS-777 <https://lf-onap.atlassian.net/browse/CPS-777>`_ Ensure all DMI operations use POST method
- `CPS-780 <https://lf-onap.atlassian.net/browse/CPS-780>`_ Add examples for parameters, request and response in openapi yaml for cps-core
- `CPS-789 <https://lf-onap.atlassian.net/browse/CPS-789>`_ CPS Data Updated Event Schema V2 to support delete operation
- `CPS-791 <https://lf-onap.atlassian.net/browse/CPS-791>`_ CPS-Core sends delete notification event
- - `CPS-817 <https://lf-onap.atlassian.net/browse/CPS-817>`_ Create Endpoint For Get Cm Handles (incl. public properties) By Name
+ - `CPS-817 <https://lf-onap.atlassian.net/browse/CPS-817>`_ Create Endpoint For Get CM Handles (incl. public properties) By Name
- `CPS-837 <https://lf-onap.atlassian.net/browse/CPS-837>`_ Add Remove and Update properties (DMI and Public) as part of CM Handle Registration update
Bug Fixes
---------
- - `CPS-762 <https://lf-onap.atlassian.net/browse/CPS-762>`_ Query cm handles for module names returns incorrect cm handle identifiers
+ - `CPS-762 <https://lf-onap.atlassian.net/browse/CPS-762>`_ Query CM Handles for module names returns incorrect CM Handle identifiers
- `CPS-788 <https://lf-onap.atlassian.net/browse/CPS-788>`_ Yang Resource formatting is incorrect
- - `CPS-783 <https://lf-onap.atlassian.net/browse/CPS-783>`_ Remove cm handle does not completely remove all cm handle information
+ - `CPS-783 <https://lf-onap.atlassian.net/browse/CPS-783>`_ Remove CM Handle does not completely remove all CM Handle information
- `CPS-841 <https://lf-onap.atlassian.net/browse/CPS-841>`_ Upgrade log4j to 2.17.1 as recommended by ONAP SECCOM
- `CPS-856 <https://lf-onap.atlassian.net/browse/CPS-856>`_ Retry mechanism not working for concurrent CmHandle registration
- `CPS-867 <https://lf-onap.atlassian.net/browse/CPS-867>`_ Database port made configurable through env variable DB_PORT
- `CPS-886 <https://lf-onap.atlassian.net/browse/CPS-886>`_ Fragment handling decreasing performance for large number of cmHandles
- `CPS-887 <https://lf-onap.atlassian.net/browse/CPS-887>`_ Increase performance of cmHandle registration for large number of schema sets in DB
- - `CPS-892 <https://lf-onap.atlassian.net/browse/CPS-892>`_ Fixed the response code during CM-Handle Registration from 201 CREATED to 204 NO_CONTENT
+ - `CPS-892 <https://lf-onap.atlassian.net/browse/CPS-892>`_ Fixed the response code during CM Handle Registration from 201 CREATED to 204 NO_CONTENT
- `CPS-893 <https://lf-onap.atlassian.net/browse/CPS-893>`_ NCMP Java API depends on NCMP-Rest-API (cyclic) through json properties on Java API
Known Limitations, Issues and Workarounds
@@ -1407,9 +1330,9 @@ Known Limitations, Issues and Workarounds
*System Limitations*
-Null can no longer be passed within the dmi plugin service names when registering a cm handle, as part of
+Null can no longer be passed within the dmi plugin service names when registering a CM Handle, as part of
`CPS-837 <https://lf-onap.atlassian.net/browse/CPS-837>`_ null is now used to indicate if a property should be removed as part
-of cm handle registration.
+of CM Handle registration.
The Absolute path to list with integer key will not work. Please refer `CPS-961 <https://lf-onap.atlassian.net/browse/CPS-961>`_
for more information.
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
index b9b1c162e7..3f7b25d2fa 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
@@ -158,11 +158,12 @@ abstract class CpsIntegrationSpecBase extends Specification {
static initialized = false
def now = OffsetDateTime.now()
+ enum ModuleNameStrategy { UNIQUE, OVERLAPPING }
+
def setup() {
if (!initialized) {
cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
- cpsAnchorService.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'owner-of-bookstore-schema-set-do-not-delete')
initialized = true
}
mockDmiServer1.setDispatcher(dmiDispatcher1)
@@ -182,7 +183,7 @@ abstract class CpsIntegrationSpecBase extends Specification {
mockDmiServer1.shutdown()
mockDmiServer2.shutdown()
mockPolicyServer.shutdown()
- cpsModuleService.deleteAllUnusedYangModuleData()
+ cpsModuleService.deleteAllUnusedYangModuleData('NFP-Operational')
}
def static readResourceDataFile(filename) {
@@ -265,9 +266,14 @@ abstract class CpsIntegrationSpecBase extends Specification {
}
def registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(dmiPlugin, moduleSetTag, numberOfCmHandles, offset) {
+ registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(dmiPlugin, moduleSetTag, numberOfCmHandles, offset, ModuleNameStrategy.UNIQUE)
+ }
+
+ def registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(dmiPlugin, moduleSetTag, numberOfCmHandles, offset, ModuleNameStrategy moduleNameStrategy ) {
def cmHandles = []
def id = offset
- def moduleReferences = (1..200).collect { "${moduleSetTag}Module${it}" }
+ def modulePrefix = moduleNameStrategy.OVERLAPPING.equals(moduleNameStrategy) ? 'same' : moduleSetTag
+ def moduleReferences = (1..200).collect { "${modulePrefix}Module${it}" }
(1..numberOfCmHandles).each {
def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: "ch-${id}", moduleSetTag: moduleSetTag, alternateId: NO_ALTERNATE_ID)
cmHandles.add(ncmpServiceCmHandle)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/AnchorServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/AnchorServiceIntegrationSpec.groovy
index 2bd5a4a1be..ca321119ea 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/AnchorServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/AnchorServiceIntegrationSpec.groovy
@@ -59,17 +59,17 @@ class AnchorServiceIntegrationSpec extends FunctionalSpecBase {
and: '1 anchor with "other" schema set is created'
createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE, 'otherSchemaSet')
objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, 'otherSchemaSet', 'anchor3')
- then: 'there are 4 anchors in the general test database'
- assert objectUnderTest.getAnchors(GENERAL_TEST_DATASPACE).size() == 4
- and: 'there are 3 anchors associated with bookstore schema set'
- assert objectUnderTest.getAnchorsBySchemaSetName(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET).size() == 3
+ then: 'there are 3 anchors in the general test database'
+ assert objectUnderTest.getAnchors(GENERAL_TEST_DATASPACE).size() == 3
+ and: 'there are 2 anchors associated with bookstore schema set'
+ assert objectUnderTest.getAnchorsBySchemaSetName(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET).size() == 2
and: 'there is 1 anchor associated with other schema set'
assert objectUnderTest.getAnchorsBySchemaSetName(GENERAL_TEST_DATASPACE, 'otherSchemaSet').size() == 1
}
def 'Querying anchor(name)s (depends on previous test!).'() {
- expect: 'there are now 4 anchors using the "stores" module (both schema sets use the same modules) '
- assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores', 'bookstore-types']).size() == 4
+ expect: 'there are now 3 anchors using the "stores" module (both schema sets use the same modules)'
+ assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores', 'bookstore-types']).size() == 3
and: 'there are no anchors using both "stores" and a "unused-model"'
assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores', 'unused-model']).size() == 0
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/DataspaceServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/DataspaceServiceIntegrationSpec.groovy
index 178b0227ca..47a332adc9 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/DataspaceServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/DataspaceServiceIntegrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -32,8 +32,6 @@ class DataspaceServiceIntegrationSpec extends FunctionalSpecBase {
def setup() { objectUnderTest = cpsDataspaceService }
- def cleanup() { cpsModuleService.deleteAllUnusedYangModuleData() }
-
def 'Dataspace CRUD operations.'() {
when: 'a dataspace is created'
objectUnderTest.createDataspace('newDataspace')
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
index d8010875c1..c787b4209e 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
@@ -61,8 +61,6 @@ class ModuleServiceIntegrationSpec extends FunctionalSpecBase {
def setup() { objectUnderTest = cpsModuleService }
- def cleanup() { objectUnderTest.deleteAllUnusedYangModuleData() }
-
/*
C R E A T E S C H E M A S E T U S E - C A S E S
*/
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy
index 6f063fb222..c4946b48b9 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleCreateSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -178,9 +178,9 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
assert dmiPluginRegistrationResponse.createdCmHandles.sort { it.cmHandle } == [
CmHandleRegistrationResponse.createSuccessResponse('ch-3'),
CmHandleRegistrationResponse.createSuccessResponse('ch-4'),
- CmHandleRegistrationResponse.createFailureResponse('ch-5', NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED),
+ CmHandleRegistrationResponse.createFailureResponse('ch-5', NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST),
CmHandleRegistrationResponse.createSuccessResponse('ch-6'),
- CmHandleRegistrationResponse.createFailureResponse('ch-7', NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED),
+ CmHandleRegistrationResponse.createFailureResponse('ch-7', NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST),
]
cleanup: 'deregister CM handles'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpdateSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpdateSpec.groovy
index f2593ce587..22bbaa81df 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpdateSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpdateSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -76,8 +76,8 @@ class CmHandleUpdateSpec extends CpsIntegrationSpecBase {
def dmiPluginRegistrationResponse =
objectUnderTest.updateDmiRegistration(new DmiPluginRegistration(dmiPlugin: DMI1_URL, updatedCmHandles: [cmHandleToUpdate]))
- then: 'registration gives failure response, due to alternate ID being already associated'
- assert dmiPluginRegistrationResponse.updatedCmHandles == [CmHandleRegistrationResponse.createFailureResponse('ch-1', NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED)]
+ then: 'registration gives failure response, due to cm-handle already existing'
+ assert dmiPluginRegistrationResponse.updatedCmHandles == [CmHandleRegistrationResponse.createFailureResponse('ch-1', NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST)]
and: 'the CM-handle still has the old alternate ID'
assert objectUnderTest.getNcmpServiceCmHandle('ch-1').alternateId == 'original'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy
index 28714fd123..097a043556 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/CmHandleUpgradeSpec.groovy
@@ -79,7 +79,6 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
cleanup: 'deregister CM-handle and remove all associated module resources'
deregisterCmHandle(DMI1_URL, cmHandleId)
- cpsModuleService.deleteAllUnusedYangModuleData()
where: 'following module set tags are used'
initialModuleSetTag | updatedModuleSetTag
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy
index 43db9b208e..81fbc3c4f7 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/ModuleSyncWatchdogIntegrationSpec.groovy
@@ -20,17 +20,18 @@
package org.onap.cps.integration.functional.ncmp
+import com.hazelcast.map.IMap
import io.micrometer.core.instrument.MeterRegistry
-import spock.lang.Ignore
-
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
import org.onap.cps.integration.base.CpsIntegrationSpecBase
import org.onap.cps.ncmp.impl.inventory.sync.ModuleSyncWatchdog
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.util.StopWatch
+import spock.lang.Ignore
import spock.util.concurrent.PollingConditions
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+
class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
ModuleSyncWatchdog objectUnderTest
@@ -38,11 +39,15 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
@Autowired
MeterRegistry meterRegistry
+ @Autowired
+ IMap<String, Integer> cmHandlesByState
+
def executorService = Executors.newFixedThreadPool(2)
def PARALLEL_SYNC_SAMPLE_SIZE = 100
def setup() {
objectUnderTest = moduleSyncWatchdog
+ clearCmHandleStateGauge()
}
def cleanup() {
@@ -64,18 +69,16 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
deregisterSequenceOfCmHandles(DMI1_URL, PARALLEL_SYNC_SAMPLE_SIZE, 1)
}
- @Ignore
- /** this test has intermittent failures, due to timeouts.
+ /** this test has intermittent failures, due to race conditions
* Ignored but left here as it might be valuable to further optimization investigations.
**/
-
+ @Ignore
def 'CPS-2478 Highlight (and improve) module sync inefficiencies.'() {
given: 'register 250 cm handles with module set tag cps-2478-A'
def numberOfTags = 2
def cmHandlesPerTag = 250
def totalCmHandles = numberOfTags * cmHandlesPerTag
def offset = 1
- def minimumBatches = totalCmHandles / 100
registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(DMI1_URL, 'cps-2478-A', cmHandlesPerTag, offset)
and: 'register anther 250 cm handles with module set tag cps-2478-B'
offset += cmHandlesPerTag
@@ -85,23 +88,21 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
when: 'sync all advised cm handles'
objectUnderTest.moduleSyncAdvisedCmHandles()
Thread.sleep(100)
- then: 'retry until both schema sets are stored in db (1 schema set for each module set tag)'
- def dbSchemaSetStorageTimer = meterRegistry.get('cps.module.persistence.schemaset.store').timer()
- new PollingConditions().within(10, () -> {
- objectUnderTest.moduleSyncAdvisedCmHandles()
- Thread.sleep(100)
- assert dbSchemaSetStorageTimer.count() == 2
- })
- then: 'wait till at least 5 batches of state updates are done (often more because of retries of locked cm handles)'
- def dbStateUpdateTimer = meterRegistry.get('cps.ncmp.cmhandle.state.update.batch').timer()
+ then: 'Keep processing until there are no more LOCKED or ADVISED cm handles'
new PollingConditions().within(10, () -> {
- assert dbStateUpdateTimer.count() >= minimumBatches
+ def advised = cmHandlesByState.get('advisedCmHandlesCount')
+ def locked = cmHandlesByState.get('lockedCmHandlesCount')
+ if ( locked > 0 | advised > 0 ) {
+ println "CPS-2576 Need to retry ${locked} LOCKED / ${advised} ADVISED cm Handles"
+ objectUnderTest.moduleSyncAdvisedCmHandles()
+ Thread.sleep(100)
+ }
+ assert cmHandlesByState.get('lockedCmHandlesCount') + cmHandlesByState.get('advisedCmHandlesCount') == 0
})
- and: 'one call to DMI per module set tag to get module references (may be more due to parallel processing of batches)'
- def dmiModuleRetrievalTimer = meterRegistry.get('cps.ncmp.inventory.module.references.from.dmi').timer()
- assert dmiModuleRetrievalTimer.count() >= numberOfTags && dmiModuleRetrievalTimer.count() <= minimumBatches
-
and: 'log the relevant instrumentation'
+ def dmiModuleRetrievalTimer = meterRegistry.get('cps.ncmp.inventory.module.references.from.dmi').timer()
+ def dbSchemaSetStorageTimer = meterRegistry.get('cps.module.persistence.schemaset.store').timer()
+ def dbStateUpdateTimer = meterRegistry.get('cps.ncmp.cmhandle.state.update.batch').timer()
logInstrumentation(dmiModuleRetrievalTimer, 'get modules from DMI ')
logInstrumentation(dbSchemaSetStorageTimer, 'store schema sets ')
logInstrumentation(dbStateUpdateTimer, 'batch state updates ')
@@ -110,7 +111,6 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
def stopWatch = new StopWatch()
stopWatch.start()
deregisterSequenceOfCmHandles(DMI1_URL, totalCmHandles, 1)
- cpsModuleService.deleteAllUnusedYangModuleData()
stopWatch.stop()
println "*** CPS-2478, Deletion of $totalCmHandles cm handles took ${stopWatch.getTotalTimeMillis()} milliseconds"
}
@@ -131,6 +131,30 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
deregisterSequenceOfCmHandles(DMI1_URL, PARALLEL_SYNC_SAMPLE_SIZE, 1)
}
+ /** this test has intermittent failures, due to race conditions
+ * Ignored but left here as it might be valuable to further optimization investigations.
+ **/
+ @Ignore
+ def 'Schema sets with overlapping modules processed at the same time (DB constraint violation).'() {
+ given: 'register one batch (100) cm handles of tag A (with overlapping module names)'
+ registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(DMI1_URL, 'tagA', 100, 1, ModuleNameStrategy.OVERLAPPING)
+ and: 'register another batch cm handles of tag B (with overlapping module names)'
+ registerSequenceOfCmHandlesWithManyModuleReferencesButDoNotWaitForReady(DMI1_URL, 'tagB', 100, 101, ModuleNameStrategy.OVERLAPPING)
+ and: 'populate the work queue with both batches'
+ objectUnderTest.populateWorkQueueIfNeeded()
+ when: 'advised cm handles are processed on 2 threads (exactly one batch for each)'
+ objectUnderTest.moduleSyncAdvisedCmHandles()
+ executorService.execute(moduleSyncAdvisedCmHandles)
+ then: 'wait till all cm handles have been processed'
+ new PollingConditions().within(10, () -> {
+ assert getNumberOfProcessedCmHandles() == 200
+ })
+ then: 'at least 1 cm handle is in state LOCKED'
+ assert cmHandlesByState.get('lockedCmHandlesCount') >= 1
+ cleanup: 'remove all test cm handles'
+ deregisterSequenceOfCmHandles(DMI1_URL, 200, 1)
+ }
+
def 'Populate module sync work queue on two parallel threads with a slight difference in start time.'() {
// This test proved that the issue in CPS-2403 did not arise if the the queue was populated and given time to be distributed
given: 'the queue is empty at the start'
@@ -169,4 +193,21 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
}
}
+ def moduleSyncAdvisedCmHandles = () -> {
+ try {
+ objectUnderTest.moduleSyncAdvisedCmHandles()
+ } catch (InterruptedException e) {
+ e.printStackTrace()
+ }
+ }
+
+ def clearCmHandleStateGauge() {
+ cmHandlesByState.keySet().each { cmHandlesByState.put(it, 0)}
+ }
+
+ def getNumberOfProcessedCmHandles() {
+ return cmHandlesByState.get('readyCmHandlesCount') + cmHandlesByState.get('lockedCmHandlesCount')
+ }
+
+
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy
index 613f760b0c..e52d3f819c 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/ModuleQueryPerfTest.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -100,7 +100,7 @@ class ModuleQueryPerfTest extends CpsPerfTestBase {
cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, (i..i+100).collect {SCHEMA_SET_PREFIX + it})
}
cpsModuleService.deleteSchemaSetsWithCascade(CPS_PERFORMANCE_TEST_DATASPACE, [SCHEMA_SET_PREFIX + '0'])
- cpsModuleService.deleteAllUnusedYangModuleData()
+ cpsModuleService.deleteAllUnusedYangModuleData(CPS_PERFORMANCE_TEST_DATASPACE)
}
// This makes a Yang module of approximately target length in bytes by padding the description field with many '*'
diff --git a/k6-tests/ncmp/common/utils.js b/k6-tests/ncmp/common/utils.js
index 66d2dfe448..6bedb1f949 100644
--- a/k6-tests/ncmp/common/utils.js
+++ b/k6-tests/ncmp/common/utils.js
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
+ * Copyright (C) 2024-2025 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ export const NCMP_BASE_URL = testConfig.hosts.ncmpBaseUrl;
export const DMI_PLUGIN_URL = testConfig.hosts.dmiStubUrl;
export const CONTAINER_UP_TIME_IN_SECONDS = testConfig.hosts.containerUpTimeInSeconds;
export const LEGACY_BATCH_TOPIC_NAME = 'legacy_batch_topic';
-export const TOTAL_CM_HANDLES = 20000;
+export const TOTAL_CM_HANDLES = 50000;
export const REGISTRATION_BATCH_SIZE = 100;
export const READ_DATA_FOR_CM_HANDLE_DELAY_MS = 300; // must have same value as in docker-compose.yml
export const WRITE_DATA_FOR_CM_HANDLE_DELAY_MS = 670; // must have same value as in docker-compose.yml