Merge "CPS-2187 - #6 Add module Set Tag to ncmp (single cm handle) data request to...
[cps.git] / integration-test / src / test / groovy / org / onap / cps / integration / base / CpsIntegrationSpecBase.groovy
1 /*
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
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.integration.base
22
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
26
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
62
63 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService])
64 @Testcontainers
65 @EnableAutoConfiguration
66 @AutoConfigureMockMvc
67 @EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
68 @ComponentScan(basePackages = ['org.onap.cps'])
69 @EntityScan('org.onap.cps.spi.entities')
70 abstract class CpsIntegrationSpecBase extends Specification {
71
72     @Shared
73     DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
74
75     @Shared
76     KafkaTestContainer kafkaTestContainer = KafkaTestContainer.getInstance()
77
78     @Autowired
79     MockMvc mvc
80
81     @Autowired
82     CpsDataspaceService cpsDataspaceService
83
84     @Autowired
85     CpsAnchorService cpsAnchorService
86
87     @Autowired
88     CpsDataService cpsDataService
89
90     @Autowired
91     CpsModuleService cpsModuleService
92
93     @Autowired
94     CpsQueryService cpsQueryService
95
96     @Autowired
97     SessionManager sessionManager
98
99     @Autowired
100     NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService
101
102     @Autowired
103     NetworkCmProxyDataService networkCmProxyDataService
104
105     @Autowired
106     NetworkCmProxyQueryService networkCmProxyQueryService
107
108     @Autowired
109     ModuleSyncWatchdog moduleSyncWatchdog
110
111     @Autowired
112     JsonObjectMapper jsonObjectMapper
113
114     @Autowired
115     InventoryPersistence inventoryPersistence
116
117     MockWebServer mockDmiServer = null
118     DmiDispatcher dmiDispatcher = new DmiDispatcher()
119
120     def DMI_URL = null
121
122     static NO_MODULE_SET_TAG = ''
123     static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
124     static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
125
126     def static initialized = false
127     def now = OffsetDateTime.now()
128
129     def setup() {
130         if (!initialized) {
131             cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
132             createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
133             initialized = true
134         }
135         mockDmiServer = new MockWebServer()
136         mockDmiServer.setDispatcher(dmiDispatcher)
137         mockDmiServer.start()
138         DMI_URL = String.format("http://%s:%s", mockDmiServer.getHostName(), mockDmiServer.getPort())
139     }
140
141     def cleanup() {
142         mockDmiServer.shutdown()
143     }
144
145     def static readResourceDataFile(filename) {
146         return new File('src/test/resources/data/' + filename).text
147     }
148
149     // *** CPS Integration Test Utilities ***
150
151     def static countDataNodesInTree(DataNode dataNode) {
152         return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
153     }
154
155     def static countDataNodesInTree(Collection<DataNode> dataNodes) {
156         int nodeCount = 0
157         for (DataNode parent : dataNodes) {
158             nodeCount += countDataNodesInTree(parent)
159         }
160         return nodeCount
161     }
162
163     def getBookstoreYangResourcesNameToContentMap() {
164         def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
165         def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
166         return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
167     }
168
169     def createStandardBookStoreSchemaSet(targetDataspace) {
170         cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
171     }
172
173     def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
174         cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
175     }
176
177     def dataspaceExists(dataspaceName) {
178         try {
179             cpsDataspaceService.getDataspace(dataspaceName)
180         } catch (DataspaceNotFoundException ignored) {
181             return false
182         }
183         return true
184     }
185
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())
190         }
191     }
192
193     def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) {
194         def innerJson = (1..numberOfElements).collect {
195             '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}'
196         }.join(',')
197         return '{"' + name + '":[' + innerJson + ']}'
198     }
199
200     def createLeafList(name, numberOfElements, valuePrefix) {
201         def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',')
202         return '"' + name + '":[' + innerJson + ']'
203     }
204
205     // *** NCMP Integration Test Utilities ***
206
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
213         })
214     }
215
216     def deregisterCmHandle(dmiPlugin, cmHandleId) {
217         deregisterCmHandles(dmiPlugin, [cmHandleId])
218     }
219
220     def deregisterCmHandles(dmiPlugin, cmHandleIds) {
221         networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds))
222     }
223
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)
230     }
231 }