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.ncmp.api.impl.inventory.InventoryPersistence
31 import org.onap.cps.api.CpsAnchorService
32 import org.onap.cps.api.CpsDataService
33 import org.onap.cps.api.CpsDataspaceService
34 import org.onap.cps.api.CpsModuleService
35 import org.onap.cps.api.CpsQueryService
36 import org.onap.cps.integration.DatabaseTestContainer
37 import org.onap.cps.integration.KafkaTestContainer
38 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService
39 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
40 import org.onap.cps.ncmp.api.NetworkCmProxyQueryService
41 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
42 import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleSyncWatchdog
43 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
44 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
45 import org.onap.cps.spi.exceptions.DataspaceNotFoundException
46 import org.onap.cps.spi.model.DataNode
47 import org.onap.cps.spi.repository.DataspaceRepository
48 import org.onap.cps.spi.utils.SessionManager
49 import org.onap.cps.utils.JsonObjectMapper
50 import org.springframework.beans.factory.annotation.Autowired
51 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
52 import org.springframework.boot.autoconfigure.domain.EntityScan
53 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
54 import org.springframework.boot.test.context.SpringBootTest
55 import org.springframework.context.annotation.ComponentScan
56 import org.springframework.data.jpa.repository.config.EnableJpaRepositories
57 import org.springframework.test.web.servlet.MockMvc
58 import org.testcontainers.spock.Testcontainers
59 import spock.lang.Shared
60 import spock.lang.Specification
61 import spock.util.concurrent.PollingConditions
63 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService])
65 @EnableAutoConfiguration
67 @EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
68 @ComponentScan(basePackages = ['org.onap.cps'])
69 @EntityScan('org.onap.cps.spi.entities')
70 abstract class CpsIntegrationSpecBase extends Specification {
73 DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
76 KafkaTestContainer kafkaTestContainer = KafkaTestContainer.getInstance()
82 CpsDataspaceService cpsDataspaceService
85 CpsAnchorService cpsAnchorService
88 CpsDataService cpsDataService
91 CpsModuleService cpsModuleService
94 CpsQueryService cpsQueryService
97 SessionManager sessionManager
100 NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService
103 NetworkCmProxyDataService networkCmProxyDataService
106 NetworkCmProxyQueryService networkCmProxyQueryService
109 ModuleSyncWatchdog moduleSyncWatchdog
112 JsonObjectMapper jsonObjectMapper
115 InventoryPersistence inventoryPersistence
117 MockWebServer mockDmiServer = null
118 DmiDispatcher dmiDispatcher = new DmiDispatcher()
122 static NO_MODULE_SET_TAG = ''
123 static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
124 static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
126 def static initialized = false
127 def now = OffsetDateTime.now()
131 cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
132 createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
135 mockDmiServer = new MockWebServer()
136 mockDmiServer.setDispatcher(dmiDispatcher)
137 mockDmiServer.start()
138 DMI_URL = String.format("http://%s:%s", mockDmiServer.getHostName(), mockDmiServer.getPort())
142 mockDmiServer.shutdown()
145 def static readResourceDataFile(filename) {
146 return new File('src/test/resources/data/' + filename).text
149 // *** CPS Integration Test Utilities ***
151 def static countDataNodesInTree(DataNode dataNode) {
152 return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
155 def static countDataNodesInTree(Collection<DataNode> dataNodes) {
157 for (DataNode parent : dataNodes) {
158 nodeCount += countDataNodesInTree(parent)
163 def getBookstoreYangResourcesNameToContentMap() {
164 def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
165 def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
166 return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
169 def createStandardBookStoreSchemaSet(targetDataspace) {
170 cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
173 def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
174 cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
177 def dataspaceExists(dataspaceName) {
179 cpsDataspaceService.getDataspace(dataspaceName)
180 } catch (DataspaceNotFoundException ignored) {
186 def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
187 (1..numberOfAnchors).each {
188 cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
189 cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now())
193 def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) {
194 def innerJson = (1..numberOfElements).collect {
195 '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}'
197 return '{"' + name + '":[' + innerJson + ']}'
200 def createLeafList(name, numberOfElements, valuePrefix) {
201 def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',')
202 return '"' + name + '":[' + innerJson + ']'
205 // *** NCMP Integration Test Utilities ***
207 def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag) {
208 def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag)
209 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate]))
210 moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
211 new PollingConditions().within(3, () -> {
212 CmHandleState.READY == networkCmProxyDataService.getCmHandleCompositeState(cmHandleId).cmHandleState
216 def deregisterCmHandle(dmiPlugin, cmHandleId) {
217 deregisterCmHandles(dmiPlugin, [cmHandleId])
220 def deregisterCmHandles(dmiPlugin, cmHandleIds) {
221 networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds))
224 def overrideCmHandleLastUpdateTime(cmHandleId, newUpdateTime) {
225 String ISO_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
226 DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_PATTERN);
227 def jsonForUpdate = '{ "state": { "last-update-time": "%s" } }'.formatted(ISO_TIMESTAMP_FORMATTER.format(newUpdateTime))
228 cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
229 NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='${cmHandleId}']", jsonForUpdate, now)