Add endpoint for deleting templates 65/130165/5
authorJozsef Csongvai <jozsef.csongvai@bell.ca>
Mon, 16 May 2022 15:12:51 +0000 (11:12 -0400)
committerkuldipr <kuldip.rai@amdocs.com>
Mon, 29 Aug 2022 20:01:31 +0000 (16:01 -0400)
Issue-ID: CCSDK-3735
Signed-off-by: Jozsef Csongvai <jozsef.csongvai@bell.ca>
Signed-off-by: kuldipr <kuldip.rai@amdocs.com>
Change-Id: I80d0da87651933da103e79d878902da743bb134e

ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionServiceTest.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt

index 0d8946e..1ee9f79 100644 (file)
@@ -16,6 +16,7 @@
 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db
 
 import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Modifying
 import org.springframework.data.jpa.repository.Query
 import org.springframework.data.repository.query.Param
 import org.springframework.stereotype.Repository
@@ -162,4 +163,69 @@ interface TemplateResolutionRepository : JpaRepository<TemplateResolution, Strin
         artifactName: String,
         occurrence: Int
     )
+
+    @Transactional
+    fun deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(
+        resourceId: String,
+        resourceType: String,
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactName: String
+    ): Int
+
+    @Transactional
+    fun deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+        key: String,
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactName: String
+    ): Int
+
+    @Transactional
+    @Modifying
+    @Query(
+        value = """
+        DELETE FROM TEMPLATE_RESOLUTION WHERE resolution_key = :resolutionKey
+            AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion
+            AND artifact_name = :artifactName
+            AND occurrence > (
+                SELECT MAX(occurrence) - :lastN FROM TEMPLATE_RESOLUTION
+                WHERE resolution_key = :resolutionKey AND blueprint_name = :blueprintName
+                    AND blueprint_version = :blueprintVersion AND artifact_name = :artifactName
+                )
+    """,
+        nativeQuery = true
+    )
+    fun deleteTemplates(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactName: String,
+        resolutionKey: String,
+        lastN: Int
+    ): Int
+
+    @Transactional
+    @Modifying
+    @Query(
+        value = """
+        DELETE FROM TEMPLATE_RESOLUTION WHERE resource_type = :resourceType
+            AND resource_id = :resourceId AND artifact_name = :artifactName
+            AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion
+            AND occurrence > (
+                SELECT MAX(occurrence) - :lastN FROM TEMPLATE_RESOLUTION
+                WHERE resource_type = :resourceType
+                    AND resource_id = :resourceId AND blueprint_name = :blueprintName
+                    AND blueprint_version = :blueprintVersion AND artifact_name = :artifactName
+            )
+    """,
+        nativeQuery = true
+    )
+    fun deleteTemplates(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactName: String,
+        resourceType: String,
+        resourceId: String,
+        lastN: Int
+    ): Int
 }
index 906aedf..af6d1ab 100644 (file)
@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory
 import org.springframework.dao.DataIntegrityViolationException
 import org.springframework.dao.EmptyResultDataAccessException
 import org.springframework.stereotype.Service
+import java.lang.IllegalArgumentException
 import java.util.UUID
 
 @Service
@@ -336,4 +337,55 @@ class TemplateResolutionService(private val templateResolutionRepository: Templa
             artifactPrefix
         )
     }
+
+    suspend fun deleteTemplates(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactPrefix: String,
+        resolutionKey: String,
+        lastNOccurrences: Int?
+    ): Int = lastNOccurrences?.let {
+        if (lastNOccurrences < 0) {
+            throw IllegalArgumentException("last N occurrences must be a positive integer")
+        }
+        templateResolutionRepository.deleteTemplates(
+            blueprintName,
+            blueprintVersion,
+            artifactPrefix,
+            resolutionKey,
+            it
+        )
+    } ?: templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+        resolutionKey,
+        blueprintName,
+        blueprintVersion,
+        artifactPrefix
+    )
+
+    suspend fun deleteTemplates(
+        blueprintName: String,
+        blueprintVersion: String,
+        artifactPrefix: String,
+        resourceType: String,
+        resourceId: String,
+        lastNOccurrences: Int?
+    ): Int = lastNOccurrences?.let {
+        if (lastNOccurrences < 0) {
+            throw IllegalArgumentException("last N occurrences must be a positive integer")
+        }
+        templateResolutionRepository.deleteTemplates(
+            blueprintName,
+            blueprintVersion,
+            artifactPrefix,
+            resourceType,
+            resourceId,
+            it
+        )
+    } ?: templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(
+        resourceId,
+        resourceType,
+        blueprintName,
+        blueprintVersion,
+        artifactPrefix
+    )
 }
