2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 Nordix Foundation
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.integration.functional
23 import org.onap.cps.integration.base.CpsIntegrationSpecBase
24 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
25 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
26 import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleSyncWatchdog
27 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
28 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
29 import org.onap.cps.spi.exceptions.DataNodeNotFoundException
30 import org.springframework.beans.factory.annotation.Autowired
31 import org.springframework.http.HttpStatus
32 import org.springframework.http.MediaType
33 import org.springframework.test.web.client.MockRestServiceServer
34 import spock.util.concurrent.PollingConditions
36 import static org.springframework.test.web.client.match.MockRestRequestMatchers.anything
37 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo
38 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
40 class NcmpCmHandleRegistrationSpec extends CpsIntegrationSpecBase {
42 NetworkCmProxyDataService objectUnderTest
45 ModuleSyncWatchdog moduleSyncWatchdog
47 static final DMI_URL = 'http://mock-dmi-server'
49 def moduleReferencesResponse
50 def moduleResourcesResponse
53 objectUnderTest = networkCmProxyDataService
54 mockDmiServer = MockRestServiceServer.createServer(restTemplate)
55 moduleReferencesResponse = readResourceDataFile('mock-dmi-responses/ietfYangModuleResponse.json')
56 moduleResourcesResponse = readResourceDataFile('mock-dmi-responses/ietfYangModuleResourcesResponse.json')
59 def 'CM Handle is READY when Registration is successful.'() {
60 given: 'a CM handle to create'
61 def cmHandlesToCreate = [new NcmpServiceCmHandle(cmHandleId: 'cm-1')]
63 and: 'DMI registration params'
64 def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI_URL, createdCmHandles: cmHandlesToCreate)
65 dmiPluginRegistration.validateDmiPluginRegistration()
67 and: 'DMI returns modules'
68 mockDmiServer.expect(requestTo("${DMI_URL}/dmi/v1/ch/cm-1/modules"))
69 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(moduleReferencesResponse))
70 mockDmiServer.expect(requestTo("${DMI_URL}/dmi/v1/ch/cm-1/moduleResources"))
71 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(moduleResourcesResponse))
73 when: 'a CM-handle is registered'
74 def dmiPluginRegistrationResponse = networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
76 then: 'registration gives expected response'
77 assert dmiPluginRegistrationResponse.createdCmHandles.size() == 1
79 and: 'CM-handle is initially in ADVISED state'
80 assert CmHandleState.ADVISED == objectUnderTest.getCmHandleCompositeState('cm-1').cmHandleState
82 when: 'module sync runs'
83 moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
85 then: 'CM-handle goes to READY state'
86 new PollingConditions().within(3, () -> {
87 assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState('cm-1').cmHandleState
90 and: 'DMI received expected requests'
91 mockDmiServer.verify()
94 def 'CM Handle goes to LOCKED state when DMI gives error during module sync.'() {
95 given: 'a CM handle to create'
96 def cmHandlesToCreate = [new NcmpServiceCmHandle(cmHandleId: 'cm-2')]
98 and: 'DMI registration params'
99 def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI_URL, createdCmHandles: cmHandlesToCreate)
100 dmiPluginRegistration.validateDmiPluginRegistration()
102 and: 'DMI returns error code'
103 mockDmiServer.expect(anything()).andRespond(withStatus(HttpStatus.SERVICE_UNAVAILABLE))
105 when: 'a CM-handle is registered'
106 def dmiPluginRegistrationResponse = networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
108 then: 'registration gives expected response'
109 assert dmiPluginRegistrationResponse.createdCmHandles.size() == 1
111 and: 'CM-handle is initially in ADVISED state'
112 assert CmHandleState.ADVISED == objectUnderTest.getCmHandleCompositeState('cm-2').cmHandleState
114 when: 'module sync runs'
115 moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
117 then: 'CM-handle goes to LOCKED state'
118 new PollingConditions().within(3, () -> {
119 assert CmHandleState.LOCKED == objectUnderTest.getCmHandleCompositeState('cm-2').cmHandleState
122 and: 'DMI received expected requests'
123 mockDmiServer.verify()
126 def 'Deregister CM-handles.'() {
127 given: 'a list of CM handles to remove'
128 def cmHandlesToRemove = ['cm-1', 'cm-2']
130 and: 'DMI registration parameters are set'
131 def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI_URL, removedCmHandles: cmHandlesToRemove)
132 dmiPluginRegistration.validateDmiPluginRegistration()
134 when: 'the CM-handles are deregistered'
135 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
137 then: 'the CM-handles no longer exists'
138 assert !objectUnderTest.getAllCmHandleIdsByDmiPluginIdentifier(DMI_URL).contains('cm-1')
139 assert !objectUnderTest.getAllCmHandleIdsByDmiPluginIdentifier(DMI_URL).contains('cm-2')