Merge "Add trust level notification schema"
authorToine Siebelink <toine.siebelink@est.tech>
Thu, 2 Nov 2023 20:36:35 +0000 (20:36 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 2 Nov 2023 20:36:35 +0000 (20:36 +0000)
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapper.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy
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/models/NcmpServiceCmHandle.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy

index 62c9eb0..9b5a1fd 100644 (file)
@@ -136,6 +136,10 @@ components:
         moduleSetTag:
           type: string
           example: "my-module-set-tag"
+        trustLevel:
+            type: string
+            enum: [COMPLETE, NONE]
+            example: "COMPLETE"
     RestCmHandleProperties:
       type: object
       additionalProperties:
index af785d5..045b8a7 100644 (file)
@@ -56,6 +56,7 @@ public interface NcmpRestInputMapper {
     @Mapping(source = "cmHandle", target = "cmHandleId")
     @Mapping(source = "cmHandleProperties", target = "dmiProperties")
     @Mapping(source = "publicCmHandleProperties", target = "publicProperties")
+    @Mapping(source = "trustLevel", target = "registrationTrustLevel")
     NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle);
 
     RestModuleReference toRestModuleReference(
index dfe7bf3..c4dd91e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022 Nordix Foundation
+ *  Copyright (C) 2022-2023 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 package org.onap.cps.ncmp.rest.controller
 
 import org.mapstruct.factory.Mappers
+import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters
 import org.onap.cps.ncmp.rest.model.ConditionProperties
@@ -39,8 +40,8 @@ class NcmpRestInputMapperSpec extends Specification {
 
     def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() {
         given: 'a rest cm handle input'
-            def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties,
-                publicCmHandleProperties: publicProperties)
+            def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: registrationDmiProperties,
+                publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel)
             def restDmiPluginRegistration = new RestDmiPluginRegistration(
                 createdCmHandles: [inputRestCmHandle])
         when: 'to plugin dmi registration is called'
@@ -50,12 +51,13 @@ class NcmpRestInputMapperSpec extends Specification {
         and: 'the converted cm handle has the same id'
             result.createdCmHandles[0].cmHandleId == 'example-id'
         and: '(empty) properties are converted correctly'
-            result.createdCmHandles[0].dmiProperties == expectedDmiProperties
-            result.createdCmHandles[0].publicProperties == expectedPublicProperties
+            result.createdCmHandles[0].dmiProperties == mappedDmiProperties
+            result.createdCmHandles[0].publicProperties == mappedPublicProperties
+            result.createdCmHandles[0].registrationTrustLevel == mappedTrustLevel
         where: 'the following parameters are used'
-            scenario                    | dmiProperties                            | publicProperties                                         || expectedDmiProperties                     | expectedPublicProperties
-            'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property']   || ['Property-Example': 'example property']  | ['Public-Property-Example': 'public example property']
-            'no properties'             | null                                     | null                                                     || [:]                                       | [:]
+            scenario                    | registrationDmiProperties                | registrationPublicProperties                           | registrationTrustLevel || mappedDmiProperties                      | mappedPublicProperties                                 | mappedTrustLevel
+            'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | 'COMPLETE'             || ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | TrustLevel.COMPLETE
+            'no properties'             | null                                     | null                                                   | null                   || [:]                                      | [:]                                                    | null
     }
 
     def 'Handling empty dmi registration'() {
index febd1cf..4ec00da 100755 (executable)
@@ -99,7 +99,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
     private final CpsDataService cpsDataService;
     private final IMap<String, Object> moduleSyncStartedOnCmHandles;
-    private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
+    private final Map<String, TrustLevel> trustLevelPerCmHandle;
 
     @Override
     public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
@@ -113,6 +113,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
 
         if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) {
+            populateTrustLevelPerCmHandleCache(dmiPluginRegistration);
             dmiPluginRegistrationResponse.setCreatedCmHandles(
                     parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration));
         }
@@ -127,8 +128,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
                     parseAndProcessUpgradedCmHandlesInRegistration(dmiPluginRegistration));
         }
 
-        setTrustLevelPerDmiPlugin(dmiPluginRegistration);
-
         return dmiPluginRegistrationResponse;
     }
 
@@ -487,11 +486,17 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         return cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId).toList();
     }
 
