2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2023-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.base
23 import java.time.OffsetDateTime
24 import org.onap.cps.api.CpsAnchorService
25 import org.onap.cps.api.CpsDataService
26 import org.onap.cps.api.CpsDataspaceService
27 import org.onap.cps.api.CpsModuleService
28 import org.onap.cps.api.CpsQueryService
29 import org.onap.cps.integration.DatabaseTestContainer
30 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService
31 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
32 import org.onap.cps.ncmp.api.NetworkCmProxyQueryService
33 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
34 import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleSyncWatchdog
35 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
36 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
37 import org.onap.cps.spi.exceptions.DataspaceNotFoundException
38 import org.onap.cps.spi.model.DataNode
39 import org.onap.cps.spi.repository.DataspaceRepository
40 import org.onap.cps.spi.utils.SessionManager
41 import org.springframework.beans.factory.annotation.Autowired
42 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
43 import org.springframework.boot.autoconfigure.domain.EntityScan
44 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
45 import org.springframework.boot.test.context.SpringBootTest
46 import org.springframework.context.annotation.ComponentScan
47 import org.springframework.data.jpa.repository.config.EnableJpaRepositories
48 import org.springframework.http.HttpStatus
49 import org.springframework.http.MediaType
50 import org.springframework.test.web.client.MockRestServiceServer
51 import org.springframework.test.web.servlet.MockMvc
52 import org.springframework.web.client.RestTemplate
53 import org.testcontainers.spock.Testcontainers
54 import spock.lang.Shared
55 import spock.lang.Specification
56 import spock.util.concurrent.PollingConditions
58 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo
59 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
61 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService])
63 @EnableAutoConfiguration
65 @EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
66 @ComponentScan(basePackages = ['org.onap.cps'])
67 @EntityScan('org.onap.cps.spi.entities')
68 abstract class CpsIntegrationSpecBase extends Specification {
71 DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
77 CpsDataspaceService cpsDataspaceService
80 CpsAnchorService cpsAnchorService
83 CpsDataService cpsDataService
86 CpsModuleService cpsModuleService
89 CpsQueryService cpsQueryService
92 SessionManager sessionManager
95 NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService
98 NetworkCmProxyDataService networkCmProxyDataService
101 NetworkCmProxyQueryService networkCmProxyQueryService
104 RestTemplate restTemplate
107 ModuleSyncWatchdog moduleSyncWatchdog
109 MockRestServiceServer mockDmiServer = null
111 static final DMI_URL = 'http://mock-dmi-server'
113 def static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
114 def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
116 def static initialized = false
117 def now = OffsetDateTime.now()
121 cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
122 createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
125 mockDmiServer = MockRestServiceServer.createServer(restTemplate)
129 mockDmiServer.reset()
132 def static readResourceDataFile(filename) {
133 return new File('src/test/resources/data/' + filename).text
136 // *** CPS Integration Test Utilities ***
138 def static countDataNodesInTree(DataNode dataNode) {
139 return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
142 def static countDataNodesInTree(Collection<DataNode> dataNodes) {
144 for (DataNode parent : dataNodes) {
145 nodeCount += countDataNodesInTree(parent)
150 def getBookstoreYangResourcesNameToContentMap() {
151 def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
152 def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
153 return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
156 def createStandardBookStoreSchemaSet(targetDataspace) {
157 cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
160 def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
161 cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
164 def dataspaceExists(dataspaceName) {
166 cpsDataspaceService.getDataspace(dataspaceName)
167 } catch (DataspaceNotFoundException ignored) {
173 def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
174 (1..numberOfAnchors).each {
175 cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
176 cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now())
180 def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) {
181 def innerJson = (1..numberOfElements).collect {
182 '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}'
184 return '{"' + name + '":[' + innerJson + ']}'
187 def createLeafList(name, numberOfElements, valuePrefix) {
188 def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',')
189 return '"' + name + '":[' + innerJson + ']'
192 // *** NCMP Integration Test Utilities ***
194 def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag, dmiModuleReferencesResponse, dmiModuleResourcesResponse) {
195 def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag)
196 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate]))
197 mockDmiResponsesForRegistration(dmiPlugin, cmHandleId, dmiModuleReferencesResponse, dmiModuleResourcesResponse)
198 moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
199 new PollingConditions().within(3, () -> {
200 CmHandleState.READY == networkCmProxyDataService.getCmHandleCompositeState(cmHandleId).cmHandleState
202 mockDmiServer.reset()
205 def deregisterCmHandle(dmiPlugin, cmHandleId) {
206 deregisterCmHandles(dmiPlugin, [cmHandleId])
209 def deregisterCmHandles(dmiPlugin, cmHandleIds) {
210 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds))
213 def mockDmiResponsesForRegistration(dmiPlugin, cmHandleId, dmiModuleReferencesResponse, dmiModuleResourcesResponse) {
214 if (dmiModuleReferencesResponse != null) {
215 mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/modules"))
216 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(dmiModuleReferencesResponse))
218 if (dmiModuleResourcesResponse != null) {
219 mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/moduleResources"))
220 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(dmiModuleResourcesResponse))