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 static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
24 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR
25 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT
27 import java.time.OffsetDateTime
28 import java.time.format.DateTimeFormatter
29 import okhttp3.mockwebserver.MockWebServer
30 import org.onap.cps.api.CpsAnchorService
31 import org.onap.cps.api.CpsDataService
32 import org.onap.cps.api.CpsDataspaceService
33 import org.onap.cps.api.CpsModuleService
34 import org.onap.cps.api.CpsQueryService
35 import org.onap.cps.integration.DatabaseTestContainer
36 import org.onap.cps.integration.KafkaTestContainer
37 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService
38 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
39 import org.onap.cps.ncmp.api.NetworkCmProxyQueryService
40 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
41 import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleSyncWatchdog
42 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
43 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
44 import org.onap.cps.spi.exceptions.DataspaceNotFoundException
45 import org.onap.cps.spi.model.DataNode
46 import org.onap.cps.spi.repository.DataspaceRepository
47 import org.onap.cps.spi.utils.SessionManager
48 import org.onap.cps.utils.JsonObjectMapper
49 import org.springframework.beans.factory.annotation.Autowired
50 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
51 import org.springframework.boot.autoconfigure.domain.EntityScan
52 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
53 import org.springframework.boot.test.context.SpringBootTest
54 import org.springframework.context.annotation.ComponentScan
55 import org.springframework.data.jpa.repository.config.EnableJpaRepositories
56 import org.springframework.test.web.servlet.MockMvc
57 import org.testcontainers.spock.Testcontainers
58 import spock.lang.Shared
59 import spock.lang.Specification
60 import spock.util.concurrent.PollingConditions
62 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService])
64 @EnableAutoConfiguration
66 @EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
67 @ComponentScan(basePackages = ['org.onap.cps'])
68 @EntityScan('org.onap.cps.spi.entities')
69 abstract class CpsIntegrationSpecBase extends Specification {
72 DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
75 KafkaTestContainer kafkaTestContainer = KafkaTestContainer.getInstance()
81 CpsDataspaceService cpsDataspaceService
84 CpsAnchorService cpsAnchorService
87 CpsDataService cpsDataService
90 CpsModuleService cpsModuleService
93 CpsQueryService cpsQueryService
96 SessionManager sessionManager
99 NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService
102 NetworkCmProxyDataService networkCmProxyDataService
105 NetworkCmProxyQueryService networkCmProxyQueryService
108 ModuleSyncWatchdog moduleSyncWatchdog
111 JsonObjectMapper jsonObjectMapper
113 MockWebServer mockDmiServer = null
114 DmiDispatcher dmiDispatcher = new DmiDispatcher()
118 static NO_MODULE_SET_TAG = ''
119 static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
120 static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
122 def static initialized = false
123 def now = OffsetDateTime.now()
127 cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
128 createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
131 mockDmiServer = new MockWebServer()
132 mockDmiServer.setDispatcher(dmiDispatcher)
133 mockDmiServer.start()
134 DMI_URL = String.format("http://%s:%s", mockDmiServer.getHostName(), mockDmiServer.getPort())
138 mockDmiServer.shutdown()
141 def static readResourceDataFile(filename) {
142 return new File('src/test/resources/data/' + filename).text
145 // *** CPS Integration Test Utilities ***
147 def static countDataNodesInTree(DataNode dataNode) {
148 return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
151 def static countDataNodesInTree(Collection<DataNode> dataNodes) {
153 for (DataNode parent : dataNodes) {
154 nodeCount += countDataNodesInTree(parent)
159 def getBookstoreYangResourcesNameToContentMap() {
160 def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
161 def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
162 return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
165 def createStandardBookStoreSchemaSet(targetDataspace) {
166 cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
169 def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
170 cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
173 def dataspaceExists(dataspaceName) {
175 cpsDataspaceService.getDataspace(dataspaceName)
176 } catch (DataspaceNotFoundException ignored) {
182 def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
183 (1..numberOfAnchors).each {
184 cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
185 cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now())
189 def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) {
190 def innerJson = (1..numberOfElements).collect {
191 '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}'
193 return '{"' + name + '":[' + innerJson + ']}'
196 def createLeafList(name, numberOfElements, valuePrefix) {
197 def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',')
198 return '"' + name + '":[' + innerJson + ']'
201 // *** NCMP Integration Test Utilities ***
203 def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag) {
204 def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag)
205 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate]))
206 moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
207 new PollingConditions().within(3, () -> {
208 CmHandleState.READY == networkCmProxyDataService.getCmHandleCompositeState(cmHandleId).cmHandleState
212 def deregisterCmHandle(dmiPlugin, cmHandleId) {
213 deregisterCmHandles(dmiPlugin, [cmHandleId])
216 def deregisterCmHandles(dmiPlugin, cmHandleIds) {
217 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds))
220 def overrideCmHandleLastUpdateTime(cmHandleId, newUpdateTime) {
221 String ISO_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
222 DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_PATTERN);
223 def jsonForUpdate = '{ "state": { "last-update-time": "%s" } }'.formatted(ISO_TIMESTAMP_FORMATTER.format(newUpdateTime))
224 cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
225 NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='${cmHandleId}']", jsonForUpdate, now)