Add resource definition resolution service. 84/92684/5
authorBrinda Santh <brindasanth@in.ibm.com>
Mon, 5 Aug 2019 13:50:15 +0000 (09:50 -0400)
committerDan Timoney <dtimoney@att.com>
Fri, 9 Aug 2019 21:51:14 +0000 (21:51 +0000)
Change-Id: Ife75d290540e3ed0e0dfd0a82785a498607a2d25
Issue-ID: CCSDK-1577
Signed-off-by: Brinda Santh <brindasanth@in.ibm.com>
19 files changed:
ms/blueprintsprocessor/cba-parent/pom.xml
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt [deleted file]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt
ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt
ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt
ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt
ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt

index a7ee058..7605791 100644 (file)
@@ -31,6 +31,7 @@
 
     <build>
         <sourceDirectory>${project.basedir}/Scripts/kotlin</sourceDirectory>
+        <testSourceDirectory>${project.basedir}/Tests/kotlin</testSourceDirectory>
         <resources>
             <resource>
                 <directory>${project.basedir}/Environments</directory>
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt
deleted file mode 100644 (file)
index 5f3a5cd..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.
- */
-
-package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
-
-import org.jetbrains.kotlin.script.util.DependsOn
-import org.jetbrains.kotlin.script.util.Repository
-import kotlin.script.experimental.annotations.KotlinScript
-import kotlin.script.experimental.api.ScriptCompilationConfiguration
-import kotlin.script.experimental.api.defaultImports
-import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
-import kotlin.script.experimental.jvm.jvm
-
-@KotlinScript(fileExtension = "resourceassignmentprocessor.kts",
-        compilationConfiguration = ResourceAssignmentProcessorScriptConfiguration::class)
-abstract class ResourceAssignmentProcessorScript {
-
-}
-
-object ResourceAssignmentProcessorScriptConfiguration : ScriptCompilationConfiguration(
-        {
-            defaultImports(DependsOn::class, Repository::class)
-            jvm {
-                dependenciesFromCurrentContext(
-                        wholeClasspath = true
-                )
-            }
-        }
-)
\ No newline at end of file
index a487628..1b02ebe 100644 (file)
@@ -163,6 +163,35 @@ class ResourceAssignmentBuilder(private val name: String, private val dictionary
         resourceAssignment.property = PropertyDefinitionBuilder(name, type, required, description).apply(block).build()
     }
 
