Modify cmHandle registration for alternateId

    - added alternate id to the interface for persisting the new value
    - updated unit tests to validate the new field

Issue-ID: CPS-1985
Signed-off-by: leventecsanyi <levente.csanyi@est.tech>
Change-Id: I81e61f2ea2ecc5d8c0938af00fa81a99e27e2e23
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml
index 9b5a1fd..1815b47 100644
--- a/cps-ncmp-rest/docs/openapi/components.yaml
+++ b/cps-ncmp-rest/docs/openapi/components.yaml
@@ -140,6 +140,9 @@
             type: string
             enum: [COMPLETE, NONE]
             example: "COMPLETE"
+        alternateId:
+          type: string
+          example: "my-alternate-id"
     RestCmHandleProperties:
       type: object
       additionalProperties:
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy
index c4dd91e..0bc0c1e 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy
@@ -41,7 +41,7 @@
     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: registrationDmiProperties,
-                publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel)
+                publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel, alternateId: 'my-alternate-id', moduleSetTag: 'my-module-set-tag')
             def restDmiPluginRegistration = new RestDmiPluginRegistration(
                 createdCmHandles: [inputRestCmHandle])
         when: 'to plugin dmi registration is called'
@@ -54,6 +54,9 @@
             result.createdCmHandles[0].dmiProperties == mappedDmiProperties
             result.createdCmHandles[0].publicProperties == mappedPublicProperties
             result.createdCmHandles[0].registrationTrustLevel == mappedTrustLevel
+        and: 'alternate ID and module set tag converted correctly'
+            result.createdCmHandles[0].alternateId == 'my-alternate-id'
+            result.createdCmHandles[0].moduleSetTag == 'my-module-set-tag'
         where: 'the following parameters are used'
             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
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 1afe5c7..469d75a 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -328,7 +328,8 @@
                             dmiPluginRegistration.getDmiDataPlugin(),
                             dmiPluginRegistration.getDmiModelPlugin(),
                             cmHandle,
-                            cmHandle.getModuleSetTag());
+                            cmHandle.getModuleSetTag(),
+                            cmHandle.getAlternateId());
                     yangModelCmHandles.add(yangModelCmHandle);
                     initialTrustLevelPerCmHandleId.put(cmHandle.getCmHandleId(), cmHandle.getRegistrationTrustLevel());
                 });
@@ -420,7 +421,7 @@
                 .withLockReason(MODULE_UPGRADE, lockReasonWithModuleSetTag).build());
         return YangModelCmHandle.toYangModelCmHandle(dmiPluginRegistration.getDmiPlugin(),
                 dmiPluginRegistration.getDmiDataPlugin(), dmiPluginRegistration.getDmiModelPlugin(),
-                ncmpServiceCmHandle, moduleSetTag);
+                ncmpServiceCmHandle, moduleSetTag, ncmpServiceCmHandle.getAlternateId());
     }
 
     private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
index b6a04d3..b54c154 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
@@ -87,7 +87,8 @@
                 (String) cmHandleDataNode.getLeaves().get("dmi-data-service-name"),
                 (String) cmHandleDataNode.getLeaves().get("dmi-model-service-name"),
                 ncmpServiceCmHandle,
-                (String) cmHandleDataNode.getLeaves().get("module-set-tag")
+                (String) cmHandleDataNode.getLeaves().get("module-set-tag"),
+                (String) cmHandleDataNode.getLeaves().get("alternate-id")
         );
     }
 
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
index f930d5b..ba36b1a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
@@ -68,6 +68,9 @@
     @JsonProperty("module-set-tag")
     private String moduleSetTag;
 
+    @JsonProperty("alternate-id")
+    private String alternateId;
+
     @JsonProperty("additional-properties")
     private List<Property> dmiProperties;
 
@@ -91,6 +94,7 @@
         copy.dmiProperties = original.getDmiProperties() == null ? null : new ArrayList<>(original.getDmiProperties());
         copy.publicProperties =
                 original.getPublicProperties() == null ? null : new ArrayList<>(original.getPublicProperties());
