Enable versioned resource resolution by using occurrence
[ccsdk/cds.git] / ms / blueprintsprocessor / functions / resource-resolution / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / functions / resource / resolution / db / ResourceResolutionDBService.kt
index 5335b14..1f0171f 100644 (file)
@@ -26,7 +26,7 @@ import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.slf4j.LoggerFactory
 import org.springframework.dao.EmptyResultDataAccessException
 import org.springframework.stereotype.Service
-import java.util.*
+import java.util.UUID
 
 @Service
 class ResourceResolutionDBService(private val resourceResolutionRepository: ResourceResolutionRepository) {
@@ -34,8 +34,11 @@ 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> {
+        bluePrintRuntimeService: BluePrintRuntimeService<*>,
+        key: String,
+        occurrence: Int,
+        artifactPrefix: String
+    ): List<ResourceResolution> {
         return try {
             val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
 
@@ -47,16 +50,20 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
                 blueprintVersion,
                 artifactPrefix,
                 key,
-                occurrence)
+                occurrence
+            )
         } catch (e: EmptyResultDataAccessException) {
             emptyList()
         }
     }
 
     suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
-        bluePrintRuntimeService: BluePrintRuntimeService<*>, resourceId: String,
-        resourceType: String, occurrence: Int,
-        artifactPrefix: String): List<ResourceResolution> {
+        bluePrintRuntimeService: BluePrintRuntimeService<*>,
+        resourceId: String,
+        resourceType: String,
+        occurrence: Int,
+        artifactPrefix: String
+    ): List<ResourceResolution> {
         return try {
 
             val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
@@ -70,55 +77,67 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
                 artifactPrefix,
                 resourceId,
                 resourceType,
-                occurrence)
+                occurrence
+            )
         } catch (e: EmptyResultDataAccessException) {
             emptyList()
         }
     }
 
-    suspend fun readValue(blueprintName: String,
-                          blueprintVersion: String,
-                          artifactPrefix: String,
-                          resolutionKey: String,
-                          name: String): ResourceResolution = withContext(Dispatchers.IO) {
+    suspend fun readValue(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactPrefix: String,
+        resolutionKey: String,
+        name: String
+    ): ResourceResolution? = withContext(Dispatchers.IO) {
 
         resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName(
             resolutionKey,
             blueprintName,
             blueprintVersion,
             artifactPrefix,
-            name)
+            name
+        )
     }
 
-    suspend fun readWithResolutionKey(blueprintName: String,
-                                      blueprintVersion: String,
-                                      artifactPrefix: String,
-                                      resolutionKey: String): List<ResourceResolution> = withContext(Dispatchers.IO) {
+    suspend fun readWithResolutionKey(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactPrefix: String,
+        resolutionKey: String
+    ): List<ResourceResolution> = withContext(Dispatchers.IO) {
 
         resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
             resolutionKey,
             blueprintName,
             blueprintVersion,
-            artifactPrefix)
+            artifactPrefix
+        )
     }
 
-    suspend fun readWithResourceIdAndResourceType(blueprintName: String,
-                                                  blueprintVersion: String,
-                                                  resourceId: String,
-                                                  resourceType: String): List<ResourceResolution> =
+    suspend fun readWithResourceIdAndResourceType(
+        blueprintName: String,
+        blueprintVersion: String,
+        resourceId: String,
+        resourceType: String
+    ): List<ResourceResolution> =
         withContext(Dispatchers.IO) {
 
             resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
                 blueprintName,
                 blueprintVersion,
                 resourceId,
-                resourceType)
+                resourceType
+            )
         }
 
