summaryrefslogtreecommitdiffstats
path: root/ms/blueprintsprocessor/functions/resource-resolution
diff options
context:
space:
mode:
Diffstat (limited to 'ms/blueprintsprocessor/functions/resource-resolution')
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt52
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt111
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt57
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt68
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt15
-rwxr-xr-xms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt31
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt35
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt147
8 files changed, 393 insertions, 123 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 2039d2e5a..fd14cc8c1 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
@@ -21,11 +21,13 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory
import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
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
+import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Component
@Component("component-resource-resolution")
@@ -35,41 +37,51 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
override suspend fun processNB(executionRequest: ExecutionServiceInput) {
- val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE)
- val resolutionKey = 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)
-
+ val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE).asInt()
+ val resolutionKey = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY)?.asText() ?: ""
+ val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)?.asBoolean() ?: false
+ val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID)?.asText() ?: ""
+ val resourceType = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE)?.asText() ?: ""
val properties: MutableMap<String, Any> = mutableMapOf()
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult?.asBoolean() ?: false
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = resolutionKey?.asText() ?: ""
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId?.asText() ?: ""
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType?.asText() ?: ""
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = resolutionKey
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence
+
+ val jsonResponse = JsonNodeFactory.instance.objectNode()
+
+ // validate inputs if we need to store the resource and template resolution.
+ if (storeResult) {
+ if (resolutionKey.isNotEmpty() && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) {
+ throw BluePrintProcessorException("Can't proceed with the resolution: either provide resolution-key OR combination of resource-id and resource-type.")
+ } else if ((resourceType.isNotEmpty() && resourceId.isEmpty()) || (resourceType.isEmpty() && resourceId.isNotEmpty())) {
+ throw BluePrintProcessorException("Can't proceed with the resolution: both resource-id and resource-type should be provided, one of them is missing.")
+ } else if (resourceType.isEmpty() && resourceId.isEmpty() && resolutionKey.isEmpty()) {
+ throw BluePrintProcessorException("Can't proceed with the resolution: can't persist resolution without a correlation key. " +
+ "Either provide a resolution-key OR combination of resource-id and resource-type OR set `storeResult` to false.")
+ }
+ }
val artifactPrefixNamesNode = getOperationInput(ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES)
val artifactPrefixNames = JacksonUtils.getListFromJsonNode(artifactPrefixNamesNode, String::class.java)
- val resourceAssignmentRuntimeService =
- ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactPrefixNames.toString())
-
- val jsonResponse = JsonNodeFactory.instance.objectNode()
- for (j in 1..occurrence.asInt()) {
- val key = resolutionKey?.asText() + "-" + j
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key
+ for (j in 1..occurrence) {
+ properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = j
- val response = resourceResolutionService.resolveResources(resourceAssignmentRuntimeService,
+ 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, response.asJsonNode())
+ if (occurrence != 1) {
+ jsonResponse.set(Integer.toString(j), response.asJsonNode())
} else {
jsonResponse.setAll(response.asObjectNode())
}
+
}
// Set Output Attributes
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 1270298a8..e08ac520a 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,13 +20,14 @@ 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.ResourceResolution
import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService
import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService
import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
-import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty
import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
@@ -60,7 +61,7 @@ interface ResourceResolutionService {
@Service(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION)
open class ResourceResolutionServiceImpl(private var applicationContext: ApplicationContext,
- private var resolutionResultService: TemplateResolutionService,
+ private var templateResolutionDBService: TemplateResolutionService,
private var blueprintTemplateService: BluePrintTemplateService,
private var resourceResolutionDBService: ResourceResolutionDBService) :
ResourceResolutionService {
@@ -76,22 +77,30 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
override suspend fun resolveFromDatabase(bluePrintRuntimeService: BluePrintRuntimeService<*>,
artifactTemplate: String,
resolutionKey: String): String {
- return resolutionResultService.read(bluePrintRuntimeService, artifactTemplate, resolutionKey)
+ return templateResolutionDBService.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+ bluePrintRuntimeService,
+ artifactTemplate,
+ resolutionKey)
}
override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
artifactNames: List<String>,
properties: Map<String, Any>): MutableMap<String, String> {
+
+ val resourceAssignmentRuntimeService =
+ ResourceAssignmentUtils.transformToRARuntimeService(bluePrintRuntimeService, artifactNames.toString())
+
val resolvedParams: MutableMap<String, String> = hashMapOf()
artifactNames.forEach { artifactName ->
- val resolvedContent = resolveResources(bluePrintRuntimeService, nodeTemplateName,
+ val resolvedContent = resolveResources(resourceAssignmentRuntimeService, nodeTemplateName,
artifactName, properties)
resolvedParams[artifactName] = resolvedContent
}
return resolvedParams
}
+
override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
artifactPrefix: String, properties: Map<String, Any>): String {
@@ -111,6 +120,13 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
as? MutableList<ResourceAssignment>
?: throw BluePrintProcessorException("couldn't get Dictionary Definitions")
+ if (isToStore(properties)) {
+ val existingResourceResolution = isNewResolution(bluePrintRuntimeService, properties, artifactPrefix)
+ if (existingResourceResolution.isNotEmpty()) {
+ updateResourceAssignmentWithExisting(existingResourceResolution, resourceAssignments)
+ }
+ }
+
// Get the Resource Dictionary Name
val resourceDefinitions: MutableMap<String, ResourceDefinition> = ResourceAssignmentUtils
.resourceDefinitions(bluePrintRuntimeService.bluePrintContext().rootPath)
@@ -128,10 +144,9 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName,
artifactTemplate, 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)")
+ if (isToStore(properties)) {
+ templateResolutionDBService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix)
+ log.info("Template resolution saved into database successfully : ($properties)")
}
return resolvedContent
@@ -154,7 +169,9 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
coroutineScope {
bulkSequenced.forEach { batchResourceAssignments ->
// Execute Non Dependent Assignments in parallel ( ie asynchronously )
- val deferred = batchResourceAssignments.filter { it.name != "*" && it.name != "start" }
+ val deferred = batchResourceAssignments
+ .filter { it.name != "*" && it.name != "start" }
+ .filter { it.status != BluePrintConstants.STATUS_SUCCESS }
.map { resourceAssignment ->
async {
val dictionaryName = resourceAssignment.dictionaryName
@@ -197,12 +214,6 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
}
- private fun isToStore(properties: Map<String, Any>): Boolean {
- return properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
- && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean
- }
-
-
/**
* If the Source instance is "input", then it is not mandatory to have source Resource Definition, So it can
* derive the default input processor.
@@ -233,4 +244,74 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
return processorName
}
+
+ // Check whether to store or not the resolution of resource and template
+ private fun isToStore(properties: Map<String, Any>): Boolean {
+ return properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
+ && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean
+ }
+
+ // Check whether resolution already exist in the database for the specified resolution-key or resourceId/resourceType
+ private suspend fun isNewResolution(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+ properties: Map<String, Any>,
+ artifactPrefix: String): List<ResourceResolution> {
+ val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
+ val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] as String
+ val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
+ val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
+
+ if (resolutionKey.isNotEmpty()) {
+ val existingResourceAssignments =
+ resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence(
+ bluePrintRuntimeService,
+ resolutionKey,
+ occurrence,
+ artifactPrefix)
+ if (existingResourceAssignments.isNotEmpty()) {
+ log.info("Resolution with resolutionKey=($resolutionKey) already exist - will resolve all resources not already resolved.",
+ resolutionKey)
+ }
+ return existingResourceAssignments
+ } else if (resourceId.isNotEmpty() && resourceType.isNotEmpty()) {
+ val existingResourceAssignments =
+ resourceResolutionDBService.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
+ bluePrintRuntimeService,
+ resourceId,
+ resourceType,
+
+ occurrence,
+ artifactPrefix)
+ if (existingResourceAssignments.isNotEmpty()) {
+ log.info("Resolution with resourceId=($resourceId) and resourceType=($resourceType) already exist - will resolve " +
+ "all resources not already resolved.")
+ }
+ return existingResourceAssignments
+ }
+ return emptyList()
+ }
+
+ // Update the resource assignment list with the status of the resource that have already been resolved
+ private fun updateResourceAssignmentWithExisting(resourceResolutionList: List<ResourceResolution>,
+ resourceAssignmentList: MutableList<ResourceAssignment>) {
+ resourceResolutionList.forEach { resourceResolution ->
+ if (resourceResolution.status == BluePrintConstants.STATUS_SUCCESS) {
+ resourceAssignmentList.forEach {
+ if (compareOne(resourceResolution, it)) {
+ log.info("Resource ({}) already resolve: value=({})", it.name, resourceResolution.value)
+ it.property!!.value = resourceResolution.value!!.asJsonPrimitive()
+ it.status = resourceResolution.status
+ }
+ }
+ }
+ }
+ }
+
+ // Comparision between what we have in the database vs what we have to assign.
+ private fun compareOne(resourceResolution: ResourceResolution, resourceAssignment: ResourceAssignment): Boolean {
+ return (resourceResolution.name == resourceAssignment.name
+ && resourceResolution.dictionaryName == resourceAssignment.dictionaryName
+ && resourceResolution.dictionarySource == resourceAssignment.dictionarySource
+ && resourceResolution.dictionaryVersion == resourceAssignment.version)
+ }
+
}
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
index fa922cde5..baabfd913 100644
--- 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
@@ -24,6 +24,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.io.Serializable
import java.util.*
import javax.persistence.Column
+import javax.persistence.ElementCollection
import javax.persistence.Entity
import javax.persistence.EntityListeners
import javax.persistence.Id
@@ -38,23 +39,6 @@ import javax.persistence.TemporalType
@Proxy(lazy = false)
class ResourceResolution : Serializable {
- @Id
- @Column(name = "resource_resolution_id")
- var id: String? = null
-
- @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.",
- required = true)
- @Column(name = "resolution_key", nullable = false)
- var resolutionKey: String? = null
-
- @get:ApiModelProperty(value = "Resolution type.", required = true, example = "ServiceInstance, VfModule, VNF")
- @Column(name = "resource_type", nullable = false)
- var resourceType: String? = null
-
- @get:ApiModelProperty(value = "ID associated with the resolution type in the inventory system.", required = true)
- @Column(name = "resource_id", nullable = false)
- var resourceId: String? = null
-
@get:ApiModelProperty(value = "Name of the CBA.", required = true)
@Column(name = "blueprint_name", nullable = false)
var blueprintName: String? = null
@@ -67,19 +51,43 @@ class ResourceResolution : Serializable {
@Column(name = "artifact_name", nullable = false)
var artifactName: String? = null
+ @get:ApiModelProperty(value = "Name of the resource.", required = true)
+ @Column(name = "name", nullable = false)
+ var name: String? = null
+
+ @get:ApiModelProperty(value = "Value of the resolution.", required = true)
+ @Lob
+ @Column(name = "value", nullable = false)
+ var value: String? = null
+
@get:ApiModelProperty(value = "Whether success of failure.", required = true)
@Column(name = "status", nullable = false)
var status: String? = null
- @get:ApiModelProperty(value = "Name of the resource.", required = true)
- @Column(name = "name", nullable = false)
- var name: String? = null
+ @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.",
+ required = true)
+ @Column(name = "resolution_key", nullable = false)
+ var resolutionKey: String? = null
+
+ @get:ApiModelProperty(value = "Resolution type.", required = true, example = "ServiceInstance, VfModule, VNF")
+ @Column(name = "resource_type", nullable = false)
+ var resourceType: String? = null
+
+ @get:ApiModelProperty(value = "ID associated with the resolution type in the inventory system.", required = true)
+ @Column(name = "resource_id", nullable = false)
+ var resourceId: String? = null
+
+ @get:ApiModelProperty(value = "If resolution occurred multiple time, this field provides the index.",
+ required = true)
+ @Column(name = "occurrence", nullable = false)
+ var occurrence: Int = 0
@get:ApiModelProperty(value = "Name of the data dictionary used for the resolution.", required = true)
@Column(name = "dictionary_name", nullable = false)
var dictionaryName: String? = null
- @get:ApiModelProperty(value = "Source associated with the data dictionary used for the resolution.", required = true)
+ @get:ApiModelProperty(value = "Source associated with the data dictionary used for the resolution.",
+ required = true)
@Column(name = "dictionary_status", nullable = false)
var dictionarySource: String? = null
@@ -87,10 +95,9 @@ class ResourceResolution : Serializable {
@Column(name = "dictionary_version", nullable = false)
var dictionaryVersion: Int = 0
- @get:ApiModelProperty(value = "Value of the resolution.", required = true)
- @Lob
- @Column(name = "value", nullable = false)
- var value: String? = null
+ @Id
+ @Column(name = "resource_resolution_id")
+ var id: String? = null
@get:ApiModelProperty(value = "Creation date of the resolution.", required = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
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
index c6ffde742..e9679eeba 100644
--- 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
@@ -25,6 +25,7 @@ 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.dao.EmptyResultDataAccessException
import org.springframework.stereotype.Service
import java.util.*
@@ -33,6 +34,49 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
private val log = LoggerFactory.getLogger(ResourceResolutionDBService::class.toString())
+ suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence(
+ bluePrintRuntimeService: BluePrintRuntimeService<*>, key: String,
+ occurrence: Int, artifactPrefix: String): List<ResourceResolution> {
+ return try {
+ val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
+
+ val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
+ val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
+
+ resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence(
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ key,
+ occurrence)
+ } catch (e: EmptyResultDataAccessException) {
+ emptyList()
+ }
+ }
+
+ suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
+ bluePrintRuntimeService: BluePrintRuntimeService<*>, resourceId: String,
+ resourceType: String, occurrence: Int,
+ artifactPrefix: String): List<ResourceResolution> {
+ return try {
+
+ val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
+
+ val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
+ val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
+
+ resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ resourceId,
+ resourceType,
+ occurrence)
+ } catch (e: EmptyResultDataAccessException) {
+ emptyList()
+ }
+ }
+
suspend fun readValue(blueprintName: String,
blueprintVersion: String,
artifactPrefix: String,
@@ -81,12 +125,11 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
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()
+
+ val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] as String
+ val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
+ val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
+ val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
write(blueprintName,
blueprintVersion,
@@ -94,7 +137,8 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
resourceId,
resourceType,
artifactPrefix,
- resourceAssignment)
+ resourceAssignment,
+ occurrence)
}
suspend fun write(blueprintName: String,
@@ -103,20 +147,22 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
resourceId: String,
resourceType: String,
artifactPrefix: String,
- resourceAssignment: ResourceAssignment): ResourceResolution = withContext(Dispatchers.IO) {
+ resourceAssignment: ResourceAssignment,
+ occurrence: Int = 0): ResourceResolution = withContext(Dispatchers.IO) {
val resourceResolution = ResourceResolution()
resourceResolution.id = UUID.randomUUID().toString()
resourceResolution.artifactName = artifactPrefix
+ resourceResolution.occurrence = occurrence
resourceResolution.blueprintVersion = blueprintVersion
resourceResolution.blueprintName = blueprintName
resourceResolution.resolutionKey = resolutionKey
resourceResolution.resourceType = resourceType
resourceResolution.resourceId = resourceId
- if (BluePrintConstants.STATUS_FAILURE == resourceAssignment.status) {
- resourceResolution.value = ""
- } else {
+ if (BluePrintConstants.STATUS_SUCCESS == resourceAssignment.status) {
resourceResolution.value = JacksonUtils.getValue(resourceAssignment.property?.value!!).toString()
+ } else {
+ resourceResolution.value = ""
}
resourceResolution.name = resourceAssignment.name
resourceResolution.dictionaryName = resourceAssignment.dictionaryName
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 d2cbf8411..429041e14 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
@@ -34,4 +34,19 @@ interface ResourceResolutionRepository : JpaRepository<ResourceResolution, Strin
blueprintVersion: String,
resourceId: String,
resourceType: String): List<ResourceResolution>
+
+ fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence(
+ blueprintName: String?,
+ blueprintVersion: String?,
+ artifactName: String,
+ resolutionKey: String,
+ occurrence: Int): List<ResourceResolution>
+
+ fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
+ blueprintName: String?,
+ blueprintVersion: String?,
+ artifactName: String,
+ resourceId: String,
+ resourceType: String,
+ occurrence: Int): 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/TemplateResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt
index ae24a9ac2..70aadb4b1 100755
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt
@@ -38,15 +38,6 @@ import javax.persistence.TemporalType
@Proxy(lazy = false)
class TemplateResolution : Serializable {
- @Id
- @Column(name = "template_resolution_id")
- var id: String? = null
-
- @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.",
- required = true)
- @Column(name = "resolution_key", nullable = false)
- var resolutionKey: String? = null
-
@get:ApiModelProperty(value = "Name of the CBA.", required = true)
@Column(name = "blueprint_name", nullable = false)
var blueprintName: String? = null
@@ -64,6 +55,28 @@ class TemplateResolution : Serializable {
@Column(name = "result", nullable = false)
var result: String? = null
+ @get:ApiModelProperty(value = "Resolution Key uniquely identifying the resolution of a given artifact within a CBA.",
+ required = true)
+ @Column(name = "resolution_key", nullable = false)
+ var resolutionKey: String? = null
+
+ @get:ApiModelProperty(value = "Resolution type.", required = true, example = "ServiceInstance, VfModule, VNF")
+ @Column(name = "resource_type", nullable = false)
+ var resourceType: String? = null
+
+ @get:ApiModelProperty(value = "ID associated with the resolution type in the inventory system.", required = true)
+ @Column(name = "resource_id", nullable = false)
+ var resourceId: String? = null
+
+ @get:ApiModelProperty(value = "If resolution occurred multiple time, this field provides the index.",
+ required = true)
+ @Column(name = "occurrence", nullable = false)
+ var occurrence: Int = 0
+
+ @Id
+ @Column(name = "template_resolution_id")
+ var id: String? = null
+
@get:ApiModelProperty(value = "Creation date of the resolution.", required = true)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
@LastModifiedDate
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt
index 136b5e952..440663f25 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt
@@ -16,10 +16,39 @@
package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db
import org.springframework.data.jpa.repository.JpaRepository
+import javax.transaction.Transactional
interface TemplateResolutionRepository : JpaRepository<TemplateResolution, String> {
- fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?,
- blueprintVersion: String?,
- artifactName: String): TemplateResolution
+ fun findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resourceId: String,
+ resourceType: String,
+ blueprintName: String?,
+ blueprintVersion: String?,
+ artifactName: String,
+ occurrence: Int): TemplateResolution ?
+
+ fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ key: String,
+ blueprintName: String?,
+ blueprintVersion: String?,
+ artifactName: String,
+ occurrence: Int): TemplateResolution ?
+
+ @Transactional
+ fun deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resourceId: String,
+ resourceType: String,
+ blueprintName: String?,
+ blueprintVersion: String?,
+ artifactName: String,
+ occurrence: Int)
+
+ @Transactional
+ fun deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ key: String,
+ blueprintName: String?,
+ blueprintVersion: String?,
+ artifactName: String,
+ occurrence: Int)
}
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt
index c4e36401f..44662965d 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt
@@ -21,36 +21,65 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.Reso
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.slf4j.LoggerFactory
import org.springframework.dao.DataIntegrityViolationException
+import org.springframework.dao.EmptyResultDataAccessException
import org.springframework.stereotype.Service
import java.util.*
@Service
class TemplateResolutionService(private val templateResolutionRepository: TemplateResolutionRepository) {
- suspend fun read(bluePrintRuntimeService: BluePrintRuntimeService<*>,
- artifactPrefix: String,
- resolutionKey: String): String = withContext(Dispatchers.IO) {
+ private val log = LoggerFactory.getLogger(TemplateResolutionService::class.toString())
- val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
+ suspend fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+ bluePrintRuntimeService: BluePrintRuntimeService<*>,
+ artifactPrefix: String,
+ resolutionKey: String): String =
+ withContext(Dispatchers.IO) {
- val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
- val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
+ val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
- read(blueprintName, blueprintVersion, artifactPrefix, resolutionKey)
- }
+ val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
+ val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
- suspend fun read(blueprintName: String,
- blueprintVersion: String,
- artifactPrefix: String,
- resolutionKey: String): String = withContext(Dispatchers.IO) {
+ findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ resolutionKey)
+ }
- templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
- resolutionKey,
- blueprintName,
- blueprintVersion,
- artifactPrefix).result!!
- }
+ suspend fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(blueprintName: String,
+ blueprintVersion: String,
+ artifactPrefix: String,
+ resolutionKey: String,
+ occurrence: Int = 0): String =
+ withContext(Dispatchers.IO) {
+
+ templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resolutionKey,
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ occurrence)?.result ?: throw EmptyResultDataAccessException(1)
+ }
+
+ suspend fun findByResoureIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(blueprintName: String,
+ blueprintVersion: String,
+ artifactPrefix: String,
+ resourceId: String,
+ resourceType: String,
+ occurrence: Int = 0): String =
+ withContext(Dispatchers.IO) {
+
+ templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resourceId,
+ resourceType,
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ occurrence)?.result!!
+ }
suspend fun write(properties: Map<String, Any>,
result: String, bluePrintRuntimeService: BluePrintRuntimeService<*>,
@@ -60,30 +89,68 @@ class TemplateResolutionService(private val templateResolutionRepository: Templa
val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
- val resolutionKey =
- properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY].toString()
+ val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] as String
+ val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
+ val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
+ val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
- write(blueprintName, blueprintVersion, resolutionKey, artifactPrefix, result)
+ write(blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ result,
+ occurrence,
+ resolutionKey,
+ resourceId,
+ resourceType)
}
- suspend fun write(blueprintName: String,
- blueprintVersion: String,
- resolutionKey: String,
- artifactPrefix: String,
- template: String): TemplateResolution = withContext(Dispatchers.IO) {
-
- val resourceResolutionResult = TemplateResolution()
- resourceResolutionResult.id = UUID.randomUUID().toString()
- resourceResolutionResult.artifactName = artifactPrefix
- resourceResolutionResult.blueprintVersion = blueprintVersion
- resourceResolutionResult.blueprintName = blueprintName
- resourceResolutionResult.resolutionKey = resolutionKey
- resourceResolutionResult.result = template
-
- try {
- templateResolutionRepository.saveAndFlush(resourceResolutionResult)
- } catch (ex: DataIntegrityViolationException) {
- throw BluePrintException("Failed to store resource api result.", ex)
+ suspend fun write(blueprintName: String, blueprintVersion: String, artifactPrefix: String,
+ template: String, occurrence: Int = 0, resolutionKey: String = "", resourceId: String = "",
+ resourceType: String = ""): TemplateResolution =
+ withContext(Dispatchers.IO) {
+
+ val resourceResolutionResult = TemplateResolution()
+ resourceResolutionResult.id = UUID.randomUUID().toString()
+ resourceResolutionResult.artifactName = artifactPrefix
+ resourceResolutionResult.blueprintVersion = blueprintVersion
+ resourceResolutionResult.blueprintName = blueprintName
+ resourceResolutionResult.resolutionKey = resolutionKey
+ resourceResolutionResult.resourceId = resourceId
+ resourceResolutionResult.resourceType = resourceType
+ resourceResolutionResult.result = template
+ resourceResolutionResult.occurrence = occurrence
+
+ // Overwrite template resolution-key of resourceId/resourceType already existant
+ if (resolutionKey.isNotEmpty()) {
+ templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resolutionKey, blueprintName, blueprintVersion, artifactPrefix, occurrence)?.let {
+ log.info("Overwriting template resolution for blueprintName=($blueprintVersion), blueprintVersion=($blueprintName), " +
+ "artifactName=($artifactPrefix) and resolutionKey=($resolutionKey)")
+ templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resolutionKey,
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ occurrence)
+ }
+ } else if (resourceId.isNotEmpty() && resourceType.isNotEmpty()) {
+ templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resourceId, resourceType, blueprintName, blueprintVersion, artifactPrefix, occurrence)?.let {
+ log.info("Overwriting template resolution for blueprintName=($blueprintVersion), blueprintVersion=($blueprintName), " +
+ "artifactName=($artifactPrefix), resourceId=($resourceId) and resourceType=($resourceType)")
+ templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
+ resourceId,
+ resourceType,
+ blueprintName,
+ blueprintVersion,
+ artifactPrefix,
+ occurrence)
+ }
+ }
+ try {
+ templateResolutionRepository.saveAndFlush(resourceResolutionResult)
+ } catch (ex: DataIntegrityViolationException) {
+ throw BluePrintException("Failed to store resource api result.", ex)
+ }
}
- }
} \ No newline at end of file