+        copy.alternateId = original.getAlternateId();
         return copy;
     }
 
@@ -107,13 +111,15 @@
                                                         final String dmiDataServiceName,
                                                         final String dmiModelServiceName,
                                                         final NcmpServiceCmHandle ncmpServiceCmHandle,
-                                                        final String moduleSetTag) {
+                                                        final String moduleSetTag,
+                                                        final String alternateId) {
         final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle();
         yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleId());
         yangModelCmHandle.setDmiServiceName(dmiServiceName);
         yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName);
         yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName);
         yangModelCmHandle.setModuleSetTag(moduleSetTag == null ? StringUtils.EMPTY : moduleSetTag);
+        yangModelCmHandle.setAlternateId(alternateId);
         yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
         yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
                 ncmpServiceCmHandle.getPublicProperties()));
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
index f323079..4989878 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
@@ -23,7 +23,6 @@
 import com.fasterxml.jackson.annotation.JsonSetter;
 import com.fasterxml.jackson.annotation.Nulls;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
@@ -59,18 +58,6 @@
     @JsonSetter(nulls = Nulls.AS_EMPTY)
     private TrustLevel registrationTrustLevel;
 
-    /**
-     * NcmpServiceCmHandle copy constructor.
-     *
-     * @param ncmpServiceCmHandle Ncmp Service CmHandle
-     */
-    public NcmpServiceCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) {
-        this.cmHandleId = ncmpServiceCmHandle.getCmHandleId();
-        this.dmiProperties = new LinkedHashMap<>(ncmpServiceCmHandle.getDmiProperties());
-        this.publicProperties = new LinkedHashMap<>(ncmpServiceCmHandle.getPublicProperties());
-        this.compositeState = ncmpServiceCmHandle.getCompositeState() != null ? new CompositeState(
-                ncmpServiceCmHandle.getCompositeState()) : null;
-        this.moduleSetTag = ncmpServiceCmHandle.getModuleSetTag();
-        this.registrationTrustLevel = ncmpServiceCmHandle.getRegistrationTrustLevel();
-    }
+    @JsonSetter(nulls = Nulls.AS_EMPTY)
+    private String alternateId;
 }
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy
index 5384f31..d5225cd 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy
@@ -62,7 +62,7 @@
             def ncmpServiceCmHandle = new NcmpServiceCmHandle()
             ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.ADVISED).build())
             ncmpServiceCmHandle.cmHandleId = 'ch-1'
-            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, moduleSetTag)
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, moduleSetTag, '')
         and: 'DMI operations returns some module references'
             def moduleReferences =  [ new ModuleReference('module1','1'), new ModuleReference('module2','2') ]
             mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
@@ -91,7 +91,7 @@
             ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder().withLockReason(MODULE_UPGRADE, 'Upgrade to ModuleSetTag: tag-1').build())
             def dmiServiceName = 'some service name'
             ncmpServiceCmHandle.cmHandleId = 'upgraded-ch'
-            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '', '', ncmpServiceCmHandle,'tag-1')
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '', '', ncmpServiceCmHandle,'tag-1', '')
         and: 'some module references'
             def moduleReferences =  [ new ModuleReference('module1','1') ]
         and: 'cache or DMI operations returns some module references for upgraded cm handle'
@@ -127,7 +127,7 @@
             ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder()
                 .withLockReason(MODULE_UPGRADE, 'Upgrade to ModuleSetTag: targetModuleSetTag').build())
             ncmpServiceCmHandle.setCmHandleId('cmHandleId-1')
