Merge "Use default values for timers in docker-compose"
authorPriyank Maheshwari <priyank.maheshwari@est.tech>
Mon, 26 Feb 2024 11:54:05 +0000 (11:54 +0000)
committerGerrit Code Review <gerrit@onap.org>
Mon, 26 Feb 2024 11:54:05 +0000 (11:54 +0000)
60 files changed:
checkstyle/pom.xml
cps-application/pom.xml
cps-application/src/main/resources/application.yml
cps-bom/pom.xml
cps-dependencies/pom.xml
cps-events/pom.xml
cps-ncmp-events/pom.xml
cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
cps-ncmp-rest-stub/pom.xml
cps-ncmp-rest/lombok.config
cps-ncmp-rest/pom.xml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
cps-ncmp-service/lombok.config
cps-ncmp-service/pom.xml
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducer.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumer.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpInEventConsumer.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevelManager.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDog.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducerSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumerSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionNcmpInEventConsumerSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/AlternateIdCheckerSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponseSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoaderSpec.groovy
cps-ncmp-service/src/test/resources/application.yml
cps-ncmp-service/src/test/resources/cmSubscription/cmNotificationSubscriptionDmiOutEvent.json [new file with mode: 0644]
cps-parent/pom.xml
cps-path-parser/pom.xml
cps-rest/pom.xml
cps-ri/pom.xml
cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
cps-service/pom.xml
dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java
dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/application.yml
dmi-plugin-demo-and-csit-stub/pom.xml
docs/cps-ncmp-message-status-codes.rst
docs/release-notes.rst
integration-test/pom.xml
integration-test/src/test/resources/application.yml
jacoco-report/pom.xml
pom.xml
releases/3.4.4-container.yaml [new file with mode: 0644]
releases/3.4.4.yaml [new file with mode: 0644]
spotbugs/pom.xml
version.properties

index 95794b1..f794dc2 100644 (file)
@@ -26,7 +26,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.onap.cps</groupId>
     <artifactId>checkstyle</artifactId>
-    <version>3.4.4-SNAPSHOT</version>
+    <version>3.4.5-SNAPSHOT</version>
 
     <profiles>
         <profile>
index 6466bcf..e7ba2c5 100644 (file)
@@ -28,7 +28,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
             <groupId>org.springdoc</groupId>
             <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-http</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-        </dependency>
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-registry-prometheus</artifactId>
index e56e0e1..207341c 100644 (file)
@@ -64,7 +64,7 @@ spring:
 
     liquibase:
         change-log: classpath:changelog/changelog-master.yaml
-        labels: ${LIQUIBASE_LABELS}
+        label-filter: ${LIQUIBASE_LABELS}
 
     servlet:
         multipart:
@@ -200,7 +200,6 @@ ncmp:
             parallelism-level: 10
 
     model-loader:
-        subscription: true
         maximum-attempt-count: 20
 
 # Custom Hazelcast Config.
index ecd442c..da315d3 100644 (file)
@@ -25,7 +25,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.onap.cps</groupId>
     <artifactId>cps-bom</artifactId>
-    <version>3.4.4-SNAPSHOT</version>
+    <version>3.4.5-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <description>This artifact contains dependencyManagement declarations of all published CPS components.</description>
index 2f1a4d2..c3f038d 100644 (file)
@@ -27,7 +27,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.onap.cps</groupId>
     <artifactId>cps-dependencies</artifactId>
-    <version>3.4.4-SNAPSHOT</version>
+    <version>3.4.5-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <name>${project.groupId}:${project.artifactId}</name>
@@ -85,7 +85,7 @@
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-dependencies</artifactId>
-                <version>3.1.2</version>
+                <version>3.2.2</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
-            <dependency>
-                <groupId>org.springframework</groupId>
-                <artifactId>spring-test</artifactId>
-                <version>6.0.11</version>
-            </dependency>
             <dependency>
                 <groupId>io.springfox</groupId>
                 <artifactId>springfox-boot-starter</artifactId>
             </dependency>
             <dependency>
                 <groupId>io.hypersistence</groupId>
-                <artifactId>hypersistence-utils-hibernate-60</artifactId>
-                <version>3.5.0</version>
+                <artifactId>hypersistence-utils-hibernate-63</artifactId>
+                <version>3.7.3</version>
             </dependency>
             <dependency>
                 <groupId>io.micrometer</groupId>
                 <artifactId>groovy-json</artifactId>
                 <version>${groovy.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-server</artifactId>
-                <version>${jetty-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-http</artifactId>
-                <version>${jetty-version}</version>
-            </dependency>
             <dependency>
                 <groupId>org.jetbrains</groupId>
                 <artifactId>annotations</artifactId>
                 <version>22.0.0</version>
             </dependency>
-            <dependency>
-                <groupId>org.junit.jupiter</groupId>
-                <artifactId>junit-jupiter-api</artifactId>
-                <version>5.10.0</version>
-            </dependency>
             <dependency>
                 <groupId>org.liquibase</groupId>
                 <artifactId>liquibase-core</artifactId>
index 662d150..7db3338 100644 (file)
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 6e63843..c14504d 100644 (file)
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 25d4939..ab6d8f8 100644 (file)
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-ncmp-rest-stub</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>cps-ncmp-rest-stub-app</artifactId>
index 1a8e89b..ebe4d7f 100644 (file)
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-ncmp-rest-stub</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
     </parent>
     <artifactId>cps-ncmp-rest-stub-service</artifactId>
 
             <groupId>org.onap.cps</groupId>
             <artifactId>cps-ncmp-rest</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-        </dependency>
         <!-- T E S T - D E P E N D E N C I E S -->
         <dependency>
             <groupId>org.spockframework</groupId>
index a35a886..74dd34a 100644 (file)
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 0736fc5..e4122df 100644 (file)
@@ -18,3 +18,4 @@
 
 config.stopBubbling = true
 lombok.addLombokGeneratedAnnotation = true
+lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
index f363c01..ae3650e 100644 (file)
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 6ec2444..73bd8d7 100755 (executable)
@@ -39,6 +39,7 @@ import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
 import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
 import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
 import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
@@ -62,6 +63,7 @@ import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties;
 import org.onap.cps.ncmp.rest.util.DeprecationHelper;
 import org.onap.cps.spi.model.ModuleDefinition;
 import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.util.StringUtils;
@@ -83,6 +85,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
     private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler;
     private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler;
     private final DataOperationRequestMapper dataOperationRequestMapper;
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_CM_HANDLE_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerCmHandle;
 
     /**
index 1fba85b..6776ef0 100644 (file)
@@ -18,3 +18,4 @@
 
 config.stopBubbling = true
 lombok.addLombokGeneratedAnnotation = true
+lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
index 9beb6b7..d6ea71b 100644 (file)
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index b9c834c..462679e 100644 (file)
@@ -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.
@@ -36,7 +36,8 @@ public enum NcmpResponseStatus {
     SUBSCRIPTION_PENDING("106", "subscription pending for all cm handles"),
     UNKNOWN_ERROR("108", "Unknown error"),
     CM_HANDLE_ALREADY_EXIST("109", "cm-handle already exists"),
-    CM_HANDLE_INVALID_ID("110", "cm-handle has an invalid character(s) in id");
+    CM_HANDLE_INVALID_ID("110", "cm-handle has an invalid character(s) in id"),
+    ALTERNATE_ID_ALREADY_ASSOCIATED("111", "alternate id already associated");
 
     private final String code;
     private final String message;
index 1f2748b..ab83486 100755 (executable)
@@ -24,6 +24,7 @@
 
 package org.onap.cps.ncmp.api.impl;
 
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_READY;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST;
@@ -50,6 +51,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.onap.cps.api.CpsDataService;
 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
 import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler;
 import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
@@ -83,6 +85,7 @@ import org.onap.cps.spi.exceptions.DataValidationException;
 import org.onap.cps.spi.model.ModuleDefinition;
 import org.onap.cps.spi.model.ModuleReference;
 import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 
@@ -101,6 +104,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
     private final CpsDataService cpsDataService;
     private final IMap<String, Object> moduleSyncStartedOnCmHandles;
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
     private final TrustLevelManager trustLevelManager;
     private final AlternateIdChecker alternateIdChecker;
@@ -306,45 +310,17 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
     }
 
-    /**
-     * THis method registers a cm handle and initiates modules sync.
-     *
-     * @param dmiPluginRegistration dmi plugin registration information.
-     * @return cm-handle registration response for create cm-handle requests.
-     */
-    public List<CmHandleRegistrationResponse> parseAndProcessCreatedCmHandlesInRegistration(
-        final DmiPluginRegistration dmiPluginRegistration, final Collection<String> acceptedCmHandleIds) {
-        final List<NcmpServiceCmHandle> cmHandlesToBeCreated = dmiPluginRegistration.getCreatedCmHandles();
-        final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size());
-        final List<YangModelCmHandle> yangModelCmHandles = new ArrayList<>(cmHandlesToBeCreated.size());
-        cmHandlesToBeCreated
-                .forEach(cmHandle -> {
-                    if (acceptedCmHandleIds.contains(cmHandle.getCmHandleId())) {
-                        final YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(
-                                dmiPluginRegistration.getDmiPlugin(),
-                                dmiPluginRegistration.getDmiDataPlugin(),
-                                dmiPluginRegistration.getDmiModelPlugin(),
-                                cmHandle,
-                                cmHandle.getModuleSetTag(),
-                                cmHandle.getAlternateId());
-                        yangModelCmHandles.add(yangModelCmHandle);
-                        initialTrustLevelPerCmHandleId.put(cmHandle.getCmHandleId(),
-                            cmHandle.getRegistrationTrustLevel());
-                    }
-                });
-        return registerNewCmHandles(yangModelCmHandles, initialTrustLevelPerCmHandleId);
-    }
-
-    protected List<CmHandleRegistrationResponse> parseAndProcessDeletedCmHandlesInRegistration(
-        final List<String> tobeRemovedCmHandles) {
+    protected void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
+                                         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
+        final List<String> tobeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles();
         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
-            new ArrayList<>(tobeRemovedCmHandles.size());
+            new ArrayList<>(tobeRemovedCmHandleIds.size());
         final Collection<YangModelCmHandle> yangModelCmHandles =
-            inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandles);
+            inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandleIds);
         updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING);
 
         final Set<String> notDeletedCmHandles = new HashSet<>();
