Make UatExecutor accessible inside a CBA JUnit test 79/130779/7
authorFrank Kimmlingen <frank.kimmlingen@telekom.de>
Wed, 7 Sep 2022 09:23:52 +0000 (11:23 +0200)
committerFrank Kimmlingen <frank.kimmlingen@telekom.de>
Fri, 9 Sep 2022 12:59:06 +0000 (12:59 +0000)
Issue-ID: CCSDK-3748
Signed-off-by: Frank Kimmlingen <frank.kimmlingen@telekom.de>
Change-Id: Icbc0a44d91fd08f2e06a12bcdf016655a2b2282d

15 files changed:
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/META-INF/maven/archetype-metadata.xml
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintAcceptanceSunnyTest.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/SampleResourceResolutionTest.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/base/BaseBlueprintsAcceptanceTest.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/base/BaseUatResourceResolutionTest.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/SmartColorDiscriminator.kt [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintVelocityTemplateTest.kt
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/application-test.properties [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/application.properties [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/error-messages_en.properties [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/logback-test.xml [new file with mode: 0644]
components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/pom.xml
components/model-catalog/blueprint-model/test-blueprint-kotlin-parent/pom.xml
docs/modelingconcepts/test.rst
ms/blueprintsprocessor/application/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/utils/UatExecutor.kt

index 84096e1..874556d 100644 (file)
         <include>**/*.txt</include>
       </includes>
     </fileSet>
+    <fileSet encoding="UTF-8">
+      <directory>Tests/resources</directory>
+      <includes>
+        <include>**/*.properties</include>
+        <include>**/*.xml</include>
+        <include>**/*.yaml</include>
+        <include>**/*.yml</include>
+      </includes>
+    </fileSet>
     <fileSet encoding="UTF-8">
       <directory>Definitions</directory>
       <includes>
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintAcceptanceSunnyTest.kt b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintAcceptanceSunnyTest.kt
new file mode 100644 (file)
index 0000000..f40104b
--- /dev/null
@@ -0,0 +1,27 @@
+package org.onap.ccsdk.cds.blueprintsprocessor.uat
+
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.base.BaseBlueprintsAcceptanceTest
+import kotlin.test.Ignore
+
+/**
+ * This is a sample implementation of a test class using {@see BaseBlueprintsAcceptanceTest}
+ * Please find "TODO" comments, where you need to make your changes
+ */
+class BlueprintAcceptanceSunnyTest : BaseBlueprintsAcceptanceTest() {
+
+    // TODO: remove @Ignore to activate the test
+    @Ignore
+    @Test
+    fun `Blueprint User Acceptance Tests sunny case`() {
+        runBlocking {
+
+            // TODO: replace the following parameters with yours, if needed.
+            // As long as you have only one uat.yaml in the Tests folder of the cba,
+            // you can leave the parameters as they are.
+
+            callRunUat("../cba", "Tests/uat.yaml")
+        }
+    }
+}
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/SampleResourceResolutionTest.kt b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/SampleResourceResolutionTest.kt
new file mode 100644 (file)
index 0000000..74e1761
--- /dev/null
@@ -0,0 +1,86 @@
+package org.onap.ccsdk.cds.blueprintsprocessor.uat
+
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.base.BaseUatResourceResolutionTest
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import java.nio.file.Path
+import kotlin.test.Ignore
+import kotlin.test.assertEquals
+
+
+/**
+ * This is a sample implementation of a test class using {@see BaseUatResourceResolutionTest}
+ * Please find "TODO" comments, where you need to make your changes
+ */
+class SampleResourceResolutionTest : BaseUatResourceResolutionTest() {
+
+    companion object {
+        val log: Logger = LoggerFactory.getLogger(SampleResourceResolutionTest::class.java)
+        private val cwd: String = Path.of("").toAbsolutePath().toString()
+        val blueprintBasePath : String = cwd
+        // TODO: exchange here the real path to the request json
+        val fileNameExecutionServiceInput : String = "$cwd/Tests/sample-resourceresolution-request.json"
+    }
+
+    // TODO: remove @Ignore to activate the test
+    @Ignore
+    @Test
+    @Throws(Exception::class)
+    fun `test resolveResource for nodeTemplate fetch-nf-config-process`() {
+        runBlocking {
+            callResolveResources(
+                blueprintBasePath,
+
+                // TODO: replace the following parameters with yours
+                fileNameExecutionServiceInput,
+                "workflowName",
+                "nodeTemplateName",
+                "artifactPrefixName"
+            )
+        }.let { (templateMap, assignmentList) ->
+            // list of pairs
+            val expectedAssignmentList = mutableListOf(
+                // TODO: only samples
+                "service-instance-id" to "fb84c76d-676e-4a36-9237-52089594292b",
+                "service-instance-name" to "cucp-1",
+                "vnf-id" to "de59d80e-cbce-4898-9e3c-3a917e89d834"
+                // TODO: add your key value pairs here
+            )
+
+            // assert size of list
+            assertEquals(expectedAssignmentList.size, assignmentList.size)
+
+            val list = expectedAssignmentList.zip(assignmentList)
+            list.forEach {
+                    (expected, actual) ->
+                run {
+
+                    // do individual assertions here
+
+                    // names must be equal
+                    assertEquals(expected.first, actual.name)
+                    when (expected.first) {
+                        // TODO: fill in here your concrete ObjectNode names
+                        "objectNodeName1", "objectNodeName2" -> {
+                            // ObjectNodes
+                            log.info("expected name[${expected.first}] actual name[${actual.name}] " +
+                                    "-> expected value[${expected.second}] actual value[${actual.property?.value.toString()}]")
+
+                            // values must be equal
+                            assertEquals(expected.second, actual.property?.value.toString())
+                        }
+                        else -> {
+                            // TextNodes. This is the default case
+                            log.info("expected name[${expected.first}] actual name[${actual.name}] " +
+                                    "-> expected value[${expected.second}] actual value[${actual.property?.value?.asText()}]")
+                            // values must be equal
+                            assertEquals(expected.second, actual.property?.value?.asText())
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/base/BaseBlueprintsAcceptanceTest.kt b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/base/BaseBlueprintsAcceptanceTest.kt
new file mode 100644 (file)
index 0000000..c0c33b6
--- /dev/null
@@ -0,0 +1,177 @@
+package org.onap.ccsdk.cds.blueprintsprocessor.uat.base
+
+import kotlinx.coroutines.runBlocking
+import org.junit.runner.RunWith
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.message.prioritization.MessagePrioritizationStateService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.message.prioritization.service.SampleMessagePrioritizationService
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.base.BaseBlueprintsAcceptanceTest.TestSecuritySettings
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.base.BaseBlueprintsAcceptanceTest.WorkingFoldersInitializer
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.utils.UatExecutor
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintArchiveUtils.Companion.compressToBytes
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.support.BeanDefinitionBuilder
+import org.springframework.beans.factory.support.BeanDefinitionRegistry
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.context.ApplicationContextInitializer
+import org.springframework.context.ConfigurableApplicationContext
+import org.springframework.stereotype.Component
+import org.springframework.stereotype.Service
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.TestPropertySource
+import org.springframework.test.context.junit4.SpringRunner
+import org.springframework.test.context.support.TestPropertySourceUtils
+import org.springframework.util.Base64Utils
+import java.io.File
+import java.io.IOException
+import java.nio.file.*
+import java.nio.file.attribute.BasicFileAttributes
+import javax.annotation.PreDestroy
+import kotlin.test.BeforeTest
+import kotlin.test.AfterTest
+
+
+/**
+ * This is a SpringBootTest abstract Base class, that executes UAT (User Acceptance Tests) by calling
+ * callRunUat in an implementation class.
+ * See https://docs.onap.org/projects/onap-ccsdk-cds/en/latest/modelingconcepts/test.html and
+ * https://github.com/onap/ccsdk-cds/blob/master/components/model-catalog/blueprint-model/uat-blueprints/README.md
+ * for further information concerning the CDS UAT concept.
+ */
+
+@RunWith(SpringRunner::class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ContextConfiguration(
+    initializers = [
+        WorkingFoldersInitializer::class,
+        TestSecuritySettings.ServerContextInitializer::class
+    ]
+)
+@TestPropertySource(locations = ["classpath:application-test.properties"])
+abstract class BaseBlueprintsAcceptanceTest() {
+    @BeforeTest
+    fun setScope() {
+        LogColor.setContextColor(LogColor.COLOR_TEST_CLIENT)
+    }
+
+    @AfterTest
+    fun clearScope() {
+        LogColor.resetContextColor()
+    }
+
+    companion object {
+        private val log: Logger = LoggerFactory.getLogger(BaseBlueprintsAcceptanceTest::class.java)
+    }
+
+    @Autowired
+    // Bean is created programmatically by {@link WorkingFoldersInitializer#initialize(String)}
+    @Suppress("SpringJavaInjectionPointsAutowiringInspection")
+    lateinit var tempFolder: ExtendedTemporaryFolder
+
+    @Autowired
+    lateinit var uatExecutor: UatExecutor
+
+    @BeforeTest
+    fun cleanupTemporaryFolder() {
+        tempFolder.deleteAllFiles()
+    }
+
+    protected suspend fun callRunUat(pathName: String, uatFilename: String) {
+        runBlocking {
+            val dir = File(pathName)
+            val rootFs =  FileSystems.newFileSystem(dir.canonicalFile.toPath(), null)
+            log.info("dirname: ${dir.toString()} rootFs ${rootFs}")
+
+            val uatSpec = rootFs.getPath(uatFilename).toFile().readText()
+            val cbaBytes = compressToBytes(rootFs.getPath("/"))
+            uatExecutor.execute(uatSpec, cbaBytes)
+        }
+    }
+
+    @Service
+    open class TestMessagePrioritizationService(messagePrioritizationStateService: MessagePrioritizationStateService) :
+        SampleMessagePrioritizationService(messagePrioritizationStateService)
+    @Component
+    class WorkingFoldersInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
+
+        override fun initialize(context: ConfigurableApplicationContext) {
+            val tempFolder = ExtendedTemporaryFolder()
+            val properties = listOf("Deploy", "Archive", "Working")
+                .map { "blueprintsprocessor.blueprint${it}Path=${tempFolder.newFolder(it).absolutePath.replace("\\", "/")}" }
+                .toTypedArray()
+            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, *properties)
+            // Expose tempFolder as a bean so it can be accessed via DI
+            registerSingleton(context, "tempFolder", ExtendedTemporaryFolder::class.java, tempFolder)
+        }
+
+        @Suppress("SameParameterValue")
+        private fun <T> registerSingleton(
+            context: ConfigurableApplicationContext,
+            beanName: String,
+            beanClass: Class<T>,
+            instance: T
+        ) {
+            val builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass) { instance }
+            (context.beanFactory as BeanDefinitionRegistry).registerBeanDefinition(beanName, builder.beanDefinition)
+        }
+    }
+
+    class ExtendedTemporaryFolder {
+
+        private val tempFolder = createTempDir("uat")
+
+        @PreDestroy
+        fun delete() = tempFolder.deleteRecursively()
+
+        /**
+         * A delegate to org.junit.rules.TemporaryFolder.TemporaryFolder.newFolder(String).
+         */
+        fun newFolder(folderName: String): File {
+            val dir = File(tempFolder, folderName)
+            if (!dir.mkdir()) {
+                throw IOException("Unable to create temporary directory $dir.")
+            }
+            return dir
+        }
+
+        /**
+         * Delete all files under the root temporary folder recursively. The folders are preserved.
+         */
+        fun deleteAllFiles() {
+            Files.walkFileTree(
+                tempFolder.toPath(),
+                object : SimpleFileVisitor<Path>() {
+                    @Throws(IOException::class)
+                    override fun visitFile(file: Path?, attrs: BasicFileAttributes?): FileVisitResult {
+                        file?.toFile()?.delete()
+                        return FileVisitResult.CONTINUE
+                    }
+                }
+            )
+        }
+    }
+    class TestSecuritySettings {
+        companion object {
+
+            private const val authUsername = "walter.white"
+            private const val authPassword = "Heisenberg"
+
+            fun clientAuthToken() =
+                "Basic " + Base64Utils.encodeToString("$authUsername:$authPassword".toByteArray())
+        }
+
+        class ServerContextInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
+
+            override fun initialize(context: ConfigurableApplicationContext) {
+                TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
+                    context,
+                    "security.user.name=$authUsername",
+                    "security.user.password={noop}$authPassword"
+                )
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/base/BaseUatResourceResolutionTest.kt b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/base/BaseUatResourceResolutionTest.kt
new file mode 100644 (file)
index 0000000..633486c
--- /dev/null
@@ -0,0 +1,269 @@
+package org.onap.ccsdk.cds.blueprintsprocessor.uat.base
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.nhaarman.mockitokotlin2.any
+import com.nhaarman.mockitokotlin2.eq
+import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.whenever
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.spyk
+import org.mockito.Answers
+import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertiesService
+import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertyConfiguration
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.PayloadUtils
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionServiceImpl
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionRepository
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionRepository
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.CapabilityResourceResolutionProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.DefaultResourceResolutionProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.InputResourceResolutionProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.RestResourceResolutionProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts.DeprecatedBlueprintJythonService
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.MockInvocationLogger
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.utils.ExpectationDefinition
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.utils.UatDefinition
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.utils.UatExecutor.MockPreInterceptor
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.utils.UatExecutor.SpyPostInterceptor
+import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext
+import org.springframework.context.ApplicationContext
+
+import java.io.File
+import java.nio.file.Path
+import kotlin.test.BeforeTest
+
+/**
+ * This abstract base class supports tests of single workflow steps in an isolated manner, that are using
+ * {@see org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionComponent}.
+ * This means all the used external systems like e.g. sdnc or aai are mocked and must response with the correct
+ * BlueprintWebClientService.WebClientResponse to let the ressource resolution work properly.
+ *
+ * The component inside CDS, which is responsible for resolving resources is ResourceResolutionService.
+ * The ResourceResolutionService is using ResourceAssignmentProcessor's like e.g.
+ * InputResourceResolutionProcessor, DefaultResourceResolutionProcessor, RestResourceResolutionProcessor
+ * and CapabilityResourceResolutionProcessor
+ *
+ * These classes are only partially mocked by mockk spyk() function. This means, that the real classes are used
+ * and only some methods are rewritten via every {}.returns(...) functions
+ *
+ * For example the creation of ResourceAssignmentProcessor's are mocked in multiple
+ *
+ * every {applicationContext.getBean("${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}???")}
+ * .returns( ResourceResolutionProcessorXXX() ) functions.
+ *
+ * The test is also based on UAT concept of the CDS project.
+ * The test makes usage of following classes:
+ *
+ * SpyService: Decorator for overwriting the function for handling the rest based communication with external systems
+ * fun exchangeResource(methodType: String,path: String,request: String,headers: Map<String, String>):
+ *  WebClientResponse<String>
+ * Uses ExpectationDefinition from the uat.yaml
+ *
+ * uat.MockPreInterceptor: Interceptor that hooks in the factory method of creation the different rest clients for
+ * external systems
+ * BluePrintRestLibPropertyService.blueprintWebClientService(selector: String): BlueprintWebClientService
+ * It is used for exchanging the "real service" by a mock (here a mockito based one)
+ *
+ * uat.SpyPostInterceptor: Interceptor that hooks in the factory method of creation the different rest clients for
+ * external systems
+ * BluePrintRestLibPropertyService.blueprintWebClientService(selector: String): BlueprintWebClientService
+ * It is used to inject the uat.SpyService decorator
+ *
+ * In a whole we do have the following decorator chain:  uat.SpyService ( Mockito mock (real service) )
+ *
+ * {@see UatDefinition}: Model of behaviour of external systems. Used at runtime as a representation for
+ * request / response correlation of the external systems. It is loaded from the uat.yaml
+ *
+  *
+ * Prerequisites
+ * - in the cba Definition folder the enriched data_types.json and node_types.json needs to be in the actual version.
+ *   inside the json workflow file (e.g. parameter-consistency.json) the includes to these json must be available.
+ * - uat.yaml for UatDefinition must be inside the cba/Test/ directory of the cba. This uat.yaml file must be adapted,
+ *   if the logic inside the steps changes.
+ *   See https://wiki.onap.org/pages/viewpage.action?pageId=59965554#ModelingConcepts-tests for details
+ */
+abstract class BaseUatResourceResolutionTest {
+    private val resolutionKey = "resolutionKey"
+    private val resourceId = "1"
+    private val resourceType = "ServiceInstance"
+    private val occurrence = 0
+
+    // protected, bacause they maybe needed to be manipulated in inherited test classes
+    protected val props = hashMapOf<String, Any>()
+    protected var preInterceptor = MockPreInterceptor()
+    protected var postInterceptor = SpyPostInterceptor(ObjectMapper())
+    protected lateinit var resourceResolutionService: ResourceResolutionService
+    protected lateinit var applicationContext : ApplicationContext
+
+    companion object {
+        private val log: Logger = LoggerFactory.getLogger(BaseUatResourceResolutionTest::class.java)
+        private val mockLoggingListener = MockInvocationLogger(LogColor.markerOf(LogColor.COLOR_MOCKITO))
+    }
+
+    @BeforeTest
+    fun setup() {
+        props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = false
+        props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] = resolutionKey
+        props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId
+        props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType
+        props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence
+        props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_SUMMARY] = false
+
+        applicationContext = spyk(ReactiveWebServerApplicationContext())
+        val templateResolutionRepository = mockk<TemplateResolutionRepository>()
+        val templateResolutionService = spyk(TemplateResolutionService(templateResolutionRepository))
+        val bluePrintLoadConfiguration = spyk(BluePrintLoadConfiguration())
+        val bluePrintTemplateService = spyk(BluePrintTemplateService(bluePrintLoadConfiguration))
+        val resourceResolutionRepository = mockk<ResourceResolutionRepository>()
+        val resourceResolutionDBService = spyk(ResourceResolutionDBService(resourceResolutionRepository))
+
+        // ResourceResolutionService
+        resourceResolutionService = spyk(
+            ResourceResolutionServiceImpl(
+            applicationContext,
+            templateResolutionService,
+            bluePrintTemplateService,
+            resourceResolutionDBService)
+        )
+
+        // BluePrintRestLibPropertyService: setInterceptors "MockPreInterceptor" and "SpyPostInterceptor"
+        val bluePrintPropertyConfiguration = spyk(BluePrintPropertyConfiguration())
+        val bluePrintPropertiesService = spyk(BluePrintPropertiesService(bluePrintPropertyConfiguration))
+        val bluePrintRestLibPropertyService = BluePrintRestLibPropertyService(bluePrintPropertiesService)
+        bluePrintRestLibPropertyService.setInterceptors(preInterceptor, postInterceptor)
+
+        // ComponentFunctionScriptingService needed for CapabilityResourceResolutionProcessor
+        val blueprintJythonService = spyk(DeprecatedBlueprintJythonService())
+        val componentFunctionScriptingService = ComponentFunctionScriptingService(applicationContext, blueprintJythonService)
+
+        // Add ResourceResolutionProcessor's to the Spring ApplicationContext
+        // if more needed, add them in your own setUp method in derived test class
+        every { applicationContext.getBean("${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-input") }.returns(
+            InputResourceResolutionProcessor()
+        )
+        every { applicationContext.getBean("${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-default") }.returns(
+            DefaultResourceResolutionProcessor()
+        )
+        every { applicationContext.getBean("${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-rest") }.returns(
+            RestResourceResolutionProcessor(bluePrintRestLibPropertyService)
+        )
+        every { applicationContext.getBean("${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-capability") }.returns(
+            CapabilityResourceResolutionProcessor(componentFunctionScriptingService)
+        )
+
+        // create the Mockit mocks defined in the uat.yaml
+        createMockitoMocksByUatDefinition()
+    }
+
+    private fun createMockitoMocksByUatDefinition() {
+        // read uat file
+        val cwd: String = Path.of("").toAbsolutePath().toString()
+        log.info("current working directory : $cwd")
+
+        val uatSpec: String = File("$cwd/Tests/uat.yaml").readText(Charsets.UTF_8)
+        val uat = UatDefinition.load(jacksonObjectMapper(), uatSpec)
+        val expectationsPerClient = uat.externalServices.associateBy(
+            { service ->
+                createRestClientMock(service.expectations).also { restClient ->
+                    // side-effect: register restClient to override real instance
+                    preInterceptor.registerMock(service.selector, restClient)
+                }
+            },
+            { service -> service.expectations }
+        )
+    }
+
+    private fun createRestClientMock(restExpectations: List<ExpectationDefinition>):
+            BlueprintWebClientService {
+        val restClient = mock<BlueprintWebClientService>(
+            defaultAnswer = Answers.RETURNS_SMART_NULLS,
+            // our custom verboseLogging handler
+            invocationListeners = arrayOf(mockLoggingListener)
+        )
+
+        // Delegates to overloaded exchangeResource(String, String, String, Map<String, String>)
+        whenever(restClient.exchangeResource(any(), any(), any()))
+            .thenAnswer { invocation ->
+                val method = invocation.arguments[0] as String
+                val path = invocation.arguments[1] as String
+                val request = invocation.arguments[2] as String
+                restClient.exchangeResource(method, path, request, emptyMap())
+            }
+        for (expectation in restExpectations) {
+            var stubbing = whenever(
+                restClient.exchangeResource(
+                    eq(expectation.request.method),
+                    eq(expectation.request.path),
+                    any(),
+                    any()
+                )
+            )
+            for (response in expectation.responses) {
+                stubbing = stubbing.thenReturn(
+                    BlueprintWebClientService.WebClientResponse(
+                        response.status,
+                        response.body.toString()
+                    )
+                )
+            }
+        }
+        return restClient
+    }
+
+    protected suspend fun callResolveResources(
+        blueprintBasePath: String,
+        fileNameExecutionServiceInput: String,
+        workflowName: String,
+        nodeTemplateName: String,
+        artifactPrefixName: String
+    ): Pair<String, MutableList<ResourceAssignment>> {
+        val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(
+            "12345",
+            blueprintBasePath
+        )
+
+        val executionServiceInput =
+            JacksonUtils.readValueFromFile(
+                fileNameExecutionServiceInput,
+                ExecutionServiceInput::class.java
+            )!!
+
+        val resourceAssignmentRuntimeService =
+            ResourceAssignmentUtils.transformToRARuntimeService(
+                bluePrintRuntimeService,
+                "testResolveResource"
+            )
+
+        // Prepare Inputs
+        PayloadUtils.prepareInputsFromWorkflowPayload(
+            bluePrintRuntimeService,
+            executionServiceInput.payload,
+            workflowName
+        )
+
+        return resourceResolutionService.resolveResources(
+            resourceAssignmentRuntimeService,
+            nodeTemplateName,
+            artifactPrefixName,
+            props
+        )
+    }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/SmartColorDiscriminator.kt b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/uat/logging/SmartColorDiscriminator.kt
new file mode 100644 (file)
index 0000000..4798701
--- /dev/null
@@ -0,0 +1,24 @@
+package org.onap.ccsdk.cds.blueprintsprocessor.uat.logging
+
+import ch.qos.logback.classic.spi.ILoggingEvent
+import ch.qos.logback.core.sift.AbstractDiscriminator
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.ColorMarker
+import org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.LogColor.MDC_COLOR_KEY
+
+class SmartColorDiscriminator : AbstractDiscriminator<ILoggingEvent>() {
+
+    var defaultValue: String = "white"
+
+    override fun getKey(): String {
+        return MDC_COLOR_KEY
+    }
+
+    fun setKey() {
+        throw UnsupportedOperationException("Key not settable. Using $MDC_COLOR_KEY")
+    }
+
+    override fun getDiscriminatingValue(e: ILoggingEvent): String =
+        (e.marker as? ColorMarker)?.name
+            ?: e.mdcPropertyMap?.get(MDC_COLOR_KEY)
+            ?: defaultValue
+}
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/application-test.properties b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/application-test.properties
new file mode 100644 (file)
index 0000000..b23cdb2
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright Â© 2019 Nordix Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+spring.http.log-request-details=true
+
+# Error Managements
+error.catalog.applicationId=cds
+error.catalog.type=properties
+error.catalog.errorDefinitionDir=./src/test/resources/
+
+blueprintsprocessor.httpPort=0
+blueprintsprocessor.grpcEnable=true
+blueprintsprocessor.grpcPort=0
+
+blueprintsprocessor.db.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1
+blueprintsprocessor.db.username=sa
+blueprintsprocessor.db.password=
+blueprintsprocessor.db.driverClassName=org.h2.Driver
+blueprintsprocessor.db.hibernateHbm2ddlAuto=create-drop
+blueprintsprocessor.db.hibernateDDLAuto=update
+blueprintsprocessor.db.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy
+blueprintsprocessor.db.hibernateDialect=org.hibernate.dialect.H2Dialect
+
+# The properties bellow are set programmatically
+#blueprintsprocessor.blueprintDeployPath=
+#blueprintsprocessor.blueprintArchivePath=
+#blueprintsprocessor.blueprintWorkingPath=
+#security.user.name=
+#security.user.password=
+
+# Python executor
+blueprints.processor.functions.python.executor.executionPath=../../../components/scripts/python/ccsdk_blueprints
+blueprints.processor.functions.python.executor.modulePaths=\
+  ../../../components/scripts/python/ccsdk_blueprints,\
+  ../../../components/scripts/python/ccsdk_netconf,\
+  ../../../components/scripts/python/ccsdk_restconf
+
+# Executor Options
+blueprintsprocessor.cliExecutor.enabled=true
+blueprintsprocessor.netconfExecutor.enabled=true
+
+blueprintsprocessor.restconfEnabled=true
+
+
+#Encrypted username and password for health check service
+endpoints.user.name=eHbVUbJAj4AG2522cSbrOQ==
+endpoints.user.password=eHbVUbJAj4AG2522cSbrOQ==
+
+#BaseUrls for health check blueprint processor services
+blueprintprocessor.healthcheck.baseUrl=http://localhost:8080/
+blueprintprocessor.healthcheck.mapping-service-name-with-service-link=[Execution service,/api/v1/execution-service/health-check],[Resources service,/api/v1/resources/health-check],[Template service,/api/v1/template/health-check]
+
+#BaseUrls for health check Cds Listener services
+cdslistener.healthcheck.baseUrl=http://cds-sdc-listener:8080/
+cdslistener.healthcheck.mapping-service-name-with-service-link=[SDC Listener service,/api/v1/sdclistener/healthcheck]
+
+#K8s Plugin properties
+blueprintprocessor.k8s.plugin.username=test
+blueprintprocessor.k8s.plugin.password=pass
+blueprintprocessor.k8s.plugin.url=http://multicloud-k8s:9015/
+
+#Workflow store configuration
+#workflow Audit request
+blueprintsprocessor.workflow.self-service-api.audit.storeEnable=false
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/application.properties b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/application.properties
new file mode 100644 (file)
index 0000000..cc047db
--- /dev/null
@@ -0,0 +1,104 @@
+#
+# Copyright Â© 2017-2018 AT&T Intellectual Property.
+#
+# Modifications Copyright Â© 2019 IBM, Bell Canada.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Web server config
+server.port=8080
+### START -Controller Blueprints Properties
+# Load Resource Source Mappings
+resourceSourceMappings=processor-db=source-db,input=source-input,default=source-default,sdnc=source-rest,aai-data=source-rest,capability=source-capability
+
+# Controller Blueprints Core Configuration
+blueprintsprocessor.blueprintDeployPath=/opt/app/onap/blueprints/deploy
+blueprintsprocessor.blueprintArchivePath=/opt/app/onap/blueprints/archive
+blueprintsprocessor.blueprintWorkingPath=/opt/app/onap/blueprints/working
+
+# Controller Blueprint Load Configurations
+# blueprints.load.initial-data may be overridden by ENV variables
+blueprintsprocessor.loadInitialData=false
+blueprintsprocessor.loadBluePrint=false
+blueprintsprocessor.loadBluePrintPaths=/opt/app/onap/model-catalog/blueprint-model/service-blueprint
+blueprintsprocessor.loadModelType=false
+blueprintsprocessor.loadModeTypePaths=/opt/app/onap/model-catalog/definition-type/starter-type
+blueprintsprocessor.loadResourceDictionary=false
+blueprintsprocessor.loadResourceDictionaryPaths=/opt/app/onap/model-catalog/resource-dictionary/starter-dictionary
+
+# CBA file extension
+controllerblueprints.loadCbaExtension=zip
+
+### END -Controller Blueprints Properties
+
+blueprintsprocessor.grpcEnable=false
+blueprintsprocessor.httpPort=8080
+blueprintsprocessor.grpcPort=9111
+
+# Primary Database Configuration
+blueprintsprocessor.db.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
+blueprintsprocessor.db.username=sa
+blueprintsprocessor.db.password=
+blueprintsprocessor.db.driverClassName=org.h2.Driver
+blueprintsprocessor.db.hibernateHbm2ddlAuto=create-drop
+blueprintsprocessor.db.hibernateDDLAuto=update
+blueprintsprocessor.db.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy
+blueprintsprocessor.db.hibernateDialect=org.hibernate.dialect.H2Dialect
+# Python executor
+blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython/ccsdk_blueprints
+blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython/ccsdk_blueprints
+
+security.user.password:{bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu
+security.user.name:ccsdkapps
+
+# Error Managements
+error.catalog.applicationId=cds
+error.catalog.type=properties
+error.catalog.errorDefinitionDir=./Tests/resources/
+
+# Executor Options
+blueprintsprocessor.resourceResolution.enabled=true
+blueprintsprocessor.netconfExecutor.enabled=true
+blueprintsprocessor.restConfExecutor.enabled=true
+blueprintsprocessor.cliExecutor.enabled=true
+blueprintsprocessor.remoteScriptCommand.enabled=false
+
+
+# Kafka-message-lib Configurations
+blueprintsprocessor.messageconsumer.self-service-api.kafkaEnable=false
+blueprintsprocessor.messageconsumer.self-service-api.type=kafka-basic-auth
+blueprintsprocessor.messageconsumer.self-service-api.bootstrapServers=127.0.0.1:9092
+blueprintsprocessor.messageconsumer.self-service-api.groupId=receiver-id
+blueprintsprocessor.messageconsumer.self-service-api.topic=receiver.t
+blueprintsprocessor.messageconsumer.self-service-api.clientId=request-receiver-client-id
+blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=1000
+
+# Kafka audit service Configurations
+blueprintsprocessor.messageproducer.self-service-api.audit.kafkaEnable=false
+blueprintsprocessor.messageproducer.self-service-api.audit.request.type=kafka-basic-auth
+blueprintsprocessor.messageproducer.self-service-api.audit.request.bootstrapServers=127.0.0.1:9092
+blueprintsprocessor.messageproducer.self-service-api.audit.request.clientId=audit-request-producer-client-id
+blueprintsprocessor.messageproducer.self-service-api.audit.request.topic=audit-request-producer.t
+
+blueprintsprocessor.messageproducer.self-service-api.audit.response.type=kafka-basic-auth
+blueprintsprocessor.messageproducer.self-service-api.audit.response.bootstrapServers=127.0.0.1:9092
+blueprintsprocessor.messageproducer.self-service-api.audit.response.clientId=audit-response-producer-client-id
+blueprintsprocessor.messageproducer.self-service-api.audit.response.topic=audit-response-producer.t
+
+
+endpoints.user.name=eHbVUbJAj4AG2522cSbrOQ==
+endpoints.user.password=eHbVUbJAj4AG2522cSbrOQ==
+
+#Workflow store configuration
+#workflow Audit request
+blueprintsprocessor.workflow.self-service-api.audit.storeEnable=false
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/error-messages_en.properties b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/error-messages_en.properties
new file mode 100644 (file)
index 0000000..71196ce
--- /dev/null
@@ -0,0 +1,91 @@
+#
+# Copyright Â© 2020 IBM, Bell Canada
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+org.onap.ccsdk.cds.blueprintsprocessor.generic_failure=cause=Internal error in Blueprint Processor run time.,action=Contact CDS administrator team.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_writing_fail=cause=Fail to write resources files.,action=Please reload your files and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+org.onap.ccsdk.cds.blueprintsprocessor.unsupported_media_type=cause=An invalid media was provided.,action=Please make sure your media or artifact is in the proper structure or format.
+
+# Self Service API
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.generic_failure=cause=Internal error in Self Service API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.generic_process_failure=cause=Internal error while processing REST call to the Self Service API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.invalid_file_extension=cause=Failed trying to upload a non ZIP file format.,action=Please reload your file and make sure it is in ZIP format.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.resource_writing_fail=cause=Fail to write resources files.,action=Please reload your files and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+org.onap.ccsdk.cds.blueprintsprocessor.selfservice.api.unsupported_media_type=cause=An invalid media was provided.,action=Please make sure your media or artifact is in the proper structure or format.
+
+# Designer API
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.generic_failure=cause=Internal error while processing REST call to the Designer API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.invalid_file_extension=cause=Failed trying to upload a non ZIP file format.,action=Please reload your file and make sure it is in ZIP format.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.resource_writing_fail=cause=Fail to write resources files.,action=Please reload your files and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+org.onap.ccsdk.cds.blueprintsprocessor.designer.api.unsupported_media_type=cause=An invalid media was provided.,action=Please make sure your media or artifact is in the proper structure or format.
+
+# Resource API
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.generic_failure=cause=Internal error while processing REST call to the Resource API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.invalid_file_extension=cause=Failed trying to upload a non ZIP file format.,action=Please reload your file and make sure it is in ZIP format.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.resource_writing_fail=cause=Fail to write resources files.,action=Please reload your files and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.api.unsupported_media_type=cause=An invalid media was provided.,action=Please make sure your media or artifact is in the proper structure or format.
+
+
+# Configs API
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.generic_failure=cause=Internal error while processing REST call to the Configs API.,action=Verify the request and try again.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.resource_path_missing=cause=Resource path missing or wrong.,action=Please reload your artifact in run time.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.io_file_interrupt=cause=IO file system interruption.,action=Please reload your file and make sure it is in the right format.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.unauthorized_request=cause=The request requires user authentication.,action=Please provide the right credentials.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.request_not_found=cause=Request mapping doesn't exist.,action=Please verify your request.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.conflict_adding_resource=cause=Duplicated entry while saving resource.,action=Please make the saving model doesn't exist.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.duplicate_data=cause=Duplicated data - was expecting one result, got more than one.,action=Please provide single resource at a time.
+org.onap.ccsdk.cds.blueprintsprocessor.configs.api.resource_not_found=cause=No response was found for this request in the server.,action=Provide the ID to find the resource.
+
+# Python Executor
+org.onap.ccsdk.cds.blueprintsprocessor.functions.python.executor.generic_failure=cause=Internal error in Blueprint Processor run time.,action=Contact CDS administrator team.
+
+# Resource resolution
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.invalid_request_format=cause=bad request provided.,action=Verify the request payload.
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.resource_not_found=cause=No response was found for this resolution in CDS.,action=Verify definition of the resource in CBA. 
+org.onap.ccsdk.cds.blueprintsprocessor.resource.resolution.internal_error=cause=Internal error while processing Resource Resolution.,action=Verify the payload.
+
+org.onap.ccsdk.cds.sdclistener.generic_failure=cause=Internal error in SDC Listener.,action=Contact CDS administrator team.
diff --git a/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/logback-test.xml b/components/model-catalog/blueprint-model/archetype-blueprint/src/main/resources/archetype-resources/Tests/resources/logback-test.xml
new file mode 100644 (file)
index 0000000..ed1fb9d
--- /dev/null
@@ -0,0 +1,51 @@
+<!--
+  ~ Copyright Â© 2017-2018 AT&T Intellectual Property.
+  ~ Modifications Copyright (C) 2019 Nordix Foundation.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<configuration>
+    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.onap.ccsdk.cds.blueprintsprocessor.uat.logging.SmartColorDiscriminator">
+            <defaultValue>white</defaultValue>
+        </discriminator>
+        <sift>
+            <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+                <encoder>
+                    <pattern>%${color}(%d{HH:mm:ss.SSS}|%X{RequestID}|%X{InvocationID}| %-5level %-40.40logger{39} : %msg%n)</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
+
+    <logger name="org.springframework.web.HttpLogging" level="debug"/>
+    <logger name="org.springframework.web.reactive.function.client.ExchangeFunctions" level="debug"/>
+
+    <!-- Helpful to optimize Spring Context caching to speed-up tests
+         and prevent resorting to @DirtiesContext as much as possible -->
+    <logger name="org.springframework.test.context.cache" level="debug"/>
+
+    <!-- Please refer to https://thoughts-on-java.org/hibernate-logging-guide/
+         for a lengthy discussion on good Hibernate logging practices -->
+    <logger name="org.hibernate.SQL" level="debug"/>
+    <logger name="org.hibernate.type.descriptor.sql" level="debug"/>
+
+    <logger name="org.apache.http" level="debug"/>
+    <logger name="org.apache.http.wire" level="error"/>
+
+    <root level="info">
+        <appender-ref ref="SIFT"/>
+    </root>
+
+</configuration>
index 48875dc..12c5d6b 100644 (file)
@@ -20,7 +20,7 @@
     <parent>
         <groupId>org.onap.ccsdk.cds.components.cba</groupId>
         <artifactId>test-blueprint-kotlin-parent</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
     </parent>
 
     <groupId>${groupId}</groupId>
index cc272ec..9d4678c 100644 (file)
     <name>Components Model Catalog - Blueprints Model - Test Kotlin Parent</name>
 
     <dependencies>
+        <dependency>
+            <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+            <artifactId>blueprintsprocessor-application</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.onap.ccsdk.cds.blueprintsprocessor.modules</groupId>
             <artifactId>execution-service</artifactId>
                 <directory>${project.basedir}/Environments</directory>
             </resource>
         </resources>
+        <testResources>
+            <testResource>
+                <directory>${project.basedir}/Tests/resources</directory>
+            </testResource>
+        </testResources>
         <plugins>
             <plugin>
                 <groupId>org.jacoco</groupId>
             </plugin>
             <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven-surefire-plugin.version}</version>
                 <executions>
                     <execution>
                         <id>default-test</id>
                         <phase>test</phase>
+                        <configuration>
+                            <!-- Sets the VM argument line used when unit tests are run. -->
+                            <argLine>-Xmx1024m </argLine>
+                            <reuseForks>false</reuseForks>
+                            <forkCount>1</forkCount>
+                        </configuration>
                         <goals>
                             <goal>test</goal>
                         </goals>
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>2.6</version>
+                <executions>
+                    <execution>
+                        <id>copy-test-resources</id>
+                        <goals>
+                            <goal>testResources</goal>
+                        </goals>
+                        <phase>process-test-resources</phase>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
 
                                         def publishEndpoint = properties['cds.publish.endpoint'] ?: 'api/v1/blueprint-model/publish'
 
                                         def throwIfPropMissing(prop) {
-                                        value = properties[prop]
-                                        if (!value || "".equals(value)) {
-                                        throw new RuntimeException("Property missing: $prop")
-                                        }
-                                        return value
+                                            value = properties[prop]
+                                            if (!value || "".equals(value)) {
+                                                throw new RuntimeException("Property missing: $prop")
+                                            }
+                                            return value
                                         }
 
                                         def buildRequest(endpoint, fileName) {
-                                        body = new MultipartBody.Builder()
-                                        .setType(MultipartBody.FORM)
-                                        .addFormDataPart("file",
-                                        fileName,
-                                        RequestBody.create(MediaType.parse('application/zip'), new File(target, fileName)))
-                                        .build()
+                                            body = new MultipartBody.Builder()
+                                                    .setType(MultipartBody.FORM)
+                                                    .addFormDataPart("file",
+                                                            fileName,
+                                                            RequestBody.create(MediaType.parse('application/zip'), new File(target, fileName)))
+                                                    .build()
 
-                                        return new Request.Builder()
-                                        .url("$protocol://$host:$port/$endpoint")
-                                        .addHeader('Authorization', Credentials.basic(userName, password))
-                                        .post(body)
-                                        .build()
+                                            return new Request.Builder()
+                                                    .url("$protocol://$host:$port/$endpoint")
+                                                    .addHeader('Authorization', Credentials.basic(userName, password))
+                                                    .post(body)
+                                                    .build()
                                         }
 
                                         def logAndThrow(msg) {
-                                        if(response) {
-                                        log.error(response.body().string())
-                                        }
-                                        throw new RuntimeException(msg)
+                                            if(response) {
+                                                log.error(response.body().string())
+                                            }
+                                            throw new RuntimeException(msg)
                                         }
 
                                         response = null
                                         try {
-                                        def client = new OkHttpClient()
+                                            def client = new OkHttpClient()
 
-                                        response = client.newCall(buildRequest(enrichEndpoint, cba)).execute()
-                                        if (!response || !response.isSuccessful()) {
-                                        logAndThrow("Failed to enrich CBA")
-                                        }
+                                            response = client.newCall(buildRequest(enrichEndpoint, cba)).execute()
+                                            if (!response || !response.isSuccessful()) {
+                                                logAndThrow("Failed to enrich CBA")
+                                            }
 
-                                        IOUtils.copy(
-                                        response.body().byteStream(),
-                                        new FileOutputStream(new File(target, enrichedCba))
-                                        )
-                                        log.info("Created enriched cba: $enrichedCba")
+                                            IOUtils.copy(
+                                                    response.body().byteStream(),
+                                                    new FileOutputStream(new File(target, enrichedCba))
+                                            )
+                                            log.info("Created enriched cba: $enrichedCba")
 
-                                        response = client.newCall(buildRequest(publishEndpoint, enrichedCba)).execute()
-                                        if (!response || !response.isSuccessful()) {
-                                        logAndThrow("Failed to publish CBA")
-                                        }
+                                            response = client.newCall(buildRequest(publishEndpoint, enrichedCba)).execute()
+                                            if (!response || !response.isSuccessful()) {
+                                                logAndThrow("Failed to publish CBA")
+                                            }
 
-                                        log.info("CBA Deployed")
-                                        log.info(response.body().string())
+                                            log.info("CBA Deployed")
+                                            log.info(response.body().string())
                                         } finally {
-                                        if (response) {
-                                        response.close()
-                                        }
+                                            if (response) {
+                                                response.close()
+                                            }
                                         }
                                     </source>
                                 </configuration>
index 1ea8b88..cd29d88 100644 (file)
@@ -39,4 +39,45 @@ Reference link for sample generated uat.yaml file for pnf plug & play use case:
 
 As UAT is part of unit testing, it runs in jenkins job
 `ccsdk-cds-master-verify-java <https://jenkins.onap.org/job/ccsdk-cds-master-verify-java/>`_
-whenever a new commit/patch pushed on gerrit in ccsdk/cds repo.
\ No newline at end of file
+whenever a new commit/patch pushed on gerrit in ccsdk/cds repo.
+
+Executing UAT based test inside you own CBA as SpringBootTest based JUnit test
+*******************************************************************************
+
+Beside the above mentioned internal usage of UATs, it is also possible to execute the User Acceptance Tests (UATs)
+locally inside your own CBA as a "simple JUnit" test.
+Therefor there exists an abstract *SpringBootTest* class **BaseBlueprintsAcceptanceTest**
+(see class in *archetype-blueprint*).
+From this you need to implement an inherited class e.g. **BlueprintAcceptanceSunnyTest**
+(see class in *archetype-blueprint*), which only needs to specify the **uat.yaml** file, that should be executed.
+This means it is possible to simply integrate this kind of tests in your own regression test suite.
+
+UATs aims to fully test your workflow of your CBA.
+
+The BPP runs in an almost production-like configuration with some minor exceptions:
+
+* It uses an embedded, in-memory, and initially empty H2 database, running in MySQL/MariaDB compatibility mode;
+* All external services are mocked.
+
+For further information about User Acceptance Tests (UATs) see the following README.md inside the CDS repository
+
+`Link to uat-blueprints README.md in CDS Github repository
+<https://github.com/onap/ccsdk-cds/blob/master/components/model-catalog/blueprint-model/uat-blueprints/README.md>`_
+
+Additionally please mention, that you also need resources, which configures the SpringBootTest. These resources you can
+also find in the *archetype-blueprint* (Tests/resources folder).
+
+To have a good starting point with your cba development, please generate the cba *archetype-blueprint* project with
+the following command.
+
+.. code-block:: bash
+
+   mvn archetype:generate -DarchetypeGroupId=org.onap.ccsdk.cds.components.cba \
+                          -DarchetypeArtifactId=archetype-blueprint \
+                          -DarchetypeVersion=1.4.0-SNAPSHOT \
+                          -DgroupId=org.onap.ccsdk.cds.components.cba \
+                          -DartifactId=testUat \
+                          -Dversion=1.0-SNAPSHOT
+
+There you will find the above mentioned base class, sample class and resources you could use as a starting point for
+writing UAT tests inside your own CBA.
\ No newline at end of file
index 5adc816..b97dbf7 100644 (file)
@@ -71,7 +71,7 @@ import java.util.concurrent.ConcurrentHashMap
  * @author Eliezio Oliveira
  */
 @Component
-class UatExecutor(
+open class UatExecutor(
     private val environment: ConfigurableEnvironment,
     private val restClientFactory: BluePrintRestLibPropertyService,
     private val mapper: ObjectMapper
@@ -298,7 +298,7 @@ class UatExecutor(
         return "Basic " + Base64Utils.encodeToString("$username:$plainPassword".toByteArray())
     }
 
-    private class MockPreInterceptor : BluePrintRestLibPropertyService.PreInterceptor {
+    open class MockPreInterceptor : BluePrintRestLibPropertyService.PreInterceptor {
 
         private val mocks = ConcurrentHashMap<String, BlueprintWebClientService>()
 
@@ -314,7 +314,7 @@ class UatExecutor(
         }
     }
 
-    private class SpyPostInterceptor(private val mapper: ObjectMapper) : BluePrintRestLibPropertyService.PostInterceptor {
+    open class SpyPostInterceptor(private val mapper: ObjectMapper) : BluePrintRestLibPropertyService.PostInterceptor {
 
         private val spies = ConcurrentHashMap<String, SpyService>()
 
@@ -336,7 +336,7 @@ class UatExecutor(
             spies.values.toList()
     }
 
-    private class SpyService(
+    open class SpyService(
         private val mapper: ObjectMapper,
         val selector: String,
         private val realService: BlueprintWebClientService