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.context.SpringBootTest
45 import org.springframework.context.annotation.ComponentScan
46 import org.springframework.data.jpa.repository.config.EnableJpaRepositories
47 import org.springframework.http.HttpStatus
48 import org.springframework.http.MediaType
49 import org.springframework.test.web.client.MockRestServiceServer
50 import org.springframework.web.client.RestTemplate
51 import org.testcontainers.spock.Testcontainers
52 import spock.lang.Shared
53 import spock.lang.Specification
54 import spock.util.concurrent.PollingConditions
56 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo
57 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
59 @SpringBootTest(classes = [CpsDataspaceService])
61 @EnableAutoConfiguration
62 @EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
63 @ComponentScan(basePackages = ['org.onap.cps'])
64 @EntityScan('org.onap.cps.spi.entities')
65 abstract class CpsIntegrationSpecBase extends Specification {
68 DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
71 CpsDataspaceService cpsDataspaceService
74 CpsAnchorService cpsAnchorService
77 CpsDataService cpsDataService
80 CpsModuleService cpsModuleService
83 CpsQueryService cpsQueryService
86 SessionManager sessionManager
89 NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService
92 NetworkCmProxyDataService networkCmProxyDataService
95 NetworkCmProxyQueryService networkCmProxyQueryService
98 RestTemplate restTemplate
101 ModuleSyncWatchdog moduleSyncWatchdog
103 MockRestServiceServer mockDmiServer = null
105 static final DMI_URL = 'http://mock-dmi-server'
107 def static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
108 def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
110 def static initialized = false
111 def now = OffsetDateTime.now()
115 cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
116 createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
119 mockDmiServer = MockRestServiceServer.createServer(restTemplate)
123 mockDmiServer.reset()
126 def static readResourceDataFile(filename) {
127 return new File('src/test/resources/data/' + filename).text
130 // *** CPS Integration Test Utilities ***
132 def static countDataNodesInTree(DataNode dataNode) {
133 return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
136 def static countDataNodesInTree(Collection<DataNode> dataNodes) {
138 for (DataNode parent : dataNodes) {
139 nodeCount += countDataNodesInTree(parent)
144 def getBookstoreYangResourcesNameToContentMap() {
145 def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
146 def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
147 return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
150 def createStandardBookStoreSchemaSet(targetDataspace) {
151 cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
154 def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
155 cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
158 def dataspaceExists(dataspaceName) {
160 cpsDataspaceService.getDataspace(dataspaceName)
161 } catch (DataspaceNotFoundException ignored) {
167 def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
168 (1..numberOfAnchors).each {
169 cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
170 cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now())
174 def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) {
175 def innerJson = (1..numberOfElements).collect {
176 '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}'
178 return '{"' + name + '":[' + innerJson + ']}'
181 def createLeafList(name, numberOfElements, valuePrefix) {
182 def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',')
183 return '"' + name + '":[' + innerJson + ']'
186 // *** NCMP Integration Test Utilities ***
188 def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag, dmiModuleReferencesResponse, dmiModuleResourcesResponse) {
189 def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag)
190 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate]))
191 mockDmiResponsesForRegistration(dmiPlugin, cmHandleId, dmiModuleReferencesResponse, dmiModuleResourcesResponse)
192 moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
193 new PollingConditions().within(3, () -> {
194 CmHandleState.READY == networkCmProxyDataService.getCmHandleCompositeState(cmHandleId).cmHandleState
196 mockDmiServer.reset()
199 def deregisterCmHandle(dmiPlugin, cmHandleId) {
200 deregisterCmHandles(dmiPlugin, [cmHandleId])
203 def deregisterCmHandles(dmiPlugin, cmHandleIds) {
204 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds))
207 def mockDmiResponsesForRegistration(dmiPlugin, cmHandleId, dmiModuleReferencesResponse, dmiModuleResourcesResponse) {
208 if (dmiModuleReferencesResponse != null) {
209 mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/modules"))
210 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(dmiModuleReferencesResponse))
212 if (dmiModuleResourcesResponse != null) {
213 mockDmiServer.expect(requestTo("${dmiPlugin}/dmi/v1/ch/${cmHandleId}/moduleResources"))
214 .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(dmiModuleResourcesResponse))