-        for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandles, DELETE_BATCH_SIZE)) {
+        for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) {
             try {
                 batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
                 tobeRemovedCmHandleBatch.forEach(cmHandleId ->
@@ -362,60 +338,58 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
                 }
             }
         }
-
         yangModelCmHandles.removeIf(yangModelCmHandle -> notDeletedCmHandles.contains(yangModelCmHandle.getId()));
         updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETED);
-
-        return cmHandleRegistrationResponses;
+        dmiPluginRegistrationResponse.setRemovedCmHandles(cmHandleRegistrationResponses);
     }
 
-    private void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
+    protected void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
-        if (!dmiPluginRegistration.getRemovedCmHandles().isEmpty()) {
-            dmiPluginRegistrationResponse.setRemovedCmHandles(
-                parseAndProcessDeletedCmHandlesInRegistration(dmiPluginRegistration.getRemovedCmHandles()));
-        }
-    }
+        final List<NcmpServiceCmHandle> ncmpServiceCmHandles = dmiPluginRegistration.getCreatedCmHandles();
+        final List<CmHandleRegistrationResponse> failedCmHandleRegistrationResponses = new ArrayList<>();
 
-    private void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
-                                         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
-        final Collection<String> acceptedCmHandleIds = alternateIdChecker
-            .getIdsOfCmHandlesWithAcceptableAlternateId(dmiPluginRegistration.getCreatedCmHandles());
-        if (!acceptedCmHandleIds.isEmpty()) {
-            dmiPluginRegistrationResponse.setCreatedCmHandles(
-                parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration, acceptedCmHandleIds));
-        }
-    }
+        try {
+            final Collection<String> rejectedCmHandleIds
+                = checkAlternateIds(ncmpServiceCmHandles, failedCmHandleRegistrationResponses);
 
-    private void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
-                                         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
-        if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) {
-            dmiPluginRegistrationResponse.setUpdatedCmHandles(
-                networkCmProxyDataServicePropertyHandler
-                    .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()));
+            final Collection<String> succeededCmHandleIds = persistCmHandlesWithState(dmiPluginRegistration,
+                dmiPluginRegistrationResponse, ncmpServiceCmHandles, rejectedCmHandleIds);
+
+            processTrustLevels(ncmpServiceCmHandles, succeededCmHandleIds);
+
+        } catch (final AlreadyDefinedException alreadyDefinedException) {
+            failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponsesFromXpaths(
+                alreadyDefinedException.getAlreadyDefinedObjectNames(), CM_HANDLE_ALREADY_EXIST));
+        } catch (final Exception exception) {
+            final Collection<String> cmHandleIds =
+                ncmpServiceCmHandles.stream().map(NcmpServiceCmHandle::getCmHandleId).collect(Collectors.toList());
+            failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse
+                .createFailureResponses(cmHandleIds, exception));
         }
+        final List<CmHandleRegistrationResponse> mergedCmHandleRegistrationResponses
+            = new ArrayList<>(failedCmHandleRegistrationResponses);
+        mergedCmHandleRegistrationResponses.addAll(dmiPluginRegistrationResponse.getCreatedCmHandles());
+
+        dmiPluginRegistrationResponse.setCreatedCmHandles(mergedCmHandleRegistrationResponses);
     }
 
-    private void processUpgradedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
-                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
-        if (dmiPluginRegistration.getUpgradedCmHandles() != null
-            && !dmiPluginRegistration.getUpgradedCmHandles().getCmHandles().isEmpty()) {
-            dmiPluginRegistrationResponse.setUpgradedCmHandles(
-                parseAndProcessUpgradedCmHandlesInRegistration(dmiPluginRegistration));
-        }
+    protected void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
+                                         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
+        dmiPluginRegistrationResponse.setUpdatedCmHandles(networkCmProxyDataServicePropertyHandler
+            .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()));
     }
 
+    protected void processUpgradedCmHandles(
+        final DmiPluginRegistration dmiPluginRegistration,
+        final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
 
-    protected List<CmHandleRegistrationResponse> parseAndProcessUpgradedCmHandlesInRegistration(
-        final DmiPluginRegistration dmiPluginRegistration) {
-
-        final List<String> upgradedCmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles();
+        final List<String> cmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles();
         final String upgradedModuleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag();
         final Map<YangModelCmHandle, CmHandleState> acceptedCmHandleStatePerCmHandle
-                = new HashMap<>(upgradedCmHandleIds.size());
-        final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(upgradedCmHandleIds.size());
+            = new HashMap<>(cmHandleIds.size());
+        final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(cmHandleIds.size());
 
-        for (final String cmHandleId : upgradedCmHandleIds) {
+        for (final String cmHandleId : cmHandleIds) {
             try {
                 final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
                 if (yangModelCmHandle.getCompositeState().getCmHandleState() == CmHandleState.READY) {
@@ -442,7 +416,61 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
             }
         }
         cmHandleUpgradeResponses.addAll(upgradeCmHandles(acceptedCmHandleStatePerCmHandle));
-        return cmHandleUpgradeResponses;
+        dmiPluginRegistrationResponse.setUpgradedCmHandles(cmHandleUpgradeResponses);
+    }
+
+    private Collection<String> checkAlternateIds(
+        final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
+        final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
+        final Collection<String> rejectedCmHandleIds = alternateIdChecker
+            .getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated);
+        cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(
+            rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED));
+        return rejectedCmHandleIds;
+    }
+
+    private List<String> persistCmHandlesWithState(final DmiPluginRegistration dmiPluginRegistration,
+                                                   final DmiPluginRegistrationResponse dmiPluginRegistrationResponse,
+                                                   final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
+                                                   final Collection<String> rejectedCmHandleIds) {
+        final List<String> succeededCmHandleIds = new ArrayList<>(cmHandlesToBeCreated.size());
+        final List<YangModelCmHandle> yangModelCmHandlesToRegister = new ArrayList<>(cmHandlesToBeCreated.size());
+        final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
+            new ArrayList<>(cmHandlesToBeCreated.size());
+        for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
+            if (!rejectedCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
+                yangModelCmHandlesToRegister.add(getYangModelCmHandle(dmiPluginRegistration, ncmpServiceCmHandle));
+                cmHandleRegistrationResponses.add(
+                    CmHandleRegistrationResponse.createSuccessResponse(ncmpServiceCmHandle.getCmHandleId()));
+                succeededCmHandleIds.add(ncmpServiceCmHandle.getCmHandleId());
+            }
+        }
+        lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandlesToRegister);
+        dmiPluginRegistrationResponse.setCreatedCmHandles(cmHandleRegistrationResponses);
+        return succeededCmHandleIds;
+    }
+
+    private YangModelCmHandle getYangModelCmHandle(final DmiPluginRegistration dmiPluginRegistration,
+                                                   final NcmpServiceCmHandle ncmpServiceCmHandle) {
+        return YangModelCmHandle.toYangModelCmHandle(
+            dmiPluginRegistration.getDmiPlugin(),
+            dmiPluginRegistration.getDmiDataPlugin(),
+            dmiPluginRegistration.getDmiModelPlugin(),
+            ncmpServiceCmHandle,
+            ncmpServiceCmHandle.getModuleSetTag(),
+            ncmpServiceCmHandle.getAlternateId());
+    }
+
+    private void processTrustLevels(final Collection<NcmpServiceCmHandle> cmHandlesToBeCreated,
+                                    final Collection<String> succeededCmHandleIds) {
+        final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size());
+        for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
+            if (succeededCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
+                initialTrustLevelPerCmHandleId.put(ncmpServiceCmHandle.getCmHandleId(),
+                    ncmpServiceCmHandle.getRegistrationTrustLevel());
+            }
+        }
+        trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
     }
 
     private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle,
@@ -488,15 +516,14 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) {
         inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
-        inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId
-            + "']");
+        inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']");
         removeDeletedCmHandleFromModuleSyncMap(cmHandleId);
     }
 