+    fun source(source: NodeTemplate) {
+        resourceAssignment.dictionarySourceDefinition = source
+    }
+
+    fun sourceInput(block: SourceInputNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceInputNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceDefault(block: SourceDefaultNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceDefaultNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceDb(block: SourceDbNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceDbNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceRest(block: SourceRestNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceRestNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
+    fun sourceCapability(block: SourceCapabilityNodeTemplateBuilder.() -> Unit) {
+        resourceAssignment.dictionarySourceDefinition = SourceCapabilityNodeTemplateBuilder(dictionarySource, "")
+                .apply(block).build()
+    }
+
     fun dependencies(dependencies: MutableList<String>) {
         resourceAssignment.dependencies = dependencies
     }
index b9b7103..d3b69c7 100644 (file)
@@ -26,6 +26,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.R
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceDefinitionUtils.createResourceAssignments
 import org.onap.ccsdk.cds.controllerblueprints.core.*
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
@@ -36,6 +37,7 @@ import org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils.BulkResourceS
 import org.slf4j.LoggerFactory
 import org.springframework.context.ApplicationContext
 import org.springframework.stereotype.Service
+import java.util.*
 
 interface ResourceResolutionService {
 
@@ -50,6 +52,14 @@ interface ResourceResolutionService {
     suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
                                  artifactPrefix: String, properties: Map<String, Any>): String
 
+    /** Resolve resources for all the sources defined in a particular resource Definition[resolveDefinition]
+     * with other [resourceDefinitions] dependencies for the sources [sources]
+     * Used to get the same resource values from multiple sources. **/
+    suspend fun resolveResourceDefinition(blueprintRuntimeService: BluePrintRuntimeService<*>,
+                                          resourceDefinitions: MutableMap<String, ResourceDefinition>,
+                                          resolveDefinition: String, sources: List<String>)
+            : MutableMap<String, JsonNode>
+
     suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>,
                                            resourceDefinitions: MutableMap<String, ResourceDefinition>,
                                            resourceAssignments: MutableList<ResourceAssignment>,
@@ -86,12 +96,12 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
                                           properties: Map<String, Any>): MutableMap<String, JsonNode> {
 
         val resourceAssignmentRuntimeService =
-            ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactNames.toString())
+                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactNames.toString())
 
         val resolvedParams: MutableMap<String, JsonNode> = hashMapOf()
         artifactNames.forEach { artifactName ->
             val resolvedContent = resolveResources(resourceAssignmentRuntimeService, nodeTemplateName,
-                artifactName, properties)
+                    artifactName, properties)
 
             resolvedParams[artifactName] = resolvedContent.asJsonType()
         }
@@ -151,6 +161,21 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
         return resolvedContent
     }
 
+    override suspend fun resolveResourceDefinition(blueprintRuntimeService: BluePrintRuntimeService<*>,
+                                                   resourceDefinitions: MutableMap<String, ResourceDefinition>,
+                                                   resolveDefinition: String, sources: List<String>)
+            : MutableMap<String, JsonNode> {
+
+        // Populate Dummy Resource Assignments
+        val resourceAssignments = createResourceAssignments(resourceDefinitions, resolveDefinition, sources)
+
+        resolveResourceAssignments(blueprintRuntimeService, resourceDefinitions, resourceAssignments,
+                UUID.randomUUID().toString(), hashMapOf())
+
+        // Get the data from Resource Assignments
+        return ResourceAssignmentUtils.generateResourceForAssignments(resourceAssignments)
+    }
+
     /**
      * Iterate the Batch, get the Resource Assignment, dictionary Name, Look for the Resource definition for the
      * name, then get the type of the Resource Definition, Get the instance for the Resource Type and process the
@@ -165,7 +190,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
         val bulkSequenced = BulkResourceSequencingUtils.process(resourceAssignments)
 
         // Check the BlueprintRuntime Service Should be ResourceAssignmentRuntimeService
-        val resourceAssignmentRuntimeService = if (!(blueprintRuntimeService is ResourceAssignmentRuntimeService)) {
+        val resourceAssignmentRuntimeService = if (blueprintRuntimeService !is ResourceAssignmentRuntimeService) {
             ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, artifactPrefix)
         } else {
             blueprintRuntimeService
index 49cb83e..0ea71ec 100644 (file)
@@ -27,14 +27,12 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.config.ConfigurableBeanFactory
-import org.springframework.context.ApplicationContext
 import org.springframework.context.annotation.Scope
 import org.springframework.stereotype.Service
 
 @Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-capability")
 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-open class CapabilityResourceResolutionProcessor(private val applicationContext: ApplicationContext,
-                                                 private var componentFunctionScriptingService: ComponentFunctionScriptingService)
+open class CapabilityResourceResolutionProcessor(private var componentFunctionScriptingService: ComponentFunctionScriptingService)
     : ResourceAssignmentProcessor() {
 
     private val log = LoggerFactory.getLogger(CapabilityResourceResolutionProcessor::class.java)
@@ -47,12 +45,14 @@ open class CapabilityResourceResolutionProcessor(private val applicationContext:
 
     override suspend fun processNB(resourceAssignment: ResourceAssignment) {
 
-        val resourceDefinition = resourceDictionaries[resourceAssignment.dictionaryName]
-                ?: throw BluePrintProcessorException("couldn't get resource definition for ${resourceAssignment.dictionaryName}")
+        val dName = resourceAssignment.dictionaryName!!
+        val dSource = resourceAssignment.dictionarySource!!
+        val resourceDefinition = resourceDefinition(resourceAssignment.dictionaryName!!)
 
-        val resourceSource = resourceDefinition.sources[resourceAssignment.dictionarySource]
-                ?: throw BluePrintProcessorException("couldn't get resource definition " +
-                        "${resourceAssignment.dictionaryName} source(${resourceAssignment.dictionarySource})")
+        /** Check Resource Assignment has the source definitions, If not get from Resource Definition **/
+        val resourceSource = resourceAssignment.dictionarySourceDefinition
+                ?: resourceDefinition?.sources?.get(dSource)
+                ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
 
         val resourceSourceProps = checkNotNull(resourceSource.properties) { "failed to get $resourceSource properties" }
         /**
@@ -96,10 +96,6 @@ open class CapabilityResourceResolutionProcessor(private val applicationContext:
                 .scriptInstance<ResourceAssignmentProcessor>(raRuntimeService.bluePrintContext(), scriptType,
                         scriptClassReference)
 
-        instanceDependencies.forEach { instanceDependency ->
-            scriptPropertyInstances[instanceDependency] = applicationContext
-                    .getBean(instanceDependency)
-        }
         return scriptComponent
     }
 
index 987390f..600de13 100644 (file)
@@ -18,8 +18,6 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor
 
 import com.fasterxml.jackson.databind.node.JsonNodeFactory
-import com.fasterxml.jackson.databind.node.MissingNode
-import com.fasterxml.jackson.databind.node.NullNode
 import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibGenericService
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.BluePrintDBLibPropertySevice
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.PrimaryDBLibGenericService
@@ -41,7 +39,7 @@ import java.util.*
  *
  * @author Kapil Singal
  */
-@Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-processor-db")
+@Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-db")
 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropertySevice: BluePrintDBLibPropertySevice,
                                                private val primaryDBLibGenericService: PrimaryDBLibGenericService)