index a2550ed..65304b2 100644 (file)
@@ -220,4 +220,48 @@ class TemplateResolutionServiceTest {
             assertEquals(tr, res)
         }
     }
+
+    @Test
+    fun deleteTemplatesResolutionKeyAll() {
+        every {
+            templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(resolutionKey, blueprintName, blueprintVersion, artifactPrefix)
+        }.returns(1)
+        runBlocking {
+            val result = templateResolutionService.deleteTemplates(blueprintName, blueprintVersion, artifactPrefix, resolutionKey, null)
+            assertEquals(1, result)
+        }
+    }
+
+    @Test
+    fun deleteTemplatesResolutionKeyLastN() {
+        every {
+            templateResolutionRepository.deleteTemplates(blueprintName, blueprintVersion, artifactPrefix, resolutionKey, 1)
+        }.returns(1)
+        runBlocking {
+            val result = templateResolutionService.deleteTemplates(blueprintName, blueprintVersion, artifactPrefix, resolutionKey, 1)
+            assertEquals(1, result)
+        }
+    }
+
+    @Test
+    fun deleteTemplatesResourceIdAndTypeAll() {
+        every {
+            templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(resourceId, resourceType, blueprintName, blueprintVersion, artifactPrefix)
+        }.returns(1)
+        runBlocking {
+            val result = templateResolutionService.deleteTemplates(blueprintName, blueprintVersion, artifactPrefix, resourceType, resourceId, null)
+            assertEquals(1, result)
+        }
+    }
+
+    @Test
+    fun deleteTemplatesResourceIdAndTypeLastN() {
+        every {
+            templateResolutionRepository.deleteTemplates(blueprintName, blueprintVersion, artifactPrefix, resourceType, resourceType, 1)
+        }.returns(1)
+        runBlocking {
+            val result = templateResolutionService.deleteTemplates(blueprintName, blueprintVersion, artifactPrefix, resourceType, resourceType, 1)
+            assertEquals(1, result)
+        }
+    }
 }
index 03ba347..49e0313 100644 (file)
@@ -255,4 +255,41 @@ open class TemplateController(private val templateResolutionService: TemplateRes
 
         ResponseEntity.ok().body(resultStored)
     }
+
+    @RequestMapping(
+        path = [""],
+        method = [RequestMethod.DELETE], produces = [MediaType.APPLICATION_JSON_VALUE]
+    )
+    @PreAuthorize("hasRole('USER')")
+    fun deleteTemplates(
+        @ApiParam(value = "Name of the CBA", required = true)
+        @RequestParam(value = "bpName", required = true) bpName: String,
+        @ApiParam(value = "Version of the CBA", required = true)
+        @RequestParam(value = "bpVersion", required = true) bpVersion: String,
+        @ApiParam(value = "Artifact name", required = true)
+        @RequestParam(value = "artifactName", required = true, defaultValue = "") artifactName: String,
+        @ApiParam(value = "Resolution Key associated with the template", required = false)
+        @RequestParam(value = "resolutionKey", required = false) resolutionKey: String?,
+        @ApiParam(value = "resourceType associated with the template, must be used with resourceId", required = false)
+        @RequestParam(value = "resourceType", required = false) resourceType: String?,
+        @ApiParam(value = "Resolution Key associated with the template, must be used with resourceType", required = false)
+        @RequestParam(value = "resourceId", required = false) resourceId: String?,
+        @ApiParam(value = "Only delete last N occurrences", required = false)
+        @RequestParam(value = "lastN", required = false) lastN: Int?
+    ) = runBlocking {
+        when {
+            resolutionKey?.isNotBlank() == true -> templateResolutionService.deleteTemplates(
+                bpName, bpVersion, artifactName, resolutionKey, lastN
+            )
+            resourceType?.isNotBlank() == true && resourceId?.isNotBlank() == true ->
+                templateResolutionService.deleteTemplates(
+                    bpName, bpVersion, artifactName, resourceType, resourceId, lastN
+                )
+            else -> throw httpProcessorException(
+                ErrorCatalogCodes.REQUEST_NOT_FOUND,
+                ResourceApiDomains.RESOURCE_API,
+                "Either use resolutionKey or resourceType + resourceId. Values cannot be blank"
+            )
+        }.let { ResponseEntity.ok().body(DeleteResponse(it)) }
+    }
 }