-    private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> tobeRemovedCmHandles) {
-        inventoryPersistence.deleteSchemaSetsWithCascade(tobeRemovedCmHandles);
-        inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(tobeRemovedCmHandles));
-        tobeRemovedCmHandles.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
+    private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) {
+        inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds);
+        inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds));
+        cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
     }
 
     private Collection<String> mapCmHandleIdsToXpaths(final Collection<String> cmHandles) {
@@ -506,25 +533,9 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     // CPS-1239 Robustness cleaning of in progress cache
-    private void removeDeletedCmHandleFromModuleSyncMap(final String deletedCmHandleId) {
-        if (moduleSyncStartedOnCmHandles.remove(deletedCmHandleId) != null) {
-            log.debug("{} removed from in progress map", deletedCmHandleId);
-        }
-    }
-
-    private List<CmHandleRegistrationResponse> registerNewCmHandles(final List<YangModelCmHandle> yangModelCmHandles,
-                                                                    final Map<String, TrustLevel>
-                                                                            initialTrustLevelPerCmHandleId) {
-        final Set<String> cmHandleIds = initialTrustLevelPerCmHandleId.keySet();
-        try {
-            lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandles);
-            trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
-            return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds);
-        } catch (final AlreadyDefinedException alreadyDefinedException) {
-            return CmHandleRegistrationResponse.createFailureResponses(
-                    alreadyDefinedException.getAlreadyDefinedObjectNames(), CM_HANDLE_ALREADY_EXIST);
-        } catch (final Exception exception) {
-            return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, exception);
+    private void removeDeletedCmHandleFromModuleSyncMap(final String cmHandleId) {
+        if (moduleSyncStartedOnCmHandles.remove(cmHandleId) != null) {
+            log.debug("{} removed from in progress map", cmHandleId);
         }
     }
 
@@ -553,6 +564,4 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
     }
 
-
-
 }