@@ -50,7 +48,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
     private val logger = LoggerFactory.getLogger(DatabaseResourceAssignmentProcessor::class.java)
 
     override fun getName(): String {
-        return "${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-processor-db"
+        return "${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-db"
     }
 
     override suspend fun processNB(resourceAssignment: ResourceAssignment) {
@@ -60,7 +58,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
             // Check if It has Input
             try {
                 val value = raRuntimeService.getInputValue(resourceAssignment.name)
-                if (value !is NullNode && value !is MissingNode) {
+                if (value.returnNullIfMissing() != null) {
                     logger.info("processor-db source template key (${resourceAssignment.name}) found from input and value is ($value)")
                     ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value)
                 } else {
@@ -79,11 +77,13 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
     }
 
     private fun setValueFromDB(resourceAssignment: ResourceAssignment) {
-        val dName = resourceAssignment.dictionaryName
-        val dSource = resourceAssignment.dictionarySource
-        val resourceDefinition = resourceDictionaries[dName]
-                ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dName")
-        val resourceSource = resourceDefinition.sources[dSource]
+        val dName = resourceAssignment.dictionaryName!!
+        val dSource = resourceAssignment.dictionarySource!!
+        val resourceDefinition = resourceDefinition(dName)
+
+        /** Check Resource Assignment has the source definitions, If not get from Resource Definition **/
+        val resourceSource = resourceAssignment.dictionarySourceDefinition
+                ?: resourceDefinition?.sources?.get(dSource)
                 ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
         val resourceSourceProperties = checkNotNull(resourceSource.properties) {
             "failed to get source properties for $dName "
@@ -188,7 +188,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert
                 val row = rows[0]
                 val objectNode = JacksonUtils.objectMapper.createObjectNode()
                 for (mapping in outputKeyMapping.entries) {
-                    val dbColumnValue = checkNotNull(row[mapping.key])
+                    val dbColumnValue = checkNotNull(row[mapping.value])
                     val propertyTypeForDataType = ResourceAssignmentUtils.getPropertyType(raRuntimeService, type, mapping.key)
                     JacksonUtils.populatePrimitiveValues(mapping.key, dbColumnValue, propertyTypeForDataType, objectNode)
                 }
index 1abcea8..2a7d19b 100644 (file)
@@ -38,7 +38,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
     private val log = LoggerFactory.getLogger(ResourceAssignmentProcessor::class.java)
 
     lateinit var raRuntimeService: ResourceAssignmentRuntimeService
-    lateinit var resourceDictionaries: MutableMap<String, ResourceDefinition>
+    var resourceDictionaries: MutableMap<String, ResourceDefinition> = hashMapOf()
 
     var scriptPropertyInstances: MutableMap<String, Any> = hashMapOf()
     lateinit var scriptType: String
@@ -62,9 +62,8 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
         return value
     }
 
-    open fun resourceDefinition(name: String): ResourceDefinition {
-        return resourceDictionaries[name]
-                ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)")
+    open fun resourceDefinition(name: String): ResourceDefinition? {
+        return if (resourceDictionaries.containsKey(name)) resourceDictionaries[name] else null
     }
 
     open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, JsonNode> {
index 3bf0b35..57e0286 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor
 
-import com.fasterxml.jackson.databind.node.ArrayNode
 import com.fasterxml.jackson.databind.node.MissingNode
 import com.fasterxml.jackson.databind.node.NullNode
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR
@@ -56,29 +55,30 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
             // Check if It has Input
             val value = getFromInput(resourceAssignment)
             if (value == null || value is MissingNode || value is NullNode) {
-                val dName = resourceAssignment.dictionaryName
-                val dSource = resourceAssignment.dictionarySource
-                val resourceDefinition = resourceDictionaries[dName]
-                    ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dName")
+                val dName = resourceAssignment.dictionaryName!!
+                val dSource = resourceAssignment.dictionarySource!!
+                val resourceDefinition = resourceDefinition(dName)
 
-                val resourceSource = resourceDefinition.sources[dSource]
-                    ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
+                /** Check Resource Assignment has the source definitions, If not get from Resource Definitions **/
+                val resourceSource = resourceAssignment.dictionarySourceDefinition
+                        ?: resourceDefinition?.sources?.get(dSource)
+                        ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
 
                 val resourceSourceProperties =
-                    checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
+                        checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
 
                 val sourceProperties =
-                    JacksonUtils.getInstanceFromMap(resourceSourceProperties, RestResourceSource::class.java)
+                        JacksonUtils.getInstanceFromMap(resourceSourceProperties, RestResourceSource::class.java)
 
                 val path = nullToEmpty(sourceProperties.path)
                 val inputKeyMapping =
-                    checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
+                        checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
                 val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping).toMutableMap()
 
                 // Resolving content Variables
                 val payload = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.payload), resolvedInputKeyMapping)
                 val urlPath =
-                    resolveFromInputKeyMapping(checkNotNull(sourceProperties.urlPath), resolvedInputKeyMapping)
+                        resolveFromInputKeyMapping(checkNotNull(sourceProperties.urlPath), resolvedInputKeyMapping)
                 val verb = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.verb), resolvedInputKeyMapping)
 
                 logger.info("$dSource dictionary information : ($urlPath), ($inputKeyMapping), (${sourceProperties.outputKeyMapping})")