-    suspend fun write(properties: Map<String, Any>,
-                      bluePrintRuntimeService: BluePrintRuntimeService<*>,
-                      artifactPrefix: String,
-                      resourceAssignment: ResourceAssignment): ResourceResolution = withContext(Dispatchers.IO) {
+    suspend fun write(
+        properties: Map<String, Any>,
+        bluePrintRuntimeService: BluePrintRuntimeService<*>,
+        artifactPrefix: String,
+        resourceAssignment: ResourceAssignment
+    ): ResourceResolution = withContext(Dispatchers.IO) {
 
         val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
 
@@ -130,24 +149,28 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
         val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
         val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
 
-        write(blueprintName,
+        write(
+            blueprintName,
             blueprintVersion,
             resolutionKey,
             resourceId,
             resourceType,
             artifactPrefix,
             resourceAssignment,
-            occurrence)
+            occurrence
+        )
     }
 
-    suspend fun write(blueprintName: String,
-                      blueprintVersion: String,
-                      resolutionKey: String,
-                      resourceId: String,
-                      resourceType: String,
-                      artifactPrefix: String,
-                      resourceAssignment: ResourceAssignment,
-                      occurrence: Int = 0): ResourceResolution = withContext(Dispatchers.IO) {
+    suspend fun write(
+        blueprintName: String,
+        blueprintVersion: String,
+        resolutionKey: String,
+        resourceId: String,
+        resourceType: String,
+        artifactPrefix: String,
+        resourceAssignment: ResourceAssignment,
+        occurrence: Int = 0
+    ): ResourceResolution = withContext(Dispatchers.IO) {
 
         val resourceResolution = ResourceResolution()
         resourceResolution.id = UUID.randomUUID().toString()
@@ -158,16 +181,16 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
         resourceResolution.resolutionKey = resolutionKey
         resourceResolution.resourceType = resourceType
         resourceResolution.resourceId = resourceId
-        if (BluePrintConstants.STATUS_SUCCESS == resourceAssignment.status) {
-            resourceResolution.value = JacksonUtils.getValue(resourceAssignment.property?.value!!).toString()
-        } else {
-            resourceResolution.value = ""
-        }
+        resourceResolution.value = resourceAssignment.property?.value?.let {
+            if (BluePrintConstants.STATUS_SUCCESS == resourceAssignment.status)
+                JacksonUtils.getValue(it).toString()
+            else ""
+        } ?: ""
         resourceResolution.name = resourceAssignment.name
         resourceResolution.dictionaryName = resourceAssignment.dictionaryName
         resourceResolution.dictionaryVersion = resourceAssignment.version
         resourceResolution.dictionarySource = resourceAssignment.dictionarySource
-        resourceResolution.status = resourceAssignment.status
+        resourceResolution.status = resourceAssignment.status ?: BluePrintConstants.STATUS_FAILURE
 
         try {
             resourceResolutionRepository.saveAndFlush(resourceResolution)
@@ -175,4 +198,83 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso
             throw BluePrintException("Failed to store resource resolution result.", ex)
         }
     }
-}
\ No newline at end of file
+
+    /**
+     * This is a deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKey method to delete resources
+     * associated to a specific resolution-key
+     *
+     * @param blueprintName name of the CBA
+     * @param blueprintVersion version of the CBA
+     * @param artifactName name of the artifact
+     * @param resolutionKey value of the resolution-key
+     */
+    suspend fun deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKey(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactName: String,
+        resolutionKey: String
+    ) {
+        resourceResolutionRepository.deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKey(
+            blueprintName,
+            blueprintVersion,
+            artifactName,
+            resolutionKey
+        )
+    }
+
+    suspend fun deleteResourceResolutionList(listResourceResolution: List<ResourceResolution>) = withContext(Dispatchers.IO) {
+        try {
+            resourceResolutionRepository.deleteInBatch(listResourceResolution)
+        } catch (ex: Exception) {
+            throw BluePrintException("Failed to batch delete resource resolution", ex)
+        }
+    }
+
+    /**
+     * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
+     * The 'occurrence' is used to persist new resource resolution in the DB.
+     *
+     * @param resolutionKey
+     * @param blueprintName
+     * @param blueprintVersion
+     * @param artifactPrefix
+     */
+    suspend fun findNextOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+        resolutionKey: String,
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactPrefix: String
+    ) = withContext(Dispatchers.IO) {
+        val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+            resolutionKey,
+            blueprintName,
+            blueprintVersion,
+            artifactPrefix
+        )
+        maxOccurrence?.inc() ?: 1
+    }
+
+    /**
+     * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
+     * The 'occurrence' is used to persist new resource resolution in the DB.
+     *
+     * @param blueprintName
+     * @param blueprintVersion
+     * @param resourceId
+     * @param resourceType
+     */
+    suspend fun findNextOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+        blueprintName: String,
+        blueprintVersion: String,
+        resourceId: String,
+        resourceType: String
+    ) = withContext(Dispatchers.IO) {
+        val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+            blueprintName,
+            blueprintVersion,
+            resourceId,
+            resourceType
+        )
+        maxOccurrence?.inc() ?: 1
+    }
+}