-    private void setTrustLevelPerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
-        if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
-            trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiPlugin(), TrustLevel.COMPLETE);
-        } else {
-            trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiDataPlugin(), TrustLevel.COMPLETE);
+    private void populateTrustLevelPerCmHandleCache(final DmiPluginRegistration dmiPluginRegistration) {
+        for (final NcmpServiceCmHandle cmHandle: dmiPluginRegistration.getCreatedCmHandles()) {
+            if (cmHandle.getRegistrationTrustLevel() == null) {
+                if (trustLevelPerCmHandle.containsKey(cmHandle.getCmHandleId())) {
+                    log.warn("CmHandle : {}, Already exists, Initial trustLevel ignored.", cmHandle.getCmHandleId());
+                } else {
+                    trustLevelPerCmHandle.put(cmHandle.getCmHandleId(), TrustLevel.COMPLETE);
+                }
+            } else {
+                trustLevelPerCmHandle.put(cmHandle.getCmHandleId(), cmHandle.getRegistrationTrustLevel());
+            }
         }
     }
 
index 0b50346..f323079 100644 (file)
@@ -29,6 +29,7 @@ import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
+import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
 import org.springframework.validation.annotation.Validated;
 
 /**
@@ -55,6 +56,9 @@ public class NcmpServiceCmHandle {
     @JsonSetter(nulls = Nulls.AS_EMPTY)
     private String moduleSetTag;
 
+    @JsonSetter(nulls = Nulls.AS_EMPTY)
+    private TrustLevel registrationTrustLevel;
+
     /**
      * NcmpServiceCmHandle copy constructor.
      *
@@ -67,5 +71,6 @@ public class NcmpServiceCmHandle {
         this.compositeState = ncmpServiceCmHandle.getCompositeState() != null ? new CompositeState(
                 ncmpServiceCmHandle.getCompositeState()) : null;
         this.moduleSetTag = ncmpServiceCmHandle.getModuleSetTag();
+        this.registrationTrustLevel = ncmpServiceCmHandle.getRegistrationTrustLevel();
     }
 }
index 0f40906..c87efce 100644 (file)
@@ -68,7 +68,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
     def mockCpsDataService = Mock(CpsDataService)
     def mockModuleSyncStartedOnCmHandles = Mock(IMap<String, Object>)
-    def mockTrustLevelPerDmiPlugin = Mock(IMap<String, TrustLevel>)
+    def trustLevelPerCmHandle = [:]
     def objectUnderTest = getObjectUnderTest()
 
     def 'DMI Registration: Create, Update, Delete & Upgrade operations are processed in the right order'() {
@@ -128,13 +128,11 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'create cm handles registration and sync modules is called with the correct plugin information'
             1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration)
-        and: 'dmi is added to the trustLevel map'
-            1 * mockTrustLevelPerDmiPlugin.put(dmiPluginRegisteredName, TrustLevel.COMPLETE)
         where:
-            scenario                          | dmiPlugin  | dmiModelPlugin | dmiDataPlugin | dmiPluginRegisteredName
-            'combined DMI plugin'             | 'service1' | ''             | ''            | 'service1'
-            'data & model DMI plugins'        | ''         | 'service1'     | 'service2'    | 'service2'
-            'data & model using same service' | ''         | 'service1'     | 'service1'    | 'service1'
+            scenario                          | dmiPlugin  | dmiModelPlugin | dmiDataPlugin
+            'combined DMI plugin'             | 'service1' | ''             | ''
+            'data & model DMI plugins'        | ''         | 'service1'     | 'service2'
+            'data & model using same service' | ''         | 'service1'     | 'service1'
     }
 
     def 'Create CM-handle Validation: Invalid DMI plugin service name with #scenario'() {
@@ -193,6 +191,24 @@ 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)]
+        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'
+            assert trustLevelPerCmHandle.get(cmHandleId) == expectedTrustLevel
+        where:
+            scenario                                   | cmHandleId | registrationTrustLevel || expectedNumberOfCreatedCmHandles | expectedTrustLevel
+            'new cmHandleId and trustLevel'            | 'ch-new'   | TrustLevel.COMPLETE    || 2                                | TrustLevel.COMPLETE
+            'existing cmHandleId with null trustLevel' | 'ch-1'     | null                   || 1                                | TrustLevel.NONE
+            'cmHandleId with null trustLevel'          | 'ch-new'   | null                   || 2                                | TrustLevel.COMPLETE
+    }
+
     def 'Create CM-Handle Multiple Requests: All cm-handles creation requests are processed with some failures'() {
         given: 'a registration with three cm-handles to be created'
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
@@ -387,7 +403,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
         return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
                 mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries,
                 stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService,
-                mockModuleSyncStartedOnCmHandles, mockTrustLevelPerDmiPlugin))
+                mockModuleSyncStartedOnCmHandles, trustLevelPerCmHandle))
     }
 
     def addPersistedYangModelCmHandles(ids) {