From f2dde8ba531cd4783fbc0872c406ec6e0d097c54 Mon Sep 17 00:00:00 2001 From: Steve Siani Date: Fri, 13 Sep 2019 18:09:43 -0400 Subject: Bug-fix - CDS Processor-DB & Default Dictionary not working Issue-ID: CCSDK-1718 Issue-ID: CCSDK-1717 Issue-ID: CCSDK-1746 Refactoring Resource Resolution Component Use Case: ---------- Input Value (IV): It can be API Input Value or API Default value If a Resource is marked as Input -> pick IV If a Resource is marked as other than Input -> pick IV -> if IV is not present then resolve it as per DataDictionary Definition ** Return Error if Resource is not resolved using assert : ResourceAssignmentUtils.assertTemplateKeyValueNotNull Change-Id: Ib92d970d07a1dcf7362ab499a398de49ae8323a1 Change-Id: I42c1c15070f77bc9e7e73cc0dc2ee3a30ff19564 Signed-off-by: Steve Siani --- .../src/main/resources/application.properties | 2 +- .../resolution/ResourceResolutionConstants.kt | 1 + .../CapabilityResourceResolutionProcessor.kt | 72 ++-- .../DatabaseResourceAssignmentProcessor.kt | 45 +-- .../DefaultResourceResolutionProcessor.kt | 9 +- .../processor/InputResourceResolutionProcessor.kt | 12 +- .../processor/ResourceAssignmentProcessor.kt | 19 +- .../processor/RestResourceResolutionProcessor.kt | 55 +-- .../resolution/utils/ResourceAssignmentUtils.kt | 424 +++++++++++++++------ .../mock/MockRestResourceResolutionProcessor.kt | 21 +- .../CapabilityResourceResolutionProcessorTest.kt | 44 ++- .../utils/ResourceAssignmentUtilsTest.kt | 260 ++++++------- 12 files changed, 581 insertions(+), 383 deletions(-) (limited to 'ms') diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties index 75d9cbaad..944474a38 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties @@ -103,4 +103,4 @@ blueprintsprocessor.messageconsumer.self-service-api.pollMillSec=1000 blueprintsprocessor.messageproducer.self-service-api.type=kafka-basic-auth blueprintsprocessor.messageproducer.self-service-api.bootstrapServers=127.0.0.1:9092 blueprintsprocessor.messageproducer.self-service-api.clientId=default-client-id -blueprintsprocessor.messageproducer.self-service-api.topic=producer.t +blueprintsprocessor.messageproducer.self-service-api.topic=producer.t \ 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/ResourceResolutionConstants.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt index 769644288..537074383 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt @@ -29,4 +29,5 @@ object ResourceResolutionConstants { const val RESOURCE_RESOLUTION_INPUT_OCCURRENCE = "occurrence" const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id" const val RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE = "resource-type" + const val RESOURCE_RESOLUTION_LOG_PROTECTED_METADATA = "log-protect" } \ 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/processor/CapabilityResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt index 0ea71ece7..9867cd658 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 @@ -32,8 +32,8 @@ import org.springframework.stereotype.Service @Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-capability") @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) -open class CapabilityResourceResolutionProcessor(private var componentFunctionScriptingService: ComponentFunctionScriptingService) - : ResourceAssignmentProcessor() { +open class CapabilityResourceResolutionProcessor(private var componentFunctionScriptingService: ComponentFunctionScriptingService) : + ResourceAssignmentProcessor() { private val log = LoggerFactory.getLogger(CapabilityResourceResolutionProcessor::class.java) @@ -44,57 +44,65 @@ open class CapabilityResourceResolutionProcessor(private var componentFunctionSc } override suspend fun processNB(resourceAssignment: ResourceAssignment) { - - val dName = resourceAssignment.dictionaryName!! - val dSource = resourceAssignment.dictionarySource!! - val resourceDefinition = resourceDefinition(resourceAssignment.dictionaryName!!) - - /** Check Resource Assignment has the source definitions, If not get from Resource Definition **/ - val resourceSource = resourceAssignment.dictionarySourceDefinition + // Execute only if value is not in Input + if (!setFromInput(resourceAssignment)) { + val dName = resourceAssignment.dictionaryName!! + val dSource = resourceAssignment.dictionarySource!! + val resourceDefinition = resourceDefinition(resourceAssignment.dictionaryName!!) + + /** 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" } - /** - * Get the Capability Resource Source Info from Property Definitions. - */ - val capabilityResourceSourceProperty = JacksonUtils + val resourceSourceProps = + checkNotNull(resourceSource.properties) { "failed to get $resourceSource properties" } + /** + * Get the Capability Resource Source Info from Property Definitions. + */ + val capabilityResourceSourceProperty = JacksonUtils .getInstanceFromMap(resourceSourceProps, CapabilityResourceSource::class.java) - val scriptType = capabilityResourceSourceProperty.scriptType - val scriptClassReference = capabilityResourceSourceProperty.scriptClassReference - val instanceDependencies = capabilityResourceSourceProperty.instanceDependencies ?: listOf() + val scriptType = capabilityResourceSourceProperty.scriptType + val scriptClassReference = capabilityResourceSourceProperty.scriptClassReference + val instanceDependencies = capabilityResourceSourceProperty.instanceDependencies ?: listOf() - componentResourceAssignmentProcessor = scriptInstance(scriptType, scriptClassReference, instanceDependencies) + componentResourceAssignmentProcessor = + scriptInstance(scriptType, scriptClassReference, instanceDependencies) - checkNotNull(componentResourceAssignmentProcessor) { - "failed to get capability resource assignment processor($scriptClassReference)" - } + checkNotNull(componentResourceAssignmentProcessor) { + "failed to get capability resource assignment processor($scriptClassReference)" + } - // Assign Current Blueprint runtime and ResourceDictionaries - componentResourceAssignmentProcessor!!.scriptType = scriptType - componentResourceAssignmentProcessor!!.raRuntimeService = raRuntimeService - componentResourceAssignmentProcessor!!.resourceDictionaries = resourceDictionaries + // Assign Current Blueprint runtime and ResourceDictionaries + componentResourceAssignmentProcessor!!.scriptType = scriptType + componentResourceAssignmentProcessor!!.raRuntimeService = raRuntimeService + componentResourceAssignmentProcessor!!.resourceDictionaries = resourceDictionaries - // Invoke componentResourceAssignmentProcessor - componentResourceAssignmentProcessor!!.executeScript(resourceAssignment) + // Invoke componentResourceAssignmentProcessor + componentResourceAssignmentProcessor!!.executeScript(resourceAssignment) + } } override suspend fun recoverNB(runtimeException: RuntimeException, resourceAssignment: ResourceAssignment) { raRuntimeService.getBluePrintError() - .addError("Failed in CapabilityResourceResolutionProcessor : ${runtimeException.message}") + .addError("Failed in CapabilityResourceResolutionProcessor : ${runtimeException.message}") ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, runtimeException.message) } suspend fun scriptInstance(scriptType: String, scriptClassReference: String, instanceDependencies: List) : ResourceAssignmentProcessor { - log.info("creating resource resolution of script type($scriptType), reference name($scriptClassReference) and" + - "instanceDependencies($instanceDependencies)") + log.info( + "creating resource resolution of script type($scriptType), reference name($scriptClassReference) and" + + "instanceDependencies($instanceDependencies)" + ) val scriptComponent = componentFunctionScriptingService - .scriptInstance(raRuntimeService.bluePrintContext(), scriptType, - scriptClassReference) + .scriptInstance( + raRuntimeService.bluePrintContext(), scriptType, + scriptClassReference + ) 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 6645a631a..8d21e9a70 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 @@ -23,7 +23,10 @@ import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.PrimaryDBLibGenericServ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.DatabaseResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils -import org.onap.ccsdk.cds.controllerblueprints.core.* +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty 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.ResourceDictionaryConstants @@ -40,9 +43,10 @@ import java.util.* */ @Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-db") @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) -open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropertySevice: BluePrintDBLibPropertySevice, - private val primaryDBLibGenericService: PrimaryDBLibGenericService) - : ResourceAssignmentProcessor() { +open class DatabaseResourceAssignmentProcessor( + private val bluePrintDBLibPropertySevice: BluePrintDBLibPropertySevice, + private val primaryDBLibGenericService: PrimaryDBLibGenericService +) : ResourceAssignmentProcessor() { private val logger = LoggerFactory.getLogger(DatabaseResourceAssignmentProcessor::class.java) @@ -53,20 +57,10 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert override suspend fun processNB(resourceAssignment: ResourceAssignment) { try { validate(resourceAssignment) - // Check if It has Input - try { - val value = raRuntimeService.getInputValue(resourceAssignment.name) - 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 { - setValueFromDB(resourceAssignment) - } - } catch (e: BluePrintProcessorException) { + if (!setFromInput(resourceAssignment)) { setValueFromDB(resourceAssignment) } - // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) } catch (e: Exception) { @@ -82,12 +76,13 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert /** 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)") + ?: 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 " } - val sourceProperties = JacksonUtils.getInstanceFromMap(resourceSourceProperties, DatabaseResourceSource::class.java) + val sourceProperties = + JacksonUtils.getInstanceFromMap(resourceSourceProperties, DatabaseResourceSource::class.java) val sql = checkNotNull(sourceProperties.query) { "failed to get request query for $dName under $dSource properties" @@ -131,7 +126,7 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert //placeholder to get the list of DB sources. //TODO: This will be replaced with a DB - private fun getListOfDBSources(): Array = arrayOf(ResourceDictionaryConstants.PROCESSOR_DB) + private fun getListOfDBSources(): Array = arrayOf(ResourceDictionaryConstants.PROCESSOR_DB) private fun populateNamedParameter(inputKeyMapping: Map): Map { val namedParameters = HashMap() @@ -145,7 +140,11 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert } @Throws(BluePrintProcessorException::class) - private fun populateResource(resourceAssignment: ResourceAssignment, sourceProperties: DatabaseResourceSource, rows: List>) { + private fun populateResource( + resourceAssignment: ResourceAssignment, + sourceProperties: DatabaseResourceSource, + rows: List> + ) { val dName = resourceAssignment.dictionaryName val dSource = resourceAssignment.dictionarySource val type = nullToEmpty(resourceAssignment.property?.type) @@ -159,8 +158,10 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert "Failed to get database query result into Json node." } - val parsedResponseNode = ResourceAssignmentUtils.parseResponseNode(responseNode, resourceAssignment, - raRuntimeService, outputKeyMapping) + val parsedResponseNode = ResourceAssignmentUtils.parseResponseNode( + responseNode, resourceAssignment, + raRuntimeService, outputKeyMapping + ) ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, parsedResponseNode) } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt index 954b60522..9a83b0cc0 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DefaultResourceResolutionProcessor.kt @@ -17,7 +17,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor -import com.fasterxml.jackson.databind.node.MissingNode import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException @@ -44,17 +43,15 @@ open class DefaultResourceResolutionProcessor : ResourceAssignmentProcessor() { override suspend fun processNB(resourceAssignment: ResourceAssignment) { try { - var value = getFromInput(resourceAssignment) - if (value == null || value is MissingNode) { - value = resourceAssignment.property?.defaultValue + if (!setFromInput(resourceAssignment)) { + val value = resourceAssignment.property?.defaultValue ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value) } // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) - throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", - e) + throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", e) } } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt index db51453b4..a78e7872e 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessor.kt @@ -17,14 +17,11 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor -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 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment -import org.slf4j.LoggerFactory import org.springframework.beans.factory.config.ConfigurableBeanFactory import org.springframework.context.annotation.Scope import org.springframework.stereotype.Service @@ -38,8 +35,6 @@ import org.springframework.stereotype.Service @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) open class InputResourceResolutionProcessor : ResourceAssignmentProcessor() { - private val logger = LoggerFactory.getLogger(InputResourceResolutionProcessor::class.java) - override fun getName(): String { return "${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-input" } @@ -47,12 +42,7 @@ open class InputResourceResolutionProcessor : ResourceAssignmentProcessor() { override suspend fun processNB(resourceAssignment: ResourceAssignment) { try { if (isNotEmpty(resourceAssignment.name)) { - val value = raRuntimeService.getInputValue(resourceAssignment.name) - // if value is null don't call setResourceDataValue to populate the value - if (value !is MissingNode && value !is NullNode) { - logger.info("input source template key (${resourceAssignment.name}) found from input and value is ($value)") - ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value) - } + setFromInput(resourceAssignment) } // Check the value has populated for mandatory case ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) 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 2a7d19b94..af89bcef6 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 @@ -22,10 +22,7 @@ import com.fasterxml.jackson.databind.JsonNode import org.apache.commons.collections.MapUtils import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService 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.BluePrintException -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException -import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.* import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment @@ -48,18 +45,20 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode scriptPropertyInstanceType(name: String): T { return scriptPropertyInstances as? T - ?: throw BluePrintProcessorException("couldn't get script property instance ($name)") + ?: throw BluePrintProcessorException("couldn't get script property instance ($name)") } - open fun getFromInput(resourceAssignment: ResourceAssignment): JsonNode? { - var value: JsonNode? = null + open fun setFromInput(resourceAssignment: ResourceAssignment): Boolean { try { - value = raRuntimeService.getInputValue(resourceAssignment.name) - ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value) + val value = raRuntimeService.getInputValue(resourceAssignment.name) + if (value.returnNullIfMissing() != null) { + ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value) + return true + } } catch (e: BluePrintProcessorException) { // NoOp - couldn't find value from input } - return value + return false } open fun resourceDefinition(name: String): ResourceDefinition? { 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 da156096e..dab6ff79f 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,14 +17,15 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor -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 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.RestResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService -import org.onap.ccsdk.cds.controllerblueprints.core.* +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException +import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.isNotEmpty +import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment import org.slf4j.LoggerFactory @@ -39,8 +40,8 @@ import org.springframework.stereotype.Service */ @Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-rest") @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) -open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyService: BluePrintRestLibPropertyService) - : ResourceAssignmentProcessor() { +open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyService: BluePrintRestLibPropertyService) : + ResourceAssignmentProcessor() { private val logger = LoggerFactory.getLogger(RestResourceResolutionProcessor::class.java) @@ -53,32 +54,31 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS validate(resourceAssignment) // Check if It has Input - val value = getFromInput(resourceAssignment) - if (value == null || value is MissingNode || value is NullNode) { + if (!setFromInput(resourceAssignment)) { val dName = resourceAssignment.dictionaryName!! val dSource = resourceAssignment.dictionarySource!! val resourceDefinition = resourceDefinition(dName) /** 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)") + ?: 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})") @@ -95,7 +95,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS 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) } @@ -104,13 +104,14 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment) } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) - throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", - e) + throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", e) } } - fun blueprintWebClientService(resourceAssignment: ResourceAssignment, - restResourceSource: RestResourceSource): BlueprintWebClientService { + fun blueprintWebClientService( + resourceAssignment: ResourceAssignment, + restResourceSource: RestResourceSource + ): BlueprintWebClientService { return if (isNotEmpty(restResourceSource.endpointSelector)) { val restPropertiesJson = raRuntimeService.resolveDSLExpression(restResourceSource.endpointSelector!!) blueprintRestLibPropertyService.blueprintWebClientService(restPropertiesJson) @@ -120,12 +121,14 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS } @Throws(BluePrintProcessorException::class) - private fun populateResource(resourceAssignment: ResourceAssignment, sourceProperties: RestResourceSource, - restResponse: String, path: String) { + private fun populateResource( + resourceAssignment: ResourceAssignment, sourceProperties: RestResourceSource, + restResponse: String, path: String + ) { val dName = resourceAssignment.dictionaryName val dSource = resourceAssignment.dictionarySource val type = nullToEmpty(resourceAssignment.property?.type) - lateinit var entrySchemaType: String + val metadata = resourceAssignment.property!!.metadata val outputKeyMapping = checkNotNull(sourceProperties.outputKeyMapping) { "failed to get output-key-mappings for $dName under $dSource properties" @@ -135,10 +138,14 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS val responseNode = checkNotNull(JacksonUtils.jsonNode(restResponse).at(path)) { "Failed to find path ($path) in response ($restResponse)" } - logger.info("populating value for output mapping ($outputKeyMapping), from json ($responseNode)") - val parsedResponseNode = ResourceAssignmentUtils.parseResponseNode(responseNode, resourceAssignment, - raRuntimeService, outputKeyMapping) + val valueToPrint = ResourceAssignmentUtils.getValueToLog(metadata, responseNode) + logger.info("populating value for output mapping ($outputKeyMapping), from json ($valueToPrint)") + + val parsedResponseNode = ResourceAssignmentUtils.parseResponseNode( + responseNode, resourceAssignment, + raRuntimeService, outputKeyMapping + ) // Set the List of Complex Values ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, parsedResponseNode) 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 117df1e5b..2a3820f07 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 @@ -40,22 +40,28 @@ class ResourceAssignmentUtils { private val logger = LoggerFactory.getLogger(ResourceAssignmentUtils::class.toString()) suspend fun resourceDefinitions(blueprintBasePath: String): MutableMap { - val dictionaryFile = normalizedFile(blueprintBasePath, BluePrintConstants.TOSCA_DEFINITIONS_DIR, - ResourceResolutionConstants.FILE_NAME_RESOURCE_DEFINITION_TYPES) + val dictionaryFile = normalizedFile( + blueprintBasePath, BluePrintConstants.TOSCA_DEFINITIONS_DIR, + ResourceResolutionConstants.FILE_NAME_RESOURCE_DEFINITION_TYPES + ) checkFileExists(dictionaryFile) { "resource definition file(${dictionaryFile.absolutePath}) is missing" } return JacksonReactorUtils.getMapFromFile(dictionaryFile, ResourceDefinition::class.java) } @Throws(BluePrintProcessorException::class) - fun setResourceDataValue(resourceAssignment: ResourceAssignment, - raRuntimeService: ResourceAssignmentRuntimeService, value: Any?) { + fun setResourceDataValue( + resourceAssignment: ResourceAssignment, + raRuntimeService: ResourceAssignmentRuntimeService, value: Any? + ) { // TODO("See if Validation is needed in future with respect to conversion and Types") return setResourceDataValue(resourceAssignment, raRuntimeService, value.asJsonType()) } @Throws(BluePrintProcessorException::class) - fun setResourceDataValue(resourceAssignment: ResourceAssignment, - raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode) { + fun setResourceDataValue( + resourceAssignment: ResourceAssignment, + raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode + ) { val resourceProp = checkNotNull(resourceAssignment.property) { "Failed in setting resource value for resource mapping $resourceAssignment" } @@ -65,29 +71,39 @@ class ResourceAssignmentUtils { if (resourceAssignment.dictionaryName.isNullOrEmpty()) { resourceAssignment.dictionaryName = resourceAssignment.name - logger.warn("Missing dictionary key, setting with template key (${resourceAssignment.name}) " + - "as dictionary key (${resourceAssignment.dictionaryName})") + logger.warn( + "Missing dictionary key, setting with template key (${resourceAssignment.name}) " + + "as dictionary key (${resourceAssignment.dictionaryName})" + ) } try { if (resourceProp.type.isNotEmpty()) { - logger.info("Setting Resource Value ($value) for Resource Name " + - "(${resourceAssignment.name}), definition(${resourceAssignment.dictionaryName}) " + - "of type (${resourceProp.type})") + val metadata = resourceAssignment.property!!.metadata + val valueToPrint = getValueToLog(metadata, value) + logger.info( + "Setting Resource Value ($valueToPrint) for Resource Name " + + "(${resourceAssignment.name}), definition(${resourceAssignment.dictionaryName}) " + + "of type (${resourceProp.type})" + ) setResourceValue(resourceAssignment, raRuntimeService, value) resourceAssignment.updatedDate = Date() resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM resourceAssignment.status = BluePrintConstants.STATUS_SUCCESS } } catch (e: Exception) { - throw BluePrintProcessorException("Failed in setting value for template key " + - "(${resourceAssignment.name}) and dictionary key (${resourceAssignment.dictionaryName}) of " + - "type (${resourceProp.type}) with error message (${e.message})", e) + throw BluePrintProcessorException( + "Failed in setting value for template key " + + "(${resourceAssignment.name}) and dictionary key (${resourceAssignment.dictionaryName}) of " + + "type (${resourceProp.type}) with error message (${e.message})", e + ) } } - private fun setResourceValue(resourceAssignment: ResourceAssignment, - raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode) { + private fun setResourceValue( + resourceAssignment: ResourceAssignment, + raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode + ) { // TODO("See if Validation is needed wrt to type before storing") raRuntimeService.putResolutionStore(resourceAssignment.name, value) raRuntimeService.putDictionaryStore(resourceAssignment.dictionaryName!!, value) @@ -109,7 +125,8 @@ class ResourceAssignmentUtils { "Failed to populate mandatory resource resource mapping $resourceAssignment" } if (resourceProp.required != null && resourceProp.required!! - && (resourceProp.value == null || resourceProp.value!!.returnNullIfMissing() == null)) { + && (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)") } @@ -122,17 +139,26 @@ class ResourceAssignmentUtils { val mapper = ObjectMapper() val root: ObjectNode = mapper.createObjectNode() + var containsLogProtected = false assignments.forEach { if (isNotEmpty(it.name) && it.property != null) { val rName = it.name + val metadata = it.property!!.metadata val type = nullToEmpty(it.property?.type).toLowerCase() val value = useDefaultValueIfNull(it, rName) - logger.info("Generating Resource name ($rName), type ($type), value ($value)") + val valueToPrint = getValueToLog(metadata, value) + if (checkIfLogIsProtected(metadata)) { + containsLogProtected = true + } + logger.trace("Generating Resource name ($rName), type ($type), value ($valueToPrint)") root.set(rName, value) } } result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root) - logger.info("Generated Resource Param Data ($result)") + + if (!containsLogProtected) { + logger.info("Generated Resource Param Data ($result)") + } } catch (e: Exception) { throw BluePrintProcessorException("Resource Assignment is failed with $e.message", e) } @@ -146,16 +172,22 @@ class ResourceAssignmentUtils { assignments.forEach { if (isNotEmpty(it.name) && it.property != null) { val rName = it.name + val metadata = it.property!!.metadata val type = nullToEmpty(it.property?.type).toLowerCase() val value = useDefaultValueIfNull(it, rName) - logger.trace("Generating Resource name ($rName), type ($type), value ($value)") + val valueToPrint = getValueToLog(metadata, value) + + logger.trace("Generating Resource name ($rName), type ($type), value ($valueToPrint)") data[rName] = value } } return data } - private fun useDefaultValueIfNull(resourceAssignment: ResourceAssignment, resourceAssignmentName: String): JsonNode { + private fun useDefaultValueIfNull( + resourceAssignment: ResourceAssignment, + resourceAssignmentName: String + ): JsonNode { if (resourceAssignment.property?.value == null) { val defaultValue = "\${$resourceAssignmentName}" return TextNode(defaultValue) @@ -167,8 +199,10 @@ class ResourceAssignmentUtils { fun transformToRARuntimeService(blueprintRuntimeService: BluePrintRuntimeService<*>, templateArtifactName: String): ResourceAssignmentRuntimeService { - val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService(blueprintRuntimeService.id(), - blueprintRuntimeService.bluePrintContext()) + val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService( + blueprintRuntimeService.id(), + blueprintRuntimeService.bluePrintContext() + ) resourceAssignmentRuntimeService.createUniqueId(templateArtifactName) resourceAssignmentRuntimeService.setExecutionContext(blueprintRuntimeService.getExecutionContext() as MutableMap) @@ -180,7 +214,8 @@ class ResourceAssignmentUtils { propertyName: String): String { lateinit var type: String try { - val dataTypeProps = checkNotNull(raRuntimeService.bluePrintContext().dataTypeByName(dataTypeName)?.properties) + val dataTypeProps = + checkNotNull(raRuntimeService.bluePrintContext().dataTypeByName(dataTypeName)?.properties) val propertyDefinition = checkNotNull(dataTypeProps[propertyName]) type = checkNotEmpty(propertyDefinition.type) { "Couldn't get data type ($dataTypeName)" } @@ -195,14 +230,18 @@ class ResourceAssignmentUtils { @Throws(BluePrintProcessorException::class) fun parseResponseNode(responseNode: JsonNode, resourceAssignment: ResourceAssignment, raRuntimeService: ResourceAssignmentRuntimeService, outputKeyMapping: MutableMap): JsonNode { + val metadata = resourceAssignment.property!!.metadata try { if ((resourceAssignment.property?.type).isNullOrEmpty()) { throw BluePrintProcessorException("Couldn't get data dictionary type for dictionary name (${resourceAssignment.name})") } val type = resourceAssignment.property!!.type + val valueToPrint = getValueToLog(metadata, responseNode) + + logger.info("For template key (${resourceAssignment.name}) setting value as ($valueToPrint)") return when (type) { in BluePrintTypes.validPrimitiveTypes() -> { - parseResponseNodeForPrimitiveTypes(responseNode, resourceAssignment, outputKeyMapping) + parseResponseNodeForPrimitiveTypes(responseNode, outputKeyMapping) } in BluePrintTypes.validCollectionTypes() -> { // Array Types @@ -219,190 +258,333 @@ class ResourceAssignmentUtils { } } - private fun parseResponseNodeForPrimitiveTypes(responseNode: JsonNode, resourceAssignment: ResourceAssignment, + //TODO: Need to Refactor + private fun parseResponseNodeForPrimitiveTypes(responseNode: JsonNode, outputKeyMapping: MutableMap): JsonNode { - val dName = resourceAssignment.dictionaryName - logger.info("For template key (${resourceAssignment.name}) setting value as ($responseNode)") - var result: JsonNode? = responseNode + if (responseNode.isComplexType()) { val key = outputKeyMapping.keys.firstOrNull() - var returnNode: JsonNode? = responseNode + var returnNode: JsonNode? if (responseNode is ArrayNode) { val arrayNode = responseNode.toList() val firstElement = if (key.isNullOrEmpty()) { arrayNode.first() - } - else{ + } else { arrayNode.firstOrNull { element -> element.isComplexType() && element.has(outputKeyMapping[key]) } } + returnNode = firstElement + } else { + returnNode = responseNode + } - if (firstElement.isNull() || (firstElement!!.isComplexType() && !firstElement!!.has(outputKeyMapping[key])) - || (!result!!.isComplexType() && result is NullNode)) { - if (key.isNullOrEmpty()) { - throw BluePrintProcessorException("Fail to find mapping in the responseNode.") - } - else { - throw BluePrintProcessorException("Fail to find response with output key mapping ($key) in result.") - } + if (returnNode.isNull() || (returnNode!!.isComplexType() && !returnNode.has(outputKeyMapping[key]))) { + if (key.isNullOrEmpty()) { + throw BluePrintProcessorException("Fail to find mapping in the responseNode.") + } else { + throw BluePrintProcessorException("Fail to find response with output key mapping ($key) in result.") } - returnNode = firstElement } - result = if (returnNode!!.isComplexType()) { + result = if (returnNode.isComplexType()) { returnNode[outputKeyMapping[key]] + } else { + responseNode } - else { - returnNode + } else { + if (outputKeyMapping.isNotEmpty()) { + throw BluePrintProcessorException("Fail to find key-value in response node to map output-key-mapping.") } } return result!! } - private fun parseResponseNodeForCollection(responseNode: JsonNode, resourceAssignment: ResourceAssignment, - raRuntimeService: ResourceAssignmentRuntimeService, - outputKeyMapping: MutableMap): JsonNode { + private fun parseResponseNodeForCollection( + responseNode: JsonNode, resourceAssignment: ResourceAssignment, + raRuntimeService: ResourceAssignmentRuntimeService, + outputKeyMapping: MutableMap + ): JsonNode { val dName = resourceAssignment.dictionaryName + val metadata = resourceAssignment.property!!.metadata + var resultNode: JsonNode if ((resourceAssignment.property?.entrySchema?.type).isNullOrEmpty()) { - throw BluePrintProcessorException("Couldn't get data type for dictionary type " + - "(${resourceAssignment.property!!.type}) and dictionary name ($dName)") + throw BluePrintProcessorException( + "Couldn't get data type for dictionary type " + + "(${resourceAssignment.property!!.type}) and dictionary name ($dName)" + ) } val entrySchemaType = resourceAssignment.property!!.entrySchema!!.type var arrayNode = JacksonUtils.objectMapper.createArrayNode() - if (outputKeyMapping.isNotEmpty()) { when (responseNode) { is ArrayNode -> { val responseArrayNode = responseNode.toList() for (responseSingleJsonNode in responseArrayNode) { - val arrayChildNode = parseArrayNodeElementWithOutputKeyMapping(raRuntimeService, responseSingleJsonNode, - outputKeyMapping, entrySchemaType) + val arrayChildNode = parseSingleElementOfArrayResponseNode( + entrySchemaType, + outputKeyMapping, raRuntimeService, responseSingleJsonNode, metadata + ) arrayNode.add(arrayChildNode) } + resultNode = arrayNode } is ObjectNode -> { val responseArrayNode = responseNode.rootFieldsToMap() - val arrayNodeResult = parseObjectNodeWithOutputKeyMapping(responseArrayNode, outputKeyMapping, entrySchemaType) - arrayNode.addAll(arrayNodeResult) + resultNode = + parseObjectResponseNode(entrySchemaType, outputKeyMapping, responseArrayNode, metadata) } else -> { throw BluePrintProcessorException("Key-value response expected to match the responseNode.") } } - } - else { + } else { when (responseNode) { is ArrayNode -> { responseNode.forEach { elementNode -> arrayNode.add(elementNode) } + resultNode = arrayNode } is ObjectNode -> { val responseArrayNode = responseNode.rootFieldsToMap() for ((key, responseSingleJsonNode) in responseArrayNode) { val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() - JacksonUtils.populateJsonNodeValues(key, responseSingleJsonNode, entrySchemaType, arrayChildNode) + logKeyValueResolvedResource(metadata, key, responseSingleJsonNode, entrySchemaType) + JacksonUtils.populateJsonNodeValues( + key, + responseSingleJsonNode, + entrySchemaType, + arrayChildNode + ) arrayNode.add(arrayChildNode) } + resultNode = arrayNode } else -> { - arrayNode.add(responseNode) + resultNode = responseNode } } } - logger.info("For template key (${resourceAssignment.name}) setting value as ($arrayNode)") - - return arrayNode + return resultNode } - private fun parseResponseNodeForComplexType(responseNode: JsonNode, resourceAssignment: ResourceAssignment, - raRuntimeService: ResourceAssignmentRuntimeService, - outputKeyMapping: MutableMap): JsonNode { - val entrySchemaType = resourceAssignment.property!!.type - val dictionaryName = resourceAssignment.dictionaryName!! - - var result: ObjectNode - if (checkOutputKeyMappingInDataTypeProperties(entrySchemaType, outputKeyMapping, raRuntimeService)) - { - result = parseArrayNodeElementWithOutputKeyMapping(raRuntimeService, responseNode, outputKeyMapping, entrySchemaType) - } - else { - val childNode = JacksonUtils.objectMapper.createObjectNode() - if (outputKeyMapping.isNotEmpty()) { - outputKeyMapping.map { - val responseKeyValue = if (responseNode.has(it.key)) { - responseNode.get(it.key) + private fun parseSingleElementOfArrayResponseNode( + entrySchemaType: String, outputKeyMapping: MutableMap, + raRuntimeService: ResourceAssignmentRuntimeService, + responseNode: JsonNode, metadata: MutableMap? + ): ObjectNode { + val outputKeyMappingHasOnlyOneElement = checkIfOutputKeyMappingProvideOneElement(outputKeyMapping) + when (entrySchemaType) { + in BluePrintTypes.validPrimitiveTypes() -> { + if (outputKeyMappingHasOnlyOneElement) { + val outputKeyMap = outputKeyMapping.entries.first() + return parseSingleElementNodeWithOneOutputKeyMapping( + responseNode, + outputKeyMap.key, + outputKeyMap.value, + entrySchemaType, + metadata + ) + } else { + throw BluePrintProcessorException("Expect one entry in output-key-mapping") + } + } + else -> { + return when { + checkOutputKeyMappingAllElementsInDataTypeProperties( + entrySchemaType, + outputKeyMapping, + raRuntimeService + ) -> { + parseSingleElementNodeWithAllOutputKeyMapping( + responseNode, + outputKeyMapping, + entrySchemaType, + metadata + ) } - else { - NullNode.getInstance() + outputKeyMappingHasOnlyOneElement -> { + val outputKeyMap = outputKeyMapping.entries.first() + parseSingleElementNodeWithOneOutputKeyMapping( + responseNode, + outputKeyMap.key, + outputKeyMap.value, + entrySchemaType, + metadata + ) + } + else -> { + throw BluePrintProcessorException("Output-key-mapping do not map the Data Type $entrySchemaType") } - - JacksonUtils.populateJsonNodeValues(it.value, - responseKeyValue, entrySchemaType, childNode) } } - else { - JacksonUtils.populateJsonNodeValues(dictionaryName, responseNode, entrySchemaType, childNode) - } - result = childNode } - return result } - private fun parseArrayNodeElementWithOutputKeyMapping(raRuntimeService: ResourceAssignmentRuntimeService, - responseSingleJsonNode: JsonNode, outputKeyMapping: - MutableMap, entrySchemaType: String): ObjectNode { + private fun parseObjectResponseNode( + entrySchemaType: String, outputKeyMapping: MutableMap, + responseArrayNode: MutableMap, metadata: MutableMap? + ): ObjectNode { + val outputKeyMappingHasOnlyOneElement = checkIfOutputKeyMappingProvideOneElement(outputKeyMapping) + if (outputKeyMappingHasOnlyOneElement) { + val outputKeyMap = outputKeyMapping.entries.first() + return parseObjectResponseNodeWithOneOutputKeyMapping( + responseArrayNode, outputKeyMap.key, outputKeyMap.value, + entrySchemaType, metadata + ) + } else { + throw BluePrintProcessorException("Output-key-mapping do not map the Data Type $entrySchemaType") + } + } + + private fun parseSingleElementNodeWithOneOutputKeyMapping( + responseSingleJsonNode: JsonNode, outputKeyMappingKey: + String, outputKeyMappingValue: String, type: String, metadata: MutableMap? + ): ObjectNode { val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() + val responseKeyValue = if (responseSingleJsonNode.has(outputKeyMappingValue)) { + responseSingleJsonNode.get(outputKeyMappingValue) + } else { + NullNode.getInstance() + } + + logKeyValueResolvedResource(metadata, outputKeyMappingKey, responseKeyValue, type) + JacksonUtils.populateJsonNodeValues(outputKeyMappingKey, responseKeyValue, type, arrayChildNode) + + return arrayChildNode + } + + private fun parseSingleElementNodeWithAllOutputKeyMapping( + responseSingleJsonNode: JsonNode, + outputKeyMapping: MutableMap, + type: String, metadata: MutableMap? + ): ObjectNode { + val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() outputKeyMapping.map { - val responseKeyValue = if (responseSingleJsonNode.has(it.key)) { - responseSingleJsonNode.get(it.key) - } - else { + val responseKeyValue = if (responseSingleJsonNode.has(it.value)) { + responseSingleJsonNode.get(it.value) + } else { NullNode.getInstance() } - val propertyTypeForDataType = ResourceAssignmentUtils - .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) + logKeyValueResolvedResource(metadata, it.key, responseKeyValue, type) + JacksonUtils.populateJsonNodeValues(it.key, responseKeyValue, type, arrayChildNode) } - return arrayChildNode } - private fun parseObjectNodeWithOutputKeyMapping(responseArrayNode: MutableMap, - outputKeyMapping: MutableMap, - entrySchemaType: String): ArrayNode { - val arrayNode = JacksonUtils.objectMapper.createArrayNode() - outputKeyMapping.map { - val objectNode = JacksonUtils.objectMapper.createObjectNode() - val responseSingleJsonNode = responseArrayNode.filterKeys { key -> key == it.key }.entries.firstOrNull() + private fun parseObjectResponseNodeWithOneOutputKeyMapping( + responseArrayNode: MutableMap, + outputKeyMappingKey: String, outputKeyMappingValue: String, + type: String, metadata: MutableMap? + ): ObjectNode { + val objectNode = JacksonUtils.objectMapper.createObjectNode() + val responseSingleJsonNode = responseArrayNode.filterKeys { key -> + key == outputKeyMappingValue + }.entries.firstOrNull() + + if (responseSingleJsonNode == null) { + logKeyValueResolvedResource(metadata, outputKeyMappingKey, NullNode.getInstance(), type) + JacksonUtils.populateJsonNodeValues(outputKeyMappingKey, NullNode.getInstance(), type, objectNode) + } else { + logKeyValueResolvedResource(metadata, outputKeyMappingKey, responseSingleJsonNode.value, type) + JacksonUtils.populateJsonNodeValues(outputKeyMappingKey, responseSingleJsonNode.value, type, objectNode) + } + return objectNode + } - if (responseSingleJsonNode == null) { - JacksonUtils.populateJsonNodeValues(it.value, NullNode.getInstance(), entrySchemaType, objectNode) - } - else - { - JacksonUtils.populateJsonNodeValues(it.value, responseSingleJsonNode.value, entrySchemaType, objectNode) + private fun parseResponseNodeForComplexType( + responseNode: JsonNode, resourceAssignment: ResourceAssignment, + raRuntimeService: ResourceAssignmentRuntimeService, + outputKeyMapping: MutableMap + ): JsonNode { + val entrySchemaType = resourceAssignment.property!!.type + val dictionaryName = resourceAssignment.dictionaryName!! + val metadata = resourceAssignment.property!!.metadata + val outputKeyMappingHasOnlyOneElement = checkIfOutputKeyMappingProvideOneElement(outputKeyMapping) + + if (outputKeyMapping.isNotEmpty()) { + return when { + checkOutputKeyMappingAllElementsInDataTypeProperties( + entrySchemaType, + outputKeyMapping, + raRuntimeService + ) -> { + parseSingleElementNodeWithAllOutputKeyMapping( + responseNode, + outputKeyMapping, + entrySchemaType, + metadata + ) + } + outputKeyMappingHasOnlyOneElement -> { + val outputKeyMap = outputKeyMapping.entries.first() + parseSingleElementNodeWithOneOutputKeyMapping( + responseNode, outputKeyMap.key, outputKeyMap.value, + entrySchemaType, metadata + ) + } + else -> { + throw BluePrintProcessorException("Output-key-mapping do not map the Data Type $entrySchemaType") + } } - arrayNode.add(objectNode) + } else { + val childNode = JacksonUtils.objectMapper.createObjectNode() + JacksonUtils.populateJsonNodeValues(dictionaryName, responseNode, entrySchemaType, childNode) + return childNode } - - return arrayNode } - private fun checkOutputKeyMappingInDataTypeProperties(dataTypeName: String, outputKeyMapping: MutableMap, - raRuntimeService: ResourceAssignmentRuntimeService): Boolean { + private fun checkOutputKeyMappingAllElementsInDataTypeProperties( + dataTypeName: String, outputKeyMapping: MutableMap, + raRuntimeService: ResourceAssignmentRuntimeService + ): Boolean { val dataTypeProps = raRuntimeService.bluePrintContext().dataTypeByName(dataTypeName)?.properties val result = outputKeyMapping.filterKeys { !dataTypeProps!!.containsKey(it) }.keys.firstOrNull() return result == null } + + private fun logKeyValueResolvedResource( + metadata: MutableMap?, + key: String, + value: JsonNode, + type: String + ) { + val valueToPrint = getValueToLog(metadata, value) + + logger.info( + "For List Type Resource: key ($key), value ($valueToPrint), " + + "type ({$type})" + ) + } + + private fun checkIfOutputKeyMappingProvideOneElement(outputKeyMapping: MutableMap): Boolean { + return (outputKeyMapping.size == 1) + } + + fun getValueToLog(metadata: MutableMap?, value: Any): Any { + return if (checkIfLogIsProtected(metadata)) { + "*************" + } else { + value + } + } + + private fun checkIfLogIsProtected(metadata: MutableMap?): Boolean { + var checkProtected = false + if (metadata != null && + metadata.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_LOG_PROTECTED_METADATA) + ) { + val protectedMetadata = metadata[ResourceResolutionConstants.RESOURCE_RESOLUTION_LOG_PROTECTED_METADATA] + if (protectedMetadata == "yes" || protectedMetadata == "y") { + checkProtected = true + } + } + return checkProtected + } } } \ 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/mock/MockRestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt index e80663094..203b7ea30 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/mock/MockRestResourceResolutionProcessor.kt @@ -17,7 +17,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.moc import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.ArrayNode -import com.fasterxml.jackson.databind.node.MissingNode import org.apache.commons.collections.MapUtils import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.RestResourceSource @@ -55,8 +54,7 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe override suspend fun processNB(executionRequest: ResourceAssignment) { try { // Check if It has Input - val value = getFromInput(executionRequest) - if (value == null || value is MissingNode) { + if (!setFromInput(executionRequest)) { val dName = executionRequest.dictionaryName val dSource = executionRequest.dictionarySource val resourceDefinition = resourceDictionaries[dName] @@ -66,7 +64,7 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe val resourceSourceProperties = resourceSource!!.properties val sourceProperties = - JacksonUtils.getInstanceFromMap(resourceSourceProperties!!, RestResourceSource::class.java) + JacksonUtils.getInstanceFromMap(resourceSourceProperties!!, RestResourceSource::class.java) val path = nullToEmpty(sourceProperties.path) val inputKeyMapping = sourceProperties.inputKeyMapping @@ -76,7 +74,7 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe // 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})") @@ -98,8 +96,7 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe } } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(executionRequest, e.message) - throw BluePrintProcessorException("Failed in template resolutionKey ($executionRequest) assignments with: ${e.message}", - e) + throw BluePrintProcessorException("Failed in template resolutionKey ($executionRequest) assignments with: ${e.message}", e) } } @@ -139,10 +136,12 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe outputKeyMapping!!.map { val responseKeyValue = responseSingleJsonNode.get(it.key) val propertyTypeForDataType = ResourceAssignmentUtils - .getPropertyType(raRuntimeService, entrySchemaType, it.key) + .getPropertyType(raRuntimeService, entrySchemaType, it.key) - JacksonUtils.populateJsonNodeValues(it.value, - responseKeyValue, propertyTypeForDataType, arrayChildNode) + JacksonUtils.populateJsonNodeValues( + it.value, + responseKeyValue, propertyTypeForDataType, arrayChildNode + ) } arrayNode.add(arrayChildNode) } @@ -157,7 +156,7 @@ class MockRestResourceResolutionProcessor(private val blueprintRestLibPropertySe outputKeyMapping!!.map { val responseKeyValue = responseNode.get(it.key) val propertyTypeForDataType = ResourceAssignmentUtils - .getPropertyType(raRuntimeService, entrySchemaType, it.key) + .getPropertyType(raRuntimeService, entrySchemaType, it.key) JacksonUtils.populateJsonNodeValues(it.value, responseKeyValue, propertyTypeForDataType, objectNode) } // Set the List of Complex Values 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 f020f2952..98f68ebaa 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,6 +18,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor +import com.fasterxml.jackson.databind.node.NullNode import io.mockk.coEvery import io.mockk.every import io.mockk.mockk @@ -48,12 +49,16 @@ import kotlin.test.assertNotNull import kotlin.test.assertTrue @RunWith(SpringRunner::class) -@ContextConfiguration(classes = [CapabilityResourceResolutionProcessor::class, ComponentFunctionScriptingService::class, - BluePrintScriptsServiceImpl::class, - BlueprintJythonService::class, PythonExecutorProperty::class, MockCapabilityService::class]) -@TestPropertySource(properties = -["blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints", - "blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints"]) +@ContextConfiguration( + classes = [CapabilityResourceResolutionProcessor::class, ComponentFunctionScriptingService::class, + BluePrintScriptsServiceImpl::class, + BlueprintJythonService::class, PythonExecutorProperty::class, MockCapabilityService::class] +) +@TestPropertySource( + properties = + ["blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints", + "blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints"] +) class CapabilityResourceResolutionProcessorTest { @Autowired @@ -65,17 +70,21 @@ class CapabilityResourceResolutionProcessorTest { val componentFunctionScriptingService = mockk() coEvery { componentFunctionScriptingService - .scriptInstance(any(), any(), any()) + .scriptInstance(any(), any(), any()) } returns MockCapabilityScriptRA() val raRuntimeService = mockk() every { raRuntimeService.bluePrintContext() } returns mockk() + every { raRuntimeService.getInputValue("test-property") } returns NullNode.getInstance() - val capabilityResourceResolutionProcessor = CapabilityResourceResolutionProcessor(componentFunctionScriptingService) + val capabilityResourceResolutionProcessor = + CapabilityResourceResolutionProcessor(componentFunctionScriptingService) capabilityResourceResolutionProcessor.raRuntimeService = raRuntimeService - val resourceAssignment = BluePrintTypes.resourceAssignment(name = "test-property", dictionaryName = "ra-dict-name", - dictionarySource = "capability") { + val resourceAssignment = BluePrintTypes.resourceAssignment( + name = "test-property", dictionaryName = "ra-dict-name", + dictionarySource = "capability" + ) { property("string", true, "") sourceCapability { definedProperties { @@ -87,8 +96,10 @@ class CapabilityResourceResolutionProcessorTest { } val status = capabilityResourceResolutionProcessor.applyNB(resourceAssignment) assertTrue(status, "failed to execute capability source") - assertEquals("assigned-data".asJsonPrimitive(), resourceAssignment.property!!.value, - "assigned value miss match") + assertEquals( + "assigned-data".asJsonPrimitive(), resourceAssignment.property!!.value, + "assigned value miss match" + ) } } @@ -97,15 +108,18 @@ class CapabilityResourceResolutionProcessorTest { runBlocking { val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext( - "./../../../../components/model-catalog/blueprint-model/test-blueprint/capability_python") + "./../../../../components/model-catalog/blueprint-model/test-blueprint/capability_python" + ) val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext) capabilityResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService val resourceDefinition = JacksonUtils - .readValueFromClassPathFile("mapping/capability/jython-resource-definitions.json", - ResourceDefinition::class.java)!! + .readValueFromClassPathFile( + "mapping/capability/jython-resource-definitions.json", + ResourceDefinition::class.java + )!! val resourceDefinitions: MutableMap = mutableMapOf() resourceDefinitions[resourceDefinition.name] = resourceDefinition capabilityResourceResolutionProcessor.resourceDictionaries = resourceDefinitions diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt index 9365c3e34..728e1165a 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt @@ -22,7 +22,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.NullNode import com.fasterxml.jackson.databind.node.TextNode import io.mockk.every import io.mockk.spyk @@ -42,11 +41,25 @@ import kotlin.test.assertEquals data class IpAddress(val port: String, val ip: String) data class Host(val name: String, val ipAddress: IpAddress) data class ExpectedResponseIp(val ip: String) -data class ExpectedResponsePort(val port: String) +data class ExpectedResponseIpAddress(val ipAddress: IpAddress) class ResourceAssignmentUtilsTest { private lateinit var resourceAssignmentRuntimeService: ResourceAssignmentRuntimeService + private lateinit var inputMapToTestPrimitiveTypeWithValue: JsonNode + private lateinit var inputMapToTestPrimitiveTypeWithKeyValue: JsonNode + private lateinit var inputMapToTestCollectionOfPrimitiveType: JsonNode + private lateinit var inputMapToTestCollectionOfComplexTypeWithOneOutputKeyMapping: JsonNode + private lateinit var inputMapToTestCollectionOfComplexTypeWithAllOutputKeyMapping: JsonNode + private lateinit var inputMapToTestComplexTypeWithOneOutputKeyMapping: JsonNode + private lateinit var inputMapToTestComplexTypeWithAllOutputKeyMapping: JsonNode + private lateinit var expectedValueToTestPrimitiveType: JsonNode + private lateinit var expectedValueToTesCollectionOfPrimitiveType: JsonNode + private lateinit var expectedValueToTestCollectionOfComplexTypeWithOneOutputKeyMapping: JsonNode + private lateinit var expectedValueToTestComplexTypeWithOneOutputKeyMapping: JsonNode + private lateinit var expectedValueToTestComplexTypeWithAllOutputKeyMapping: JsonNode + private lateinit var expectedValueToTestCollectionOfComplexTypeWithAllOutputKeyMapping: JsonNode + @Before fun setup() { @@ -55,6 +68,11 @@ class ResourceAssignmentUtilsTest { resourceAssignmentRuntimeService = spyk(ResourceAssignmentRuntimeService("1234", bluePrintContext)) + //Init input map and expected values for tests + initInputMapAndExpectedValuesForPrimitiveType() + initInputMapAndExpectedValuesForCollection() + initInputMapAndExpectedValuesForComplexType() + val propertiesDefinition1 = PropertyDefinition().apply { type = "string" id = "port" @@ -149,146 +167,127 @@ class ResourceAssignmentUtilsTest { @Test fun parseResponseNodeTestForPrimitivesTypes(){ - // Input values for primitive type - val keyValue = mutableMapOf() - keyValue["value"]= "1.2.3.1" - val expectedPrimitiveType = TextNode("1.2.3.1") + var outcome = prepareResponseNodeForTest("sample-value", "string", "", + inputMapToTestPrimitiveTypeWithValue) + assertEquals(expectedValueToTestPrimitiveType, outcome, "Unexpected outcome returned for primitive type of simple String") - var outcome = prepareResponseNodeForTest("sample-value", "string", - "", "1.2.3.1".asJsonPrimitive()) - assertEquals(expectedPrimitiveType, outcome, "Unexpected outcome returned for primitive type of simple String") - outcome = prepareResponseNodeForTest("sample-key-value", "string", "", keyValue) - assertEquals(expectedPrimitiveType, outcome, "Unexpected outcome returned for primitive type of key-value String") + outcome = prepareResponseNodeForTest("sample-key-value", "string", "", + inputMapToTestPrimitiveTypeWithKeyValue) + assertEquals(expectedValueToTestPrimitiveType, outcome, "Unexpected outcome returned for primitive type of key-value String") } @Test fun parseResponseNodeTestForCollectionsOfString(){ - // Input values for collection type - val mapOfString = mutableMapOf() - mapOfString["value1"] = "1.2.3.1" - mapOfString["port"] = "8888" - mapOfString["value2"] = "1.2.3.2" - val arrayOfKeyValue = arrayListOf(ExpectedResponseIp("1.2.3.1"), - ExpectedResponsePort( "8888"), ExpectedResponseIp("1.2.3.2")) - - val mutableMapKeyValue = mutableMapOf() - mutableMapKeyValue["value1"] = "1.2.3.1" - mutableMapKeyValue["port"] = "8888" - - //List - val expectedListOfString = arrayOfKeyValue.asJsonType() var outcome = prepareResponseNodeForTest("listOfString", "list", - "string", mapOfString.asJsonType()) - assertEquals(expectedListOfString, outcome, "unexpected outcome returned for list of String") + "string", inputMapToTestCollectionOfPrimitiveType) + assertEquals(expectedValueToTesCollectionOfPrimitiveType, outcome, "unexpected outcome returned for list of String") - //Map - val expectedMapOfString = mutableMapOf() - expectedMapOfString["ip"] = "1.2.3.1".asJsonPrimitive() - expectedMapOfString["port"] = "8888".asJsonPrimitive() - - val arrayNode = JacksonUtils.objectMapper.createArrayNode() - expectedMapOfString.map { - val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() - arrayChildNode.set(it.key, it.value) - arrayNode.add(arrayChildNode) - } - val arrayChildNode1 = JacksonUtils.objectMapper.createObjectNode() - arrayChildNode1.set("ip", NullNode.getInstance()) - arrayNode.add(arrayChildNode1) outcome = prepareResponseNodeForTest("mapOfString", "map", "string", - mutableMapKeyValue.asJsonType()) - assertEquals(arrayNode, outcome, "unexpected outcome returned for map of String") - } - - @Test - fun parseResponseNodeTestForCollectionsOfJsonNode(){ - // Input values for collection type - val mapOfString = mutableMapOf() - mapOfString["value1"] = "1.2.3.1".asJsonPrimitive() - mapOfString["port"] = "8888".asJsonPrimitive() - mapOfString["value2"] = "1.2.3.2".asJsonPrimitive() - val arrayOfKeyValue = arrayListOf(ExpectedResponseIp("1.2.3.1"), - ExpectedResponsePort( "8888"), ExpectedResponseIp("1.2.3.2")) - - val mutableMapKeyValue = mutableMapOf() - mutableMapKeyValue["value1"] = "1.2.3.1".asJsonPrimitive() - mutableMapKeyValue["port"] = "8888".asJsonPrimitive() - - //List - val expectedListOfString = arrayOfKeyValue.asJsonType() - var outcome = prepareResponseNodeForTest("listOfString", "list", - "string", mapOfString.asJsonType()) - assertEquals(expectedListOfString, outcome, "unexpected outcome returned for list of String") - - //Map - val expectedMapOfString = mutableMapOf() - expectedMapOfString["ip"] = "1.2.3.1".asJsonPrimitive() - expectedMapOfString["port"] = "8888".asJsonPrimitive() - val arrayNode = JacksonUtils.objectMapper.createArrayNode() - expectedMapOfString.map { - val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() - arrayChildNode.set(it.key, it.value) - arrayNode.add(arrayChildNode) - } - val arrayChildNode1 = JacksonUtils.objectMapper.createObjectNode() - arrayChildNode1.set("ip", NullNode.getInstance()) - arrayNode.add(arrayChildNode1) - outcome = prepareResponseNodeForTest("mapOfString", "map", - "string", mutableMapKeyValue.asJsonType()) - assertEquals(arrayNode, outcome, "unexpected outcome returned for map of String") + inputMapToTestCollectionOfPrimitiveType) + assertEquals(expectedValueToTesCollectionOfPrimitiveType, outcome, "unexpected outcome returned for map of String") } @Test fun parseResponseNodeTestForCollectionsOfComplexType(){ - // Input values for collection type - val mapOfComplexType = mutableMapOf() - mapOfComplexType["value1"] = IpAddress("1111", "1.2.3.1").asJsonType() - mapOfComplexType["value2"] = IpAddress("2222", "1.2.3.2").asJsonType() - mapOfComplexType["value3"] = IpAddress("3333", "1.2.3.3").asJsonType() + var outcome = prepareResponseNodeForTest("listOfMyDataTypeWithOneOutputKeyMapping", "list", + "ip-address", inputMapToTestCollectionOfComplexTypeWithOneOutputKeyMapping) + assertEquals(expectedValueToTestCollectionOfComplexTypeWithOneOutputKeyMapping, outcome, "unexpected outcome returned for list of String") - //List - val arrayNode = JacksonUtils.objectMapper.createArrayNode() - mapOfComplexType.map { - val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() - arrayChildNode.set("ipAddress", it.value) - arrayNode.add(arrayChildNode) - } - var outcome = prepareResponseNodeForTest("listOfMyDataType", "list", - "ip-address", mapOfComplexType.asJsonType()) - assertEquals(arrayNode, outcome, "unexpected outcome returned for list of String") + outcome = prepareResponseNodeForTest("listOfMyDataTypeWithAllOutputKeyMapping", "list", + "ip-address", inputMapToTestCollectionOfComplexTypeWithAllOutputKeyMapping) + assertEquals(expectedValueToTestCollectionOfComplexTypeWithAllOutputKeyMapping, outcome, "unexpected outcome returned for list of String") } @Test fun `parseResponseNodeTestForComplexType find one output key mapping`(){ - // Input values for complex type - val objectNode = JacksonUtils.objectMapper.createObjectNode() - - // Input values for collection type - val mapOfComplexType = mutableMapOf() - mapOfComplexType["value"] = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType() - mapOfComplexType["port"] = "8888".asJsonType() - mapOfComplexType["something"] = "1.2.3.2".asJsonType() - - val expectedComplexType = objectNode.set("ipAddress", Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType()) val outcome = prepareResponseNodeForTest("complexTypeOneKeys", "host", - "", mapOfComplexType.asJsonType()) - assertEquals(expectedComplexType, outcome, "Unexpected outcome returned for complex type") + "", inputMapToTestComplexTypeWithOneOutputKeyMapping) + assertEquals(expectedValueToTestComplexTypeWithOneOutputKeyMapping, outcome, "Unexpected outcome returned for complex type") } @Test fun `parseResponseNodeTestForComplexType find all output key mapping`(){ - // Input values for complex type - val objectNode = JacksonUtils.objectMapper.createObjectNode() + val outcome = prepareResponseNodeForTest("complexTypeAllKeys", "host", + "", inputMapToTestComplexTypeWithAllOutputKeyMapping) + assertEquals(expectedValueToTestComplexTypeWithAllOutputKeyMapping, outcome, "Unexpected outcome returned for complex type") + } + + private fun initInputMapAndExpectedValuesForPrimitiveType() { + inputMapToTestPrimitiveTypeWithValue = "1.2.3.1".asJsonType() + val keyValue = mutableMapOf() + keyValue["value"]= "1.2.3.1" + inputMapToTestPrimitiveTypeWithKeyValue = keyValue.asJsonType() + expectedValueToTestPrimitiveType = TextNode("1.2.3.1") + } + + private fun initInputMapAndExpectedValuesForCollection(){ + val listOfIps = arrayListOf("1.2.3.1", "1.2.3.2", "1.2.3.3") + val arrayNodeForList1 = JacksonUtils.objectMapper.createArrayNode() + listOfIps.forEach { + val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() + arrayChildNode.set("value", it.asJsonPrimitive()) + arrayNodeForList1.add(arrayChildNode) + } + inputMapToTestCollectionOfPrimitiveType = arrayNodeForList1 + + expectedValueToTesCollectionOfPrimitiveType = arrayListOf(ExpectedResponseIp("1.2.3.1"), + ExpectedResponseIp( "1.2.3.2"), ExpectedResponseIp("1.2.3.3")).asJsonType() + - // Input values for collection type + val listOfIpAddresses = arrayListOf(IpAddress("1111", "1.2.3.1").asJsonType(), + IpAddress("2222", "1.2.3.2").asJsonType(), IpAddress("3333", "1.2.3.3").asJsonType()) + val arrayNodeForList2 = JacksonUtils.objectMapper.createArrayNode() + listOfIpAddresses.forEach { + val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() + arrayChildNode.set("value", it.asJsonType()) + arrayNodeForList2.add(arrayChildNode) + } + inputMapToTestCollectionOfComplexTypeWithOneOutputKeyMapping = arrayNodeForList2 + + val arrayNodeForList3 = JacksonUtils.objectMapper.createArrayNode() + var childNode = JacksonUtils.objectMapper.createObjectNode() + childNode.set("port", "1111".asJsonPrimitive()) + childNode.set("ip", "1.2.3.1".asJsonPrimitive()) + arrayNodeForList3.add(childNode) + childNode = JacksonUtils.objectMapper.createObjectNode() + childNode.set("port", "2222".asJsonPrimitive()) + childNode.set("ip", "1.2.3.2".asJsonPrimitive()) + arrayNodeForList3.add(childNode) + childNode = JacksonUtils.objectMapper.createObjectNode() + childNode.set("port", "3333".asJsonPrimitive()) + childNode.set("ip", "1.2.3.3".asJsonPrimitive()) + arrayNodeForList3.add(childNode) + inputMapToTestCollectionOfComplexTypeWithAllOutputKeyMapping = arrayNodeForList3 + + expectedValueToTestCollectionOfComplexTypeWithOneOutputKeyMapping = arrayListOf(ExpectedResponseIpAddress(IpAddress("1111", "1.2.3.1")), + ExpectedResponseIpAddress(IpAddress("2222", "1.2.3.2")), ExpectedResponseIpAddress( + IpAddress("3333", "1.2.3.3"))).asJsonType() + expectedValueToTestCollectionOfComplexTypeWithAllOutputKeyMapping = arrayListOf(IpAddress("1111", "1.2.3.1"), + IpAddress("2222", "1.2.3.2"), + IpAddress("3333", "1.2.3.3")).asJsonType() + } + + private fun initInputMapAndExpectedValuesForComplexType(){ val mapOfComplexType = mutableMapOf() - mapOfComplexType["name"] = "my-ipAddress".asJsonType() - mapOfComplexType["ipAddress"] = IpAddress("1111", "1.2.3.1").asJsonType() + mapOfComplexType["value"] = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType() + mapOfComplexType["port"] = "8888".asJsonType() + mapOfComplexType["something"] = "1.2.3.2".asJsonType() + inputMapToTestComplexTypeWithOneOutputKeyMapping = mapOfComplexType.asJsonType() - val expectedComplexType = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType() - val outcome = prepareResponseNodeForTest("complexTypeAllKeys", "host", - "", mapOfComplexType.asJsonType()) - assertEquals(expectedComplexType, outcome, "Unexpected outcome returned for complex type") + val objectNode = JacksonUtils.objectMapper.createObjectNode() + expectedValueToTestComplexTypeWithOneOutputKeyMapping = objectNode.set("host", Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType()) + + val childNode1 = JacksonUtils.objectMapper.createObjectNode() + childNode1.set("name", "my-ipAddress".asJsonPrimitive()) + childNode1.set("ipAddress", IpAddress("1111", "1.2.3.1").asJsonType()) + childNode1.set("port", "8888".asJsonType()) + childNode1.set("something", IpAddress("2222", "1.2.3.1").asJsonType()) + inputMapToTestComplexTypeWithAllOutputKeyMapping = childNode1 + + val childNode2 = JacksonUtils.objectMapper.createObjectNode() + childNode2.set("name", "my-ipAddress".asJsonPrimitive()) + childNode2.set("ipAddress", IpAddress("1111", "1.2.3.1").asJsonType()) + expectedValueToTestComplexTypeWithAllOutputKeyMapping = childNode2 } private fun prepareResponseNodeForTest(dictionary_source: String, sourceType: String, entrySchema: String, @@ -355,27 +354,28 @@ class ResourceAssignmentUtilsTest { val outputMapping = mutableMapOf() when (dictionary_source) { - "listOfString", "mapOfString" -> { - //List of string - outputMapping["value1"] = "ip" - outputMapping["port"] = "port" - outputMapping["value2"] = "ip" - } - "listOfMyDataType", "mapOfMyDataType" -> { - //List or map of complex Type - outputMapping["value1"] = "ipAddress" - outputMapping["value2"] = "ipAddress" - outputMapping["value3"] = "ipAddress" - } "sample-key-value", "sample-value" -> { //Primary Type if (dictionary_source=="sample-key-value") outputMapping["sample-ip"] = "value" } + "listOfString", "mapOfString" -> { + //List of string + outputMapping["ip"] = "value" + } + "listOfMyDataTypeWithOneOutputKeyMapping", "listOfMyDataTypeWithAllOutputKeyMapping" -> { + //List or map of complex Type + if (dictionary_source == "listOfMyDataTypeWithOneOutputKeyMapping") + outputMapping["ipAddress"] = "value" + else { + outputMapping["port"] = "port" + outputMapping["ip"] = "ip" + } + } else -> { //Complex Type if (dictionary_source == "complexTypeOneKeys") - outputMapping["value"] = "ipAddress" + outputMapping["host"] = "value" else { outputMapping["name"] = "name" outputMapping["ipAddress"] = "ipAddress" -- cgit 1.2.3-korg