@@ -91,12 +91,11 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                 val outputKeyMapping = sourceProperties.outputKeyMapping
                 if (responseStatusCode in 200..299 && outputKeyMapping.isNullOrEmpty()) {
                     logger.info("AS>> outputKeyMapping==null, will not populateResource")
-                }
-                else if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
+                } else if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
                     populateResource(resourceAssignment, sourceProperties, responseBody, path)
                 } else {
                     val errMsg =
-                        "Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath) response_code: ($responseStatusCode)"
+                            "Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath) response_code: ($responseStatusCode)"
                     logger.warn(errMsg)
                     throw BluePrintProcessorException(errMsg)
                 }
@@ -106,7 +105,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
         } catch (e: Exception) {
             ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message)
             throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}",
-                e)
+                    e)
         }
     }
 
@@ -161,13 +160,13 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                         outputKeyMapping.map {
                             val responseKeyValue = responseSingleJsonNode.get(it.key)
                             val propertyTypeForDataType = ResourceAssignmentUtils
-                                .getPropertyType(raRuntimeService, entrySchemaType, it.key)
+                                    .getPropertyType(raRuntimeService, entrySchemaType, it.key)
 
                             logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), " +
                                     "type  ({$propertyTypeForDataType})")
 
                             JacksonUtils.populateJsonNodeValues(it.value,
-                                responseKeyValue, propertyTypeForDataType, arrayChildNode)
+                                    responseKeyValue, propertyTypeForDataType, arrayChildNode)
                         }
                         arrayNode.add(arrayChildNode)
                     }
@@ -185,7 +184,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                 outputKeyMapping.map {
                     val responseKeyValue = responseNode.get(it.key)
                     val propertyTypeForDataType = ResourceAssignmentUtils
-                        .getPropertyType(raRuntimeService, entrySchemaType, it.key)
+                            .getPropertyType(raRuntimeService, entrySchemaType, it.key)
 
                     logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), type  ({$propertyTypeForDataType})")
                     JacksonUtils.populateJsonNodeValues(it.value, responseKeyValue, propertyTypeForDataType, objectNode)
