diff options
Diffstat (limited to 'ms/blueprintsprocessor/functions/resource-resolution')
11 files changed, 396 insertions, 125 deletions
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..7c2c11c06 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,41 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re override suspend fun processNB(executionRequest: ExecutionServiceInput) { - val properties: MutableMap<String, Any> = 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) + val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID) + val resourceType = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE) - 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<String, Any> = mutableMapOf() + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult?.asBoolean() ?: false + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key?.asText() ?: "" + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId?.asText() ?: "" + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType?.asText() ?: "" 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..929e9e8df 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,11 @@ 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" + const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id" + const val RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE = "resource-type" }
\ 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/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index fe5906220..b1482934f 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionResultService import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils @@ -48,27 +49,26 @@ interface ResourceResolutionService { suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, artifactPrefix: String, properties: Map<String, Any>): String - suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactMapping: String, artifactTemplate: String?): String - suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>, resourceDefinitions: MutableMap<String, ResourceDefinition>, resourceAssignments: MutableList<ResourceAssignment>, - identifierName: String) + artifactPrefix: String, + properties: Map<String, Any>) } @Service(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) open class ResourceResolutionServiceImpl(private var applicationContext: ApplicationContext, private var resolutionResultService: ResourceResolutionResultService, - private var blueprintTemplateService: BluePrintTemplateService) : - ResourceResolutionService { + private var blueprintTemplateService: BluePrintTemplateService, + private var resourceResolutionDBService: ResourceResolutionDBService) : + ResourceResolutionService { private val log = LoggerFactory.getLogger(ResourceResolutionService::class.java) override fun registeredResourceSources(): List<String> { return applicationContext.getBeanNamesForType(ResourceAssignmentProcessor::class.java) - .filter { it.startsWith(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) } - .map { it.substringAfter(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) } + .filter { it.startsWith(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) } + .map { it.substringAfter(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) } } override suspend fun resolveFromDatabase(bluePrintRuntimeService: BluePrintRuntimeService<*>, @@ -78,12 +78,13 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica } override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactNames: List<String>, properties: Map<String, Any>): MutableMap<String, String> { + artifactNames: List<String>, + properties: Map<String, Any>): MutableMap<String, String> { val resolvedParams: MutableMap<String, String> = hashMapOf() artifactNames.forEach { artifactName -> val resolvedContent = resolveResources(bluePrintRuntimeService, nodeTemplateName, - artifactName, properties) + artifactName, properties) resolvedParams[artifactName] = resolvedContent } return resolvedParams @@ -97,52 +98,38 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica // Resource Assignment Artifact Definition Name val artifactMapping = "$artifactPrefix-mapping" - val result = resolveResources(bluePrintRuntimeService, nodeTemplateName, - artifactMapping, artifactTemplate) - - if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) - && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) { - resolutionResultService.write(properties, result, bluePrintRuntimeService, artifactPrefix) - log.info("resolution saved into database successfully : ($properties)") - } - - return result - } - - - override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, - artifactMapping: String, artifactTemplate: String?): String { - val resolvedContent: String log.info("Resolving resource for template artifact($artifactTemplate) with resource assignment artifact($artifactMapping)") - val identifierName = artifactTemplate ?: "no-template" - val resourceAssignmentContent = - bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactMapping) + bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactMapping) val resourceAssignments: MutableList<ResourceAssignment> = - JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment::class.java) - as? MutableList<ResourceAssignment> - ?: throw BluePrintProcessorException("couldn't get Dictionary Definitions") + JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment::class.java) + as? MutableList<ResourceAssignment> + ?: throw BluePrintProcessorException("couldn't get Dictionary Definitions") // Get the Resource Dictionary Name val resourceDefinitions: MutableMap<String, ResourceDefinition> = ResourceAssignmentUtils - .resourceDefinitions(bluePrintRuntimeService.bluePrintContext().rootPath) + .resourceDefinitions(bluePrintRuntimeService.bluePrintContext().rootPath) // Resolve resources - resolveResourceAssignments(bluePrintRuntimeService, resourceDefinitions, resourceAssignments, identifierName) + resolveResourceAssignments(bluePrintRuntimeService, + resourceDefinitions, + resourceAssignments, + artifactPrefix, + properties) val resolvedParamJsonContent = - ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignments.toList()) + ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignments.toList()) - // Check Template is there - if (artifactTemplate != null) { - resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName, - artifactTemplate, resolvedParamJsonContent) + resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName, + artifactTemplate, resolvedParamJsonContent) - } else { - resolvedContent = resolvedParamJsonContent + if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) + && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) { + resolutionResultService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix) + log.info("template resolution saved into database successfully : ($properties)") } return resolvedContent @@ -156,44 +143,55 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica override suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>, resourceDefinitions: MutableMap<String, ResourceDefinition>, resourceAssignments: MutableList<ResourceAssignment>, - identifierName: String) { + artifactPrefix: String, + properties: Map<String, Any>) { val bulkSequenced = BulkResourceSequencingUtils.process(resourceAssignments) val resourceAssignmentRuntimeService = - ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, identifierName) + ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, artifactPrefix) coroutineScope { bulkSequenced.forEach { batchResourceAssignments -> // Execute Non Dependent Assignments in parallel ( ie asynchronously ) val deferred = batchResourceAssignments.filter { it.name != "*" && it.name != "start" } - .map { resourceAssignment -> - async { - val dictionaryName = resourceAssignment.dictionaryName - val dictionarySource = resourceAssignment.dictionarySource - /** - * Get the Processor name - */ - val processorName = processorName(dictionaryName!!, dictionarySource!!, resourceDefinitions) - - val resourceAssignmentProcessor = - applicationContext.getBean(processorName) as? ResourceAssignmentProcessor - ?: throw BluePrintProcessorException("failed to get resource processor ($processorName) " + - "for resource assignment(${resourceAssignment.name})") - try { - // Set BluePrint Runtime Service - resourceAssignmentProcessor.raRuntimeService = resourceAssignmentRuntimeService - // Set Resource Dictionaries - resourceAssignmentProcessor.resourceDictionaries = resourceDefinitions - // Invoke Apply Method - resourceAssignmentProcessor.applyNB(resourceAssignment) - // Set errors from RA - blueprintRuntimeService.setBluePrintError(resourceAssignmentRuntimeService.getBluePrintError()) - } catch (e: RuntimeException) { - log.error("Fail in processing ${resourceAssignment.name}", e) - throw BluePrintProcessorException(e) + .map { resourceAssignment -> + async { + val dictionaryName = resourceAssignment.dictionaryName + val dictionarySource = resourceAssignment.dictionarySource + /** + * Get the Processor name + */ + val processorName = processorName(dictionaryName!!, dictionarySource!!, resourceDefinitions) + + val resourceAssignmentProcessor = + applicationContext.getBean(processorName) as? ResourceAssignmentProcessor + ?: throw BluePrintProcessorException("failed to get resource processor ($processorName) " + + "for resource assignment(${resourceAssignment.name})") + try { + // Set BluePrint Runtime Service + resourceAssignmentProcessor.raRuntimeService = resourceAssignmentRuntimeService + // Set Resource Dictionaries + resourceAssignmentProcessor.resourceDictionaries = resourceDefinitions + // Invoke Apply Method + resourceAssignmentProcessor.applyNB(resourceAssignment) + + if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) + && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) { + resourceResolutionDBService.write(properties, + blueprintRuntimeService, + artifactPrefix, + resourceAssignment) + log.info("resolution saved into database successfully : ($resourceAssignment)") } + + // Set errors from RA + blueprintRuntimeService.setBluePrintError(resourceAssignmentRuntimeService.getBluePrintError()) + } catch (e: RuntimeException) { + log.error("Fail in processing ${resourceAssignment.name}", e) + throw BluePrintProcessorException(e) } } + } log.debug("Resolving (${deferred.size})resources parallel.") deferred.awaitAll() } @@ -217,10 +215,10 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica } else -> { val resourceDefinition = resourceDefinitions[dictionaryName] - ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dictionaryName") + ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dictionaryName") val resourceSource = resourceDefinition.sources[dictionarySource] - ?: throw BluePrintProcessorException("couldn't get resource definition $dictionaryName source($dictionarySource)") + ?: throw BluePrintProcessorException("couldn't get resource definition $dictionaryName source($dictionarySource)") ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR.plus(resourceSource.type) } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt new file mode 100644 index 000000000..767a1feaf --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt @@ -0,0 +1,91 @@ +/* + * Copyright © 2019 Bell Canada + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db + +import com.fasterxml.jackson.annotation.JsonFormat +import com.fasterxml.jackson.annotation.JsonProperty +import org.hibernate.annotations.Proxy +import org.springframework.data.annotation.LastModifiedDate +import org.springframework.data.jpa.domain.support.AuditingEntityListener +import java.io.Serializable +import java.util.* +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.EntityListeners +import javax.persistence.Id +import javax.persistence.Lob +import javax.persistence.Table +import javax.persistence.Temporal +import javax.persistence.TemporalType + +@EntityListeners(AuditingEntityListener::class) +@Entity +@Table(name = "RESOURCE_RESOLUTION") +@Proxy(lazy = false) +class ResourceResolution : Serializable { + + @Id + @Column(name = "resource_resolution_id") + var id: String? = null + + @Column(name = "resolution_key", nullable = false) + var resolutionKey: String? = null + + @Column(name = "resource_type", nullable = false) + var resourceType: String? = null + + @Column(name = "resource_id", nullable = false) + var resourceId: String? = null + + @Column(name = "blueprint_name", nullable = false) + var blueprintName: String? = null + + @Column(name = "blueprint_version", nullable = false) + var blueprintVersion: String? = null + + @Column(name = "artifact_name", nullable = false) + var artifactName: String? = null + + @Column(name = "status", nullable = false) + var status: String? = null + + @Column(name = "name", nullable = false) + var name: String? = null + + @Column(name = "dictionary_vname", nullable = false) + var dictionaryName: String? = null + + @Column(name = "dictionary_status", nullable = false) + var dictionarySource: String? = null + + @Column(name = "dictionary_version", nullable = false) + var dictionaryVersion: Int = 0 + + @Lob + @Column(name = "value", nullable = false) + var value: String? = null + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @LastModifiedDate + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "creation_date") + var createdDate = Date() + + companion object { + private const val serialVersionUID = 1L + } +}
\ 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/db/ResourceResolutionDBService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt new file mode 100644 index 000000000..81239be30 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService +import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils +import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment +import org.slf4j.LoggerFactory +import org.springframework.dao.DataIntegrityViolationException +import org.springframework.stereotype.Service +import java.util.* + +@Service +class ResourceResolutionDBService(private val resourceResolutionRepository: ResourceResolutionRepository) { + + private val log = LoggerFactory.getLogger(ResourceResolutionDBService::class.toString()) + + suspend fun readValue(blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String, + name: String): ResourceResolution = withContext(Dispatchers.IO) { + + resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix, + name) + } + + suspend fun readWithResolutionKey(blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String): List<ResourceResolution> = withContext(Dispatchers.IO) { + + resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix) + } + + suspend fun readWithResourceIdAndResourceType(blueprintName: String, + blueprintVersion: String, + resourceId: String, + resourceType: String): List<ResourceResolution> = withContext(Dispatchers.IO) { + + resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType( + blueprintName, + blueprintVersion, + resourceId, + resourceType) + } + + suspend fun write(properties: Map<String, Any>, + bluePrintRuntimeService: BluePrintRuntimeService<*>, + artifactPrefix: String, + resourceAssignment: ResourceAssignment): ResourceResolution = withContext(Dispatchers.IO) { + + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + val resolutionKey = + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY].toString() + val resourceType = + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE].toString() + val resourceId = + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID].toString() + + write(blueprintName, + blueprintVersion, + resolutionKey, + resourceId, + resourceType, + artifactPrefix, + resourceAssignment) + } + + suspend fun write(blueprintName: String, + blueprintVersion: String, + resolutionKey: String, + resourceId: String, + resourceType: String, + artifactPrefix: String, + resourceAssignment: ResourceAssignment): ResourceResolution = withContext(Dispatchers.IO) { + + val resourceResolution = ResourceResolution() + resourceResolution.id = UUID.randomUUID().toString() + resourceResolution.artifactName = artifactPrefix + resourceResolution.blueprintVersion = blueprintVersion + resourceResolution.blueprintName = blueprintName + resourceResolution.resolutionKey = resolutionKey + resourceResolution.resourceType = resourceType + resourceResolution.resourceId = resourceId + resourceResolution.value = JacksonUtils.getValue(resourceAssignment.property?.value!!).toString() + resourceResolution.name = resourceAssignment.name + resourceResolution.dictionaryName = resourceAssignment.dictionaryName + resourceResolution.dictionaryVersion = resourceAssignment.version + resourceResolution.dictionarySource = resourceAssignment.dictionarySource + resourceResolution.status = resourceAssignment.status + + try { + resourceResolutionRepository.saveAndFlush(resourceResolution) + } catch (ex: Exception) { + throw BluePrintException("Failed to store resource resolution result.", ex) + } + } +}
\ 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/db/ResourceResolutionRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt index 72bb4a384..d2cbf8411 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt @@ -17,9 +17,21 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db import org.springframework.data.jpa.repository.JpaRepository -interface ResourceResolutionRepository : JpaRepository<ResourceResolutionResult, String> { +interface ResourceResolutionRepository : JpaRepository<ResourceResolution, String> { - fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?, - blueprintVersion: String?, - artifactName: String): ResourceResolutionResult -} + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName(key: String, + blueprintName: String?, + blueprintVersion: String?, + artifactName: String, + name: String): ResourceResolution + + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(resolutionKey: String, + blueprintName: String, + blueprintVersion: String, + artifactPrefix: String): List<ResourceResolution> + + fun findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(blueprintName: String, + blueprintVersion: String, + resourceId: String, + resourceType: String): List<ResourceResolution> +}
\ 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/db/ResourceResolutionResultRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt new file mode 100644 index 000000000..efc130a84 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db + +import org.springframework.data.jpa.repository.JpaRepository + +interface ResourceResolutionResultRepository : JpaRepository<ResourceResolutionResult, String> { + + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?, + blueprintVersion: String?, + artifactName: String): ResourceResolutionResult +} diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt index 3cb9dec63..ebb34ba4a 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt @@ -27,7 +27,7 @@ import org.springframework.stereotype.Service import java.util.* @Service -class ResourceResolutionResultService(private val resourceResolutionRepository: ResourceResolutionRepository) { +class ResourceResolutionResultService(private val resourceResolutionRepository: ResourceResolutionResultRepository) { suspend fun read(bluePrintRuntimeService: BluePrintRuntimeService<*>, artifactPrefix: String, resolutionKey: String): String = withContext(Dispatchers.IO) { 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) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt index 9c2a100bc..4a3e75cde 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt @@ -128,15 +128,10 @@ class ResourceResolutionServiceTest { val artifactPrefix = "another" - // Templating Artifact Definition Name - val artifactTemplate = "$artifactPrefix-template" - // Resource Assignment Artifact Definition Name - val artifactMapping = "$artifactPrefix-mapping" - // Prepare Inputs PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment") - resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", artifactMapping, artifactTemplate) + resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", artifactPrefix, mapOf<String, String>()) } } } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessorTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessorTest.kt index 2e91eb93f..242739067 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessorTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/InputResourceResolutionProcessorTest.kt @@ -15,8 +15,11 @@ */ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.TextNode +import io.mockk.every +import io.mockk.spyk import kotlinx.coroutines.runBlocking -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService @@ -28,7 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner -import kotlin.test.assertNotNull +import kotlin.test.assertTrue @RunWith(SpringRunner::class) @ContextConfiguration(classes = [InputResourceResolutionProcessor::class]) @@ -38,20 +41,21 @@ class InputResourceResolutionProcessorTest { @Autowired lateinit var inputResourceResolutionProcessor: InputResourceResolutionProcessor - @Ignore @Test - fun `test input resource resolution`() { + fun `InputResourceResolutionProcessor should be able to resolve a value for an input parameter`() { runBlocking { + val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext( "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration") - val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService("1234", bluePrintContext) + val resourceAssignmentRuntimeService = spyk(ResourceAssignmentRuntimeService("1234", bluePrintContext)) - inputResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService - inputResourceResolutionProcessor.resourceDictionaries = ResourceAssignmentUtils - .resourceDefinitions(bluePrintContext.rootPath) + // mocking input for resource resolution + val textNode: JsonNode = TextNode("any value") + every {resourceAssignmentRuntimeService.getInputValue("rr-name") } returns textNode - //TODO ("Mock the input Values") + inputResourceResolutionProcessor.raRuntimeService = resourceAssignmentRuntimeService + inputResourceResolutionProcessor.resourceDictionaries = ResourceAssignmentUtils.resourceDefinitions(bluePrintContext.rootPath) val resourceAssignment = ResourceAssignment().apply { name = "rr-name" @@ -62,9 +66,8 @@ class InputResourceResolutionProcessorTest { } } - val processorName = inputResourceResolutionProcessor.applyNB(resourceAssignment) - assertNotNull(processorName, "couldn't get Input resource assignment processor name") - println(processorName) + val operationOutcome = inputResourceResolutionProcessor.applyNB(resourceAssignment) + assertTrue(operationOutcome, "An error occurred while trying to test the InputResourceResolutionProcessor") } } -}
\ No newline at end of file +} |