/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
package org.onap.cps.integration.base
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT
+
+import java.time.OffsetDateTime
+import java.time.format.DateTimeFormatter
+import okhttp3.mockwebserver.MockWebServer
+import org.onap.cps.api.CpsAnchorService
+import org.onap.cps.api.CpsDataService
+import org.onap.cps.api.CpsDataspaceService
+import org.onap.cps.api.CpsModuleService
import org.onap.cps.api.CpsQueryService
-import org.onap.cps.api.impl.CpsAdminServiceImpl
-import org.onap.cps.api.impl.CpsDataServiceImpl
-import org.onap.cps.api.impl.CpsModuleServiceImpl
import org.onap.cps.integration.DatabaseTestContainer
+import org.onap.cps.integration.KafkaTestContainer
+import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService
+import org.onap.cps.ncmp.api.NetworkCmProxyQueryService
+import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
+import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleSyncWatchdog
+import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.spi.exceptions.DataspaceNotFoundException
import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.repository.DataspaceRepository
-import org.onap.cps.spi.impl.utils.CpsValidatorImpl
+import org.onap.cps.spi.utils.SessionManager
+import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.domain.EntityScan
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.ComponentScan
-import org.springframework.context.annotation.Lazy
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
+import org.springframework.test.web.servlet.MockMvc
import org.testcontainers.spock.Testcontainers
import spock.lang.Shared
import spock.lang.Specification
+import spock.util.concurrent.PollingConditions
-import java.time.OffsetDateTime
-
-@SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl])
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = [CpsDataspaceService])
@Testcontainers
@EnableAutoConfiguration
+@AutoConfigureMockMvc
@EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
-@ComponentScan(basePackages = ["org.onap.cps.api", "org.onap.cps.spi.repository"])
-@EntityScan("org.onap.cps.spi.entities")
-class CpsIntegrationSpecBase extends Specification {
+@ComponentScan(basePackages = ['org.onap.cps'])
+@EntityScan('org.onap.cps.spi.entities')
+abstract class CpsIntegrationSpecBase extends Specification {
@Shared
DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
+ @Shared
+ KafkaTestContainer kafkaTestContainer = KafkaTestContainer.getInstance()
+
@Autowired
- @Lazy
- CpsAdminServiceImpl cpsAdminService
+ MockMvc mvc
@Autowired
- @Lazy
- CpsDataServiceImpl cpsDataService
+ CpsDataspaceService cpsDataspaceService
@Autowired
- @Lazy
- CpsModuleServiceImpl cpsModuleService
+ CpsAnchorService cpsAnchorService
+
+ @Autowired
+ CpsDataService cpsDataService
+
+ @Autowired
+ CpsModuleService cpsModuleService
@Autowired
- @Lazy
CpsQueryService cpsQueryService
- def static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
- def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
+ @Autowired
+ SessionManager sessionManager
+
+ @Autowired
+ NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService
+
+ @Autowired
+ NetworkCmProxyDataService networkCmProxyDataService
+
+ @Autowired
+ NetworkCmProxyQueryService networkCmProxyQueryService
+
+ @Autowired
+ ModuleSyncWatchdog moduleSyncWatchdog
+
+ @Autowired
+ JsonObjectMapper jsonObjectMapper
+
+ MockWebServer mockDmiServer = null
+ DmiDispatcher dmiDispatcher = new DmiDispatcher()
+
+ def DMI_URL = null
+
+ static NO_MODULE_SET_TAG = ''
+ static GENERAL_TEST_DATASPACE = 'generalTestDataspace'
+ static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
def static initialized = false
+ def now = OffsetDateTime.now()
def setup() {
if (!initialized) {
- cpsAdminService.createDataspace(GENERAL_TEST_DATASPACE)
- def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
- cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore : bookstoreModelFileContent])
- initialized = true;
+ cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
+ createStandardBookStoreSchemaSet(GENERAL_TEST_DATASPACE)
+ initialized = true
}
+ mockDmiServer = new MockWebServer()
+ mockDmiServer.setDispatcher(dmiDispatcher)
+ mockDmiServer.start()
+ DMI_URL = String.format("http://%s:%s", mockDmiServer.getHostName(), mockDmiServer.getPort())
+ }
+
+ def cleanup() {
+ mockDmiServer.shutdown()
}
+ def static readResourceDataFile(filename) {
+ return new File('src/test/resources/data/' + filename).text
+ }
+
+ // *** CPS Integration Test Utilities ***
+
def static countDataNodesInTree(DataNode dataNode) {
return 1 + countDataNodesInTree(dataNode.getChildDataNodes())
}
return nodeCount
}
- def static readResourceDataFile(filename) {
- return new File('src/test/resources/data/' + filename).text
+ def getBookstoreYangResourcesNameToContentMap() {
+ def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
+ def bookstoreTypesFileContent = readResourceDataFile('bookstore/bookstore-types.yang')
+ return [bookstore: bookstoreModelFileContent, bookstoreTypes: bookstoreTypesFileContent]
+ }
+
+ def createStandardBookStoreSchemaSet(targetDataspace) {
+ cpsModuleService.createSchemaSet(targetDataspace, BOOKSTORE_SCHEMA_SET, getBookstoreYangResourcesNameToContentMap())
+ }
+
+ def createStandardBookStoreSchemaSet(targetDataspace, targetSchemaSet) {
+ cpsModuleService.createSchemaSet(targetDataspace, targetSchemaSet, getBookstoreYangResourcesNameToContentMap())
}
def dataspaceExists(dataspaceName) {
try {
- cpsAdminService.getDataspace(dataspaceName)
- } catch (DataspaceNotFoundException e) {
+ cpsDataspaceService.getDataspace(dataspaceName)
+ } catch (DataspaceNotFoundException ignored) {
return false
}
return true
def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
(1..numberOfAnchors).each {
- cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
- cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data, OffsetDateTime.now())
+ cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
+ cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now())
}
}
+
+ def createJsonArray(name, numberOfElements, keyName, keyValuePrefix, dataPerKey) {
+ def innerJson = (1..numberOfElements).collect {
+ '{"' + keyName + '":"' + keyValuePrefix + '-' + it + '"' + (dataPerKey.empty? '': ',' + dataPerKey) + '}'
+ }.join(',')
+ return '{"' + name + '":[' + innerJson + ']}'
+ }
+
+ def createLeafList(name, numberOfElements, valuePrefix) {
+ def innerJson = (1..numberOfElements).collect {'"' + valuePrefix + '-' + it + '"'}.join(',')
+ return '"' + name + '":[' + innerJson + ']'
+ }
+
+ // *** NCMP Integration Test Utilities ***
+
+ def registerCmHandle(dmiPlugin, cmHandleId, moduleSetTag) {
+ def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, moduleSetTag: moduleSetTag)
+ networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, createdCmHandles: [cmHandleToCreate]))
+ moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
+ new PollingConditions().within(3, () -> {
+ CmHandleState.READY == networkCmProxyDataService.getCmHandleCompositeState(cmHandleId).cmHandleState
+ })
+ }
+
+ def deregisterCmHandle(dmiPlugin, cmHandleId) {
+ deregisterCmHandles(dmiPlugin, [cmHandleId])
+ }
+
+ def deregisterCmHandles(dmiPlugin, cmHandleIds) {
+ networkCmProxyDataService.updateDmiRegistrationAndSyncModule(new DmiPluginRegistration(dmiPlugin: dmiPlugin, removedCmHandles: cmHandleIds))
+ }
+
+ def overrideCmHandleLastUpdateTime(cmHandleId, newUpdateTime) {
+ String ISO_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
+ DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_PATTERN);
+ def jsonForUpdate = '{ "state": { "last-update-time": "%s" } }'.formatted(ISO_TIMESTAMP_FORMATTER.format(newUpdateTime))
+ cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+ NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='${cmHandleId}']", jsonForUpdate, now)
+ }
}