index 8a8bfbf..f8024d9 100644 (file)
@@ -19,7 +19,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.uti
 
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.databind.node.NullNode
 import com.fasterxml.jackson.databind.node.ObjectNode
 import com.fasterxml.jackson.databind.node.TextNode
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
@@ -70,7 +69,8 @@ class ResourceAssignmentUtils {
             try {
                 if (resourceProp.type.isNotEmpty()) {
                     logger.info("Setting Resource Value ($value) for Resource Name " +
-                            "(${resourceAssignment.name}) of type (${resourceProp.type})")
+                            "(${resourceAssignment.name}), definition(${resourceAssignment.dictionaryName}) " +
+                            "of type (${resourceProp.type})")
                     setResourceValue(resourceAssignment, raRuntimeService, value)
                     resourceAssignment.updatedDate = Date()
                     resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
@@ -106,7 +106,7 @@ class ResourceAssignmentUtils {
                 "Failed to populate mandatory resource resource mapping $resourceAssignment"
             }
             if (resourceProp.required != null && resourceProp.required!!
-                    && (resourceProp.value == null || resourceProp.value !is NullNode)) {
+                    && (resourceProp.value == null || resourceProp.value!!.returnNullIfMissing() == null)) {
                 logger.error("failed to populate mandatory resource mapping ($resourceAssignment)")
                 throw BluePrintProcessorException("failed to populate mandatory resource mapping ($resourceAssignment)")
             }
@@ -137,6 +137,21 @@ class ResourceAssignmentUtils {
             return result
         }
 
+        @Throws(BluePrintProcessorException::class)
+        fun generateResourceForAssignments(assignments: List<ResourceAssignment>): MutableMap<String, JsonNode> {
+            val data: MutableMap<String, JsonNode> = hashMapOf()
+            assignments.forEach {
+                if (isNotEmpty(it.name) && it.property != null) {
+                    val rName = it.name
+                    val type = nullToEmpty(it.property?.type).toLowerCase()
+                    val value = useDefaultValueIfNull(it, rName)
+                    logger.trace("Generating Resource name ($rName), type ($type), value ($value)")
+                    data[rName] = value
+                }
+            }
+            return data
+        }
+
         private fun useDefaultValueIfNull(resourceAssignment: ResourceAssignment, resourceAssignmentName: String): JsonNode {
             if (resourceAssignment.property?.value == null) {
                 val defaultValue = "\${$resourceAssignmentName}"
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt
new file mode 100644 (file)
index 0000000..15a8c6c
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString
+import org.onap.ccsdk.cds.controllerblueprints.core.asListOfString
+import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
+
+object ResourceDefinitionUtils {
+
+    fun definitionDependencies(definition: ResourceDefinition, sources: List<String>): Set<String> {
+        val dependencies: MutableSet<String> = mutableSetOf()
+        definition.sources.forEach { (sourceName, source) ->
+            if (sources.contains(sourceName)) {
+                val keyDependenciesExists = source.properties?.containsKey("key-dependencies") ?: false
+                if (keyDependenciesExists) {
+                    dependencies.addAll(source.properties!!["key-dependencies"]!!.asListOfString())
+                }
+            }
+        }
+        return dependencies
+    }
+
+    /** Create a processing resource assignments for the resource definition  */
+    fun createResourceAssignments(resourceDefinitions: MutableMap<String, ResourceDefinition>,
+                                  resolveDefinition: String, sources: List<String>)
+            : MutableList<ResourceAssignment> {
+        /** Check if resolve definition is defined in the resource definition Map */
+        val resourceDefinition = resourceDefinitions[resolveDefinition]
+                ?: throw BluePrintProcessorException("failed to get resolve definition($resolveDefinition)")
+
+        val resourceAssignments: MutableList<ResourceAssignment> = arrayListOf()
+        /** Get the dependency property fields for the the resource definition to resolve */
+        val definitionDependencies = definitionDependencies(resourceDefinition, sources)
+        definitionDependencies.forEach { definitionDependencyName ->
+            val definitionDependency = resourceDefinitions[definitionDependencyName]
+                    ?: throw BluePrintProcessorException("failed to get dependency definition($definitionDependencyName)")
+
+            val resourceAssignment = ResourceAssignment().apply {
+                name = definitionDependency.name
+                dictionaryName = definitionDependency.name
+                /** The assumption is al resource are already resolved and shall get as input source */
+                dictionarySource = "input"
+                property = definitionDependency.property
+            }
+            resourceAssignments.add(resourceAssignment)
+        }
+
+        resourceDefinition.sources.forEach { (sourceName, source) ->
+            if (sources.contains(sourceName)) {
+                val resourceAssignment = ResourceAssignment().apply {
+                    name = "$sourceName:${resourceDefinition.name}"
+                    dictionaryName = resourceDefinition.name
+                    dictionarySource = sourceName
+                    dictionarySourceDefinition = source
+                    // Clone the PropertyDefinition, otherwise property value will be overridden
+                    property = JacksonUtils
+                            .readValue(resourceDefinition.property.asJsonString(), PropertyDefinition::class.java)
+                    val keyDependenciesExists = source.properties?.containsKey("key-dependencies") ?: false
+                    if (keyDependenciesExists) {
+                        dependencies = source.properties!!["key-dependencies"]!!.asListOfString().toMutableList()
+                    }
+                }
+                resourceAssignments.add(resourceAssignment)
+            }
+        }
+        // Populate Resource Definition's dependencies as Input Resource Assignment
+        return resourceAssignments
+    }
+}
\ No newline at end of file
index f1ad030..775c501 100644 (file)
@@ -18,6 +18,8 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
 
+import io.mockk.every
+import io.mockk.mockk
 import kotlinx.coroutines.runBlocking
 import org.junit.Assert
 import org.junit.Before
@@ -30,12 +32,18 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.utils.PayloadUtils
 import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.*
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintError
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
+import org.springframework.context.ApplicationContext
 import org.springframework.context.annotation.ComponentScan
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
@@ -84,8 +92,8 @@ class ResourceResolutionServiceTest {
     fun testRegisteredSource() {
         val sources = resourceResolutionService.registeredResourceSources()
         assertNotNull(sources, "failed to get registered sources")
-        assertTrue(sources.containsAll(arrayListOf("source-input", "source-default", "source-processor-db",
-            "source-rest")), "failed to get registered sources : $sources")
+        assertTrue(sources.containsAll(arrayListOf("source-input", "source-default", "source-db",
+                "source-rest", "source-capability")), "failed to get registered sources : $sources")
     }
 
     @Test
@@ -96,27 +104,27 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
 
             val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
-                    "testResolveResource")
+                    ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
+                            "testResolveResource")
 
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
-                "resource-assignment",
-                "baseconfig",
-                props)
+                    "resource-assignment",
+                    "baseconfig",
+                    props)
 
         }
     }
@@ -128,23 +136,23 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
             val artefactNames = listOf("baseconfig", "another")
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(bluePrintRuntimeService,
-                "resource-assignment",
-                artefactNames,
-                props)
+                    "resource-assignment",
+                    artefactNames,
+                    props)
         }
 
     }
@@ -156,27 +164,27 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
             val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
-                    "testResolveResourcesWithMappingAndTemplate")
+                    ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
+                            "testResolveResourcesWithMappingAndTemplate")
 
             val artifactPrefix = "another"
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
-                "resource-assignment",
-                artifactPrefix,
-                props)
+                    "resource-assignment",
+                    artifactPrefix,
+                    props)
         }
     }
 