index 1478c86..f5d22af 100644 (file)
@@ -77,7 +77,8 @@ public class NetworkCmProxyDataServicePropertyHandler {
      */
     public List<CmHandleRegistrationResponse> updateCmHandleProperties(
         final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles) {
-        final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>();
+        final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses
+            = new ArrayList<>(ncmpServiceCmHandles.size());
         for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) {
             final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
             try {
index 171db52..f12cc9c 100644 (file)
@@ -30,6 +30,10 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 public class TrustLevelCacheConfig extends HazelcastCacheConfig {
 
+    public static final String TRUST_LEVEL_PER_DMI_PLUGIN_BEAN_NAME = "trustLevelPerDmiPlugin";
+
+    public static final String TRUST_LEVEL_PER_CM_HANDLE_BEAN_NAME = "trustLevelPerCmHandle";
+
     private static final MapConfig trustLevelPerCmHandleCacheConfig =
             createMapConfig("trustLevelPerCmHandleCacheConfig");
 
@@ -41,7 +45,7 @@ public class TrustLevelCacheConfig extends HazelcastCacheConfig {
      *
      * @return configured map of cm handle name as keys to trust-level for values.
      */
-    @Bean
+    @Bean(TRUST_LEVEL_PER_CM_HANDLE_BEAN_NAME)
     public Map<String, TrustLevel> trustLevelPerCmHandle() {
         return createHazelcastInstance("hazelcastInstanceTrustLevelPerCmHandleMap",
                 trustLevelPerCmHandleCacheConfig).getMap("trustLevelPerCmHandle");
@@ -52,7 +56,7 @@ public class TrustLevelCacheConfig extends HazelcastCacheConfig {
      *
      * @return configured map of dmi-plugin name as keys to trust-level for values.
      */
-    @Bean
+    @Bean(TRUST_LEVEL_PER_DMI_PLUGIN_BEAN_NAME)
     public Map<String, TrustLevel> trustLevelPerDmiPlugin() {
         return createHazelcastInstance("hazelcastInstanceTrustLevelPerDmiPluginMap",
                 trustLevelPerDmiPluginCacheConfig).getMap("trustLevelPerDmiPlugin");
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducer.java
new file mode 100644 (file)
index 0000000..5c192a9
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * ============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;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+import java.net.URI;
+import java.util.UUID;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.events.EventsPublisher;
+import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent;
+import org.onap.cps.utils.JsonObjectMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+@RequiredArgsConstructor
+@ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true)
+public class CmNotificationSubscriptionDmiInEventProducer {
+
+    private final EventsPublisher<CloudEvent> eventsPublisher;
+    private final JsonObjectMapper jsonObjectMapper;
+
+    @Value("${app.ncmp.avc.subscription-forward-topic-prefix}")
+    private String cmNotificationSubscriptionDmiInEventTopic;
+
+    /**
+     * Publish the event to the provided dmi plugin with key as subscription id and the event is in Cloud Event format.
+     *
+     * @param subscriptionId                       Cm Subscription Id
+     * @param dmiPluginName                        Dmi Plugin Name
+     * @param eventType                            Type of event
+     * @param cmNotificationSubscriptionDmiInEvent Cm Notification Subscription event for Dmi
+     */
+    public void publishCmNotificationSubscriptionDmiInEvent(final String subscriptionId, final String dmiPluginName,
+            final String eventType, final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent) {
+        eventsPublisher.publishCloudEvent(cmNotificationSubscriptionDmiInEventTopic, subscriptionId,
+                buildAndGetCmNotificationDmiInEventAsCloudEvent(subscriptionId, dmiPluginName, eventType,
+                        cmNotificationSubscriptionDmiInEvent));
+
+    }
+
+    private CloudEvent buildAndGetCmNotificationDmiInEventAsCloudEvent(final String subscriptionId,
+            final String dmiPluginName, final String eventType,
+            final CmNotificationSubscriptionDmiInEvent cmNotificationSubscriptionDmiInEvent) {
+        return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withType(eventType)
+                .withSource(URI.create("NCMP")).withDataSchema(URI.create("org.onap.ncmp.dmi.cm.subscription:1.0.0"))
+                .withExtension("correlationid", subscriptionId.concat("#").concat(dmiPluginName))
+                .withData(jsonObjectMapper.asJsonBytes(cmNotificationSubscriptionDmiInEvent)).build();
+    }
+
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumer.java
new file mode 100644 (file)
index 0000000..ea72fd2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * ============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;
+
+import static org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper.toTargetEvent;
+
+import io.cloudevents.CloudEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class CmNotificationSubscriptionDmiOutEventConsumer {
+
+    /**
+     * Consume the Cm Notification Subscription event from the dmi-plugin.
+     *
+     * @param cmNotificationSubscriptionDmiOutEventConsumerRecord the event to be consumed
+     */
+    @KafkaListener(topics = "${app.ncmp.avc.subscription-response-topic}",
+            containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory")
+    public void consumeCmNotificationSubscriptionDmiOutEvent(
+            final ConsumerRecord<String, CloudEvent> cmNotificationSubscriptionDmiOutEventConsumerRecord) {
+        final CloudEvent cloudEvent = cmNotificationSubscriptionDmiOutEventConsumerRecord.value();
+        final CmNotificationSubscriptionDmiOutEvent cmNotificationSubscriptionDmiOutEvent =
+                toTargetEvent(cloudEvent, CmNotificationSubscriptionDmiOutEvent.class);
+        final String correlationId = String.valueOf(cloudEvent.getExtension("correlationid"));
+        if ("subscriptionCreateResponse".equals(cloudEvent.getType()) && cmNotificationSubscriptionDmiOutEvent != null
+                    && correlationId != null) {
+            handleCmSubscriptionCreate(correlationId, cmNotificationSubscriptionDmiOutEvent);
+        }
+    }
+
+    private void handleCmSubscriptionCreate(final String correlationId,
+            final CmNotificationSubscriptionDmiOutEvent cmNotificationSubscriptionDmiOutEvent) {
+        final String subscriptionId = correlationId.split("#")[0];
+        final String dmiPluginName = correlationId.split("#")[1];
+        log.info("Cm Subscription with id : {} handled by the dmi-plugin : {} has the status : {}", subscriptionId,
+                dmiPluginName, cmNotificationSubscriptionDmiOutEvent.getData().getStatusMessage());
+    }
+}
index bc798af..d3bde01 100644 (file)
@@ -37,9 +37,6 @@ public class CmNotificationSubscriptionNcmpInEventConsumer {
     @Value("${notification.enabled:true}")
     private boolean notificationFeatureEnabled;
 
-    @Value("${ncmp.model-loader.subscription:false}")
-    private boolean subscriptionModelLoaderEnabled;
-
     /**
      * Consume the specified event.
      *
@@ -51,10 +48,8 @@ public class CmNotificationSubscriptionNcmpInEventConsumer {
         final CloudEvent cloudEvent = subscriptionEventConsumerRecord.value();
         final CmNotificationSubscriptionNcmpInEvent cmNotificationSubscriptionNcmpInEvent =
                 toTargetEvent(cloudEvent, CmNotificationSubscriptionNcmpInEvent.class);
-        if (subscriptionModelLoaderEnabled) {
-            log.info("Subscription with name {} to be mapped to hazelcast object...",
-                    cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId());
-        }
+        log.info("Subscription with name {} to be mapped to hazelcast object...",
+                cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId());
         if ("subscriptionCreated".equals(cloudEvent.getType()) && cmNotificationSubscriptionNcmpInEvent != null) {
             log.info("Subscription for ClientID {} with name {} ...", cloudEvent.getSource(),
                     cmNotificationSubscriptionNcmpInEvent.getData().getSubscriptionId());
index 2d7ad69..a43da29 100644 (file)
@@ -34,12 +34,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
 import org.onap.cps.ncmp.api.impl.inventory.enums.PropertyType;
 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
 import org.onap.cps.spi.CpsDataPersistenceService;
 import org.onap.cps.spi.FetchDescendantsOption;
 import org.onap.cps.spi.model.DataNode;
 import org.onap.cps.spi.utils.CpsValidator;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
 @RequiredArgsConstructor
@@ -49,7 +51,11 @@ public class CmHandleQueriesImpl implements CmHandleQueries {
     private static final String DESCENDANT_PATH = "//";
     private static final String ANCESTOR_CM_HANDLES = "/ancestor::cm-handles";
     private final CpsDataPersistenceService cpsDataPersistenceService;
+
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
+
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_CM_HANDLE_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerCmHandle;
     private final CpsValidator cpsValidator;
 
index 22f18cd..4c606a9 100644 (file)
@@ -24,10 +24,12 @@ import java.util.Collection;
 import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
 import org.onap.cps.ncmp.api.impl.events.avc.ncmptoclient.AvcEventPublisher;
 import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
 import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 @Slf4j
@@ -35,7 +37,10 @@ import org.springframework.stereotype.Service;
 @RequiredArgsConstructor
 public class TrustLevelManager {
 
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_CM_HANDLE_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerCmHandle;
+
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
 
     private final InventoryPersistence inventoryPersistence;
index 6ae7ff3..78eaf3e 100644 (file)
@@ -26,8 +26,10 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
 import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
+import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
@@ -40,6 +42,8 @@ public class DmiPluginWatchDog {
     private final NetworkCmProxyDataService networkCmProxyDataService;
 
     private final TrustLevelManager trustLevelManager;
+
+    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN_BEAN_NAME)
     private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
 
     /**
index 1be1a90..4ac6537 100644 (file)
@@ -103,10 +103,10 @@ public class AlternateIdChecker {
      * @param newNcmpServiceCmHandles the proposed new cm handles
      * @return collection of cm handles ids which are acceptable
      */
-    public Collection<String> getIdsOfCmHandlesWithAcceptableAlternateId(
+    public Collection<String> getIdsOfCmHandlesWithRejectedAlternateId(
                                     final Collection<NcmpServiceCmHandle> newNcmpServiceCmHandles) {
         final Set<String> acceptedAlternateIds = new HashSet<>(newNcmpServiceCmHandles.size());
-        final Collection<String> acceptedCmHandleIds = new ArrayList<>(newNcmpServiceCmHandles.size());
+        final Collection<String> rejectedCmHandleIds = new ArrayList<>();
         for (final NcmpServiceCmHandle ncmpServiceCmHandle : newNcmpServiceCmHandles) {
             final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
             final String proposedAlternateId = ncmpServiceCmHandle.getAlternateId();
@@ -124,10 +124,11 @@ public class AlternateIdChecker {
             }
             if (isAcceptable) {
                 acceptedAlternateIds.add(proposedAlternateId);
-                acceptedCmHandleIds.add(cmHandleId);
+            } else {
+                rejectedCmHandleIds.add(cmHandleId);
             }
         }
-        return acceptedCmHandleIds;
+        return rejectedCmHandleIds;
     }
 
     private boolean alternateIdAlreadyInDb(final String alternateId) {
index 8228322..52b8d69 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ============LICENSE_START=======================================================
  *  Copyright (C) 2022 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.
@@ -76,20 +76,22 @@ public class CmHandleRegistrationResponse {
     }
 
     /**
-     * Creates a failure response based on registration error.
+     * Create a failure response of cm handle registration based on xpath and registration error.
+     * Conditions:
+     * - the xpath should be valid according to the cps path, otherwise xpath is not included in the response.
      *
-     * @param failedXpaths       list of failed Xpaths
-     * @param ncmpResponseStatus enum describing the type of registration error
-     * @return CmHandleRegistrationResponse
+     * @param failedXpaths the failed xpaths
+     * @param ncmpResponseStatus type of the registration error
+     * @return collection of cm handle registration response
      */
-    public static List<CmHandleRegistrationResponse> createFailureResponses(final Collection<String> failedXpaths,
-            final NcmpResponseStatus ncmpResponseStatus) {
+    public static List<CmHandleRegistrationResponse> createFailureResponsesFromXpaths(
+        final Collection<String> failedXpaths, final NcmpResponseStatus ncmpResponseStatus) {
         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(failedXpaths.size());
         for (final String xpath : failedXpaths) {
             try {
                 final String cmHandleId = YangDataConverter.extractCmHandleIdFromXpath(xpath);
-                cmHandleRegistrationResponses.add(
-                        CmHandleRegistrationResponse.createFailureResponse(cmHandleId, ncmpResponseStatus));
+                cmHandleRegistrationResponses
+                    .add(CmHandleRegistrationResponse.createFailureResponse(cmHandleId, ncmpResponseStatus));
             } catch (IllegalArgumentException | IllegalStateException e) {
                 log.warn("Unexpected xpath {}", xpath);
             }
@@ -97,6 +99,24 @@ public class CmHandleRegistrationResponse {
         return cmHandleRegistrationResponses;
     }
 
+    /**
+     * Create a failure response of cm handle registration based on cm handle id and registration error.
+     *
+     * @param failedCmHandleIds the failed cm handle ids
+     * @param ncmpResponseStatus type of the registration error
+     * @return collection of cm handle registration response
+     */
+    public static List<CmHandleRegistrationResponse> createFailureResponses(
+            final Collection<String> failedCmHandleIds, final NcmpResponseStatus ncmpResponseStatus) {
+        final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
+            new ArrayList<>(failedCmHandleIds.size());
+        for (final String failedCmHandleId : failedCmHandleIds) {
+            cmHandleRegistrationResponses.add(
+                CmHandleRegistrationResponse.createFailureResponse(failedCmHandleId, ncmpResponseStatus));
+        }
+        return cmHandleRegistrationResponses;
+    }
+
     /**
      * Creates a failure response based on other exception.
      *
index 4615af6..7d6a8e1 100644 (file)
@@ -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.
@@ -50,7 +50,7 @@ public class DmiPluginRegistration {
 
     private List<String> removedCmHandles = Collections.emptyList();
 
-    private UpgradedCmHandles upgradedCmHandles;
+    private UpgradedCmHandles upgradedCmHandles = new UpgradedCmHandles();
 
     /**
      * Validates plugin service names.
index 7cee87a..4c31719 100644 (file)
@@ -32,7 +32,6 @@ import org.onap.cps.api.CpsModuleService;
 import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException;
 import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
 import org.onap.cps.spi.exceptions.AlreadyDefinedException;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 @Slf4j
@@ -45,24 +44,16 @@ public class CmDataSubscriptionModelLoader extends AbstractModelLoader {
     private static final String REGISTRY_DATANODE_NAME = "datastores";
 
     public CmDataSubscriptionModelLoader(final CpsDataspaceService cpsDataspaceService,
-                                         final CpsModuleService cpsModuleService,
-                                         final CpsAnchorService cpsAnchorService,
-                                         final CpsDataService cpsDataService) {
+            final CpsModuleService cpsModuleService, final CpsAnchorService cpsAnchorService,
+            final CpsDataService cpsDataService) {
         super(cpsDataspaceService, cpsModuleService, cpsAnchorService, cpsDataService);
     }
 
-    @Value("${ncmp.model-loader.subscription:true}")
-    private boolean subscriptionModelLoaderEnabled;
-
     @Override
     public void onboardOrUpgradeModel() {
-        if (subscriptionModelLoaderEnabled) {
-            waitUntilDataspaceIsAvailable(NCMP_DATASPACE_NAME);
-            onboardSubscriptionModels();
-            log.info("Subscription Models onboarded successfully");
-        } else {
-            log.info("Subscription Model Loader is disabled");
-        }
+        waitUntilDataspaceIsAvailable(NCMP_DATASPACE_NAME);
+        onboardSubscriptionModels();
+        log.info("Subscription Models onboarded successfully");
     }
 
     private void onboardSubscriptionModels() {
index 313d1b4..cb7e1ef 100644 (file)
@@ -27,7 +27,6 @@ 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 java.util.stream.Collectors
 import org.onap.cps.ncmp.api.impl.inventory.CompositeState
 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager
 import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker
@@ -71,12 +70,18 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     def trustLevelPerDmiPlugin = [:]
     def mockTrustLevelManager = Mock(TrustLevelManager)
     def mockAlternateIdChecker = Mock(AlternateIdChecker)
-    def objectUnderTest = getObjectUnderTest()
+
+    def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
+        mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries,
+        stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService,
+        mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin, mockTrustLevelManager, mockAlternateIdChecker))
 
     def setup() {
         // always accept all cm handles
-        mockAlternateIdChecker.getIdsOfCmHandlesWithAcceptableAlternateId(_) >>
-            { args -> args[0].stream().map(it -> it.cmHandleId).collect(Collectors.toList()) }
+        mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(_) >> []
+
+        // always can find all cm handles in DB
+        mockInventoryPersistence.getYangModelCmHandles(_) >> { args -> args[0].collect { new YangModelCmHandle(id:it) } }
     }
 
     def 'DMI Registration: Create, Update, Delete & Upgrade operations are processed in the right order'() {
@@ -94,15 +99,16 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         when: 'registration is processed'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration)
         then: 'cm-handles are removed first'
-            1 * objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_)
+            1 * objectUnderTest.processRemovedCmHandles(*_)
         and: 'de-registered cm handle entry is removed from in progress map'
             1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle-2')
         then: 'cm-handles are created'
-            1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_)
+            1 * objectUnderTest.processCreatedCmHandles(*_)
         then: 'cm-handles are updated'
-            1 * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_)
+            1 * objectUnderTest.processUpdatedCmHandles(*_)
+            1 * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> []
         then: 'cm-handles are upgraded'
-            1 * objectUnderTest.parseAndProcessUpgradedCmHandlesInRegistration(*_)
+            1 * objectUnderTest.processUpgradedCmHandles(*_)
     }
 
     def 'DMI Registration upgrade operation with upgrade node state #scenario'() {
@@ -137,29 +143,6 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             'cm handle is invalid' | new DataValidationException('some error message', 'some error details')  || '110'
     }
 
-    def 'DMI Registration: Response from all operations types are in response'() {
-        given: 'a registration with operations of all three types'
-            def dmiRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server')
-            dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])])
-            dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])])
-            dmiRegistration.setRemovedCmHandles(['cmhandle-2'])
-        and: 'update cm-handles can be processed successfully'
-            def updateResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-2')]
-            mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> updateResponses
-        and: 'create cm-handles can be processed successfully'
-            def createdResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-1')]
-            objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_) >> createdResponses
-        and: 'delete cm-handles can be processed successfully'
-            def removeResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-3')]
-            objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_) >> removeResponses
-        when: 'registration is processed'
-            def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration)
-        then: 'response has values from all operations'
-            response.removedCmHandles == removeResponses
-            response.createdCmHandles == createdResponses
-            response.updatedCmHandles == updateResponses
-    }
-
     def 'Create CM-handle Validation: Registration with valid Service names: #scenario'() {
         given: 'a registration '
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: dmiPlugin, dmiModelPlugin: dmiModelPlugin,
@@ -168,7 +151,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         when: 'update registration and sync module is called with correct DMI plugin information'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'create cm handles registration and sync modules is called with the correct plugin information'
-            1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration, _)
+            1 * objectUnderTest.processCreatedCmHandles(dmiPluginRegistration, _)
         and: 'dmi is added to the dmi trustLevel map'
             assert trustLevelPerDmiPlugin.size() == 1
             assert trustLevelPerDmiPlugin.containsKey(expectedDmiPluginRegisteredName)
@@ -190,7 +173,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             def exceptionThrown = thrown(DmiRequestException.class)
             assert exceptionThrown.getMessage().contains(expectedMessageDetails)
         and: 'registration is not called'
-            0 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration)
+            0 * objectUnderTest.processCreatedCmHandles(*_)
         where:
             scenario                         | dmiPlugin  | dmiModelPlugin | dmiDataPlugin || expectedMessageDetails
             'empty DMI plugins'              | ''         | ''             | ''            || 'No DMI plugin service names'
@@ -231,22 +214,18 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             'without dmi & public properties' | [:]                      | [:]                            || [:]                                        | [:]
     }
 
-    def 'Add CM-Handle to trustLevelPerCmHandle Successfully with: #scenario.'() {
-        given: 'a registration with trustLevel and populated cache'
-            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server')
-            dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleId: 'ch-1', registrationTrustLevel: TrustLevel.NONE),
-                                                      new NcmpServiceCmHandle(cmHandleId: cmHandleId, registrationTrustLevel: registrationTrustLevel)]
+    def 'Add CM-Handle #scenario.'() {
+        given: ' registration details for one cm handles'
+            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
+                createdCmHandles:[new NcmpServiceCmHandle(cmHandleId: 'ch-1', registrationTrustLevel: registrationTrustLevel)])
         when: 'registration is updated'
-            def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
-        then: 'a successful response is received'
-            assert response.createdCmHandles.size() == expectedNumberOfCreatedCmHandles
-        and: 'trustLevel is set for the created cm-handle'
-            1 * mockTrustLevelManager.handleInitialRegistrationOfTrustLevels(_)
+            objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
+        then: 'trustLevel is set for the created cm-handle'
+            1 * mockTrustLevelManager.handleInitialRegistrationOfTrustLevels(expectedMapping)
         where:
-            scenario                                 | cmHandleId | registrationTrustLevel || expectedNumberOfCreatedCmHandles
-            'new trusted cm handle'                  | 'ch-new'   | TrustLevel.COMPLETE    || 2
-            'existing cm handle without trust level' | 'ch-1'     | null                   || 1
-            'new cm handle without trust level'      | 'ch-new'   | null                   || 2
+            scenario                 | registrationTrustLevel || expectedMapping
+            'with trusted cm handle' | TrustLevel.COMPLETE    || [ 'ch-1' : TrustLevel.COMPLETE ]
+            'without trust level'    | null                   || [ 'ch-1' : null ]
     }
 
     def 'Create CM-Handle Multiple Requests: All cm-handles creation requests are processed with some failures'() {
@@ -311,17 +290,15 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
 
     def 'Remove CmHandle Successfully: #scenario'() {
         given: 'a registration'
-            addPersistedYangModelCmHandles(['cmhandle'])
-            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
-                removedCmHandles: ['cmhandle'])
+            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', removedCmHandles: ['cmhandle'])
         and: '#scenario'
-            mockCpsModuleService.deleteSchemaSetsWithCascade(_, ['cmhandle']) >>
-                { if (!schemaSetExist) { throw new SchemaSetNotFoundException("", "") } }
+            mockCpsModuleService.deleteSchemaSetsWithCascade(_, ['cmhandle']) >>  { if (!schemaSetExist) { throw new SchemaSetNotFoundException('', '') } }
         when: 'registration is updated to delete cmhandle'
             def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'the cmHandle state is updated to "DELETING"'
-            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_)
-        and: 'method to delete relevant schema set is called once'
+            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) >>
+                { args -> args[0].values()[0] == CmHandleState.DELETING }
+        then: 'method to delete relevant schema set is called once'
             1 * mockInventoryPersistence.deleteSchemaSetsWithCascade(_)
         and: 'method to delete relevant list/list element is called once'
             1 * mockInventoryPersistence.deleteDataNodes(_)
@@ -332,7 +309,10 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
                 assert it.cmHandle == 'cmhandle'
             }
         and: 'the cmHandle state is updated to "DELETED"'
-            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_)
+            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) >>
+                { args -> args[0].values()[0] == CmHandleState.DELETED }
+        and: 'No cm handles state updates for "upgraded cm handles"'
+            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch([:])
         where:
             scenario                                            | schemaSetExist
             'schema-set exists and can be deleted successfully' | true
@@ -340,9 +320,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     }
 
     def 'Remove CmHandle: Partial Success'() {
-        given: 'some unique yang model cm handles'
-            addPersistedYangModelCmHandles(['cmhandle1', 'cmhandle2', 'cmhandle3'])
-        and: 'a registration with three cm-handles to be deleted'
+        given: 'a registration with three cm-handles to be deleted'
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
                 removedCmHandles: ['cmhandle1', 'cmhandle2', 'cmhandle3'])
         and: 'cm-handle deletion fails on batch'
@@ -359,7 +337,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle1')
         and: 'successfully de-registered cm handle 3 is removed from in progress map even though it was already being removed'
             1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle3') >> 'already in progress'
-        and: 'failed de-registered cm handle entries should not be removed from in progress map'
+        and: 'failed de-registered cm handle entries should NOT be removed from in progress map'
             0 * mockModuleSyncStartedOnCmHandles.remove('cmhandle2')
         and: '1st and 3rd cm-handle deletes successfully'
             with(response.removedCmHandles[0]) {
@@ -382,11 +360,13 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
                 assert it.size() == 2
                 assert it.every { entry -> entry.value == CmHandleState.DELETED }
             })
+        and: 'No cm handles state updates for "upgraded cm handles"'
+            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch([:])
+
     }
 
     def 'Remove CmHandle Error Handling: Schema Set Deletion failed'() {
         given: 'a registration'
-            addPersistedYangModelCmHandles(['cmhandle'])
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
                 removedCmHandles: ['cmhandle'])
         and: 'schema set batch deletion failed with unknown error'
@@ -413,7 +393,6 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
 
     def 'Remove CmHandle Error Handling: #scenario'() {
         given: 'a registration'
-            addPersistedYangModelCmHandles(['cmhandle'])
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
                 removedCmHandles: ['cmhandle'])
         and: 'cm-handle deletion fails on batch'
@@ -446,18 +425,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         when: 'the DMI plugin registration happens'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'the new alternate id is added to the cache'
-            1 * mockAlternateIdChecker.getIdsOfCmHandlesWithAcceptableAlternateId(ncmpServiceCmHandles) >> ['cmhandle1']
+            1 * mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(ncmpServiceCmHandles) >> ['cmhandle1']
     }
 
-    def getObjectUnderTest() {
-        return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
-                mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries,
-                stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService,
-                mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin, mockTrustLevelManager, mockAlternateIdChecker))
-    }
-
-    def addPersistedYangModelCmHandles(ids) {
-        def yangModelCmHandles = ids.collect { new YangModelCmHandle(id:it) }
-        mockInventoryPersistence.getYangModelCmHandles(ids) >> yangModelCmHandles
-    }
 }
index fc548eb..9b4fe14 100644 (file)
@@ -23,6 +23,8 @@
 
 package org.onap.cps.ncmp.api.impl
 
+import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse
+
 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
@@ -270,8 +272,11 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                     dmiDataPlugin: 'service2')
             dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
             mockDmiPluginRegistration.getCreatedCmHandles() >> [ncmpServiceCmHandle]
+        and: 'no rejected cm handles because of alternate ids'
+            mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(_) >> []
         when: 'parse and create cm handle in dmi registration then sync module'
-            objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(mockDmiPluginRegistration, ['test-cm-handle-id'])
+            mockDmiPluginRegistration.createdCmHandles = ['test-cm-handle-id']
+            objectUnderTest.processCreatedCmHandles(mockDmiPluginRegistration, new DmiPluginRegistrationResponse())
         then: 'system persists the cm handle state'
             1 * mockLcmEventsCmHandleStateHandler.initiateStateAdvised(_) >> {
                 args -> {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiInEventProducerSpec.groovy
new file mode 100644 (file)
index 0000000..cd9b8dd
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * ============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
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import io.cloudevents.CloudEvent
+import org.onap.cps.events.EventsPublisher
+import org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper
+import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.CmNotificationSubscriptionDmiInEvent
+import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.Cmhandle
+import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.ncmp_to_dmi.Data
+import org.onap.cps.utils.JsonObjectMapper
+import spock.lang.Specification
+
+class CmNotificationSubscriptionDmiInEventProducerSpec extends Specification {
+
+    def mockEventsPublisher = Mock(EventsPublisher)
+    def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
+    def objectUnderTest = new CmNotificationSubscriptionDmiInEventProducer(mockEventsPublisher, jsonObjectMapper)
+
+    def 'Create and Publish Cm Notification Subscription DMI In Event'() {
+        given: 'a cm subscription for a dmi plugin'
+            def subscriptionId = 'test-subscription-id'
+            def dmiPluginName = 'test-dmiplugin'
+            def eventType = 'subscriptionCreateRequest'
+            def cmNotificationSubscriptionDmiInEvent = new CmNotificationSubscriptionDmiInEvent(data: new Data(cmhandles: [new Cmhandle(cmhandleId: 'test-1', privateProperties: [:])]))
+        and: 'also we have target topic for dmiPlugin'
+            objectUnderTest.cmNotificationSubscriptionDmiInEventTopic = 'dmiplugin-test-topic'
+        when: 'the event is published'
+            objectUnderTest.publishCmNotificationSubscriptionDmiInEvent(subscriptionId, dmiPluginName, eventType, cmNotificationSubscriptionDmiInEvent)
+        then: 'the event contains the required attributes'
+            1 * mockEventsPublisher.publishCloudEvent(_, _, _) >> {
+                args ->
+                    {
+                        assert args[0] == 'dmiplugin-test-topic'
+                        assert args[1] == subscriptionId
+                        def cmNotificationSubscriptionDmiInEventAsCloudEvent = (args[2] as CloudEvent)
+                        assert cmNotificationSubscriptionDmiInEventAsCloudEvent.getExtension('correlationid') == subscriptionId + '#' + dmiPluginName
+                        assert cmNotificationSubscriptionDmiInEventAsCloudEvent.type == 'subscriptionCreateRequest'
+                        assert cmNotificationSubscriptionDmiInEventAsCloudEvent.source.toString() == 'NCMP'
+                        assert CloudEventMapper.toTargetEvent(cmNotificationSubscriptionDmiInEventAsCloudEvent, CmNotificationSubscriptionDmiInEvent) == cmNotificationSubscriptionDmiInEvent
+                    }
+            }
+    }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmNotificationSubscriptionDmiOutEventConsumerSpec.groovy
new file mode 100644 (file)
index 0000000..4f0132e
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * ============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
+
+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 com.fasterxml.jackson.databind.ObjectMapper
+import io.cloudevents.CloudEvent
+import io.cloudevents.core.builder.CloudEventBuilder
+import org.apache.kafka.clients.consumer.ConsumerRecord
+import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
+import org.onap.cps.ncmp.events.cmnotificationsubscription_merge1_0_0.dmi_to_ncmp.CmNotificationSubscriptionDmiOutEvent
+import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.utils.JsonObjectMapper
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+
+@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
+class CmNotificationSubscriptionDmiOutEventConsumerSpec extends MessagingBaseSpec {
+
+    def objectUnderTest = new CmNotificationSubscriptionDmiOutEventConsumer()
+    def logger = Spy(ListAppender<ILoggingEvent>)
+
+    @Autowired
+    JsonObjectMapper jsonObjectMapper
+
+    @Autowired
+    ObjectMapper objectMapper
+
+    void setup() {
+        ((Logger) LoggerFactory.getLogger(CmNotificationSubscriptionDmiOutEventConsumer.class)).addAppender(logger)
+        logger.start()
+    }
+
+    void cleanup() {
+        ((Logger) LoggerFactory.getLogger(CmNotificationSubscriptionDmiOutEventConsumer.class)).detachAndStopAllAppenders()
+    }
+
+
+    def 'Consume valid CM Subscription response from DMI Plugin'() {
+        given: 'a cmsubscription event'
+            def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionDmiOutEvent.json')
+            def testEventSent = jsonObjectMapper.convertJsonString(jsonData, CmNotificationSubscriptionDmiOutEvent.class)
+            def testCloudEventSent = CloudEventBuilder.v1()
+                .withData(objectMapper.writeValueAsBytes(testEventSent))
+                .withId('random-uuid')
+                .withType('subscriptionCreateResponse')
+                .withSource(URI.create('test-dmi-plugin-name'))
+                .withExtension('correlationid', 'sub-1#test-dmi-plugin-name').build()
+            def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
+        when: 'the valid event is consumed'
+            objectUnderTest.consumeCmNotificationSubscriptionDmiOutEvent(consumerRecord)
+        then: 'an event is logged with level INFO'
+            def loggingEvent = getLoggingEvent()
+            assert loggingEvent.level == Level.INFO
+        and: 'the log indicates the task completed successfully'
+            assert loggingEvent.formattedMessage == 'Cm Subscription with id : sub-1 handled by the dmi-plugin : test-dmi-plugin-name has the status : accepted'
+    }
+
+    def getLoggingEvent() {
+        return logger.list[0]
+    }
+
+}
index 6a3d4be..1074229 100644 (file)
@@ -71,8 +71,6 @@ class CmNotificationSubscriptionNcmpInEventConsumerSpec extends MessagingBaseSpe
             def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
         and: 'notifications are enabled'
             objectUnderTest.notificationFeatureEnabled = true
-        and: 'subscription model loader is enabled'
-            objectUnderTest.subscriptionModelLoaderEnabled = true
         when: 'the valid event is consumed'
             objectUnderTest.consumeSubscriptionEvent(consumerRecord)
         then: 'an event is logged with level INFO'
index f41fd6c..aaa0344 100644 (file)
@@ -76,17 +76,17 @@ class AlternateIdCheckerSpec extends Specification {
             mockInventoryPersistenceService.getCmHandleDataNodeByAlternateId(_) >>
                 {  args -> altAlreadyInDb.contains(args[0]) ? new DataNode() : throwDataNodeNotFoundException() }
         when: 'the batch of new cm handles is checked'
-            def result = objectUnderTest.getIdsOfCmHandlesWithAcceptableAlternateId(batch)
+            def result = objectUnderTest.getIdsOfCmHandlesWithRejectedAlternateId(batch)
         then: 'the result only contains the ids of the acceptable cm handles'
-            assert result.contains('ch-1') == acceptCh1
-            assert result.contains('ch-2') == acceptCh2
+            assert result.contains('ch-1') == rejectCh1
+            assert result.contains('ch-2') == rejectCh2
         where: 'the following alternate ids are used'
-            scenario                          | alt1   | alt2   | altAlreadyInDb  || acceptCh1 | acceptCh2
-            'no alternate ids'                | ''     | ''     | ['dont matter'] || true      | true
-            'new alternate ids'               | 'fdn1' | 'fdn2' | ['other fdn']   || true      | true
-            'one already used alternate id'   | 'fdn1' | 'fdn2' | ['fdn1']        || false     | true
-            'two already used alternate ids'  | 'fdn1' | 'fdn2' | ['fdn1','fdn2'] || false     | false
-            'duplicate alternate id in batch' | 'fdn1' | 'fdn1' | ['dont matter'] || true      | false
+            scenario                          | alt1   | alt2   | altAlreadyInDb  || rejectCh1 | rejectCh2
+            'no alternate ids'                | ''     | ''     | ['dont matter'] || false      | false
+            'new alternate ids'               | 'fdn1' | 'fdn2' | ['other fdn']   || false      | false
+            'one already used alternate id'   | 'fdn1' | 'fdn2' | ['fdn1']        || true       | false
+            'two already used alternate ids'  | 'fdn1' | 'fdn2' | ['fdn1','fdn2'] || true       | true
+            'duplicate alternate id in batch' | 'fdn1' | 'fdn1' | ['dont matter'] || false      | true
     }
 
     def throwDataNodeNotFoundException() {
index d76f912..7803ae3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ============LICENSE_START=======================================================
  *  Copyright (C) 2022 Bell Canada
- *  Modifications Copyright (C) 2023 Nordix Foundation
+ *  Modifications 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,6 +21,7 @@
 
 package org.onap.cps.ncmp.api.models
 
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR
 
@@ -71,7 +72,7 @@ class CmHandleRegistrationResponseSpec extends Specification {
     def 'Failed cm-handle Registration with multiple responses.'() {
         when: 'cm-handle failure response is created for 2 xpaths'
             def cmHandleRegistrationResponses =
-                CmHandleRegistrationResponse.createFailureResponses(["somePathWithId[@id='123']","somePathWithId[@id='456']"], CM_HANDLE_ALREADY_EXIST)
+                CmHandleRegistrationResponse.createFailureResponsesFromXpaths(["somePathWithId[@id='123']", "somePathWithId[@id='456']"], CM_HANDLE_ALREADY_EXIST)
         then: 'the response has the correct cm handle ids'
             assert cmHandleRegistrationResponses.size() == 2
             assert cmHandleRegistrationResponses.stream().map(it -> it.cmHandle).collect(Collectors.toList())
@@ -81,9 +82,20 @@ class CmHandleRegistrationResponseSpec extends Specification {
     def 'Failed cm-handle Registration with multiple responses with an unexpected xpath.'() {
         when: 'cm-handle failure response is created for one valid and one unexpected xpath'
             def cmHandleRegistrationResponses =
-                CmHandleRegistrationResponse.createFailureResponses(["somePathWithId[@id='123']","valid/xpath/without-id[@key='123']"], CM_HANDLE_ALREADY_EXIST)
+                CmHandleRegistrationResponse.createFailureResponsesFromXpaths(["somePathWithId[@id='123']", "valid/xpath/without-id[@key='123']"], CM_HANDLE_ALREADY_EXIST)
         then: 'the response has only one entry'
             assert cmHandleRegistrationResponses.size() == 1
     }
 
+    def 'Failed cm-handle registration based on cm handle id and registration error'() {
+        when: 'the failure response is created with "alternate id already associated" error code for 1 cm handle'
+            def cmHandleRegistrationResponses =
+                    CmHandleRegistrationResponse.createFailureResponses(['ch 1'], ALTERNATE_ID_ALREADY_ASSOCIATED)
+        then: 'the response with expected values'
+            assert cmHandleRegistrationResponses[0].cmHandle == 'ch 1'
+            assert cmHandleRegistrationResponses[0].status == Status.FAILURE
+            assert cmHandleRegistrationResponses[0].ncmpResponseStatus == ALTERNATE_ID_ALREADY_ASSOCIATED
+            assert cmHandleRegistrationResponses[0].errorText == 'alternate id already associated'
+    }
+
 }
index bde9961..f3b405b 100644 (file)
 
 package org.onap.cps.ncmp.init
 
-import org.onap.cps.api.CpsAnchorService
-import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException
-import org.onap.cps.spi.exceptions.AlreadyDefinedException
-
-import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
-
 import ch.qos.logback.classic.Level
 import ch.qos.logback.classic.Logger
 import ch.qos.logback.core.read.ListAppender
-import org.onap.cps.api.CpsDataspaceService
+import org.onap.cps.api.CpsAnchorService
 import org.onap.cps.api.CpsDataService
+import org.onap.cps.api.CpsDataspaceService
 import org.onap.cps.api.CpsModuleService
+import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException
+import org.onap.cps.spi.exceptions.AlreadyDefinedException
 import org.onap.cps.spi.model.Dataspace
 import org.slf4j.LoggerFactory
 import org.springframework.boot.context.event.ApplicationReadyEvent
 import org.springframework.context.annotation.AnnotationConfigApplicationContext
 import spock.lang.Specification
 
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
+
 class CmDataSubscriptionModelLoaderSpec extends Specification {
 
     def mockCpsDataspaceService = Mock(CpsDataspaceService)
@@ -67,9 +66,7 @@ class CmDataSubscriptionModelLoaderSpec extends Specification {
     }
 
     def 'Onboard subscription model via application ready event.'() {
-        given:'model loader is enabled'
-            objectUnderTest.subscriptionModelLoaderEnabled = true
-        and: 'dataspace is ready for use'
+        given: 'dataspace is ready for use'
             mockCpsDataspaceService.getDataspace(NCMP_DATASPACE_NAME) >> new Dataspace('')
         when: 'the application is ready'
             objectUnderTest.onApplicationEvent(Mock(ApplicationReadyEvent))
@@ -81,14 +78,14 @@ class CmDataSubscriptionModelLoaderSpec extends Specification {
             1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '{"datastores":{}}', _)
         and: 'the data service is called once to create datastore for Passthrough-operational'
             1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '/datastores',
-                    '{"datastore":[{"name":"ncmp-datastore:passthrough-operational","cm-handles":{}}]}', _, _)
+                '{"datastore":[{"name":"ncmp-datastore:passthrough-operational","cm-handles":{}}]}', _, _)
         and: 'the data service is called once to create datastore for Passthrough-running'
             1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '/datastores',
-                    '{"datastore":[{"name":"ncmp-datastore:passthrough-running","cm-handles":{}}]}', _, _)
+                '{"datastore":[{"name":"ncmp-datastore:passthrough-running","cm-handles":{}}]}', _, _)
     }
 
     def 'Create node for datastore with already defined exception.'() {
-        given:'the data service throws an Already Defined exception'
+        given: 'the data service throws an Already Defined exception'
             mockCpsDataService.saveData(*_) >> { throw AlreadyDefinedException.forDataNodes([], 'some context') }
         when: 'attempt to create datastore'
             objectUnderTest.createDatastore('some datastore')
@@ -110,16 +107,4 @@ class CmDataSubscriptionModelLoaderSpec extends Specification {
             assert thrown.details.contains('test message')
     }
 
-    def 'Subscription model loader disabled.' () {
-        given: 'model loader is disabled'
-            objectUnderTest.subscriptionModelLoaderEnabled = false
-        when: 'application is ready'
-            objectUnderTest.onApplicationEvent(Mock(ApplicationReadyEvent))
-        then: 'no interaction with admin service'
-            0 * mockCpsDataspaceService.getDataspace(_)
-        then: 'a message is logged that the function is disabled'
-            def logs = loggingListAppender.list.toString()
-            assert logs.contains('Subscription Model Loader is disabled')
-    }
-
 }
index a4bb4e8..a3283ff 100644 (file)
@@ -50,8 +50,6 @@ ncmp:
         async-executor:
             parallelism-level: 3
 
-    model-loader:
-        subscription: true
 
 # Custom Hazelcast Config.
 hazelcast:
diff --git a/cps-ncmp-service/src/test/resources/cmSubscription/cmNotificationSubscriptionDmiOutEvent.json b/cps-ncmp-service/src/test/resources/cmSubscription/cmNotificationSubscriptionDmiOutEvent.json
new file mode 100644 (file)
index 0000000..f0b78fb
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "data": {
+    "statusCode": "1",
+    "statusMessage": "accepted"
+  }
+}
\ No newline at end of file
index 6e7554b..b5a9ad1 100644 (file)
@@ -32,7 +32,7 @@
 
     <groupId>org.onap.cps</groupId>
     <artifactId>cps-parent</artifactId>
-    <version>3.4.4-SNAPSHOT</version>
+    <version>3.4.5-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <properties>
                 <plugin>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-maven-plugin</artifactId>
-                    <version>3.1.2</version>
+                    <version>3.2.2</version>
                     <executions>
                         <execution>
                             <goals>
index e6e00dc..da0265c 100644 (file)
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 022c3b8..f8ec757 100644 (file)
@@ -28,7 +28,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 2fd369b..2801d64 100644 (file)
@@ -26,7 +26,7 @@
     <parent>\r
         <groupId>org.onap.cps</groupId>\r
         <artifactId>cps-parent</artifactId>\r
-        <version>3.4.4-SNAPSHOT</version>\r
+        <version>3.4.5-SNAPSHOT</version>\r
         <relativePath>../cps-parent/pom.xml</relativePath>\r
     </parent>\r
 \r
@@ -71,7 +71,7 @@
         <!-- Add Hibernate support for Postgres datatype JSONB and Postgres arrays -->\r
         <dependency>\r
             <groupId>io.hypersistence</groupId>\r
-            <artifactId>hypersistence-utils-hibernate-60</artifactId>\r
+            <artifactId>hypersistence-utils-hibernate-63</artifactId>\r
         </dependency>\r
         <dependency>\r
             <groupId>org.projectlombok</groupId>\r
index 1e42702..b449a78 100755 (executable)
@@ -69,6 +69,7 @@ import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
 import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.retry.RetryContext;
 import org.springframework.retry.annotation.Backoff;
 import org.springframework.retry.annotation.Retryable;
 import org.springframework.retry.support.RetrySynchronizationManager;
@@ -277,8 +278,8 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
                                 dataIntegrityViolationException, newYangResourceEntities);
                 convertedException.ifPresent(
                         e -> {
-                            int retryCount = RetrySynchronizationManager.getContext() == null ? 0
-                                    : RetrySynchronizationManager.getContext().getRetryCount();
+                            final RetryContext context = RetrySynchronizationManager.getContext();
+                            int retryCount = context == null ? 0 : context.getRetryCount();
                             log.warn("Cannot persist duplicated yang resource. System will attempt this method "
                                     + "up to 5 times. Current retry count : {}", ++retryCount, e);
                         });
index de716df..93a4d3d 100644 (file)
@@ -29,7 +29,7 @@
   <parent>
     <groupId>org.onap.cps</groupId>
     <artifactId>cps-parent</artifactId>
-    <version>3.4.4-SNAPSHOT</version>
+    <version>3.4.5-SNAPSHOT</version>
     <relativePath>../cps-parent/pom.xml</relativePath>
   </parent>
 
       <artifactId>cloudevents-spring</artifactId>
     </dependency>
     <!-- T E S T   D E P E N D E N C I E S -->
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-test</artifactId>
-      <scope>test</scope>
-    </dependency>
     <dependency>
       <groupId>org.codehaus.groovy</groupId>
       <artifactId>groovy</artifactId>
index eca8871..053ac1b 100644 (file)
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>dmi-plugin-demo-and-csit-stub</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
     </parent>
 
     <artifactId>dmi-plugin-demo-and-csit-stub-app</artifactId>
             <artifactId>dmi-plugin-demo-and-csit-stub-service</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>11.0.16</version>
-        </dependency>
-        <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-            <version>6.0.0</version>
-        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
index d3142f8..47ad877 100644 (file)
@@ -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,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>dmi-plugin-demo-and-csit-stub</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
     </parent>
     <artifactId>dmi-plugin-demo-and-csit-stub-service</artifactId>
 
             </exclusions>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.googlecode.json-simple</groupId>
             <artifactId>json-simple</artifactId>
@@ -48,4 +52,4 @@
             <artifactId>cps-ncmp-rest</artifactId>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>
index 772eb05..d77cbcc 100644 (file)
@@ -89,7 +89,7 @@ public class DmiRestStubController {
      * @return ResponseEntity response entity having module response as json string.
      */
     @PostMapping("/v1/ch/{cmHandleId}/modules")
-    public ResponseEntity<String> getModuleReferences(@PathVariable final String cmHandleId,
+    public ResponseEntity<String> getModuleReferences(@PathVariable("cmHandleId") final String cmHandleId,
                                                       @RequestBody final Object moduleReferencesRequest) {
         delay(moduleReferencesDelayMs);
         final String moduleResponseContent = getModuleResourceResponse(cmHandleId,
@@ -108,7 +108,7 @@ public class DmiRestStubController {
      */
     @PostMapping("/v1/ch/{cmHandleId}/moduleResources")
     public ResponseEntity<String> retrieveModuleResources(
-            @PathVariable final String cmHandleId,
+            @PathVariable("cmHandleId") final String cmHandleId,
             @RequestBody final Object moduleResourcesReadRequest) {
         delay(moduleResourcesDelayMs);
         final String moduleResourcesResponseContent = getModuleResourceResponse(cmHandleId,
index de097a6..73e0c5c 100644 (file)
@@ -1,5 +1,5 @@
 #  ============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.
@@ -36,6 +36,12 @@ spring:
             value-serializer: io.cloudevents.kafka.CloudEventSerializer
             client-id: cps-core
 
+management:
+    endpoints:
+        web:
+            exposure:
+                include: health
+
 app:
     ncmp:
         async-m2m:
index 9fb40e3..a16a954 100644 (file)
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
 
index 20a5ae3..90590a2 100644 (file)
@@ -1,6 +1,6 @@
 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
 .. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2023 Nordix Foundation
+.. Copyright (C) 2023-2024 Nordix Foundation
 
 .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
 .. _dataOperationMessageStatusCodes:
@@ -38,6 +38,8 @@ CPS-NCMP Message Status Codes
     +-----------------+------------------------------------------------------+-----------------------------------+
     | 110             | cm-handle has an invalid character(s) in id          | Inventory                         |
     +-----------------+------------------------------------------------------+-----------------------------------+
+    | 111             | alternate id already associated                      | Inventory                         |
+    +-----------------+------------------------------------------------------+-----------------------------------+
 
 .. note::
 
index 779a347..49dc463 100644 (file)
@@ -16,6 +16,35 @@ CPS Release Notes
 ..      * * *   NEW DELHI   * * *
 ..      =========================
 
+Version: 3.4.5
+==============
+
+Release Data
+------------
+
++--------------------------------------+--------------------------------------------------------+
+| **CPS Project**                      |                                                        |
+|                                      |                                                        |
++--------------------------------------+--------------------------------------------------------+
+| **Docker images**                    | onap/cps-and-ncmp:3.4.5                                |
+|                                      |                                                        |
++--------------------------------------+--------------------------------------------------------+
+| **Release designation**              | 3.4.5 New Delhi                                        |
+|                                      |                                                        |
++--------------------------------------+--------------------------------------------------------+
+| **Release date**                     | Not yet released                                       |
+|                                      |                                                        |
++--------------------------------------+--------------------------------------------------------+
+
+Bug Fixes
+---------
+3.4.5
+
+
+Features
+--------
+
+
 Version: 3.4.4
 ==============
 
@@ -32,16 +61,19 @@ Release Data
 | **Release designation**              | 3.4.4 New Delhi                                        |
 |                                      |                                                        |
 +--------------------------------------+--------------------------------------------------------+
-| **Release date**                     | Not yet released                                       |
+| **Release date**                     | 2024 February 23                                       |
 |                                      |                                                        |
 +--------------------------------------+--------------------------------------------------------+
 
 Bug Fixes
 ---------
 3.4.4
+    - `CPS-2027 <https://jira.onap.org/browse/CPS-2027>`_ Upgrade Yang modules using module set tag functionalities fix
 
 Features
 --------
+    - `CPS-2057 <https://jira.onap.org/browse/CPS-2057>`_ Leaf lists are sorted by default if Yang model does not specify order.
+    - `CPS-2087 <https://jira.onap.org/browse/CPS-2087>`_ Performance improvement of CPS Path Queries.
 
 
 Version: 3.4.3
index 3d0125a..5a40ed2 100644 (file)
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
index d1307cd..f77cb02 100644 (file)
@@ -195,7 +195,6 @@ ncmp:
       parallelism-level: 1
 
   model-loader:
-    subscription: true
     maximum-attempt-count: 20
 
   servlet:
index 60aa6b4..c95b73a 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.onap.cps</groupId>
         <artifactId>cps-parent</artifactId>
-        <version>3.4.4-SNAPSHOT</version>
+        <version>3.4.5-SNAPSHOT</version>
         <relativePath>../cps-parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index 3f67efb..5a71e18 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
 \r
     <groupId>org.onap.cps</groupId>\r
     <artifactId>cps-aggregator</artifactId>\r
-    <version>3.4.4-SNAPSHOT</version>\r
+    <version>3.4.5-SNAPSHOT</version>\r
     <packaging>pom</packaging>\r
 \r
     <name>cps</name>\r
diff --git a/releases/3.4.4-container.yaml b/releases/3.4.4-container.yaml
new file mode 100644 (file)
index 0000000..01170f7
--- /dev/null
@@ -0,0 +1,8 @@
+distribution_type: container
+container_release_tag: 3.4.4
+project: cps
+log_dir: cps-maven-docker-stage-master/935/
+ref: 8c37c03acae232829ee4e3aab636800741159de9
+containers:
+  - name: 'cps-and-ncmp'
+    version: '3.4.4-20240223T140746Z'
diff --git a/releases/3.4.4.yaml b/releases/3.4.4.yaml
new file mode 100644 (file)
index 0000000..642770a
--- /dev/null
@@ -0,0 +1,4 @@
+distribution_type: maven
+log_dir: cps-maven-stage-master/943/
+project: cps
+version: 3.4.4
index 4a15e4e..7b38301 100644 (file)
@@ -25,7 +25,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.onap.cps</groupId>
     <artifactId>spotbugs</artifactId>
-    <version>3.4.4-SNAPSHOT</version>
+    <version>3.4.5-SNAPSHOT</version>
 
     <properties>
         <nexusproxy>https://nexus.onap.org</nexusproxy>
index 369d363..daf4035 100644 (file)
@@ -22,7 +22,7 @@
 
 major=3
 minor=4
-patch=4
+patch=5
 
 base_version=${major}.${minor}.${patch}