104166d754f4631057f717b65f466350d0550f0c
[cps.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved.
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the 'License');
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an 'AS IS' BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.integration.functional.ncmp.inventory
22
23 import org.onap.cps.api.model.DataNode
24 import org.onap.cps.api.model.ModuleReference
25 import org.onap.cps.api.parameters.FetchDescendantsOption
26 import org.onap.cps.integration.base.FunctionalSpecBase
27 import org.onap.cps.ncmp.api.inventory.models.*
28 import org.onap.cps.ncmp.impl.NetworkCmProxyInventoryFacadeImpl
29 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
30 import org.onap.cps.ncmp.impl.utils.YangDataConverter
31
32 class ModuleUpgradeServiceIntegrationSpec extends FunctionalSpecBase {
33
34     NetworkCmProxyInventoryFacadeImpl objectUnderTest
35     def cmHandleId = 'ch-1'
36
37     def setup() {
38         objectUnderTest = networkCmProxyInventoryFacade
39     }
40
41     def 'CM Handle registry (inventory) model upgrade poc (incl. backward compatibility)'() {
42         given: 'DMI plugin provides initial modules for the CM handle'
43             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
44         and: 'NCMP already has an existing module reference (old revision)'
45             def existingModule = new ModuleReference(moduleName: "dmi-registry", revision: "2024-02-23")
46             cpsModulePersistenceService.getYangResourceModuleReferences(_, _) >> [existingModule]
47         when: 'A CM-handle is registered'
48             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI1_URL)
49             dmiPluginRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleId: cmHandleId, additionalProperties: ['addProp1': 'some-value'])])
50             def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(dmiPluginRegistration)
51         then: 'The CM-handle registration succeeds'
52             assert dmiPluginRegistrationResponse.createdCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
53         and: 'The CM-handle is initialized with ADVISED state'
54             assert CmHandleState.ADVISED == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
55         then:  'The module sync watchdog is invoked for advised CM-handles'
56             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
57         then: 'After module sync, the CM-handle transitions to READY state'
58             assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
59         when: 'A new version of the dmi-registry module (upgrade) is available'
60             def newYangContent = readResourceDataFile('inventory/dmi-registry@2025-07-22.yang')
61             def newYangResourceContentPerName = ["dmi-registry@2025-07-22.yang": newYangContent]
62         then: 'The schema set is upgraded with the new module revision'
63             cpsModulePersistenceService.createSchemaSet('NCMP-Admin', 'dmi-registry-2025-07-22', newYangResourceContentPerName)
64             cpsAnchorService.updateAnchorSchemaSet('NCMP-Admin','ncmp-dmi-registry','dmi-registry-2025-07-22')
65         when: 'that state gets updated to a different value'
66             final Collection<DataNode> cmHandleDataNodes = inventoryPersistence.getCmHandleDataNodeByCmHandleId('ch-1', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
67             YangModelCmHandle yangModelCmHandle= YangDataConverter.toYangModelCmHandle(cmHandleDataNodes[0])
68             CompositeState compositeState= yangModelCmHandle.getCompositeState()
69             compositeState.setCmHandleState(CmHandleState.LOCKED)
70         then: 'the CM handle gets saved'
71             inventoryPersistence.saveCmHandleState(cmHandleId, compositeState)
72         and: 'we load the CM handle again'
73             final Collection<DataNode> updatedCmHandleDataNodes = inventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
74             YangModelCmHandle updatedYangModelCmHandle= YangDataConverter.toYangModelCmHandle(updatedCmHandleDataNodes[0])
75         and: 'the state has the new value i.e. load and save worked successfully'
76             assert updatedYangModelCmHandle.getCompositeState().cmHandleState == CmHandleState.LOCKED
77         when: 'The CM-handle additional properties are updated'
78             def dmiPluginRegistrationToUpdate = new DmiPluginRegistration(dmiPlugin: DMI1_URL)
79             dmiPluginRegistrationToUpdate.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleId: cmHandleId, additionalProperties: ['addProp1': 'value1','addProp2': 'value2'])])
80             def updatedDmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(dmiPluginRegistrationToUpdate)
81         then: 'The update response confirms SUCCESS for the CM-handle'
82             assert updatedDmiPluginRegistrationResponse.updatedCmHandles.size() == 1
83             def updatedHandleResponse = updatedDmiPluginRegistrationResponse.updatedCmHandles[0]
84             assert updatedHandleResponse.cmHandle == cmHandleId
85             assert updatedHandleResponse.status == CmHandleRegistrationResponse.Status.SUCCESS
86         and: 'Reloaded CM-handle contains the new additional properties (backward compatibility preserved)'
87             def updatedCmHandleDataNodesAfterUpdate  = inventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
88             def reloadedCmHandleAfterUpdate= YangDataConverter.toYangModelCmHandle(updatedCmHandleDataNodesAfterUpdate[0])
89             assert reloadedCmHandleAfterUpdate.additionalProperties.collectEntries { [it.name, it.value] } == [addProp1: "value1", addProp2: "value2"]
90         cleanup: 'deregister CM handle'
91             deregisterCmHandle(DMI1_URL, cmHandleId)
92     }
93
94 }