@@ -190,27 +198,81 @@ class ResourceResolutionServiceTest {
             Assert.assertNotNull("failed to create ResourceResolutionService", resourceResolutionService)
 
             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
-                "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
 
             val executionServiceInput =
-                JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
-                    ExecutionServiceInput::class.java)!!
+                    JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                            ExecutionServiceInput::class.java)!!
 
             val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
-                    "testResolveResourcesWithMappingAndTemplate")
+                    ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService,
+                            "testResolveResourcesWithMappingAndTemplate")
 
             val artifactPrefix = "another"
 
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService,
-                executionServiceInput.payload,
-                "resource-assignment")
+                    executionServiceInput.payload,
+                    "resource-assignment")
 
             resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
-                "resource-assignment",
-                artifactPrefix,
-                props)
+                    "resource-assignment",
+                    artifactPrefix,
+                    props)
+        }
+    }
+
+    @Test
+    fun testResourceResolutionForDefinition() {
+        val resourceDefinitions = BluePrintTypes.resourceDefinitions {
+            resourceDefinition(name = "port-speed", description = "Port Speed") {
+                property(type = "string", required = true)
+                sources {
+                    sourceCapability(id = "sdno", description = "SDNO Source") {
+                        definedProperties {
+                            type(BluePrintConstants.SCRIPT_KOTLIN)
+                            scriptClassReference(MockCapabilityScriptRA::class.qualifiedName!!)
+                            keyDependencies(arrayListOf("device-id"))
+                        }
+                    }
+                    sourceDb(id = "sdnc", description = "SDNC Controller") {
+                        definedProperties {
+                            endpointSelector("processor-db")
+                            query("SELECT PORT_SPEED FROM XXXX WHERE DEVICE_ID = :device_id")
+                            inputKeyMapping {
+                                map("device_id", "\$device-id")
+                            }
+                            keyDependencies(arrayListOf("device-id"))
+                        }
+                    }
+                }
+            }
+            resourceDefinition(name = "device-id", description = "Device Id") {
+                property(type = "string", required = true) {
+                    sources {
+                        sourceInput(id = "input", description = "Dependency Source") {}
+                    }
+                }
+            }
+        }
+        runBlocking {
+            val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
+            every { raRuntimeService.bluePrintContext() } returns mockk<BluePrintContext>()
+            every { raRuntimeService.getBluePrintError() } returns BluePrintError()
+            every { raRuntimeService.setBluePrintError(any())} returns Unit
+            every { raRuntimeService.getInputValue("device-id") } returns "123456".asJsonPrimitive()
+
+            val applicationContext = mockk<ApplicationContext>()
+            every { applicationContext.getBean("rr-processor-source-capability") } returns MockCapabilityScriptRA()
+            every { applicationContext.getBean("rr-processor-source-db") } returns MockCapabilityScriptRA()
+            every { applicationContext.getBean("rr-processor-source-input") } returns MockCapabilityScriptRA()
+
+            val sources = arrayListOf<String>("sdno", "sdnc")
+
+            val resourceResolutionService = ResourceResolutionServiceImpl(applicationContext, mockk(), mockk(), mockk())
+            val resolvedResources = resourceResolutionService.resolveResourceDefinition(raRuntimeService,
+                    resourceDefinitions, "port-speed", sources)
+            assertNotNull(resolvedResources, "failed to resolve the resources")
         }
     }
 }
index 4a4bcc0..f020f29 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor
 
+import io.mockk.coEvery
+import io.mockk.every
+import io.mockk.mockk
 import kotlinx.coroutines.runBlocking
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceAssignment
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts.BlueprintJythonService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts.PythonExecutorProperty
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintScriptsServiceImpl
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
 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.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
-import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintScriptsServiceImpl
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.test.context.ContextConfiguration
 import org.springframework.test.context.TestPropertySource
 import org.springframework.test.context.junit4.SpringRunner
