diff options
author | Brinda Santh <brindasanth@in.ibm.com> | 2019-08-05 09:50:15 -0400 |
---|---|---|
committer | Dan Timoney <dtimoney@att.com> | 2019-08-09 21:51:14 +0000 |
commit | 977287b586e27e2f835a5d24950abf1f2adae8be (patch) | |
tree | 86200548402e907c6cf969bd4f0a516eed937ed0 | |
parent | 4001ac13397c082ee97c7ff440fa2ead5d50b421 (diff) |
Add resource definition resolution service.
Change-Id: Ife75d290540e3ed0e0dfd0a82785a498607a2d25
Issue-ID: CCSDK-1577
Signed-off-by: Brinda Santh <brindasanth@in.ibm.com>
19 files changed, 402 insertions, 185 deletions
diff --git a/ms/blueprintsprocessor/cba-parent/pom.xml b/ms/blueprintsprocessor/cba-parent/pom.xml index a7ee0586c..760579196 100644 --- a/ms/blueprintsprocessor/cba-parent/pom.xml +++ b/ms/blueprintsprocessor/cba-parent/pom.xml @@ -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 index 5f3a5cdaf..000000000 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentProcessorScriptConfiguration.kt +++ /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 diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt index a48762832..1b02ebe70 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceDefinitionDSL.kt @@ -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 } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index b9b710390..d3b69c713 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -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 diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt index 49cb83e09..0ea71ece7 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt @@ -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 } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt index 987390fdb..600de134e 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt @@ -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) } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt index 1abcea825..2a7d19b94 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt @@ -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> { diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt index 3bf0b359a..57e028618 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt @@ -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) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt index 8a8bfbf32..f8024d92e 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt @@ -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 index 000000000..15a8c6c80 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceDefinitionUtils.kt @@ -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 diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt index f1ad03054..775c501c2 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt @@ -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") } } } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt index 4a4bcc026..f020f2952 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessorTest.kt @@ -18,25 +18,34 @@ 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 diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt index efefe0290..fd889bfbf 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibConfiguration.kt @@ -16,9 +16,10 @@ 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 diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt index cf2ca550e..2ae50424f 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/primary/BluePrintDBLibPropertyService.kt @@ -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) } diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt index 2717c3be9..d148745df 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt @@ -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 diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt index fdaf25c15..776e0411e 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintDependencyService.kt @@ -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 diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt index 9b1b66b5b..768f8753f 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt @@ -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()) } } diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt b/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt index a2f1e23e7..c222de9e5 100644 --- a/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt +++ b/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt @@ -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 diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt b/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt index dbd5b7dfe..60fe6a705 100644 --- a/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt +++ b/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt @@ -17,17 +17,19 @@ 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) } |