-            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, 'targetModuleSetTag')
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, 'targetModuleSetTag', '')
             mockCmHandleQueries.cmHandleHasState('cmHandleId-1', CmHandleState.READY) >> true
         and: 'the module service returns some module references'
             def moduleReferences = [new ModuleReference('module1', '1'), new ModuleReference('module2', '2')]
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
index 2b17e5d..c83a540 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
@@ -32,7 +32,7 @@
 class DmiServiceUrlBuilderSpec extends Specification {
 
     static YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('dmiServiceName',
-        'dmiDataServiceName', 'dmiModuleServiceName', new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id'),'')
+        'dmiDataServiceName', 'dmiModuleServiceName', new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id'),'my-module-set-tag', 'my-alternate-id')
 
     NcmpConfiguration.DmiProperties dmiProperties = new NcmpConfiguration.DmiProperties()
 
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandleSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandleSpec.groovy
index ca0015e..493db8c 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandleSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandleSpec.groovy
@@ -47,9 +47,12 @@
                 .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, 'some-sync-time').build()
             ncmpServiceCmHandle.setCompositeState(compositeState)
         when: 'it is converted to a yang model cm handle'
-            def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('', '', '', ncmpServiceCmHandle,'')
+            def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('', '', '', ncmpServiceCmHandle,'my-module-set-tag', 'my-alternate-id')
         then: 'the result has the right size'
             assert objectUnderTest.dmiProperties.size() == 1
+        and: 'the result has the correct values for module set tag and alternate ID'
+            assert objectUnderTest.moduleSetTag == 'my-module-set-tag'
+            assert objectUnderTest.alternateId == 'my-alternate-id'
         and: 'the DMI property in the result has the correct name and value'
             assert objectUnderTest.dmiProperties[0].name == 'myDmiProperty'
             assert objectUnderTest.dmiProperties[0].value == 'value1'
@@ -64,7 +67,7 @@
     def 'Resolve DMI service name: #scenario and #requiredService service require.'() {
         given: 'a yang model cm handle'
             def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName,
-                    dmiModelServiceName, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1'),'')
+                    dmiModelServiceName, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1'),'', '')
         expect:
             assert objectUnderTest.resolveDmiServiceName(requiredService) == expectedService
         where:
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/NcmpServiceCmHandleSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/NcmpServiceCmHandleSpec.groovy
deleted file mode 100644
index e42b914..0000000
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/NcmpServiceCmHandleSpec.groovy
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  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.
- *  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.models
-
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState
-import spock.lang.Specification
-
-class NcmpServiceCmHandleSpec extends Specification {
-
-
-    def 'NCMP Service CmHandle check for deep copy operation'() {
-        given: 'ncmp service cm handle'
-            def originalNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'cmhandleid',
-                dmiProperties: ['property1': 'value1', 'property2': 'value2'],
-                publicProperties: ['pubproperty1': 'value1', 'pubproperty2': 'value2'],
-                compositeState: new CompositeState(cmHandleState: CmHandleState.ADVISED, dataSyncEnabled: Boolean.FALSE))
-        when: 'we create a deep copy'
-            def deepCopiedNcmpServiceCmHandle = new NcmpServiceCmHandle(originalNcmpServiceCmHandle)
-        and: 'we change the original ncmp service cmhandle'
-            originalNcmpServiceCmHandle.dmiProperties = ['newProperty1': 'newValue1']
-            originalNcmpServiceCmHandle.publicProperties = ['newPublicProperty1': 'newPubValue1']
-            originalNcmpServiceCmHandle.compositeState = new CompositeState(cmHandleState: CmHandleState.DELETED, dataSyncEnabled: Boolean.TRUE)
-        then: 'no change in the copied dmi and public properties of ncmp service cmhandle'
-            deepCopiedNcmpServiceCmHandle.dmiProperties == ['property1': 'value1', 'property2': 'value2']
-            deepCopiedNcmpServiceCmHandle.publicProperties == ['pubproperty1': 'value1', 'pubproperty2': 'value2']
-        and: 'no change in the composite state'
-            deepCopiedNcmpServiceCmHandle.compositeState.cmHandleState == CmHandleState.ADVISED
-            deepCopiedNcmpServiceCmHandle.compositeState.dataSyncEnabled == Boolean.FALSE
-    }
-
-}