summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checkstyle/pom.xml2
-rw-r--r--cps-application/pom.xml14
-rw-r--r--cps-bom/pom.xml2
-rw-r--r--cps-dependencies/pom.xml2
-rw-r--r--cps-events/pom.xml2
-rw-r--r--cps-ncmp-events/pom.xml2
-rw-r--r--cps-ncmp-events/src/main/resources/schemas/lcm/lcm-event-schema-v1.json4
-rw-r--r--cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml2
-rw-r--r--cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml2
-rw-r--r--cps-ncmp-rest-stub/pom.xml2
-rw-r--r--cps-ncmp-rest/pom.xml2
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy6
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy31
-rw-r--r--cps-ncmp-service/pom.xml2
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfig.java)16
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java3
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionStatus.java)8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionPredicate.java34
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionCacheObject.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/ScopeFilter.java)6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java52
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java69
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java3
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java9
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java3
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java4
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy17
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy8
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/FilterStrategiesIntegrationSpec.groovy46
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/SerializationIntegrationSpec.groovy35
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfigSpec.groovy63
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfigSpec.groovy64
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy23
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy12
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImplSpec.groovy51
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy17
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy7
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasksSpec.groovy15
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurerSpec.groovy24
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy21
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapperSpec.groovy9
-rw-r--r--cps-parent/pom.xml9
-rw-r--r--cps-path-parser/pom.xml2
-rw-r--r--cps-rest/pom.xml2
-rw-r--r--cps-ri/pom.xml2
-rw-r--r--cps-service/pom.xml2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/ModuleDefinition.java6
-rw-r--r--csit/tests/cps-model-sync/cps-model-sync.robot20
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml2
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml2
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_ResourcesResponse.json12
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_Response.json12
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_ResourcesResponse.json12
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_Response.json12
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_ResourcesResponse.json12
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_Response.json12
-rw-r--r--dmi-plugin-demo-and-csit-stub/pom.xml2
-rw-r--r--docker-compose/docker-compose.yml18
-rw-r--r--docs/api/swagger/ncmp/openapi.yaml41
-rw-r--r--docs/deployment.rst2
-rw-r--r--docs/design.rst6
-rw-r--r--docs/release-notes.rst41
-rw-r--r--integration-test/pom.xml27
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy19
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy11
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy3
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy49
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy3
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy3
-rw-r--r--integration-test/src/test/resources/data/bookstore/bookstore-types.yang18
-rw-r--r--integration-test/src/test/resources/data/bookstore/bookstore.yang20
-rw-r--r--jacoco-report/pom.xml2
-rw-r--r--pom.xml2
-rw-r--r--releases/3.4.3-container.yaml8
-rw-r--r--releases/3.4.3.yaml4
-rw-r--r--spotbugs/pom.xml2
-rw-r--r--version.properties2
82 files changed, 772 insertions, 359 deletions
diff --git a/checkstyle/pom.xml b/checkstyle/pom.xml
index ff4ecb5f1..95794b165 100644
--- a/checkstyle/pom.xml
+++ b/checkstyle/pom.xml
@@ -26,7 +26,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>checkstyle</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<profiles>
<profile>
diff --git a/cps-application/pom.xml b/cps-application/pom.xml
index b3e1fe967..6466bcfe4 100644
--- a/cps-application/pom.xml
+++ b/cps-application/pom.xml
@@ -3,7 +3,7 @@
============LICENSE_START=======================================================
Copyright (c) 2021 Pantheon.tech.
Modifications Copyright (C) 2021 Bell Canada.
- Modifications Copyright (C) 2021-2023 Nordix Foundation
+ Modifications Copyright (C) 2021-2024 Nordix Foundation
Modifications Copyright (C) 2022 Deutsche Telekom AG
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,7 +28,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
@@ -183,6 +183,16 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ <configuration>
+ <classifier>springboot</classifier>
+ </configuration>
+ </execution>
+ </executions>
</plugin>
</plugins>
</build>
diff --git a/cps-bom/pom.xml b/cps-bom/pom.xml
index 54d7602cb..ecd442cf4 100644
--- a/cps-bom/pom.xml
+++ b/cps-bom/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-bom</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<packaging>pom</packaging>
<description>This artifact contains dependencyManagement declarations of all published CPS components.</description>
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index e7eb576ce..2f1a4d2d8 100644
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -27,7 +27,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-dependencies</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}:${project.artifactId}</name>
diff --git a/cps-events/pom.xml b/cps-events/pom.xml
index b1fd6f993..662d150a5 100644
--- a/cps-events/pom.xml
+++ b/cps-events/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-events/pom.xml b/cps-ncmp-events/pom.xml
index 36c69c69a..6e638438c 100644
--- a/cps-ncmp-events/pom.xml
+++ b/cps-ncmp-events/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-events/src/main/resources/schemas/lcm/lcm-event-schema-v1.json b/cps-ncmp-events/src/main/resources/schemas/lcm/lcm-event-schema-v1.json
index 7006b7836..e687303f8 100644
--- a/cps-ncmp-events/src/main/resources/schemas/lcm/lcm-event-schema-v1.json
+++ b/cps-ncmp-events/src/main/resources/schemas/lcm/lcm-event-schema-v1.json
@@ -39,6 +39,10 @@
"description": "cmHandle id",
"type": "string"
},
+ "alternateId": {
+ "description": "alternative id for cmHandle (e.g. 3GPP FDN)",
+ "type": "string"
+ },
"oldValues": {
"$ref": "#/definitions/Values"
},
diff --git a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
index cdd9eefe0..25d4939eb 100644
--- a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
+++ b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-ncmp-rest-stub</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
</parent>
<artifactId>cps-ncmp-rest-stub-app</artifactId>
diff --git a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
index 695065a48..1a8e89b68 100644
--- a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
+++ b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-ncmp-rest-stub</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
</parent>
<artifactId>cps-ncmp-rest-stub-service</artifactId>
diff --git a/cps-ncmp-rest-stub/pom.xml b/cps-ncmp-rest-stub/pom.xml
index a1c5ee04f..a35a88662 100644
--- a/cps-ncmp-rest-stub/pom.xml
+++ b/cps-ncmp-rest-stub/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml
index 27c640a63..f363c01f6 100644
--- a/cps-ncmp-rest/pom.xml
+++ b/cps-ncmp-rest/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy
index f06af6c10..4edbf3569 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy
@@ -44,7 +44,7 @@ class NcmpDatastoreRequestHandlerSpec extends Specification {
def 'Attempt to execute async get request with #scenario.'() {
given: 'notification feature is turned on/off'
objectUnderTest.notificationFeatureEnabled = notificationFeatureEnabled
- and: ' a flag to track the network service call'
+ and: 'a flag to track the network service call'
def networkServiceMethodCalled = false
and: 'the (mocked) service will use the flag to indicate if it is called'
mockNetworkCmProxyDataService.getResourceDataForCmHandle('ds', 'ch1', 'resource1', 'options', _, _) >> {
@@ -54,7 +54,7 @@ class NcmpDatastoreRequestHandlerSpec extends Specification {
objectUnderTest.executeRequest('ds', 'ch1', 'resource1', 'options', topic, false)
then: 'the task is executed in an async fashion or not'
expectedCalls * spiedCpsNcmpTaskExecutor.executeTask(*_)
- and: 'the service request is always invoked within 1 seconds'
+ and: 'the service request is invoked'
new PollingConditions().within(1) {
assert networkServiceMethodCalled == true
}
@@ -97,7 +97,7 @@ class NcmpDatastoreRequestHandlerSpec extends Specification {
objectUnderTest.executeRequest('myTopic', dataOperationRequest)
then: 'the task is executed in an async fashion'
1 * spiedCpsNcmpTaskExecutor.executeTask(*_)
- and: 'the network service is invoked within 1 seconds'
+ and: 'the network service is invoked'
new PollingConditions().within(1) {
assert networkServiceMethodCalled == true
}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy
index 55590168d..010eda964 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,10 +24,9 @@ import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.read.ListAppender
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
import org.slf4j.LoggerFactory
import spock.lang.Specification
+import spock.util.concurrent.PollingConditions
class CpsNcmpTaskExecutorSpec extends Specification {
@@ -35,25 +34,23 @@ class CpsNcmpTaskExecutorSpec extends Specification {
def logger = Spy(ListAppender<ILoggingEvent>)
def enoughTime = 100
- @BeforeEach
void setup() {
- ((Logger) LoggerFactory.getLogger(CpsNcmpTaskExecutor.class)).addAppender(logger);
- logger.start();
+ ((Logger) LoggerFactory.getLogger(CpsNcmpTaskExecutor.class)).addAppender(logger)
+ logger.start()
}
- @AfterEach
- void teardown() {
- ((Logger) LoggerFactory.getLogger(CpsNcmpTaskExecutor.class)).detachAndStopAllAppenders();
+ void cleanup() {
+ ((Logger) LoggerFactory.getLogger(CpsNcmpTaskExecutor.class)).detachAndStopAllAppenders()
}
def 'Execute successful task.'() {
when: 'task is executed'
objectUnderTest.executeTask(taskSupplier(), enoughTime)
- and: 'wait a little for async execution completion'
- Thread.sleep(10)
then: 'an event is logged with level INFO'
- def loggingEvent = getLoggingEvent()
- assert loggingEvent.level == Level.INFO
+ new PollingConditions().within(1) {
+ def loggingEvent = getLoggingEvent()
+ assert loggingEvent.level == Level.INFO
+ }
and: 'the log indicates the task completed successfully'
assert loggingEvent.formattedMessage == 'Async task completed successfully.'
}
@@ -61,11 +58,11 @@ class CpsNcmpTaskExecutorSpec extends Specification {
def 'Execute failing task.'() {
when: 'task is executed'
objectUnderTest.executeTask(taskSupplierForFailingTask(), enoughTime)
- and: 'wait a little for async execution completion'
- Thread.sleep(10)
then: 'an event is logged with level ERROR'
- def loggingEvent = getLoggingEvent()
- assert loggingEvent.level == Level.ERROR
+ new PollingConditions().within(1) {
+ def loggingEvent = getLoggingEvent()
+ assert loggingEvent.level == Level.ERROR
+ }
and: 'the original error message is logged'
assert loggingEvent.formattedMessage.contains('original exception message')
}
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index 93c60fa53..9beb6b7b0 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 4fc840929..05b83b98e 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -107,6 +107,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
private final TrustLevelManager trustLevelManager;
private final CmHandleIdMapper cmHandleIdMapper;
+ private final Map<String, Collection<ModuleReference>> moduleSetTagCache;
@Override
public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
@@ -353,13 +354,16 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
new ArrayList<>(tobeRemovedCmHandles.size());
final Collection<YangModelCmHandle> yangModelCmHandles =
inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandles);
-
+ final Set<String> moduleSetTags = yangModelCmHandles.stream().map(YangModelCmHandle::getModuleSetTag)
+ .collect(Collectors.toSet());
updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING);
final Set<String> notDeletedCmHandles = new HashSet<>();
for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandles, DELETE_BATCH_SIZE)) {
try {
batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
+ moduleSetTags.forEach(moduleSetTagCache::remove);
+ log.debug("Removed module set tags: {}", moduleSetTags);
tobeRemovedCmHandleBatch.forEach(cmHandleId ->
cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)));
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java
index 8b429d44c..1d6da90a9 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfig.java
@@ -24,26 +24,26 @@ import com.hazelcast.config.MapConfig;
import com.hazelcast.map.IMap;
import java.util.Map;
import org.onap.cps.cache.HazelcastCacheConfig;
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmSubscriptionCacheObject;
+import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
-public class CmSubscriptionEventCacheConfig extends HazelcastCacheConfig {
+public class CmNotificationSubscriptionCacheConfig extends HazelcastCacheConfig {
- private static final MapConfig cmSubscriptionEventCacheMapConfig =
- createMapConfig("cmSubscriptionEventCacheMapConfig");
+ private static final MapConfig cmNotificationSubscriptionCacheMapConfig =
+ createMapConfig("cmNotificationSubscriptionCacheMapConfig");
/**
- * Distributed instance of cm subscription information
+ * Distributed instance of cm notification subscription information
* cache that contains subscription id as key
* and incoming event data processed per dmi plugin.
*
* @return configured map of subscription events.
*/
@Bean
- public IMap<String, Map<String, CmSubscriptionCacheObject>> cmSubscriptionEventCache() {
- return createHazelcastInstance("hazelCastInstanceCmSubscriptionEvents",
- cmSubscriptionEventCacheMapConfig).getMap("cmSubscriptionEventCache");
+ public IMap<String, Map<String, DmiCmNotificationSubscriptionDetails>> cmNotificationSubscriptionCache() {
+ return createHazelcastInstance("hazelCastInstanceCmNotificationSubscription",
+ cmNotificationSubscriptionCacheMapConfig).getMap("cmNotificationSubscriptionCache");
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java
index 514967574..4f2674aca 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfig.java
@@ -21,6 +21,7 @@
package org.onap.cps.ncmp.api.impl.config.kafka;
import io.cloudevents.CloudEvent;
+import java.time.Duration;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.apache.kafka.clients.producer.ProducerConfig;
@@ -99,6 +100,7 @@ public class KafkaConfig<T> {
final ConcurrentKafkaListenerContainerFactory<String, T> containerFactory =
new ConcurrentKafkaListenerContainerFactory<>();
containerFactory.setConsumerFactory(legacyEventConsumerFactory());
+ containerFactory.getContainerProperties().setAuthExceptionRetryInterval(Duration.ofSeconds(10));
return containerFactory;
}
@@ -150,6 +152,7 @@ public class KafkaConfig<T> {
final ConcurrentKafkaListenerContainerFactory<String, CloudEvent> containerFactory =
new ConcurrentKafkaListenerContainerFactory<>();
containerFactory.setConsumerFactory(cloudEventConsumerFactory());
+ containerFactory.getContainerProperties().setAuthExceptionRetryInterval(Duration.ofSeconds(10));
return containerFactory;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionStatus.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java
index 0bc3cbe93..68d54fac9 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionStatus.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmNotificationSubscriptionStatus.java
@@ -20,13 +20,13 @@
package org.onap.cps.ncmp.api.impl.events.cmsubscription.model;
-public enum CmSubscriptionStatus {
+public enum CmNotificationSubscriptionStatus {
ACCEPTED("ACCEPTED"), REJECTED("REJECTED"), PENDING("PENDING");
- private final String cmSubscriptionStatusValue;
+ private final String cmNotificationSubscriptionStatusValue;
- CmSubscriptionStatus(final String cmSubscriptionStatusValue) {
- this.cmSubscriptionStatusValue = cmSubscriptionStatusValue;
+ CmNotificationSubscriptionStatus(final String cmNotificationSubscriptionStatusValue) {
+ this.cmNotificationSubscriptionStatusValue = cmNotificationSubscriptionStatusValue;
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionPredicate.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionPredicate.java
deleted file mode 100644
index 262126ef1..000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionPredicate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.events.cmsubscription.model;
-
-import java.util.List;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class CmSubscriptionPredicate {
-
- private List<String> targetFilter;
- private ScopeFilter scopeFilter;
-
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionCacheObject.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java
index 2888a6734..4f6caefce 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/CmSubscriptionCacheObject.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionDetails.java
@@ -26,8 +26,8 @@ import lombok.Setter;
@Getter
@Setter
-public class CmSubscriptionCacheObject {
+public class DmiCmNotificationSubscriptionDetails {
- private List<CmSubscriptionPredicate> cmSubscriptionPredicates;
- private CmSubscriptionStatus cmSubscriptionStatus;
+ private List<DmiCmNotificationSubscriptionPredicate> dmiCmNotificationSubscriptionPredicates;
+ private CmNotificationSubscriptionStatus cmNotificationSubscriptionStatus;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/ScopeFilter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java
index b9ca68761..65365808d 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/ScopeFilter.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/model/DmiCmNotificationSubscriptionPredicate.java
@@ -27,8 +27,10 @@ import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
@Getter
@Setter
-public class ScopeFilter {
+public class DmiCmNotificationSubscriptionPredicate {
+ private List<String> targetCmHandleIds;
private DatastoreType datastoreType;
- private List<String> xpathFilters;
+ private List<String> xpaths;
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java
new file mode 100644
index 000000000..189fbb53d
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceService.java
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.events.cmsubscription.service;
+
+import java.util.Collection;
+import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
+
+public interface CmNotificationSubscriptionPersistenceService {
+
+ String NCMP_DATASPACE_NAME = "NCMP-Admin";
+ String CM_SUBSCRIPTIONS_ANCHOR_NAME = "cm-data-subscriptions";
+
+ /**
+ * Check if we have an ongoing cm subscription based on the parameters.
+ *
+ * @param datastoreType valid datastore type
+ * @param cmHandleId cmhandle id
+ * @param xpath valid xpath
+ * @return true for ongoing cmsubscription , otherwise false
+ */
+ boolean isOngoingCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
+ final String xpath);
+
+ /**
+ * Get all ongoing cm notification subscription based on the parameters.
+ *
+ * @param datastoreType valid datastore type
+ * @param cmHandleId cmhandle id
+ * @param xpath valid xpath
+ * @return collection of subscription ids of ongoing cm notification subscription
+ */
+ Collection<String> getOngoingCmNotificationSubscriptionIds(final DatastoreType datastoreType,
+ final String cmHandleId, final String xpath);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java
new file mode 100644
index 000000000..ca9adb36b
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImpl.java
@@ -0,0 +1,69 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.events.cmsubscription.service;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.api.CpsQueryService;
+import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
+import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.spi.model.DataNode;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class CmNotificationSubscriptionPersistenceServiceImpl implements CmNotificationSubscriptionPersistenceService {
+
+ private static final String IS_ONGOING_CM_SUBSCRIPTION_CPS_PATH_QUERY = """
+ /datastores/datastore[@name='%s']/cm-handles/cm-handle[@id='%s']/filters/filter[@xpath='%s']""";
+
+ private final CpsQueryService cpsQueryService;
+
+ @Override
+ public boolean isOngoingCmNotificationSubscription(final DatastoreType datastoreType, final String cmHandleId,
+ final String xpath) {
+ return !getOngoingCmNotificationSubscriptionIds(datastoreType, cmHandleId, xpath).isEmpty();
+ }
+
+ @Override
+ public Collection<String> getOngoingCmNotificationSubscriptionIds(final DatastoreType datastoreType,
+ final String cmHandleId, final String xpath) {
+
+ final String isOngoingCmSubscriptionCpsPathQuery =
+ IS_ONGOING_CM_SUBSCRIPTION_CPS_PATH_QUERY.formatted(datastoreType.getDatastoreName(), cmHandleId,
+ escapeQuotesByDoublingThem(xpath));
+ final Collection<DataNode> existingNodes =
+ cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, CM_SUBSCRIPTIONS_ANCHOR_NAME,
+ isOngoingCmSubscriptionCpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS);
+ if (existingNodes.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return (List<String>) existingNodes.iterator().next().getLeaves().get("subscribers");
+ }
+
+ private static String escapeQuotesByDoublingThem(final String inputXpath) {
+ return inputXpath.replace("'", "''");
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java
index 450bc8cce..23d508b07 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreator.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -95,6 +95,7 @@ public class LcmEventsCreator {
final NcmpServiceCmHandle existingNcmpServiceCmHandle, final LcmEventType lcmEventType) {
final Event event = new Event();
event.setCmHandleId(eventCorrelationId);
+ event.setAlternateId(targetNcmpServiceCmHandle.getAlternateId());
final CmHandleValuesHolder cmHandleValuesHolder =
LcmEventsCreatorHelper.determineEventValues(targetNcmpServiceCmHandle, existingNcmpServiceCmHandle,
lcmEventType);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java
index 750be2dc8..22bbc7383 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -68,6 +68,10 @@ public class ModuleOperationsUtils {
private static final String LOCK_REASON_DETAILS_MSG_FORMAT = UPGRADE_FORMAT + " Attempt #%d failed: %s";
private static final Pattern retryAttemptPattern = Pattern.compile("Attempt #(\\d+) failed:.+");
private static final Pattern moduleSetTagPattern = Pattern.compile("Upgrade to ModuleSetTag: (\\S+)");
+ private static final String CPS_PATH_CM_HANDLES_MODEL_SYNC_FAILED_OR_UPGRADE = """
+ //lock-reason[@reason="MODULE_SYNC_FAILED"
+ or @reason="MODULE_UPGRADE"
+ or @reason="MODULE_UPGRADE_FAILED"]""";
/**
* Query data nodes for cm handles with an "ADVISED" cm handle state.
@@ -110,8 +114,7 @@ public class ModuleOperationsUtils {
*/
public List<YangModelCmHandle> getCmHandlesThatFailedModelSyncOrUpgrade() {
final List<DataNode> lockedCmHandlesAsDataNodeList
- = cmHandleQueries.queryCmHandleAncestorsByCpsPath(
- "//lock-reason[@reason=\"MODULE_SYNC_FAILED\" or @reason=\"MODULE_UPGRADE\"]",
+ = cmHandleQueries.queryCmHandleAncestorsByCpsPath(CPS_PATH_CM_HANDLES_MODEL_SYNC_FAILED_OR_UPGRADE,
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
return convertCmHandlesDataNodesToYangModelCmHandles(lockedCmHandlesAsDataNodeList);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java
index b21a2f1f8..72d322605 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,6 +91,9 @@ public class ModuleSyncService {
existingAnchorName, inUpgrade);
updateModuleSetTagCache(moduleSetTag, moduleReferencesFromExistingCmHandle);
} else {
+ if (inUpgrade) {
+ deleteSchemaSetIfExists(cmHandleId);
+ }
final Collection<ModuleReference> allModuleReferencesFromCmHandle
= syncAndCreateSchemaSet(yangModelCmHandle);
updateModuleSetTagCache(moduleSetTag, allModuleReferencesFromCmHandle);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java
index 8175fb5e7..a88adbd11 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java
@@ -73,7 +73,13 @@ public class CmHandleIdMapper {
public void removeMapping(final String cmHandleId) {
final String alternateId = alternateIdPerCmHandleId.remove(cmHandleId);
- cmHandleIdPerAlternateId.remove(alternateId);
+ removeAlternateIdWithValidation(alternateId);
+ }
+
+ private void removeAlternateIdWithValidation(final String alternateId) {
+ if (alternateId != null) {
+ cmHandleIdPerAlternateId.remove(alternateId);
+ }
}
private void initializeCache() {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
index b54c154b2..3be97e8ee 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,6 +54,7 @@ public class YangDataConverter {
final List<YangModelCmHandle.Property> publicProperties = yangModelCmHandle.getPublicProperties();
ncmpServiceCmHandle.setCmHandleId(yangModelCmHandle.getId());
ncmpServiceCmHandle.setCompositeState(yangModelCmHandle.getCompositeState());
+ ncmpServiceCmHandle.setAlternateId(yangModelCmHandle.getAlternateId());
setDmiProperties(dmiProperties, ncmpServiceCmHandle);
setPublicProperties(publicProperties, ncmpServiceCmHandle);
return ncmpServiceCmHandle;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
index ba36b1a54..03e53fc42 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2021-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -119,7 +119,7 @@ public class YangModelCmHandle {
yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName);
yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName);
yangModelCmHandle.setModuleSetTag(moduleSetTag == null ? StringUtils.EMPTY : moduleSetTag);
- yangModelCmHandle.setAlternateId(alternateId);
+ yangModelCmHandle.setAlternateId(alternateId == null ? StringUtils.EMPTY : alternateId);
yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
ncmpServiceCmHandle.getPublicProperties()));
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
index 59bf9420c..c7ac8ab8b 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
@@ -21,16 +21,15 @@
package org.onap.cps.ncmp.api.impl
-import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager
-import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper
-import org.onap.cps.ncmp.api.models.UpgradedCmHandles
-
+import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status
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.api.NcmpResponseStatus.UNKNOWN_ERROR
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status
+import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager
+import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper
+import org.onap.cps.ncmp.api.models.UpgradedCmHandles
import com.fasterxml.jackson.databind.ObjectMapper
import com.hazelcast.map.IMap
import org.onap.cps.api.CpsDataService
@@ -52,14 +51,11 @@ import org.onap.cps.spi.exceptions.DataNodeNotFoundException
import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.exceptions.SchemaSetNotFoundException
import org.onap.cps.utils.JsonObjectMapper
-import spock.lang.Shared
import spock.lang.Specification
class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
- @Shared
def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id')
-
def mockCpsModuleService = Mock(CpsModuleService)
def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
def mockDmiDataOperations = Mock(DmiDataOperations)
@@ -74,6 +70,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def mockTrustLevelManager = Mock(TrustLevelManager)
def mockCmHandleIdMapper = Mock(CmHandleIdMapper)
def objectUnderTest = getObjectUnderTest()
+ def mockModuleSetTagCache = [:]
def 'DMI Registration: Create, Update, Delete & Upgrade operations are processed in the right order'() {
given: 'a registration with operations of all types'
@@ -91,7 +88,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
then: 'cm-handles are removed first'
1 * objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_)
and: 'de-registered cm handle entry is removed from in progress map'
- 1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle-2')
+ 2 * mockModuleSyncStartedOnCmHandles.remove('cmhandle-2')
then: 'cm-handles are created'
1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_)
then: 'cm-handles are updated'
@@ -448,7 +445,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries,
stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService,
- mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin as Map<String, TrustLevel>, mockTrustLevelManager, mockCmHandleIdMapper))
+ mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin, mockTrustLevelManager, mockCmHandleIdMapper, mockModuleSetTagCache))
}
def addPersistedYangModelCmHandles(ids) {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
index 49583cec3..c835056f3 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
@@ -23,8 +23,6 @@
package org.onap.cps.ncmp.api.impl
-import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper
-
import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME
import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR
@@ -34,6 +32,7 @@ import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RU
import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE
import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE
+import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper
import com.hazelcast.map.IMap
import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService
import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler
@@ -82,6 +81,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
def stubTrustLevelPerDmiPlugin = Stub(Map<String, TrustLevel>)
def mockTrustLevelManager = Mock(TrustLevelManager)
def mockCmHandleIdMapper = Mock(CmHandleIdMapper)
+ def mockModuleSetTagCache = [:]
def NO_TOPIC = null
def NO_REQUEST_ID = null
@@ -102,8 +102,8 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
stubModuleSyncStartedOnCmHandles,
stubTrustLevelPerDmiPlugin,
mockTrustLevelManager,
- mockCmHandleIdMapper
- )
+ mockCmHandleIdMapper,
+ mockModuleSetTagCache)
def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/FilterStrategiesIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/FilterStrategiesIntegrationSpec.groovy
index bb082fd7f..fba1f953f 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/FilterStrategiesIntegrationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/FilterStrategiesIntegrationSpec.groovy
@@ -23,7 +23,6 @@ package org.onap.cps.ncmp.api.impl.async
import io.cloudevents.core.builder.CloudEventBuilder
import org.onap.cps.events.EventsPublisher
import org.onap.cps.ncmp.api.impl.config.kafka.KafkaConfig
-
import org.onap.cps.ncmp.api.kafka.ConsumerBaseSpec
import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent
import org.spockframework.spring.SpringBean
@@ -32,6 +31,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.annotation.DirtiesContext
import org.testcontainers.spock.Testcontainers
+import spock.util.concurrent.PollingConditions
import java.util.concurrent.TimeUnit
@SpringBootTest(classes =[DataOperationEventConsumer, AsyncRestRequestResponseEventConsumer, RecordFilterStrategies, KafkaConfig])
@@ -50,28 +50,34 @@ class FilterStrategiesIntegrationSpec extends ConsumerBaseSpec {
def topic
def 'Legacy event consumer with cloud event.'() {
- given: 'a cloud event of type: #eventType'
+ given: 'a data operation cloud event type'
def cloudEvent = CloudEventBuilder.v1().withId('some id')
.withType('DataOperationEvent')
.withSource(URI.create('some-source'))
.build()
when: 'send the cloud event'
cloudEventKafkaTemplate.send(topic, cloudEvent)
- and: 'wait a little for async processing of message'
+ then: 'wait a little for async processing of message (must wait to try to avoid false positives)'
TimeUnit.MILLISECONDS.sleep(300)
- then: 'event is not consumed'
+ and: 'event is not consumed'
0 * mockEventsPublisher.publishEvent(*_)
}
def 'Legacy event consumer with valid legacy event.'() {
- given: 'a cloud event of type: #eventType'
+ given: 'a legacy event'
DmiAsyncRequestResponseEvent legacyEvent = new DmiAsyncRequestResponseEvent(eventId:'legacyEventId', eventTarget:'legacyEventTarget')
+ and: 'a flag to track the publish event call'
+ def publishEventMethodCalled = false
+ and: 'the (mocked) events publisher will use the flag to indicate if it is called'
+ mockEventsPublisher.publishEvent(*_) >> {
+ publishEventMethodCalled = true
+ }
when: 'send the cloud event'
legacyEventKafkaTemplate.send(topic, legacyEvent)
- and: 'wait a little for async processing of message'
- TimeUnit.MILLISECONDS.sleep(300)
then: 'the event is consumed by the (legacy) AsynRestRequest consumer'
- 1 * mockEventsPublisher.publishEvent(*_)
+ new PollingConditions().within(1) {
+ assert publishEventMethodCalled == true
+ }
}
def 'Filtering Cloud Events on Type.'() {
@@ -80,17 +86,23 @@ class FilterStrategiesIntegrationSpec extends ConsumerBaseSpec {
.withType(eventType)
.withSource(URI.create('some-source'))
.build()
+ and: 'a flag to track the publish event call'
+ def publishEventMethodCalled = false
+ and: 'the (mocked) events publisher will use the flag to indicate if it is called'
+ mockEventsPublisher.publishCloudEvent(*_) >> {
+ publishEventMethodCalled = true
+ }
when: 'send the cloud event'
cloudEventKafkaTemplate.send(topic, cloudEvent)
- and: 'wait a little for async processing of message'
- TimeUnit.MILLISECONDS.sleep(300)
then: 'the event has only been forwarded for the correct type'
- expectedNUmberOfCallsToPublishForwardedEvent * mockEventsPublisher.publishCloudEvent(*_)
+ new PollingConditions(initialDelay: 0.3).within(1) {
+ assert publishEventMethodCalled == expectCallToPublishEventMethod
+ }
where: 'the following event types are used'
- eventType || expectedNUmberOfCallsToPublishForwardedEvent
- 'DataOperationEvent' || 1
- 'other type' || 0
- 'any type contain the word "DataOperationEvent"' || 1
+ eventType || expectCallToPublishEventMethod
+ 'DataOperationEvent' || true
+ 'other type' || false
+ 'any type contain the word "DataOperationEvent"' || true
}
//TODO Toine, add positive test with data to prove event is converted correctly (using correct factory)
@@ -98,9 +110,9 @@ class FilterStrategiesIntegrationSpec extends ConsumerBaseSpec {
def 'Non cloud events on same Topic.'() {
when: 'sending a non-cloud event on the same topic'
legacyEventKafkaTemplate.send(topic, 'simple string event')
- and: 'wait a little for async processing of message'
+ then: 'wait a little for async processing of message (must wait to try to avoid false positives)'
TimeUnit.MILLISECONDS.sleep(300)
- then: 'the event is not processed by this consumer'
+ and: 'the event is not processed by this consumer'
0 * mockEventsPublisher.publishCloudEvent(*_)
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/SerializationIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/SerializationIntegrationSpec.groovy
index 212c6734e..ee8933300 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/SerializationIntegrationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/async/SerializationIntegrationSpec.groovy
@@ -24,7 +24,6 @@ import com.fasterxml.jackson.databind.ObjectMapper
import io.cloudevents.core.builder.CloudEventBuilder
import org.onap.cps.events.EventsPublisher
import org.onap.cps.ncmp.api.impl.config.kafka.KafkaConfig
-
import org.onap.cps.ncmp.api.kafka.ConsumerBaseSpec
import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent
import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent
@@ -38,8 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.annotation.DirtiesContext
import org.testcontainers.spock.Testcontainers
-
-import java.util.concurrent.TimeUnit
+import spock.util.concurrent.PollingConditions
@SpringBootTest(classes =[DataOperationEventConsumer, AsyncRestRequestResponseEventConsumer, RecordFilterStrategies, KafkaConfig])
@DirtiesContext
@@ -59,33 +57,38 @@ class SerializationIntegrationSpec extends ConsumerBaseSpec {
@Value('${app.ncmp.async-m2m.topic}')
def topic
- def capturedForwardedEvent
-
def 'Forwarding DataOperation Event Data.'() {
given: 'a data operation cloud event'
def cloudEvent = createCloudEvent()
+ and: 'a flag to track the publish cloud event call'
+ def publishCloudEventMethodCalled = false
+ and: 'the (mocked) events publisher will use the flag to indicate if it is called and will capture the cloud event'
+ mockEventsPublisher.publishCloudEvent('some client topic', 'some-correlation-id', cloudEvent) >> {
+ publishCloudEventMethodCalled = true
+ }
when: 'send the event'
cloudEventKafkaTemplate.send(topic, cloudEvent)
- and: 'wait a little for async processing of message'
- TimeUnit.MILLISECONDS.sleep(300)
then: 'the event has been forwarded'
- 1 * mockEventsPublisher.publishCloudEvent('some client topic', 'some-correlation-id', _) >> { args -> { capturedForwardedEvent = args[2] } }
- and: 'the forwarded event is identical to the event that was sent'
- assert capturedForwardedEvent == cloudEvent
+ new PollingConditions().within(1) {
+ assert publishCloudEventMethodCalled == true
+ }
}
def 'Forwarding AsyncRestRequestResponse Event Data.'() {
given: 'async request response legacy event'
def dmiAsyncRequestResponseEvent = new DmiAsyncRequestResponseEvent(eventId: 'my-event-id',eventTarget: 'some client topic')
+ and: 'a flag to track the publish event call'
+ def publishEventMethodCalled = false
+ and: 'the (mocked) events publisher will use the flag to indicate if it is called and will capture the event'
+ mockEventsPublisher.publishEvent(*_) >> {
+ publishEventMethodCalled = true
+ }
when: 'send the event'
legacyEventKafkaTemplate.send(topic, dmiAsyncRequestResponseEvent)
- and: 'wait a little for async processing of message'
- TimeUnit.MILLISECONDS.sleep(300)
then: 'the event has been forwarded'
- 1 * mockEventsPublisher.publishEvent('some client topic', 'my-event-id', _) >> { args -> { capturedForwardedEvent = args[2] } }
- and: 'the captured id and target of the forwarded event is same as the one that was sent'
- assert capturedForwardedEvent.eventId == dmiAsyncRequestResponseEvent.eventId
- assert capturedForwardedEvent.eventTarget == dmiAsyncRequestResponseEvent.eventTarget
+ new PollingConditions().within(1) {
+ assert publishEventMethodCalled == true
+ }
}
def createCloudEvent() {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfigSpec.groovy
new file mode 100644
index 000000000..a3f41c8ef
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmNotificationSubscriptionCacheConfigSpec.groovy
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.config.embeddedcache
+
+import com.hazelcast.core.Hazelcast
+import com.hazelcast.map.IMap
+import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmNotificationSubscriptionStatus
+import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionDetails
+import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.DmiCmNotificationSubscriptionPredicate
+import org.onap.cps.ncmp.api.impl.operations.DatastoreType
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import spock.lang.Specification
+
+@SpringBootTest(classes = [CmNotificationSubscriptionCacheConfig])
+class CmNotificationSubscriptionCacheConfigSpec extends Specification {
+
+ @Autowired
+ IMap<String, Map<String, DmiCmNotificationSubscriptionDetails>> cmNotificationSubscriptionCache;
+
+ def 'Embedded (hazelcast) cache for Cm Notification Subscription Cache.'() {
+ expect: 'system is able to create an instance of the Cm Notification Subscription Cache'
+ assert null != cmNotificationSubscriptionCache
+ and: 'there is at least 1 instance'
+ assert Hazelcast.allHazelcastInstances.size() > 0
+ and: 'Cm Notification Subscription Cache is present'
+ assert Hazelcast.allHazelcastInstances.name.contains('hazelCastInstanceCmNotificationSubscription')
+ }
+
+ def 'Provided CM Subscription data'() {
+ given: 'a cm subscription properties'
+ def subscriptionId = 'sub123'
+ def dmiPluginName = 'dummydmi'
+ def cmSubscriptionPredicate = new DmiCmNotificationSubscriptionPredicate(targetCmHandleIds: ['cmhandle1', 'cmhandle2'], datastoreType: DatastoreType.PASSTHROUGH_RUNNING, xpaths: ['/a/b/c'])
+ def cmSubscriptionCacheObject = new DmiCmNotificationSubscriptionDetails(dmiCmNotificationSubscriptionPredicates: [cmSubscriptionPredicate], cmNotificationSubscriptionStatus: CmNotificationSubscriptionStatus.PENDING)
+ when: 'the cache is populated'
+ cmNotificationSubscriptionCache.put(subscriptionId, [(dmiPluginName): cmSubscriptionCacheObject])
+ then: 'the values are present in memory'
+ assert cmNotificationSubscriptionCache.get(subscriptionId) != null
+ and: 'properties match'
+ assert dmiPluginName == cmNotificationSubscriptionCache.get(subscriptionId).keySet()[0]
+ assert cmSubscriptionCacheObject.cmNotificationSubscriptionStatus == cmNotificationSubscriptionCache.get(subscriptionId).values().cmNotificationSubscriptionStatus[0]
+ assert cmSubscriptionCacheObject.dmiCmNotificationSubscriptionPredicates[0].targetCmHandleIds == cmNotificationSubscriptionCache.get(subscriptionId).values().dmiCmNotificationSubscriptionPredicates[0].targetCmHandleIds[0]
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfigSpec.groovy
deleted file mode 100644
index f1eae14d9..000000000
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/CmSubscriptionEventCacheConfigSpec.groovy
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.config.embeddedcache
-
-import com.hazelcast.core.Hazelcast
-import com.hazelcast.map.IMap
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmSubscriptionCacheObject
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmSubscriptionPredicate
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.CmSubscriptionStatus
-import org.onap.cps.ncmp.api.impl.events.cmsubscription.model.ScopeFilter
-import org.onap.cps.ncmp.api.impl.operations.DatastoreType
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-import spock.lang.Specification
-
-@SpringBootTest(classes = [CmSubscriptionEventCacheConfig])
-class CmSubscriptionEventCacheConfigSpec extends Specification {
-
- @Autowired
- IMap<String, Map<String, CmSubscriptionCacheObject>> cmSubscriptionEventCache;
-
- def 'Embedded (hazelcast) cache for Cm Subscription Event Cache.'() {
- expect: 'system is able to create an instance of the Forwarded Subscription Event Cache'
- assert null != cmSubscriptionEventCache
- and: 'there is at least 1 instance'
- assert Hazelcast.allHazelcastInstances.size() > 0
- and: 'Forwarded Subscription Event Cache is present'
- assert Hazelcast.allHazelcastInstances.name.contains('hazelCastInstanceCmSubscriptionEvents')
- }
-
- def 'Provided CM Subscription data'() {
- given: 'a cm subscription properties'
- def subscriptionId = 'sub123'
- def dmiPluginName = 'dummydmi'
- def cmSubscriptionPredicate = new CmSubscriptionPredicate(targetFilter: ['cmhandle1', 'cmhandle2'], scopeFilter: new ScopeFilter(datastoreType: DatastoreType.PASSTHROUGH_RUNNING, xpathFilters: ['/a/b/c']))
- def cmSubscriptionCacheObject = new CmSubscriptionCacheObject(cmSubscriptionPredicates: [cmSubscriptionPredicate] , cmSubscriptionStatus: CmSubscriptionStatus.PENDING)
- when: 'the cache is populated'
- cmSubscriptionEventCache.put(subscriptionId, [(dmiPluginName): cmSubscriptionCacheObject])
- then: 'the values are present in memory'
- assert cmSubscriptionEventCache.get(subscriptionId) != null
- and: 'properties match'
- assert dmiPluginName == cmSubscriptionEventCache.get(subscriptionId).keySet()[0]
- assert cmSubscriptionCacheObject.cmSubscriptionStatus == cmSubscriptionEventCache.get(subscriptionId).values().cmSubscriptionStatus[0]
- assert cmSubscriptionCacheObject.cmSubscriptionPredicates[0].targetFilter == cmSubscriptionEventCache.get(subscriptionId).values().cmSubscriptionPredicates[0].targetFilter[0]
- }
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy
index 501714a2b..3b1709d80 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfigSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START========================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
+import spock.util.concurrent.PollingConditions
import java.util.concurrent.BlockingQueue
import java.util.concurrent.TimeUnit
@@ -121,8 +122,10 @@ class SynchronizationCacheConfigSpec extends Specification {
moduleSyncStartedOnCmHandles.put('testKeyModuleSync', 'toBeExpired' as Object, 1, TimeUnit.SECONDS)
then: 'the entry is present in the map'
assert moduleSyncStartedOnCmHandles.get('testKeyModuleSync') != null
- and: 'the entry expires in less then 2 seconds'
- waitMax2SecondsForKeyExpiration(moduleSyncStartedOnCmHandles, 'testKeyModuleSync')
+ and: 'the entry expires'
+ new PollingConditions().within(10) {
+ assert moduleSyncStartedOnCmHandles.get('testKeyModuleSync') == null
+ }
}
def 'Time to Live Verify for Data Sync Semaphore'() {
@@ -130,16 +133,10 @@ class SynchronizationCacheConfigSpec extends Specification {
dataSyncSemaphores.put('testKeyDataSync', Boolean.TRUE, 1, TimeUnit.SECONDS)
then: 'the entry is present in the map'
assert dataSyncSemaphores.get('testKeyDataSync') != null
- and: 'the entry expires in less then 2 seconds'
- waitMax2SecondsForKeyExpiration(dataSyncSemaphores, 'testKeyDataSync')
- }
-
- def waitMax2SecondsForKeyExpiration(map, key) {
- def count = 0
- while ( map.get(key)!=null && ++count <= 20 ) {
- sleep(100)
- }
- return count < 20 // Should have expired in less the 20 x 100ms = 2 seconds!
+ and: 'the entry expires'
+ new PollingConditions().within(10) {
+ assert dataSyncSemaphores.get('testKeyDataSync') == null
+ }
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy
index 57e77eba3..44d6eb6a0 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy
@@ -28,8 +28,6 @@ import com.fasterxml.jackson.databind.ObjectMapper
import io.cloudevents.CloudEvent
import io.cloudevents.core.builder.CloudEventBuilder
import org.apache.kafka.clients.consumer.ConsumerRecord
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
import org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent
import org.onap.cps.ncmp.utils.TestUtils
@@ -50,15 +48,13 @@ class CmSubscriptionNcmpInEventConsumerSpec extends MessagingBaseSpec {
@Autowired
ObjectMapper objectMapper
- @BeforeEach
void setup() {
- ((Logger) LoggerFactory.getLogger(CmSubscriptionNcmpInEventConsumer.class)).addAppender(logger);
- logger.start();
+ ((Logger) LoggerFactory.getLogger(CmSubscriptionNcmpInEventConsumer.class)).addAppender(logger)
+ logger.start()
}
- @AfterEach
- void teardown() {
- ((Logger) LoggerFactory.getLogger(CmSubscriptionNcmpInEventConsumer.class)).detachAndStopAllAppenders();
+ void cleanup() {
+ ((Logger) LoggerFactory.getLogger(CmSubscriptionNcmpInEventConsumer.class)).detachAndStopAllAppenders()
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImplSpec.groovy
new file mode 100644
index 000000000..f6103ef3b
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/service/CmNotificationSubscriptionPersistenceServiceImplSpec.groovy
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.events.cmsubscription.service
+
+
+import org.onap.cps.api.CpsQueryService
+import org.onap.cps.ncmp.api.impl.operations.DatastoreType
+import org.onap.cps.spi.FetchDescendantsOption
+import org.onap.cps.spi.model.DataNode
+import spock.lang.Specification
+
+class CmNotificationSubscriptionPersistenceServiceImplSpec extends Specification {
+
+ def mockCpsQueryService = Mock(CpsQueryService)
+
+ def objectUnderTest = new CmNotificationSubscriptionPersistenceServiceImpl(mockCpsQueryService)
+
+ def 'Check ongoing cm subscription #scenario'() {
+ given: 'a valid cm subscription query'
+ def cpsPathQuery = "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-1']/filters/filter[@xpath='/cps/path']";
+ and: 'datanodes optionally returned'
+ 1 * mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions',
+ cpsPathQuery, FetchDescendantsOption.OMIT_DESCENDANTS) >> dataNode
+ when: 'we check for an ongoing cm subscription'
+ def response = objectUnderTest.isOngoingCmNotificationSubscription(DatastoreType.PASSTHROUGH_RUNNING, 'ch-1', '/cps/path')
+ then: 'we get expected response'
+ assert response == isOngoingCmSubscription
+ where: 'following scenarios are used'
+ scenario | dataNode || isOngoingCmSubscription
+ 'valid datanodes present' | [new DataNode(xpath: '/cps/path', leaves: ['subscribers': ['sub-1', 'sub-2']])] || true
+ 'no datanodes present' | [] || false
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy
index 09179539a..b7c3b873f 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -173,4 +173,19 @@ class LcmEventsCreatorSpec extends Specification {
assert result.eventCorrelationId == cmHandleId
assert result.eventId != null
}
+
+ def 'Map the LcmEvent for alternate IDs when #scenario'() {
+ given: 'NCMP cm handle details with current and old alternate IDs'
+ def existingNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, alternateId: existingAlternateId, compositeState: new CompositeState(dataSyncEnabled: false))
+ def targetNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, alternateId: targetAlternateId, compositeState: new CompositeState(dataSyncEnabled: false))
+ when: 'the event is populated'
+ def result = objectUnderTest.populateLcmEvent(cmHandleId, targetNcmpServiceCmHandle, existingNcmpServiceCmHandle)
+ then: 'the alternate ID is present or is an empty string in the payload'
+ assert result.event.alternateId == expectedEventAlternateId
+ where: 'the following alternate IDs are provided'
+ scenario | existingAlternateId | targetAlternateId || expectedEventAlternateId
+ 'same new and old alternate ID' | 'someAlternateId' | 'someAlternateId' || 'someAlternateId'
+ 'blank new and old alternate ID' | '' | '' || ''
+ 'new alternate id and blank old alternate ID' | '' | 'someAlternateId' || 'someAlternateId'
+ }
} \ No newline at end of file
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy
index 8f3d8d97b..827a548ae 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -128,10 +128,9 @@ class ModuleOperationsUtilsSpec extends Specification{
'empty module set tag' | '' || 'not-specified'
}
- def 'Get all locked Cm-Handle where Lock Reason is MODULE_SYNC_FAILED cm handle #scenario'() {
+ def 'Get all locked cm-Handles where lock reasons are model sync failed or upgrade'() {
given: 'the cps (persistence service) returns a collection of data nodes'
- mockCmHandleQueries.queryCmHandleAncestorsByCpsPath(
- '//lock-reason[@reason="MODULE_SYNC_FAILED" or @reason="MODULE_UPGRADE"]',
+ mockCmHandleQueries.queryCmHandleAncestorsByCpsPath(ModuleOperationsUtils.CPS_PATH_CM_HANDLES_MODEL_SYNC_FAILED_OR_UPGRADE,
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode]
when: 'get locked Misbehaving cm handle is called'
def result = objectUnderTest.getCmHandlesThatFailedModelSyncOrUpgrade()
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasksSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasksSpec.groovy
index 3bdac1855..ece2d9f86 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasksSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasksSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,6 @@
package org.onap.cps.ncmp.api.impl.inventory.sync
-
import static org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory.MODULE_SYNC_FAILED
import static org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory.MODULE_UPGRADE_FAILED
@@ -32,8 +31,6 @@ import ch.qos.logback.core.read.ListAppender
import com.hazelcast.config.Config
import com.hazelcast.instance.impl.HazelcastInstanceFactory
import com.hazelcast.map.IMap
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
@@ -50,15 +47,13 @@ class ModuleSyncTasksSpec extends Specification {
def logger = Spy(ListAppender<ILoggingEvent>)
- @BeforeEach
void setup() {
- ((Logger) LoggerFactory.getLogger(ModuleSyncTasks.class)).addAppender(logger);
- logger.start();
+ ((Logger) LoggerFactory.getLogger(ModuleSyncTasks.class)).addAppender(logger)
+ logger.start()
}
- @AfterEach
- void teardown() {
- ((Logger) LoggerFactory.getLogger(ModuleSyncTasks.class)).detachAndStopAllAppenders();
+ void cleanup() {
+ ((Logger) LoggerFactory.getLogger(ModuleSyncTasks.class)).detachAndStopAllAppenders()
}
def mockInventoryPersistence = Mock(InventoryPersistence)
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurerSpec.groovy
index 7760b39cb..f37d5a41e 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurerSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,35 +20,17 @@
package org.onap.cps.ncmp.api.impl.inventory.sync.config
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
-import org.onap.cps.ncmp.api.impl.inventory.sync.config.WatchdogSchedulingConfigurer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.context.ConfigurableApplicationContext
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
@SpringBootTest
-@ContextConfiguration(classes = [ConfigurableApplicationContext, WatchdogSchedulingConfigurer])
+@ContextConfiguration(classes = [WatchdogSchedulingConfigurer])
class WatchdogSchedulingConfigurerSpec extends Specification {
@Autowired
- private ConfigurableApplicationContext applicationContext;
-
- def watchdogSchedulingConfigurer;
-
- @BeforeEach
- void setup() {
- watchdogSchedulingConfigurer = (WatchdogSchedulingConfigurer) applicationContext.getBean("watchdogSchedulingConfigurer")
- }
-
- @AfterEach
- void tearDown() {
- if (applicationContext != null) {
- applicationContext.close()
- }
- }
+ WatchdogSchedulingConfigurer watchdogSchedulingConfigurer
def 'Validate watchdog scheduling configuration'() {
given: 'task scheduler configuration properties are loaded as map'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
index 3f2148f80..2229b32b0 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
@@ -21,8 +21,6 @@
package org.onap.cps.ncmp.api.impl.operations
-import org.onap.cps.events.EventsPublisher
-
import static org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper.toTargetEvent
import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL
import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING
@@ -33,8 +31,8 @@ import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_D
import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING
import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.events.EventsPublisher
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
-
import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder
import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext
@@ -49,6 +47,7 @@ import org.springframework.http.ResponseEntity
import org.springframework.test.context.ContextConfiguration
import org.springframework.http.HttpStatus
import spock.lang.Shared
+import spock.util.concurrent.PollingConditions
import java.util.concurrent.TimeoutException
@SpringBootTest
@@ -101,20 +100,24 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
def dataOperationBatchRequestJsonData = TestUtils.getResourceFileContent('dataOperationRequest.json')
def dataOperationRequest = spiedJsonObjectMapper.convertJsonString(dataOperationBatchRequestJsonData, DataOperationRequest.class)
dataOperationRequest.dataOperationDefinitions[0].cmHandleIds = [cmHandleId]
- def requestBodyAsJsonStringArg = null
and: 'a positive response from DMI service when it is called with valid request parameters'
def responseFromDmi = new ResponseEntity<Object>(HttpStatus.ACCEPTED)
def expectedDmiBatchResourceDataUrl = "ncmp/v1/data/topic=my-topic-name"
def expectedBatchRequestAsJson = '{"operations":[{"operation":"read","operationId":"operational-14","datastore":"ncmp-datastore:passthrough-operational","options":"some option","resourceIdentifier":"some resource identifier","cmHandles":[{"id":"some-cm-handle","cmHandleProperties":{"prop1":"val1"}}]}]}'
mockDmiRestClient.postOperationWithJsonData(expectedDmiBatchResourceDataUrl, _, READ.operationName) >> responseFromDmi
dmiServiceUrlBuilder.getDataOperationRequestUrl(_, _) >> expectedDmiBatchResourceDataUrl
+ and: ' a flag to track the post operation call'
+ def postOperationWithJsonDataMethodCalled = false
+ and: 'the (mocked) dmi rest client will use the flag to indicate it is called and capture the request body'
+ mockDmiRestClient.postOperationWithJsonData(expectedDmiBatchResourceDataUrl, expectedBatchRequestAsJson, READ) >> {
+ postOperationWithJsonDataMethodCalled = true
+ }
when: 'get resource data for group of cm handles are invoked'
objectUnderTest.requestResourceDataFromDmi('my-topic-name', dataOperationRequest, 'requestId')
- then: 'wait a little to allow execution of service method by task executor (on separate thread)'
- Thread.sleep(100)
- then: 'validate ncmp generated dmi request body json args'
- 1 * mockDmiRestClient.postOperationWithJsonData(expectedDmiBatchResourceDataUrl, _, READ) >> { args -> requestBodyAsJsonStringArg = args[1] }
- assert requestBodyAsJsonStringArg == expectedBatchRequestAsJson
+ then: 'validate the post operation was called and ncmp generated dmi request body json args'
+ new PollingConditions().within(1) {
+ assert postOperationWithJsonDataMethodCalled == true
+ }
}
def 'Execute (async) data operation from DMI service for #scenario.'() {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapperSpec.groovy
index 0a2962e98..55ccdf3be 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapperSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapperSpec.groovy
@@ -78,6 +78,15 @@ class CmHandleIdMapperSpec extends Specification {
assert objectUnderTest.cmHandleIdToAlternateId('my cmhandle id') == null
}
+ def 'Attempt to remove a non-existing entry from the cache.'() {
+ when: 'removing an entry that is not cached'
+ objectUnderTest.removeMapping('non-cached cmhandle id')
+ then: 'deleting from the cmhandle cache returns null'
+ assert alternateIdPerCmHandle.remove('non-cached cmhandle id') == null
+ and: 'removal from the alternate id cache is skipped'
+ 0 * cmHandlePerAlternateId.remove(_)
+ }
+
def 'Cannot update existing alternate id.'() {
given: 'attempt to update an existing alternate id'
objectUnderTest.addMapping('my cmhandle id', 'other id')
diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml
index 2856b9874..6e7554bf5 100644
--- a/cps-parent/pom.xml
+++ b/cps-parent/pom.xml
@@ -3,7 +3,7 @@
============LICENSE_START=======================================================
Copyright (c) 2021 Pantheon.tech.
Modifications Copyright (C) 2021 Bell Canada.
- Modifications Copyright (C) 2021-2023 Nordix Foundation.
+ Modifications Copyright (C) 2021-2024 Nordix Foundation.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
@@ -339,7 +339,10 @@
<include>**/*Test.java</include> <!-- Just in case of having also "normal" JUnit tests -->
</includes>
<excludes>
- <exclude>**/IT*.java</exclude>
+ <!-- maven-failsafe-plugin will run performance tests in the integration-test module,
+ so performance tests will not affect Jacoco coverage (jacoco-report module is configured
+ to aggregate results from tests run with maven-surefire-plugin only) -->
+ <exclude>**/*PerfTest.java</exclude>
</excludes>
<environmentVariables>
<!--
diff --git a/cps-path-parser/pom.xml b/cps-path-parser/pom.xml
index 4b743a725..e6e00dcf3 100644
--- a/cps-path-parser/pom.xml
+++ b/cps-path-parser/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml
index 0b31577ae..022c3b8eb 100644
--- a/cps-rest/pom.xml
+++ b/cps-rest/pom.xml
@@ -28,7 +28,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 600676838..2fd369b2a 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -26,7 +26,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-service/pom.xml b/cps-service/pom.xml
index e661f3421..de716dfa5 100644
--- a/cps-service/pom.xml
+++ b/cps-service/pom.xml
@@ -29,7 +29,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
index 0f9eb3c64..14b949e5a 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
@@ -117,8 +117,8 @@ public class CpsModuleServiceImpl implements CpsModuleService {
final Collection<String> anchorNames = cpsAnchorService.getAnchors(dataspaceName, schemaSetNames)
.stream().map(Anchor::getName).collect(Collectors.toSet());
cpsAnchorService.deleteAnchors(dataspaceName, anchorNames);
- cpsModulePersistenceService.deleteUnusedYangResourceModules();
cpsModulePersistenceService.deleteSchemaSets(dataspaceName, schemaSetNames);
+ cpsModulePersistenceService.deleteUnusedYangResourceModules();
for (final String schemaSetName : schemaSetNames) {
yangTextSchemaSourceSetCache.removeFromCache(dataspaceName, schemaSetName);
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/ModuleDefinition.java b/cps-service/src/main/java/org/onap/cps/spi/model/ModuleDefinition.java
index d7a5b38dc..909b7bc11 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/model/ModuleDefinition.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/ModuleDefinition.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +20,15 @@
package org.onap.cps.spi.model;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
+import lombok.ToString;
@Getter
@Setter
+@EqualsAndHashCode(callSuper = true)
+@ToString
public class ModuleDefinition extends ModuleReference {
private static final long serialVersionUID = -6591435720836327732L;
diff --git a/csit/tests/cps-model-sync/cps-model-sync.robot b/csit/tests/cps-model-sync/cps-model-sync.robot
index 3e8551f7f..bb881f6a6 100644
--- a/csit/tests/cps-model-sync/cps-model-sync.robot
+++ b/csit/tests/cps-model-sync/cps-model-sync.robot
@@ -34,14 +34,15 @@ ${auth} Basic Y3BzdXNlcjpjcHNyMGNrcyE=
${ncmpInventoryBasePath} /ncmpInventory
${ncmpBasePath} /ncmp
${dmiUrl} http://${DMI_HOST}:${DMI_PORT}
-${jsonDataCreate} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"cmHandle":"ietfYang-PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com", "Contact2":"storeemail2@bookstore.com"}}]}
-${jsonDataUpdate} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","updatedCmHandles":[{"cmHandle":"ietfYang-PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
+${createPayload} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"cmHandle":"ietfYang-PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com", "Contact2":"storeemail2@bookstore.com"}},{"cmHandle":"CmHandleForDelete"}]}
+${updatePayload} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","updatedCmHandles":[{"cmHandle":"ietfYang-PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
+${deletePayload} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","removedCmHandles":["CmHandleForDelete"]}
*** Test Cases ***
Register data node and sync modules.
${uri}= Set Variable ${ncmpInventoryBasePath}/v1/ch
${headers}= Create Dictionary Content-Type=application/json Authorization=${auth}
- ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${jsonDataCreate}
+ ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${createPayload}
Should Be Equal As Strings ${response.status_code} 200
Get CM Handle details and confirm it has been registered.
@@ -60,7 +61,7 @@ Get CM Handle details and confirm it has been registered.
Update data node and sync modules.
${uri}= Set Variable ${ncmpInventoryBasePath}/v1/ch
${headers}= Create Dictionary Content-Type=application/json Authorization=${auth}
- ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${jsonDataUpdate}
+ ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${updatePayload}
Should Be Equal As Strings ${response.status_code} 200
Get CM Handle details and confirm it has been updated.
@@ -76,6 +77,17 @@ Get CM Handle details and confirm it has been updated.
END
END
+Delete cm handle
+ ${uri}= Set Variable ${ncmpInventoryBasePath}/v1/ch
+ ${headers}= Create Dictionary Content-Type=application/json Authorization=${auth}
+ ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${deletePayload}
+ Should Be Equal As Strings ${response.status_code} 200
+
+Get cm handle details and confirm it has been deleted
+ ${uri}= Set Variable ${ncmpBasePath}/v1/ch/CmHandleForDelete
+ ${headers}= Create Dictionary Authorization=${auth}
+ ${response}= GET On Session CPS_URL ${uri} headers=${headers} expected_status=404
+
Get modules for registered data node
${uri}= Set Variable ${ncmpBasePath}/v1/ch/ietfYang-PNFDemo/modules
${headers}= Create Dictionary Authorization=${auth}
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
index cbb5155a3..eca8871c6 100644
--- a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>dmi-plugin-demo-and-csit-stub</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
</parent>
<artifactId>dmi-plugin-demo-and-csit-stub-app</artifactId>
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
index 9b6e40254..d3142f821 100644
--- a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>dmi-plugin-demo-and-csit-stub</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
</parent>
<artifactId>dmi-plugin-demo-and-csit-stub-service</artifactId>
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_ResourcesResponse.json b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_ResourcesResponse.json
new file mode 100644
index 000000000..5d713914d
--- /dev/null
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_ResourcesResponse.json
@@ -0,0 +1,12 @@
+[
+ {
+ "moduleName": "M1",
+ "revision": "2024-01-01",
+ "yangSource": "module M1 {\n\n namespace \"urn:ietf:params:xml:ns:yang:M1\";\n prefix \"yang\";\n\n organization\n \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n contact\n \"WG Web: <http://tools.ietf.org/wg/netmod/>\n WG List: <mailto:netmod@ietf.org>\n\n WG Chair: David Kessens\n <mailto:david.kessens@nsn.com>\n\n WG Chair: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\n\n Editor: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n description\n \"This module contains a collection of generally useful derived\n YANG data types.\n\n Copyright (c) 2013 IETF Trust and the persons identified as\n authors of the code. All rights reserved.\n\n Redistribution and use in source and binary forms, with or\n without modification, is permitted pursuant to, and subject\n to the license terms contained in, the Simplified BSD License\n set forth in Section 4.c of the IETF Trust's Legal Provisions\n Relating to IETF Documents\n (http://trustee.ietf.org/license-info).\n\n This version of this YANG module is part of RFC 6991; see\n the RFC itself for full legal notices.\";\n\n revision 2024-01-01 {\n description\n \"This revision adds the following new data types:\n - yang-identifier\n - hex-string\n - uuid\n - dotted-quad\";\n reference\n \"RFC 6991: Common YANG Data Types\";\n }\n\n revision 2010-09-24 {\n description\n \"Initial revision.\";\n reference\n \"RFC 6021: Common YANG Data Types\";\n }\n\n /*** collection of counter and gauge types ***/\n\n typedef counter32 {\n type uint32;\n description\n \"The counter32 type represents a non-negative integer\n that monotonically increases until it reaches a\n maximum value of 2^32-1 (4294967295 decimal), when it\n wraps around and starts increasing again from zero.\n\n Counters have no defined 'initial' value, and thus, a\n single value of a counter has (in general) no information\n content. Discontinuities in the monotonically increasing\n value normally occur at re-initialization of the\n management system, and at other times as specified in the\n description of a schema node using this type. If such\n other times can occur, for example, the creation of\n a schema node of type counter32 at times other than\n re-initialization, then a corresponding schema node\n should be defined, with an appropriate type, to indicate\n the last discontinuity.\n\n The counter32 type should not be used for configuration\n schema nodes. A default statement SHOULD NOT be used in\n combination with the type counter32.\n\n In the value set and its semantics, this type is equivalent\n to the Counter32 type of the SMIv2.\";\n reference\n \"RFC 2578: Structure of Management Information Version 2\n (SMIv2)\";\n }\n}\n"
+ },
+ {
+ "moduleName": "M2",
+ "revision": "2024-01-02",
+ "yangSource": "module M2 {\n\n namespace \"urn:ietf:params:xml:ns:yang:M2\";\n prefix \"yang\";\n\n organization\n \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n contact\n \"WG Web: <http://tools.ietf.org/wg/netmod/>\n WG List: <mailto:netmod@ietf.org>\n\n WG Chair: David Kessens\n <mailto:david.kessens@nsn.com>\n\n WG Chair: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\n\n Editor: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n description\n \"This module contains a collection of generally useful derived\n YANG data types.\n\n Copyright (c) 2013 IETF Trust and the persons identified as\n authors of the code. All rights reserved.\n\n Redistribution and use in source and binary forms, with or\n without modification, is permitted pursuant to, and subject\n to the license terms contained in, the Simplified BSD License\n set forth in Section 4.c of the IETF Trust's Legal Provisions\n Relating to IETF Documents\n (http://trustee.ietf.org/license-info).\n\n This version of this YANG module is part of RFC 6991; see\n the RFC itself for full legal notices.\";\n\n revision 2024-01-02 {\n description\n \"This revision adds the following new data types:\n - yang-identifier\n - hex-string\n - uuid\n - dotted-quad\";\n reference\n \"RFC 6991: Common YANG Data Types\";\n }\n\n revision 2010-09-24 {\n description\n \"Initial revision.\";\n reference\n \"RFC 6021: Common YANG Data Types\";\n }\n\n /*** collection of counter and gauge types ***/\n\n typedef counter32 {\n type uint32;\n description\n \"The counter32 type represents a non-negative integer\n that monotonically increases until it reaches a\n maximum value of 2^32-1 (4294967295 decimal), when it\n wraps around and starts increasing again from zero.\n\n Counters have no defined 'initial' value, and thus, a\n single value of a counter has (in general) no information\n content. Discontinuities in the monotonically increasing\n value normally occur at re-initialization of the\n management system, and at other times as specified in the\n description of a schema node using this type. If such\n other times can occur, for example, the creation of\n a schema node of type counter32 at times other than\n re-initialization, then a corresponding schema node\n should be defined, with an appropriate type, to indicate\n the last discontinuity.\n\n The counter32 type should not be used for configuration\n schema nodes. A default statement SHOULD NOT be used in\n combination with the type counter32.\n\n In the value set and its semantics, this type is equivalent\n to the Counter32 type of the SMIv2.\";\n reference\n \"RFC 2578: Structure of Management Information Version 2\n (SMIv2)\";\n }\n}\n"
+ }
+] \ No newline at end of file
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_Response.json b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_Response.json
new file mode 100644
index 000000000..9f20564f0
--- /dev/null
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreAWithModules_M1_M2_Response.json
@@ -0,0 +1,12 @@
+{
+ "schemas": [
+ {
+ "moduleName": "M1",
+ "revision": "2024-01-01"
+ },
+ {
+ "moduleName": "M2",
+ "revision": "2024-01-02"
+ }
+ ]
+} \ No newline at end of file
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_ResourcesResponse.json b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_ResourcesResponse.json
new file mode 100644
index 000000000..ef9b85f92
--- /dev/null
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_ResourcesResponse.json
@@ -0,0 +1,12 @@
+[
+ {
+ "moduleName": "M1",
+ "revision": "2024-01-01",
+ "yangSource": "module M1 {\n\n namespace \"urn:ietf:params:xml:ns:yang:M1\";\n prefix \"yang\";\n\n organization\n \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n contact\n \"WG Web: <http://tools.ietf.org/wg/netmod/>\n WG List: <mailto:netmod@ietf.org>\n\n WG Chair: David Kessens\n <mailto:david.kessens@nsn.com>\n\n WG Chair: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\n\n Editor: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n description\n \"This module contains a collection of generally useful derived\n YANG data types.\n\n Copyright (c) 2013 IETF Trust and the persons identified as\n authors of the code. All rights reserved.\n\n Redistribution and use in source and binary forms, with or\n without modification, is permitted pursuant to, and subject\n to the license terms contained in, the Simplified BSD License\n set forth in Section 4.c of the IETF Trust's Legal Provisions\n Relating to IETF Documents\n (http://trustee.ietf.org/license-info).\n\n This version of this YANG module is part of RFC 6991; see\n the RFC itself for full legal notices.\";\n\n revision 2024-01-01 {\n description\n \"This revision adds the following new data types:\n - yang-identifier\n - hex-string\n - uuid\n - dotted-quad\";\n reference\n \"RFC 6991: Common YANG Data Types\";\n }\n\n revision 2010-09-24 {\n description\n \"Initial revision.\";\n reference\n \"RFC 6021: Common YANG Data Types\";\n }\n\n /*** collection of counter and gauge types ***/\n\n typedef counter32 {\n type uint32;\n description\n \"The counter32 type represents a non-negative integer\n that monotonically increases until it reaches a\n maximum value of 2^32-1 (4294967295 decimal), when it\n wraps around and starts increasing again from zero.\n\n Counters have no defined 'initial' value, and thus, a\n single value of a counter has (in general) no information\n content. Discontinuities in the monotonically increasing\n value normally occur at re-initialization of the\n management system, and at other times as specified in the\n description of a schema node using this type. If such\n other times can occur, for example, the creation of\n a schema node of type counter32 at times other than\n re-initialization, then a corresponding schema node\n should be defined, with an appropriate type, to indicate\n the last discontinuity.\n\n The counter32 type should not be used for configuration\n schema nodes. A default statement SHOULD NOT be used in\n combination with the type counter32.\n\n In the value set and its semantics, this type is equivalent\n to the Counter32 type of the SMIv2.\";\n reference\n \"RFC 2578: Structure of Management Information Version 2\n (SMIv2)\";\n }\n}\n"
+ },
+ {
+ "moduleName": "M3",
+ "revision": "2024-01-03",
+ "yangSource": "module M3 {\n\n namespace \"urn:ietf:params:xml:ns:yang:M3\";\n prefix \"yang\";\n\n organization\n \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n contact\n \"WG Web: <http://tools.ietf.org/wg/netmod/>\n WG List: <mailto:netmod@ietf.org>\n\n WG Chair: David Kessens\n <mailto:david.kessens@nsn.com>\n\n WG Chair: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\n\n Editor: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n description\n \"This module contains a collection of generally useful derived\n YANG data types.\n\n Copyright (c) 2013 IETF Trust and the persons identified as\n authors of the code. All rights reserved.\n\n Redistribution and use in source and binary forms, with or\n without modification, is permitted pursuant to, and subject\n to the license terms contained in, the Simplified BSD License\n set forth in Section 4.c of the IETF Trust's Legal Provisions\n Relating to IETF Documents\n (http://trustee.ietf.org/license-info).\n\n This version of this YANG module is part of RFC 6991; see\n the RFC itself for full legal notices.\";\n\n revision 2024-01-03 {\n description\n \"This revision adds the following new data types:\n - yang-identifier\n - hex-string\n - uuid\n - dotted-quad\";\n reference\n \"RFC 6991: Common YANG Data Types\";\n }\n\n revision 2010-09-24 {\n description\n \"Initial revision.\";\n reference\n \"RFC 6021: Common YANG Data Types\";\n }\n\n /*** collection of counter and gauge types ***/\n\n typedef counter32 {\n type uint32;\n description\n \"The counter32 type represents a non-negative integer\n that monotonically increases until it reaches a\n maximum value of 2^32-1 (4294967295 decimal), when it\n wraps around and starts increasing again from zero.\n\n Counters have no defined 'initial' value, and thus, a\n single value of a counter has (in general) no information\n content. Discontinuities in the monotonically increasing\n value normally occur at re-initialization of the\n management system, and at other times as specified in the\n description of a schema node using this type. If such\n other times can occur, for example, the creation of\n a schema node of type counter32 at times other than\n re-initialization, then a corresponding schema node\n should be defined, with an appropriate type, to indicate\n the last discontinuity.\n\n The counter32 type should not be used for configuration\n schema nodes. A default statement SHOULD NOT be used in\n combination with the type counter32.\n\n In the value set and its semantics, this type is equivalent\n to the Counter32 type of the SMIv2.\";\n reference\n \"RFC 2578: Structure of Management Information Version 2\n (SMIv2)\";\n }\n}\n"
+ }
+] \ No newline at end of file
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_Response.json b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_Response.json
new file mode 100644
index 000000000..513c749a2
--- /dev/null
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreBWithModules_M1_M3_Response.json
@@ -0,0 +1,12 @@
+{
+ "schemas": [
+ {
+ "moduleName": "M1",
+ "revision": "2024-01-01"
+ },
+ {
+ "moduleName": "M3",
+ "revision": "2024-01-03"
+ }
+ ]
+} \ No newline at end of file
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_ResourcesResponse.json b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_ResourcesResponse.json
new file mode 100644
index 000000000..5d713914d
--- /dev/null
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_ResourcesResponse.json
@@ -0,0 +1,12 @@
+[
+ {
+ "moduleName": "M1",
+ "revision": "2024-01-01",
+ "yangSource": "module M1 {\n\n namespace \"urn:ietf:params:xml:ns:yang:M1\";\n prefix \"yang\";\n\n organization\n \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n contact\n \"WG Web: <http://tools.ietf.org/wg/netmod/>\n WG List: <mailto:netmod@ietf.org>\n\n WG Chair: David Kessens\n <mailto:david.kessens@nsn.com>\n\n WG Chair: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\n\n Editor: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n description\n \"This module contains a collection of generally useful derived\n YANG data types.\n\n Copyright (c) 2013 IETF Trust and the persons identified as\n authors of the code. All rights reserved.\n\n Redistribution and use in source and binary forms, with or\n without modification, is permitted pursuant to, and subject\n to the license terms contained in, the Simplified BSD License\n set forth in Section 4.c of the IETF Trust's Legal Provisions\n Relating to IETF Documents\n (http://trustee.ietf.org/license-info).\n\n This version of this YANG module is part of RFC 6991; see\n the RFC itself for full legal notices.\";\n\n revision 2024-01-01 {\n description\n \"This revision adds the following new data types:\n - yang-identifier\n - hex-string\n - uuid\n - dotted-quad\";\n reference\n \"RFC 6991: Common YANG Data Types\";\n }\n\n revision 2010-09-24 {\n description\n \"Initial revision.\";\n reference\n \"RFC 6021: Common YANG Data Types\";\n }\n\n /*** collection of counter and gauge types ***/\n\n typedef counter32 {\n type uint32;\n description\n \"The counter32 type represents a non-negative integer\n that monotonically increases until it reaches a\n maximum value of 2^32-1 (4294967295 decimal), when it\n wraps around and starts increasing again from zero.\n\n Counters have no defined 'initial' value, and thus, a\n single value of a counter has (in general) no information\n content. Discontinuities in the monotonically increasing\n value normally occur at re-initialization of the\n management system, and at other times as specified in the\n description of a schema node using this type. If such\n other times can occur, for example, the creation of\n a schema node of type counter32 at times other than\n re-initialization, then a corresponding schema node\n should be defined, with an appropriate type, to indicate\n the last discontinuity.\n\n The counter32 type should not be used for configuration\n schema nodes. A default statement SHOULD NOT be used in\n combination with the type counter32.\n\n In the value set and its semantics, this type is equivalent\n to the Counter32 type of the SMIv2.\";\n reference\n \"RFC 2578: Structure of Management Information Version 2\n (SMIv2)\";\n }\n}\n"
+ },
+ {
+ "moduleName": "M2",
+ "revision": "2024-01-02",
+ "yangSource": "module M2 {\n\n namespace \"urn:ietf:params:xml:ns:yang:M2\";\n prefix \"yang\";\n\n organization\n \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n contact\n \"WG Web: <http://tools.ietf.org/wg/netmod/>\n WG List: <mailto:netmod@ietf.org>\n\n WG Chair: David Kessens\n <mailto:david.kessens@nsn.com>\n\n WG Chair: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\n\n Editor: Juergen Schoenwaelder\n <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n description\n \"This module contains a collection of generally useful derived\n YANG data types.\n\n Copyright (c) 2013 IETF Trust and the persons identified as\n authors of the code. All rights reserved.\n\n Redistribution and use in source and binary forms, with or\n without modification, is permitted pursuant to, and subject\n to the license terms contained in, the Simplified BSD License\n set forth in Section 4.c of the IETF Trust's Legal Provisions\n Relating to IETF Documents\n (http://trustee.ietf.org/license-info).\n\n This version of this YANG module is part of RFC 6991; see\n the RFC itself for full legal notices.\";\n\n revision 2024-01-02 {\n description\n \"This revision adds the following new data types:\n - yang-identifier\n - hex-string\n - uuid\n - dotted-quad\";\n reference\n \"RFC 6991: Common YANG Data Types\";\n }\n\n revision 2010-09-24 {\n description\n \"Initial revision.\";\n reference\n \"RFC 6021: Common YANG Data Types\";\n }\n\n /*** collection of counter and gauge types ***/\n\n typedef counter32 {\n type uint32;\n description\n \"The counter32 type represents a non-negative integer\n that monotonically increases until it reaches a\n maximum value of 2^32-1 (4294967295 decimal), when it\n wraps around and starts increasing again from zero.\n\n Counters have no defined 'initial' value, and thus, a\n single value of a counter has (in general) no information\n content. Discontinuities in the monotonically increasing\n value normally occur at re-initialization of the\n management system, and at other times as specified in the\n description of a schema node using this type. If such\n other times can occur, for example, the creation of\n a schema node of type counter32 at times other than\n re-initialization, then a corresponding schema node\n should be defined, with an appropriate type, to indicate\n the last discontinuity.\n\n The counter32 type should not be used for configuration\n schema nodes. A default statement SHOULD NOT be used in\n combination with the type counter32.\n\n In the value set and its semantics, this type is equivalent\n to the Counter32 type of the SMIv2.\";\n reference\n \"RFC 2578: Structure of Management Information Version 2\n (SMIv2)\";\n }\n}\n"
+ }
+] \ No newline at end of file
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_Response.json b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_Response.json
new file mode 100644
index 000000000..9f20564f0
--- /dev/null
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/bookStoreCWithModules_M1_M2_Response.json
@@ -0,0 +1,12 @@
+{
+ "schemas": [
+ {
+ "moduleName": "M1",
+ "revision": "2024-01-01"
+ },
+ {
+ "moduleName": "M2",
+ "revision": "2024-01-02"
+ }
+ ]
+} \ No newline at end of file
diff --git a/dmi-plugin-demo-and-csit-stub/pom.xml b/dmi-plugin-demo-and-csit-stub/pom.xml
index d708f7c6e..9fb40e3cd 100644
--- a/dmi-plugin-demo-and-csit-stub/pom.xml
+++ b/dmi-plugin-demo-and-csit-stub/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml
index 11d39b59d..906945de4 100644
--- a/docker-compose/docker-compose.yml
+++ b/docker-compose/docker-compose.yml
@@ -1,7 +1,7 @@
# ============LICENSE_START=======================================================
# Copyright (c) 2020 Pantheon.tech.
# Modifications Copyright (C) 2021 Bell Canada.
-# Modifications Copyright (C) 2022-2023 Nordix Foundation.
+# Modifications Copyright (C) 2022-2024 Nordix Foundation.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -31,6 +31,14 @@ services:
POSTGRES_DB: cpsdb
POSTGRES_USER: ${DB_USERNAME:-cps}
POSTGRES_PASSWORD: ${DB_PASSWORD:-cps}
+ deploy:
+ resources:
+ reservations:
+ cpus: '1'
+ memory: 1G
+ limits:
+ cpus: '6'
+ memory: 3G
cps-and-ncmp:
container_name: cps-and-ncmp
@@ -55,6 +63,14 @@ services:
restart: unless-stopped
depends_on:
- dbpostgresql
+ deploy:
+ resources:
+ reservations:
+ cpus: '2'
+ memory: 2G
+ limits:
+ cpus: '3'
+ memory: 3G
### if kafka is not required comment out zookeeper and kafka ###
zookeeper:
diff --git a/docs/api/swagger/ncmp/openapi.yaml b/docs/api/swagger/ncmp/openapi.yaml
index 8098faefc..a1cc5d9ba 100644
--- a/docs/api/swagger/ncmp/openapi.yaml
+++ b/docs/api/swagger/ncmp/openapi.yaml
@@ -918,9 +918,9 @@ paths:
- network-cm-proxy
/v1/ch/{cm-handle}/modules/definitions:
get:
- description: "Fetch all module definitions (name, revision, yang resource) for\
- \ a given cm handle"
- operationId: getModuleDefinitionsByCmHandleId
+ description: "Get module definitions (module name, revision, yang resource)\
+ \ with options to filter on module name and revision"
+ operationId: getModuleDefinitions
parameters:
- description: "The identifier for a network function, network element, subnetwork\
\ or any other cm object by managed Network CM Proxy"
@@ -930,6 +930,21 @@ paths:
schema:
example: my-cm-handle
type: string
+ - description: Filter for a module name.This is an optional parameter
+ in: query
+ name: module-name
+ required: false
+ schema:
+ example: my-module
+ type: string
+ - description: Filter for a module revision.This is an optional parameter and
+ ignored when no module name is supplied
+ in: query
+ name: revision
+ required: false
+ schema:
+ example: 2024-01-22
+ type: string
responses:
"200":
content:
@@ -969,8 +984,7 @@ paths:
schema:
$ref: '#/components/schemas/ErrorMessage'
description: Internal Server Error
- summary: "Fetch all module definitions (name, revision, yang resource) for a\
- \ given cm handle"
+ summary: Get module definitions
tags:
- network-cm-proxy
/v1/ch/searches:
@@ -1666,6 +1680,23 @@ components:
schema:
default: /
type: string
+ moduleNameInQuery:
+ description: Filter for a module name.This is an optional parameter
+ in: query
+ name: module-name
+ required: false
+ schema:
+ example: my-module
+ type: string
+ revisionInQuery:
+ description: Filter for a module revision.This is an optional parameter and
+ ignored when no module name is supplied
+ in: query
+ name: revision
+ required: false
+ schema:
+ example: 2024-01-22
+ type: string
dataSyncEnabled:
description: Is used to enable or disable the data synchronization flag
in: query
diff --git a/docs/deployment.rst b/docs/deployment.rst
index ca7824d6d..3b5aad1bf 100644
--- a/docs/deployment.rst
+++ b/docs/deployment.rst
@@ -333,7 +333,7 @@ Below are the list of distributed datastructures that we have.
+--------------+------------------------------------+-----------------------------------------------------------+
| cps-ncmp | moduleSetTagCacheMapConfig | Stores the module set tags for cm handles. |
+--------------+------------------------------------+-----------------------------------------------------------+
-| cps-ncmp | cmSubscriptionEventCache | Stores and tracks cm notification subscription requests. |
+| cps-ncmp | cmNotificationSubscriptionCache | Stores and tracks cm notification subscription requests. |
+--------------+------------------------------------+-----------------------------------------------------------+
| cps-ncmp | alternateIdPerCmHandleId | Stores the alternate id for each cm handle id. |
+--------------+------------------------------------+-----------------------------------------------------------+
diff --git a/docs/design.rst b/docs/design.rst
index 80eb5f152..af1f5abd4 100644
--- a/docs/design.rst
+++ b/docs/design.rst
@@ -72,6 +72,12 @@ CPS Path
Several CPS APIs use the cps-path (or cpsPath in Java API) parameter.
The CPS Path is described in detail in :doc:`cps-path`.
+CPS Delta
+=========
+
+CPS Delta feature provides the ability to find the delta/difference between two JSON configurations.
+The CPS Delta feature is described in detail in :doc:`cps-delta-feature`.
+
NCMP CM Handle Querying
=======================
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index f5cef76ed..191a04d1a 100644
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -16,6 +16,34 @@ CPS Release Notes
.. * * * NEW DELHI * * *
.. =========================
+Version: 3.4.4
+==============
+
+Release Data
+------------
+
++--------------------------------------+--------------------------------------------------------+
+| **CPS Project** | |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Docker images** | onap/cps-and-ncmp:3.4.4 |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Release designation** | 3.4.4 New Delhi |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Release date** | Not yet released |
+| | |
++--------------------------------------+--------------------------------------------------------+
+
+Bug Fixes
+---------
+3.4.4
+
+Features
+--------
+
+
Version: 3.4.3
==============
@@ -32,18 +60,27 @@ Release Data
| **Release designation** | 3.4.3 New Delhi |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Release date** | Not yet released |
+| **Release date** | 2024 February 07 |
| | |
+--------------------------------------+--------------------------------------------------------+
Bug Fixes
---------
3.4.3
-
+ - `CPS-2000 <https://jira.onap.org/browse/CPS-2000>`_ Fix for Schema object cache not being distributed.
+ - `CPS-2027 <https://jira.onap.org/browse/CPS-2027>`_ Fixes for upgrade yang modules using module set tag.
+ - `CPS-2070 <https://jira.onap.org/browse/CPS-2070>`_ Add retry interval for Kafka consumer.
Features
--------
- `CPS-1824 <https://jira.onap.org/browse/CPS-1824>`_ CPS Delta between 2 anchors.
+ - `CPS-2072 <https://jira.onap.org/browse/CPS-2072>`_ Add maven classifier to Spring Boot JAR.
+
+Notes
+-----
+The maven build of cps-application has been changed so that the JAR produced by spring-boot-maven-plugin has a
+*-springboot* classifier (`CPS-2072 <https://jira.onap.org/browse/CPS-2072>`_). This means that the filename
+of the Spring Boot JAR is *cps-application-3.4.3-springboot.jar*.
Version: 3.4.2
==============
diff --git a/integration-test/pom.xml b/integration-test/pom.xml
index f03b1c63e..6947a94aa 100644
--- a/integration-test/pom.xml
+++ b/integration-test/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
============LICENSE_START=======================================================
- Copyright (c) 2023 Nordix Foundation
+ Copyright (c) 2023-2024 Nordix Foundation
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,10 +23,9 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
-
<modelVersion>4.0.0</modelVersion>
<artifactId>integration-test</artifactId>
@@ -91,29 +90,27 @@
</dependencies>
<profiles>
+ <!-- Performance tests are run with maven-failsafe-plugin using a separate profile, so they will
+ not affect Jacoco coverage. Heap size is set here to ensure consistent test environment. -->
<profile>
- <id>default</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
+ <id>include-performance</id>
+ <properties>
+ <failsafeArgLine>-Xms512m -Xmx512m</failsafeArgLine>
+ </properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
+ <artifactId>maven-failsafe-plugin</artifactId>
<configuration>
- <excludes>
- <exclude>%regex[.*PerfTest.*]</exclude>
- </excludes>
+ <includes>
+ <include>**/*PerfTest.java</include>
+ </includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
- <profile>
- <id>include-performance</id>
- </profile>
</profiles>
-
</project>
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 6dec3dbf9..b59e0ff55 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -89,8 +89,7 @@ class CpsIntegrationSpecBase extends Specification {
def setup() {
if (!initialized) {
cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
- def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore : bookstoreModelFileContent])
+ createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
initialized = true;
}
}
@@ -111,6 +110,20 @@ class CpsIntegrationSpecBase extends Specification {
return new File('src/test/resources/data/' + filename).text
}
+ def getBookstoreYangResourcesNameToContentMap() {
+ def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
+ def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
+ return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
+ }
+
+ def createStandardBookStoreSchemaSet(targetDataspace) {
+ cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
+ }
+
+ def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
+ cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
+ }
+
def dataspaceExists(dataspaceName) {
try {
cpsDataspaceService.getDataspace(dataspaceName)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
index 20687c3ea..b3b584214 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
@@ -53,11 +53,9 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
cpsDataspaceService.createDataspace(FUNCTIONAL_TEST_DATASPACE_1)
cpsDataspaceService.createDataspace(FUNCTIONAL_TEST_DATASPACE_2)
cpsDataspaceService.createDataspace(FUNCTIONAL_TEST_DATASPACE_3)
- def bookstoreYangModelAsString = readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
- cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
- cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_3, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
-
+ createStandardBookStoreSchemaSet(FUNCTIONAL_TEST_DATASPACE_1)
+ createStandardBookStoreSchemaSet(FUNCTIONAL_TEST_DATASPACE_2)
+ createStandardBookStoreSchemaSet(FUNCTIONAL_TEST_DATASPACE_3)
}
def addBookstoreData() {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy
index 99dab8426..04c5dfc4b 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -20,14 +20,14 @@
package org.onap.cps.integration.functional
+import java.time.OffsetDateTime
+
import org.onap.cps.api.CpsAnchorService
import org.onap.cps.integration.base.CpsIntegrationSpecBase
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.AlreadyDefinedException
import org.onap.cps.spi.exceptions.AnchorNotFoundException
-import java.time.OffsetDateTime
-
class CpsAnchorServiceIntegrationSpec extends CpsIntegrationSpecBase {
CpsAnchorService objectUnderTest
@@ -56,8 +56,7 @@ class CpsAnchorServiceIntegrationSpec extends CpsIntegrationSpecBase {
objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor1')
objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor2')
and: '1 anchor with "other" schema set is created'
- def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, 'otherSchemaSet', [someFileName: bookstoreModelFileContent])
+ createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE, 'otherSchemaSet')
objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, 'otherSchemaSet', 'anchor3')
then: 'there are 3 anchors in the general test database'
assert objectUnderTest.getAnchors(GENERAL_TEST_DATASPACE).size() == 3
@@ -69,7 +68,7 @@ class CpsAnchorServiceIntegrationSpec extends CpsIntegrationSpecBase {
def 'Querying anchor(name)s (depends on previous test!).'() {
expect: 'there are now 3 anchors using the "stores" module (both schema sets use the same modules) '
- assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores']).size() == 3
+ 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/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
index 3843a9f1b..64996536e 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
@@ -555,8 +555,7 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase {
assert deltaReportEntities.get('xpaths').containsAll(["/bookstore/categories[@code='1']/books[@title='The Gruffalo']", "/bookstore/categories[@code='1']/books[@title='Matilda']"])
and: 'the delta report also has expected source and target data of child nodes'
assert deltaReportEntities.get('sourcePayload').containsAll(expectedSourceDataInChildNode)
- assert deltaReportEntities.get('targetPayload').containsAll(expectedTargetDataInChildNode)
-
+ //assert deltaReportEntities.get('targetPayload').containsAll(expectedTargetDataInChildNode) CPS-2057
}
def getDeltaReportEntities(List<DeltaReport> deltaReport) {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
index 8029ae042..3807a14bc 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
@@ -35,8 +35,11 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
CpsModuleService objectUnderTest
- private static def originalNumberOfModuleReferences = 1
- private static def existingModuleReference = new ModuleReference('stores','2020-09-15')
+ private static def originalNumberOfModuleReferences = 2 // bookstore has two modules
+ private static def bookStoreModuleReference = new ModuleReference('stores','2024-01-30')
+ private static def bookStoreModuleReferenceWithNamespace = new ModuleReference('stores','2024-01-30', 'org:onap:cps:sample')
+ private static def bookStoreTypesModuleReference = new ModuleReference('bookstore-types','2024-01-30')
+ private static def bookStoreTypesModuleReferenceWithNamespace = new ModuleReference('bookstore-types','2024-01-30', 'org:onap:cps:types:sample')
static def NEW_RESOURCE_REVISION = '2023-05-10'
static def NEW_RESOURCE_CONTENT = 'module test_module {\n' +
' yang-version 1.1;\n' +
@@ -53,6 +56,8 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
def newYangResourcesNameToContentMap = [:]
def moduleReferences = []
def noNewModules = [:]
+ def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
+ def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
def setup() {
objectUnderTest = cpsModuleService
@@ -67,7 +72,7 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfNewModules)
when: 'the new schema set is created'
objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap)
- then: 'the number of module references has increased by #expectedIncrease'
+ then: 'the number of module references has increased by #numberOfNewModules'
def yangResourceModuleReferences = objectUnderTest.getYangResourceModuleReferences(FUNCTIONAL_TEST_DATASPACE_1)
originalNumberOfModuleReferences + numberOfNewModules == yangResourceModuleReferences.size()
cleanup:
@@ -106,9 +111,9 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
where: 'the following module references are provided'
scenario | numberOfNewModules | existingModuleReferences || expectedNumberOfModulesForAnchor
'empty schema set' | 0 | [ ] || 0
- 'one existing module' | 0 | [ existingModuleReference ] || 1
+ 'one existing module' | 0 | [bookStoreModuleReference ] || 1
'two new modules' | 2 | [ ] || 2
- 'two new modules, one existing' | 2 | [ existingModuleReference ] || 3
+ 'two new modules, one existing' | 2 | [bookStoreModuleReference ] || 3
'over max batch size #modules' | 101 | [ ] || 101
'two valid, one invalid module' | 2 | [ new ModuleReference('NOT EXIST','IRRELEVANT') ] || 2
}
@@ -149,25 +154,34 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
when: 'the module definitions for an anchor are retrieved'
def result = objectUnderTest.getModuleDefinitionsByAnchorName(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1)
then: 'the correct module definitions are returned'
- result == [new ModuleDefinition('stores','2020-09-15','')]
+ assert result.size() == 2
+ assert result.contains(new ModuleDefinition('stores','2024-01-30',bookstoreModelFileContent))
+ assert result.contains(new ModuleDefinition('bookstore-types','2024-01-30', bookstoreTypesFileContent))
}
def 'Retrieving module definitions: #scenarios'() {
when: 'module definitions for module name are retrieved'
def result = objectUnderTest.getModuleDefinitionsByAnchorAndModule(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, moduleName, moduleRevision)
then: 'the correct module definitions are returned'
- result == [new ModuleDefinition('stores','2020-09-15','')]
+ if (expectedNumberOfDefinitions > 0) {
+ assert result.size() == expectedNumberOfDefinitions
+ def expectedModuleDefinition = new ModuleDefinition('stores', '2024-01-30', bookstoreModelFileContent)
+ assert result[0] == expectedModuleDefinition
+ }
where: 'following parameters are used'
- scenarios | moduleName | moduleRevision
- 'both specified' | 'stores' | '2020-09-15'
- 'module name specified' | 'stores' | null
+ scenarios | moduleName | moduleRevision || expectedNumberOfDefinitions
+ 'correct module name and revision' | 'stores' | '2024-01-30' || 1
+ 'correct module name' | 'stores' | null || 1
+ 'incorrect module name' | 'other' | null || 0
+ 'incorrect revision' | 'stores' | '2025-11-22' || 0
}
def 'Retrieving yang resource module references by anchor.'() {
when: 'the yang resource module references for an anchor are retrieved'
def result = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1)
then: 'the correct module references are returned'
- result == [ existingModuleReference ]
+ assert result.size() == 2
+ assert result.containsAll(bookStoreModuleReference, bookStoreTypesModuleReference)
}
def 'Identifying new module references with #scenario'() {
@@ -179,18 +193,19 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
where: 'the following data is used'
scenario | moduleReferences || expectedResult
'just new module references' | [new ModuleReference('new1', 'r1'), new ModuleReference('new2', 'r1')] || [new ModuleReference('new1', 'r1'), new ModuleReference('new2', 'r1')]
- 'one new module,one existing reference' | [new ModuleReference('new1', 'r1'), existingModuleReference] || [new ModuleReference('new1', 'r1')]
- 'no new module references' | [existingModuleReference] || []
+ 'one new module,one existing reference' | [new ModuleReference('new1', 'r1'), bookStoreModuleReference] || [new ModuleReference('new1', 'r1')]
+ 'no new module references' | [bookStoreModuleReference] || []
'no module references' | [] || []
'module references collection is null' | null || []
}
def 'Retrieve schema set.'() {
- when: 'a specific schema set is retreived'
+ when: 'a specific schema set is retrieved'
def result = objectUnderTest.getSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET)
then: 'the result has the correct name and module(s)'
assert result.name == 'bookstoreSchemaSet'
- assert result.moduleReferences == [ new ModuleReference('stores', '2020-09-15', 'org:onap:ccsdk:sample') ]
+ assert result.moduleReferences.size() == 2
+ assert result.moduleReferences.containsAll(bookStoreModuleReferenceWithNamespace, bookStoreTypesModuleReferenceWithNamespace)
}
def 'Retrieve all schema sets.'() {
@@ -290,14 +305,14 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
def newModuleReferences = [new ModuleReference('new_0','2000-01-01'),new ModuleReference('new_1','2001-01-01')]
and: 'a list of all module references (normally retrieved from node)'
def allModuleReferences = []
- allModuleReferences.add(existingModuleReference)
+ allModuleReferences.add(bookStoreModuleReference)
allModuleReferences.addAll(newModuleReferences)
when: 'the schema set is upgraded'
objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, allModuleReferences)
then: 'the new anchor has the correct new and existing modules'
def yangResourceModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
assert yangResourceModuleReferencesAfterUpgrade.size() == 3
- assert yangResourceModuleReferencesAfterUpgrade.contains(existingModuleReference)
+ assert yangResourceModuleReferencesAfterUpgrade.contains(bookStoreModuleReference)
assert yangResourceModuleReferencesAfterUpgrade.containsAll(newModuleReferences);
cleanup:
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['targetSchema'])
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
index 920f40749..68dfb4a79 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
@@ -44,8 +44,7 @@ class CpsPerfTestBase extends PerfTestBase {
def setupPerformanceInfraStructure() {
cpsDataspaceService.createDataspace(CPS_PERFORMANCE_TEST_DATASPACE)
- def modelAsString = readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore: modelAsString])
+ createStandardBookStoreSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE)
}
def createInitialData() {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy
index a96d7f64b..ce0aab45b 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/PerfTestBase.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
package org.onap.cps.integration.performance.base
import org.onap.cps.integration.base.CpsIntegrationSpecBase
-import org.springframework.util.StopWatch
abstract class PerfTestBase extends CpsIntegrationSpecBase {
diff --git a/integration-test/src/test/resources/data/bookstore/bookstore-types.yang b/integration-test/src/test/resources/data/bookstore/bookstore-types.yang
new file mode 100644
index 000000000..5ad7b6e13
--- /dev/null
+++ b/integration-test/src/test/resources/data/bookstore/bookstore-types.yang
@@ -0,0 +1,18 @@
+module bookstore-types {
+ yang-version 1.1;
+ namespace "org:onap:cps:types:sample";
+
+ prefix types;
+
+ revision "2024-01-30" {
+ description
+ "Sample Types";
+ }
+
+ typedef year {
+ type uint16 {
+ range "1000..9999";
+ }
+ }
+
+} \ No newline at end of file
diff --git a/integration-test/src/test/resources/data/bookstore/bookstore.yang b/integration-test/src/test/resources/data/bookstore/bookstore.yang
index 9c6c42e28..2abde656d 100644
--- a/integration-test/src/test/resources/data/bookstore/bookstore.yang
+++ b/integration-test/src/test/resources/data/bookstore/bookstore.yang
@@ -1,18 +1,22 @@
module stores {
yang-version 1.1;
- namespace "org:onap:ccsdk:sample";
+ namespace "org:onap:cps:sample";
prefix book-store;
- revision "2020-09-15" {
+ import bookstore-types {
+ prefix "types";
+ revision-date 2024-01-30;
+ }
+
+ revision "2024-01-30" {
description
- "Sample Model";
+ "Extracted bookstore types";
}
- typedef year {
- type uint16 {
- range "1000..9999";
- }
+ revision "2020-09-15" {
+ description
+ "Sample Model";
}
list bookstore-address {
@@ -106,7 +110,7 @@ module stores {
type string;
}
leaf-list editions {
- type year;
+ type types:year;
}
leaf price {
type uint64;
diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml
index 47486e85e..60aa6b465 100644
--- a/jacoco-report/pom.xml
+++ b/jacoco-report/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index 42d2bfa3a..3f67efb53 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-aggregator</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cps</name>
diff --git a/releases/3.4.3-container.yaml b/releases/3.4.3-container.yaml
new file mode 100644
index 000000000..685e23008
--- /dev/null
+++ b/releases/3.4.3-container.yaml
@@ -0,0 +1,8 @@
+distribution_type: container
+container_release_tag: 3.4.3
+project: cps
+log_dir: cps-maven-docker-stage-master/934/
+ref: 7ce495b1e5871d42392b0b45fd3babd9fd5bd634
+containers:
+ - name: 'cps-and-ncmp'
+ version: '3.4.3-20240207T150310Z' \ No newline at end of file
diff --git a/releases/3.4.3.yaml b/releases/3.4.3.yaml
new file mode 100644
index 000000000..43423e1cd
--- /dev/null
+++ b/releases/3.4.3.yaml
@@ -0,0 +1,4 @@
+distribution_type: maven
+log_dir: cps-maven-stage-master/942/
+project: cps
+version: 3.4.3 \ No newline at end of file
diff --git a/spotbugs/pom.xml b/spotbugs/pom.xml
index 8fcf04031..4a15e4e3d 100644
--- a/spotbugs/pom.xml
+++ b/spotbugs/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>spotbugs</artifactId>
- <version>3.4.3-SNAPSHOT</version>
+ <version>3.4.4-SNAPSHOT</version>
<properties>
<nexusproxy>https://nexus.onap.org</nexusproxy>
diff --git a/version.properties b/version.properties
index 6c691bf22..369d36341 100644
--- a/version.properties
+++ b/version.properties
@@ -22,7 +22,7 @@
major=3
minor=4
-patch=3
+patch=4
base_version=${major}.${minor}.${patch}