diff options
Diffstat (limited to 'ms')
4 files changed, 270 insertions, 2 deletions
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 1f0171f9f..ed9e6d1d6 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 @@ -116,6 +116,87 @@ class ResourceResolutionDBService(private val resourceResolutionRepository: Reso ) } + /** + * This returns the resolutions of first N 'occurrences'. + * + * @param blueprintName + * @param blueprintVersion + * @param artifactPrefix + * @param resolutionKey + * @param firstN + */ + suspend fun findFirstNOccurrences( + blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String, + firstN: Int + ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) { + + resourceResolutionRepository.findFirstNOccurrences( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix, + firstN + ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder()) + } + + /** + * This returns the resolutions of last N 'occurrences'. + * + * @param blueprintName + * @param blueprintVersion + * @param artifactPrefix + * @param resolutionKey + * @param lastN + */ + suspend fun findLastNOccurrences( + blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String, + lastN: Int + ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) { + + resourceResolutionRepository.findLastNOccurrences( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix, + lastN + ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder()) + } + + /** + * This returns the resolutions with 'occurrence' value between begin and end. + * + * @param blueprintName + * @param blueprintVersion + * @param artifactPrefix + * @param resolutionKey + * @param begin + * @param end + */ + suspend fun findOccurrencesWithinRange( + blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String, + begin: Int, + end: Int + ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) { + + resourceResolutionRepository.findOccurrencesWithinRange( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix, + begin, + end + ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder()) + } + suspend fun readWithResourceIdAndResourceType( blueprintName: String, blueprintVersion: String, 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 8513bda88..4b707b04e 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 @@ -37,7 +37,67 @@ interface ResourceResolutionRepository : JpaRepository<ResourceResolution, Strin ): ResourceResolution? @Query( - value = "SELECT max(occurrence) FROM RESOURCE_RESOLUTION WHERE resolution_key = :key AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion AND artifact_name = :artifactName ", + value = """ + SELECT * FROM RESOURCE_RESOLUTION WHERE resolution_key = :key + AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion + AND artifact_name = :artifactName AND occurrence <= :firstN + """, + nativeQuery = true + ) + fun findFirstNOccurrences( + @Param("key")key: String, + @Param("blueprintName")blueprintName: String, + @Param("blueprintVersion")blueprintVersion: String, + @Param("artifactName")artifactName: String, + @Param("firstN")begin: Int + ): List<ResourceResolution> + + @Query( + value = """ + SELECT * FROM RESOURCE_RESOLUTION WHERE resolution_key = :key + AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion + AND artifact_name = :artifactName + AND occurrence > ( + select max(occurrence) - :lastN from RESOURCE_RESOLUTION + WHERE resolution_key = :key AND blueprint_name = :blueprintName + AND blueprint_version = :blueprintVersion AND artifact_name = :artifactName + ) + ORDER BY occurrence DESC, creation_date DESC + """, + nativeQuery = true + ) + fun findLastNOccurrences( + @Param("key")key: String, + @Param("blueprintName")blueprintName: String, + @Param("blueprintVersion")blueprintVersion: String, + @Param("artifactName")artifactName: String, + @Param("lastN")begin: Int + ): List<ResourceResolution> + + @Query( + value = """ + SELECT * FROM RESOURCE_RESOLUTION WHERE resolution_key = :key + AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion + AND artifact_name = :artifactName AND occurrence BETWEEN :begin AND :end + ORDER BY occurrence DESC, creation_date DESC + """, + nativeQuery = true + ) + fun findOccurrencesWithinRange( + @Param("key")key: String, + @Param("blueprintName")blueprintName: String, + @Param("blueprintVersion")blueprintVersion: String, + @Param("artifactName")artifactName: String, + @Param("begin")begin: Int, + @Param("end")end: Int + ): List<ResourceResolution> + + @Query( + value = """ + SELECT max(occurrence) FROM RESOURCE_RESOLUTION WHERE resolution_key = :key + AND blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion + AND artifact_name = :artifactName + """, nativeQuery = true ) fun findMaxOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( @@ -48,7 +108,11 @@ interface ResourceResolutionRepository : JpaRepository<ResourceResolution, Strin ): Int? @Query( - value = "SELECT max(occurrence) FROM RESOURCE_RESOLUTION WHERE blueprint_name = :blueprintName AND blueprint_version = :blueprintVersion AND resource_id = :resourceId AND resource_type = :resourceType ", + value = """ + SELECT max(occurrence) FROM RESOURCE_RESOLUTION WHERE blueprint_name = :blueprintName + AND blueprint_version = :blueprintVersion AND resource_id = :resourceId + AND resource_type = :resourceType + """, nativeQuery = true ) fun findMaxOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType( diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt index 635ce0e38..8d4109fcf 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBServiceTest.kt @@ -187,6 +187,75 @@ open class ResourceResolutionDBServiceTest { } @Test + fun findFirstNOccurrencesTest() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findFirstNOccurrences( + any(), any(), any(), any(), 1 + ) + } returns list + runBlocking { + val res = + resourceResolutionDBService.findFirstNOccurrences( + blueprintName, blueprintVersion, artifactPrefix, resolutionKey, 1 + ) + assertEquals(false, res.isEmpty(), "find first N occurrences test failed") + assertEquals(1, res.size) + assertNotEquals(null, res[0]) + res[0]?.let { assertEquals(2, it.size) } + } + } + + @Test + fun findLastNOccurrencesTest() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findLastNOccurrences( + any(), any(), any(), any(), 1 + ) + } returns list + runBlocking { + val res = + resourceResolutionDBService.findLastNOccurrences( + blueprintName, blueprintVersion, artifactPrefix, resolutionKey, 1 + ) + assertEquals(false, res.isEmpty(), "find last N occurrences test failed") + assertEquals(1, res.size) + assertNotEquals(null, res[0]) + res[0]?.let { assertEquals(2, it.size) } + } + } + + @Test + fun findOccurrencesWithinRangeTest() { + props[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] = occurrence + val rr1 = ResourceResolution() + val rr2 = ResourceResolution() + val list = listOf(rr1, rr2) + every { + resourceResolutionRepository.findOccurrencesWithinRange( + any(), any(), any(), any(), 0, 1 + ) + } returns list + runBlocking { + val res = + resourceResolutionDBService.findOccurrencesWithinRange( + blueprintName, blueprintVersion, artifactPrefix, resolutionKey, 0, 1 + ) + assertEquals(false, res.isEmpty(), "find occurrences within a range test failed") + assertEquals(1, res.size) + assertNotEquals(null, res[0]) + res[0]?.let { assertEquals(2, it.size) } + } + } + + @Test fun readWithResourceIdAndResourceTypeTest() { val rr1 = ResourceResolution() val rr2 = ResourceResolution() diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt index 4a2a55930..d2b7ac368 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt @@ -112,6 +112,60 @@ open class ResourceController(private var resourceResolutionDBService: ResourceR } @RequestMapping( + path = ["/occurrences"], + method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE] + ) + @ApiOperation( + value = "Get the map of resolved resources with 'occurrence' as the keys to the resolved resources ", + notes = "With optional 'occurrence' options, subset of stored resolved resources can be retrieved " + + "using the blueprint name, blueprint version, artifact name and the resolution-key.", + response = ResourceResolution::class, + responseContainer = "List", + produces = MediaType.APPLICATION_JSON_VALUE + ) + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun getOccurrences( + @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 for which to retrieve a resolved resource.", required = true) + @RequestParam(value = "artifactName", required = true, defaultValue = "") artifactName: String, + @ApiParam(value = "Resolution Key associated with the resolution.", required = true) + @RequestParam(value = "resolutionKey", required = true, defaultValue = "") resolutionKey: String, + @ApiParam(value = "Number of earlier N occurrences of the resolutions.", required = false) + @RequestParam(value = "firstN", required = false) firstN: Int?, + @ApiParam(value = "Number of latest N occurrences of the resolutions.", required = false) + @RequestParam(value = "lastN", required = false) lastN: Int?, + @ApiParam(value = "For Range option - 'begin' is the start occurrence of range of the resolutions.", required = false) + @RequestParam(value = "begin", required = false) begin: Int?, + @ApiParam(value = "For Range option - 'end' is the end occurrence of the range of the resolutions.", required = false) + @RequestParam(value = "end", required = false) end: Int? + ): ResponseEntity<Map<Int, List<ResourceResolution>>> = runBlocking { + when { + artifactName.isEmpty() -> "'artifactName' must not be empty" + resolutionKey.isEmpty() -> "'resolutionKey' must not be empty" + // Optional options - validate if provided + (firstN != null && lastN != null) -> "Retrieve occurrences using either 'firstN' OR 'lastN' option" + ((firstN != null || lastN != null) && (begin != null || end != null)) -> "Retrieve occurrences using either 'firstN' OR 'lastN' OR 'begin' and 'end' option." + ((begin != null && end == null) || (begin == null && end != null)) -> " Retrieving occurrences within range - please provide both 'begin' and 'end' option" + else -> null + }?.let { throw httpProcessorException(ErrorCatalogCodes.REQUEST_NOT_FOUND, ResourceApiDomains.RESOURCE_API, it) } + + when { + firstN != null -> + resourceResolutionDBService.findFirstNOccurrences(bpName, bpVersion, artifactName, resolutionKey, firstN) + lastN != null -> + resourceResolutionDBService.findLastNOccurrences(bpName, bpVersion, artifactName, resolutionKey, lastN) + begin != null && end != null -> + resourceResolutionDBService.findOccurrencesWithinRange(bpName, bpVersion, artifactName, resolutionKey, begin, end) + else -> + resourceResolutionDBService.readWithResolutionKey(bpName, bpVersion, artifactName, resolutionKey).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder()) + }.let { result -> ResponseEntity.ok().body(result) } + } + + @RequestMapping( method = [RequestMethod.DELETE], produces = [MediaType.APPLICATION_JSON_VALUE] ) @ApiOperation( |