From 2e2d56dba10dc8ccc9673e969f95cfb70f9b44bc Mon Sep 17 00:00:00 2001 From: Alexis de Talhouët Date: Thu, 20 Jun 2019 14:14:37 -0400 Subject: Allow multiple resolution for same node template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - also fixing default mechanism - fixes rest resolution when NullNode is returned as input value - fixes rest resolution when data type specified so raw json isn't returned, only the parsed json based on the data type Change-Id: I1f4a35c6c97000b52620c9b0cc911f15016c4e80 Issue-ID: CCSDK-1422 Signed-off-by: Alexis de Talhouët --- .../resolution/ResourceResolutionComponent.kt | 39 +++++++++++++--------- .../resolution/ResourceResolutionConstants.kt | 5 +-- .../processor/RestResourceResolutionProcessor.kt | 28 ++++++++-------- 3 files changed, 42 insertions(+), 30 deletions(-) (limited to 'ms/blueprintsprocessor') diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt index 8191db74e..0bc83763a 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt @@ -17,10 +17,11 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution +import com.fasterxml.jackson.databind.node.JsonNodeFactory import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.asObjectNode import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils import org.springframework.beans.factory.config.ConfigurableBeanFactory import org.springframework.context.annotation.Scope @@ -33,28 +34,36 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re override suspend fun processNB(executionRequest: ExecutionServiceInput) { - val properties: MutableMap = mutableMapOf() + val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE) + val key = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY) + val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) - try { - val key = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY) - val storeResult = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key.asText() - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult.asBoolean() - } catch (e: BluePrintProcessorException) { - // NoOp - these property aren't mandatory, so don't fail the process if not provided. - } + val properties: MutableMap = mutableMapOf() + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = + storeResult?.asBoolean() ?: false val artifactPrefixNamesNode = getOperationInput(ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES) val artifactPrefixNames = JacksonUtils.getListFromJsonNode(artifactPrefixNamesNode, String::class.java) - val resolvedParamContents = resourceResolutionService.resolveResources(bluePrintRuntimeService, - nodeTemplateName, - artifactPrefixNames, - properties) + val jsonResponse = JsonNodeFactory.instance.objectNode() + for (j in 1..occurrence.asInt()) { + + val response = resourceResolutionService.resolveResources(bluePrintRuntimeService, + nodeTemplateName, + artifactPrefixNames, + properties) + + // provide indexed result in output if we have multiple resolution + if (occurrence.asInt() != 1) { + jsonResponse.set(key?.asText() + "-" + j, response.asJsonNode()) + } else { + jsonResponse.setAll(response.asObjectNode()) + } + } // Set Output Attributes bluePrintRuntimeService.setNodeTemplateAttributeValue(nodeTemplateName, - ResourceResolutionConstants.OUTPUT_ASSIGNMENT_PARAMS, resolvedParamContents.asJsonNode()) + ResourceResolutionConstants.OUTPUT_ASSIGNMENT_PARAMS, jsonResponse) } override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { 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 d605c8828..9d422f1c6 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 @@ -24,8 +24,9 @@ object ResourceResolutionConstants { const val INPUT_ARTIFACT_PREFIX_NAMES = "artifact-prefix-names" const val OUTPUT_ASSIGNMENT_PARAMS = "assignment-params" const val FILE_NAME_RESOURCE_DEFINITION_TYPES = "resources_definition_types.json" - const val RESOURCE_RESOLUTION_INPUT_KEY = "resolution-key"; - const val RESOURCE_RESOLUTION_INPUT_STORE_RESULT = "store-result"; + const val RESOURCE_RESOLUTION_INPUT_KEY = "resolution-key" + const val RESOURCE_RESOLUTION_INPUT_STORE_RESULT = "store-result" + const val RESOURCE_RESOLUTION_INPUT_OCCURRENCE = "occurrence" } \ 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/RestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt index 7eefe954d..6cf1c0be7 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 @@ -19,6 +19,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.pro import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.node.MissingNode +import com.fasterxml.jackson.databind.node.NullNode import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.RestResourceSource import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils @@ -54,20 +55,20 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS // Check if It has Input val value = getFromInput(resourceAssignment) - if (value == null || value is MissingNode) { + if (value == null || value is MissingNode || value is NullNode) { val dName = resourceAssignment.dictionaryName val dSource = resourceAssignment.dictionarySource val resourceDefinition = resourceDictionaries[dName] - ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dName") + ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dName") val resourceSource = resourceDefinition.sources[dSource] - ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($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 = @@ -77,7 +78,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS // 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})") @@ -90,7 +91,8 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS if (responseStatusCode in 200..299 && !responseBody.isBlank()) { populateResource(resourceAssignment, sourceProperties, responseBody, path) } else { - val errMsg = "Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath) response_code: ($responseStatusCode)" + val errMsg = + "Failed to get $dSource result for dictionary name ($dName) using urlPath ($urlPath) response_code: ($responseStatusCode)" logger.warn(errMsg) throw BluePrintProcessorException(errMsg) } @@ -100,12 +102,12 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS } catch (e: Exception) { ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message) throw BluePrintProcessorException("Failed in template key ($resourceAssignment) assignments with: ${e.message}", - e) + e) } } fun blueprintWebClientService(resourceAssignment: ResourceAssignment, - restResourceSource: RestResourceSource): BlueprintWebClientService { + restResourceSource: RestResourceSource): BlueprintWebClientService { return if (isNotEmpty(restResourceSource.endpointSelector)) { val restPropertiesJson = raRuntimeService.resolveDSLExpression(restResourceSource.endpointSelector!!) blueprintRestLibPropertyService.blueprintWebClientService(restPropertiesJson) @@ -143,7 +145,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS entrySchemaType = checkNotEmpty(resourceAssignment.property?.entrySchema?.type) { "Entry schema is not defined for dictionary ($dName) info" } - val arrayNode = responseNode as ArrayNode + val arrayNode = JacksonUtils.objectMapper.createArrayNode() if (entrySchemaType !in BluePrintTypes.validPrimitiveTypes()) { @@ -155,13 +157,13 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS outputKeyMapping.map { val responseKeyValue = responseSingleJsonNode.get(it.key) val propertyTypeForDataType = ResourceAssignmentUtils - .getPropertyType(raRuntimeService, entrySchemaType, it.key) + .getPropertyType(raRuntimeService, entrySchemaType, it.key) logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), " + "type ({$propertyTypeForDataType})") JacksonUtils.populateJsonNodeValues(it.value, - responseKeyValue, propertyTypeForDataType, arrayChildNode) + responseKeyValue, propertyTypeForDataType, arrayChildNode) } arrayNode.add(arrayChildNode) } @@ -179,7 +181,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS outputKeyMapping.map { val responseKeyValue = responseNode.get(it.key) val propertyTypeForDataType = ResourceAssignmentUtils - .getPropertyType(raRuntimeService, entrySchemaType, it.key) + .getPropertyType(raRuntimeService, entrySchemaType, it.key) logger.info("For List Type Resource: key (${it.key}), value ($responseKeyValue), type ({$propertyTypeForDataType})") JacksonUtils.populateJsonNodeValues(it.value, responseKeyValue, propertyTypeForDataType, objectNode) -- cgit 1.2.3-korg