+import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
 
 @RunWith(SpringRunner::class)
 @ContextConfiguration(classes = [CapabilityResourceResolutionProcessor::class, ComponentFunctionScriptingService::class,
@@ -50,44 +59,36 @@ class CapabilityResourceResolutionProcessorTest {
     @Autowired
     lateinit var capabilityResourceResolutionProcessor: CapabilityResourceResolutionProcessor
 
-    @Ignore
     @Test
     fun `test kotlin capability`() {
         runBlocking {
-
-            val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext(
-                    "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
-
-            val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext)
-
-            capabilityResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService
-            capabilityResourceResolutionProcessor.resourceDictionaries = hashMapOf()
-
-
-            val scriptPropertyInstances: MutableMap<String, Any> = mutableMapOf()
-            scriptPropertyInstances["mock-service1"] = MockCapabilityService()
-            scriptPropertyInstances["mock-service2"] = MockCapabilityService()
-
-            val instanceDependencies: List<String> = listOf()
-
-            val resourceAssignmentProcessor = capabilityResourceResolutionProcessor
-                    .scriptInstance("kotlin",
-                            "ResourceAssignmentProcessor_cba\$ScriptResourceAssignmentProcessor", instanceDependencies)
-
-            assertNotNull(resourceAssignmentProcessor, "couldn't get kotlin script resource assignment processor")
-
-            val resourceAssignment = ResourceAssignment().apply {
-                name = "ra-name"
-                dictionaryName = "ra-dict-name"
-                dictionarySource = "capability"
-                property = PropertyDefinition().apply {
-                    type = "string"
+            val componentFunctionScriptingService = mockk<ComponentFunctionScriptingService>()
+            coEvery {
+                componentFunctionScriptingService
+                        .scriptInstance<ResourceAssignmentProcessor>(any(), any(), any())
+            } returns MockCapabilityScriptRA()
+
+            val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
+            every { raRuntimeService.bluePrintContext() } returns mockk<BluePrintContext>()
+
+            val capabilityResourceResolutionProcessor = CapabilityResourceResolutionProcessor(componentFunctionScriptingService)
+            capabilityResourceResolutionProcessor.raRuntimeService = raRuntimeService
+
+            val resourceAssignment = BluePrintTypes.resourceAssignment(name = "test-property", dictionaryName = "ra-dict-name",
+                    dictionarySource = "capability") {
+                property("string", true, "")
+                sourceCapability {
+                    definedProperties {
+                        type("internal")
+                        scriptClassReference(MockCapabilityScriptRA::class.qualifiedName!!)
+                        keyDependencies(arrayListOf("dep-property"))
+                    }
                 }
             }
-
-            val processorName = resourceAssignmentProcessor.applyNB(resourceAssignment)
-            assertNotNull(processorName, "couldn't get kotlin script resource assignment processor name")
-            println(processorName)
+            val status = capabilityResourceResolutionProcessor.applyNB(resourceAssignment)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals("assigned-data".asJsonPrimitive(), resourceAssignment.property!!.value,
+                    "assigned value miss match")
         }
     }
 
@@ -127,4 +128,21 @@ class CapabilityResourceResolutionProcessorTest {
 
 open class MockCapabilityService {
 
+}
+
+open class MockCapabilityScriptRA : ResourceAssignmentProcessor() {
+    val log = logger(MockCapabilityScriptRA::class)
+
+    override fun getName(): String {
+        return "MockCapabilityScriptRA"
+    }
+
+    override suspend fun processNB(executionRequest: ResourceAssignment) {
+        log.info("executing RA mock capability : ${executionRequest.name}")
+        executionRequest.property!!.value = "assigned-data".asJsonPrimitive()
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
 }
\ No newline at end of file
index efefe02..fd889bf 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.db
 
-import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.BluePrintDBLibPropertySevice
+import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.PrimaryDBLibGenericService
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
 import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.ComponentScan
@@ -39,15 +40,15 @@ open class BluePrintDBLibConfiguration(private var bluePrintProperties: BluePrin
 /**
  * Exposed Dependency Service by this SSH Lib Module
  */
-//TODO("right now not wired with name ")
 fun BluePrintDependencyService.dbLibPropertyService(): BluePrintDBLibPropertySevice =
-        instance(DBLibConstants.SERVICE_BLUEPRINT_DB_LIB_PROPERTY)
+        instance(BluePrintDBLibPropertySevice::class)
+
+fun BluePrintDependencyService.primaryDBLibGenericService(): BluePrintDBLibGenericService =
+        instance(PrimaryDBLibGenericService::class)
 
 
 class DBLibConstants {
     companion object {
-        //TODO("right now not wired with name ")
-        const val SERVICE_BLUEPRINT_DB_LIB_PROPERTY = "blueprint-db-lib-property-service"
         const val PREFIX_DB_PRIMARY: String = "blueprintsprocessor.db.primary"
 
         //list of database
@@ -62,7 +63,5 @@ class DBLibConstants {
         const val DRIVER_MYSQL_DB = "com.mysql.jdbc.Driver"
         const val DRIVER_ORACLE_DB = "oracle.jdbc.driver.OracleDriver"
         const val DRIVER_POSTGRES_DB = "org.postgresql.Driver"
-
-
     }
 }
\ No newline at end of file
index cf2ca55..2ae5042 100644 (file)
@@ -32,7 +32,7 @@ class BluePrintDBLibPropertySevice(private var bluePrintProperties: BluePrintPro
     }
 
     fun JdbcTemplate(selector: String): BluePrintDBLibGenericService {
-        val prefix = "blueprintsprocessor.database.$selector"
+        val prefix = "blueprintsprocessor.db.$selector"
         val dBConnetionProperties = dBDataSourceProperties(prefix)
         return blueprintDBDataSourceService(dBConnetionProperties)
     }
index 2717c3b..d148745 100644 (file)
@@ -21,8 +21,8 @@ import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.node.*
 import org.apache.commons.lang3.ObjectUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
-import org.slf4j.LoggerFactory
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JsonParserUtils
+import org.slf4j.LoggerFactory
 import org.slf4j.helpers.MessageFormatter
 import kotlin.reflect.KClass
 
@@ -156,6 +156,11 @@ fun ArrayNode.asListOfString(): List<String> {
     return JacksonUtils.getListFromJsonNode(this, String::class.java)
 }
 
+fun JsonNode.asListOfString(): List<String> {
+    check(this is ArrayNode) { "JsonNode is not of type ArrayNode" }
+    return this.asListOfString()
+}
+
 fun JsonNode.returnNullIfMissing(): JsonNode? {
     return if (this is NullNode || this is MissingNode) {
         null
index fdaf25c..776e041 100644 (file)
@@ -18,6 +18,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service
 
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.springframework.context.ApplicationContext
+import kotlin.reflect.KClass
 
 /**
  * Generic Bluepring Dependency Service, which will be used mainly in scripts.
@@ -44,4 +45,9 @@ object BluePrintDependencyService {
         return applicationContext.getBean(type)
                 ?: throw BluePrintProcessorException("failed to get instance($type)")
     }
+
+    inline fun <reified T> instance(type: KClass<*>): T {
+        return applicationContext.getBean(type.java) as? T
+                ?: throw BluePrintProcessorException("failed to get instance($type)")
+    }
 }
\ No newline at end of file
index 9b1b66b..768f875 100644 (file)
@@ -238,11 +238,14 @@ class JacksonUtils {
 
         fun populatePrimitiveValues(key: String, value: Any, primitiveType: String, objectNode: ObjectNode) {
             when (primitiveType.toLowerCase()) {
-                BluePrintConstants.DATA_TYPE_BOOLEAN -> objectNode.put(key, (value as BooleanNode).booleanValue())
-                BluePrintConstants.DATA_TYPE_INTEGER -> objectNode.put(key, (value as IntNode).intValue())
-                BluePrintConstants.DATA_TYPE_FLOAT -> objectNode.put(key, (value as FloatNode).floatValue())
-                BluePrintConstants.DATA_TYPE_DOUBLE -> objectNode.put(key, (value as DoubleNode).doubleValue())
-                else -> objectNode.put(key, (value as TextNode).textValue())
+                BluePrintConstants.DATA_TYPE_STRING,
+                BluePrintConstants.DATA_TYPE_BOOLEAN,
+                BluePrintConstants.DATA_TYPE_INTEGER,
+                BluePrintConstants.DATA_TYPE_FLOAT,
+                BluePrintConstants.DATA_TYPE_DOUBLE,
+                BluePrintConstants.DATA_TYPE_TIMESTAMP ->
+                    objectNode.set(key, value.asJsonPrimitive())
+                else -> objectNode.set(key, value.asJsonType())
             }
         }
 
index a2f1e23..c222de9 100644 (file)
@@ -58,6 +58,12 @@ open class ResourceAssignment {
     @JsonProperty("dictionary-source")
     var dictionarySource: String? = null
 
+    /** Modified Source definition,  Capability Source will use for script reference changes,
+     * Rest Source will use for extra headers etc **/
+    @JsonProperty("dictionary-source-definition")
+    var dictionarySourceDefinition: NodeTemplate? = null
+
+    /** Duplicate field : Shall be used directly from Dictionary Source definition dependencies. **/
     @JsonProperty("dependencies")
     var dependencies: MutableList<String>? = null
 
index dbd5b7d..60fe6a7 100644 (file)
 package org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils
 
 import org.apache.commons.collections.CollectionUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.asListOfString
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.TopologicalSortingUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.slf4j.LoggerFactory
-import java.util.ArrayList
+import java.util.*
+
 /**
  * BulkResourceSequencingUtils.
  *
  * @author Brinda Santh
  */
 object BulkResourceSequencingUtils {
-    private val log= LoggerFactory.getLogger(BulkResourceSequencingUtils::class.java)
+    private val log = LoggerFactory.getLogger(BulkResourceSequencingUtils::class.java)
 
     @JvmStatic
     fun process(resourceAssignments: MutableList<ResourceAssignment>): List<List<ResourceAssignment>> {
@@ -46,7 +48,13 @@ object BulkResourceSequencingUtils {
         // Preepare Sorting Map
         val topologySorting = TopologicalSortingUtils<ResourceAssignment>()
         resourceAssignmentMap.forEach { _, resourceAssignment ->
-            if (CollectionUtils.isNotEmpty(resourceAssignment.dependencies)) {
+            // Get the dependencies from the assignment sources, if not get from the Resource Assignment dependencies
+            if (resourceAssignment.dictionarySourceDefinition != null) {
+                val dependencies = resourceAssignment.dictionarySourceDefinition?.properties?.get("key-dependencies")?.asListOfString()
+                dependencies?.forEach { dependency ->
+                    topologySorting.add(resourceAssignmentMap[dependency]!!, resourceAssignment)
+                }
+            } else if (CollectionUtils.isNotEmpty(resourceAssignment.dependencies)) {
                 for (dependency in resourceAssignment.dependencies!!) {
                     topologySorting.add(resourceAssignmentMap[dependency]!!, resourceAssignment)
                 }