From 74701a57756a3e07f9b321e5937c2e8c4bcf6b63 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 Signed-off-by: Steve Siani Change-Id: Ia15f36d7732058161aa2addc9268dd647330f069 Issue-ID: CCSDK-1717 Signed-off-by: Steve Siani Change-Id: Ia15f36d7732058161aa2addc9268dd647330f069 --- .../resolution/ResourceResolutionConstants.kt | 2 +- .../DatabaseResourceAssignmentProcessor.kt | 5 +- .../processor/InputResourceResolutionProcessor.kt | 7 +- .../processor/RestResourceResolutionProcessor.kt | 22 +- .../resolution/utils/ResourceAssignmentUtils.kt | 331 +++++++++++++-------- 5 files changed, 224 insertions(+), 143 deletions(-) (limited to 'ms/blueprintsprocessor/functions/resource-resolution/src/main') 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 2a9218df3..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,5 +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" - val DATA_DICTIONARY_SECRET_SOURCE_TYPES = arrayOf("vault-data") //Add more secret data dictionary source type here + 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/DatabaseResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt index 6645a631a..5043c9a78 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 @@ -57,9 +57,8 @@ open class DatabaseResourceAssignmentProcessor(private val bluePrintDBLibPropert // 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) + if (ResourceAssignmentUtils.checkIfInputWasProvided(resourceAssignment, value)) { + ResourceAssignmentUtils.setInputValueIfProvided(resourceAssignment, raRuntimeService, value) } else { setValueFromDB(resourceAssignment) } 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..f26da141b 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 @@ -38,8 +38,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" } @@ -49,9 +47,8 @@ open class InputResourceResolutionProcessor : ResourceAssignmentProcessor() { 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) + if (ResourceAssignmentUtils.checkIfInputWasProvided(resourceAssignment, value)) { + ResourceAssignmentUtils.setInputValueIfProvided(resourceAssignment, raRuntimeService, value) } } // Check the value has populated for mandatory case 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 6515b11cd..ecc2c2be1 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,9 +17,6 @@ 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.DATA_DICTIONARY_SECRET_SOURCE_TYPES 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 @@ -54,8 +51,11 @@ 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) { + val value = raRuntimeService.getInputValue(resourceAssignment.name) + if (ResourceAssignmentUtils.checkIfInputWasProvided(resourceAssignment, value)) { + ResourceAssignmentUtils.setInputValueIfProvided(resourceAssignment, raRuntimeService, value) + } + else { val dName = resourceAssignment.dictionaryName!! val dSource = resourceAssignment.dictionarySource!! val resourceDefinition = resourceDefinition(dName) @@ -126,7 +126,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS 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" @@ -136,12 +136,10 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS val responseNode = checkNotNull(JacksonUtils.jsonNode(restResponse).at(path)) { "Failed to find path ($path) in response ($restResponse)" } - if (resourceAssignment.dictionarySource in DATA_DICTIONARY_SECRET_SOURCE_TYPES) { - logger.info("populating value for output mapping ($outputKeyMapping), from json (*************)") - } - else { - logger.info("populating value for output mapping ($outputKeyMapping), from json ($responseNode)") - } + + 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) 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 819246b99..7854aa49a 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 @@ -71,15 +71,11 @@ class ResourceAssignmentUtils { try { if (resourceProp.type.isNotEmpty()) { - if (resourceAssignment.dictionarySource in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES) { - logger.info("Setting Resource Value (*********) for Resource Name " + - "(${resourceAssignment.name}) of type (${resourceProp.type})") - } - else { - 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 @@ -109,6 +105,22 @@ class ResourceAssignmentUtils { } } + @Throws(BluePrintProcessorException::class) + fun setInputValueIfProvided(resourceAssignment: ResourceAssignment, + raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode) { + logger.info("${resourceAssignment.dictionarySource} source template key (${resourceAssignment.name}) " + + "found from input and value is ($value)") + try { + ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value) + } + catch (e: Exception) { + throw BluePrintProcessorException("Failed to set input value in resource name " + + "(${resourceAssignment.name}) and dictionary key (${resourceAssignment.dictionaryName}) of " + + "type (${resourceAssignment.property!!.type}) with error message (${e.message})", e) + } + + } + @Throws(BluePrintProcessorException::class) fun assertTemplateKeyValueNotNull(resourceAssignment: ResourceAssignment) { val resourceProp = checkNotNull(resourceAssignment.property) { @@ -128,27 +140,24 @@ class ResourceAssignmentUtils { val mapper = ObjectMapper() val root: ObjectNode = mapper.createObjectNode() - var containsSecret = false + 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) - if (it.dictionarySource in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES) { - logger.info("Generating Resource name ($rName), type ($type), value (************)") - containsSecret = true - } - else { - 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) - if (containsSecret) { - logger.info("Generated Resource Param Data (***********)") - } - else{ + + if (!containsLogProtected) { logger.info("Generated Resource Param Data ($result)") } } catch (e: Exception) { @@ -164,14 +173,12 @@ 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) - if (it.dictionarySource in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES) { - logger.trace("Generating Resource name ($rName), type ($type), value (************)") - } - else { - 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 } } @@ -218,19 +225,17 @@ 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 - if (resourceAssignment.dictionarySource in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES) { - logger.info("For template key (${resourceAssignment.name}) setting value as (***************)") - } - else { - logger.info("For template key (${resourceAssignment.name}) setting value as ($responseNode)") - } - + val valueToPrint = getValueToLog(metadata, responseNode) + + logger.info("For template key (${resourceAssignment.name}) setting value as ($valueToPrint)") + return when (type) { in BluePrintTypes.validPrimitiveTypes() -> { parseResponseNodeForPrimitiveTypes(responseNode, outputKeyMapping) @@ -255,7 +260,7 @@ class ResourceAssignmentUtils { 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()) { @@ -267,22 +272,30 @@ class ResourceAssignmentUtils { } } - 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.") - } - } returnNode = firstElement } - result = if (returnNode!!.isComplexType()) { + else{ + returnNode = responseNode + } + + 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.") + } + } + result = if (returnNode.isComplexType()) { returnNode[outputKeyMapping[key]] } else { - returnNode + responseNode + } + } + else { + if (outputKeyMapping.isNotEmpty()) { + throw BluePrintProcessorException("Fail to find key-value in response node to map output-key-mapping.") } } return result!! @@ -292,7 +305,8 @@ class ResourceAssignmentUtils { raRuntimeService: ResourceAssignmentRuntimeService, outputKeyMapping: MutableMap): JsonNode { val dName = resourceAssignment.dictionaryName - val dSource = resourceAssignment.dictionarySource + 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)") @@ -300,22 +314,20 @@ class ResourceAssignmentUtils { 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, dSource!!) + 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, dSource!!) - arrayNode.addAll(arrayNodeResult) + resultNode = parseObjectResponseNode(entrySchemaType, outputKeyMapping, responseArrayNode, metadata) } else -> { throw BluePrintProcessorException("Key-value response expected to match the responseNode.") @@ -328,121 +340,196 @@ class ResourceAssignmentUtils { responseNode.forEach { elementNode -> arrayNode.add(elementNode) } + resultNode = arrayNode } is ObjectNode -> { val responseArrayNode = responseNode.rootFieldsToMap() for ((key, responseSingleJsonNode) in responseArrayNode) { val arrayChildNode = JacksonUtils.objectMapper.createObjectNode() + logKeyValueResolvedResource(metadata, key, responseSingleJsonNode, entrySchemaType) JacksonUtils.populateJsonNodeValues(key, responseSingleJsonNode, entrySchemaType, arrayChildNode) arrayNode.add(arrayChildNode) } + resultNode = arrayNode } else -> { - arrayNode.add(responseNode) + resultNode = responseNode } } } - return arrayNode - } - private fun parseResponseNodeForComplexType(responseNode: JsonNode, resourceAssignment: ResourceAssignment, - raRuntimeService: ResourceAssignmentRuntimeService, - outputKeyMapping: MutableMap): JsonNode { - val entrySchemaType = resourceAssignment.property!!.type - val dictionarySource = resourceAssignment.dictionarySource!! - val dictionaryName = resourceAssignment.dictionaryName!! + return resultNode + } - var result: ObjectNode - if (checkOutputKeyMappingInDataTypeProperties(entrySchemaType, outputKeyMapping, raRuntimeService)) - { - result = parseArrayNodeElementWithOutputKeyMapping(raRuntimeService, responseNode, outputKeyMapping, entrySchemaType, dictionarySource!!) - } - 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") } - - logKeyValueResolvedResource(it.key, responseKeyValue, entrySchemaType, dictionarySource) - - 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, - dictionarySource: 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) - - logKeyValueResolvedResource(it.key, responseKeyValue, propertyTypeForDataType, dictionarySource) - 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, - dictionarySource: String): ArrayNode { - val arrayNode = JacksonUtils.objectMapper.createArrayNode() - outputKeyMapping.map { - val objectNode = JacksonUtils.objectMapper.createObjectNode() - val responseSingleJsonNode = responseArrayNode.filterKeys { key -> key == it.key }.entries.firstOrNull() - - val responseNode = responseSingleJsonNode?.value ?: NullNode.getInstance() + 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() - logKeyValueResolvedResource(it.key, responseNode, entrySchemaType, dictionarySource) + 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 + } - JacksonUtils.populateJsonNodeValues(it.value, responseNode, 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) - arrayNode.add(objectNode) + 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") + } + } + } + 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(key: String, value: JsonNode, type: String, dictionarySource: String) { - if (dictionarySource in ResourceResolutionConstants.DATA_DICTIONARY_SECRET_SOURCE_TYPES) { - logger.info("For List Type Resource: key ($key), value (****************), " + - "type ({$type})") + 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 { - logger.info("For List Type Resource: key ($key), value ($value), " + - "type ({$type})") + else{ + value + } + } + + fun checkIfInputWasProvided(resourceAssignment: ResourceAssignment, value: JsonNode) : Boolean{ + val defaultValueNode = resourceAssignment.property!!.defaultValue.asJsonType() + return (value.returnNullIfMissing() != null && value != defaultValueNode) + } + + 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 -- cgit 1.2.3-korg