2 * Copyright (C) 2019 Bell Canada.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db
18 import kotlinx.coroutines.Dispatchers
19 import kotlinx.coroutines.withContext
20 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
21 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
22 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
23 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
24 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
25 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
26 import org.slf4j.LoggerFactory
27 import org.springframework.dao.EmptyResultDataAccessException
28 import org.springframework.stereotype.Service
29 import java.lang.IllegalArgumentException
33 class ResourceResolutionDBService(private val resourceResolutionRepository: ResourceResolutionRepository) {
35 private val log = LoggerFactory.getLogger(ResourceResolutionDBService::class.toString())
37 suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence(
38 bluePrintRuntimeService: BluePrintRuntimeService<*>,
41 artifactPrefix: String
42 ): List<ResourceResolution> {
44 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
46 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
47 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
49 resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKeyAndOccurrence(
56 } catch (e: EmptyResultDataAccessException) {
61 suspend fun findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
62 bluePrintRuntimeService: BluePrintRuntimeService<*>,
66 artifactPrefix: String
67 ): List<ResourceResolution> {
70 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
72 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
73 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
75 resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceIdAndResourceTypeAndOccurrence(
83 } catch (e: EmptyResultDataAccessException) {
88 suspend fun readValue(
89 blueprintName: String,
90 blueprintVersion: String,
91 artifactPrefix: String,
92 resolutionKey: String,
94 ): ResourceResolution? = withContext(Dispatchers.IO) {
96 resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName(
105 suspend fun readWithResolutionKey(
106 blueprintName: String,
107 blueprintVersion: String,
108 artifactPrefix: String,
109 resolutionKey: String
110 ): List<ResourceResolution> = withContext(Dispatchers.IO) {
112 resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
121 * This returns the resolutions of first N 'occurrences'.
123 * @param blueprintName
124 * @param blueprintVersion
125 * @param artifactPrefix
126 * @param resolutionKey
129 suspend fun findFirstNOccurrences(
130 blueprintName: String,
131 blueprintVersion: String,
132 artifactPrefix: String,
133 resolutionKey: String,
135 ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) {
137 resourceResolutionRepository.findFirstNOccurrences(
143 ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder())
147 * This returns the resolutions of last N 'occurrences'.
149 * @param blueprintName
150 * @param blueprintVersion
151 * @param artifactPrefix
152 * @param resolutionKey
155 suspend fun findLastNOccurrences(
156 blueprintName: String,
157 blueprintVersion: String,
158 artifactPrefix: String,
159 resolutionKey: String,
161 ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) {
163 resourceResolutionRepository.findLastNOccurrences(
169 ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder())
173 * This returns the resolutions of last N 'occurrences'.
175 * @param blueprintName
176 * @param blueprintVersion
177 * @param artifactPrefix
179 * @param resourceType
182 suspend fun findLastNOccurrences(
183 blueprintName: String,
184 blueprintVersion: String,
185 artifactPrefix: String,
187 resourceType: String,
189 ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) {
191 resourceResolutionRepository.findLastNOccurrences(
198 ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder())
202 * This returns the resolutions with 'occurrence' value between begin and end.
204 * @param blueprintName
205 * @param blueprintVersion
206 * @param artifactPrefix
207 * @param resolutionKey
211 suspend fun findOccurrencesWithinRange(
212 blueprintName: String,
213 blueprintVersion: String,
214 artifactPrefix: String,
215 resolutionKey: String,
218 ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) {
220 resourceResolutionRepository.findOccurrencesWithinRange(
227 ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder())
230 suspend fun readWithResourceIdAndResourceType(
231 blueprintName: String,
232 blueprintVersion: String,
235 ): List<ResourceResolution> =
236 withContext(Dispatchers.IO) {
238 resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
247 properties: Map<String, Any>,
248 bluePrintRuntimeService: BluePrintRuntimeService<*>,
249 artifactPrefix: String,
250 resourceAssignment: ResourceAssignment
251 ): ResourceResolution = withContext(Dispatchers.IO) {
253 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
255 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
256 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
258 val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String
259 val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
260 val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
261 val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
276 blueprintName: String,
277 blueprintVersion: String,
278 resolutionKey: String,
280 resourceType: String,
281 artifactPrefix: String,
282 resourceAssignment: ResourceAssignment,
284 ): ResourceResolution = withContext(Dispatchers.IO) {
286 val resourceResolution = ResourceResolution()
287 resourceResolution.id = UUID.randomUUID().toString()
288 resourceResolution.artifactName = artifactPrefix
289 resourceResolution.occurrence = occurrence
290 resourceResolution.blueprintVersion = blueprintVersion
291 resourceResolution.blueprintName = blueprintName
292 resourceResolution.resolutionKey = resolutionKey
293 resourceResolution.resourceType = resourceType
294 resourceResolution.resourceId = resourceId
295 resourceResolution.value = resourceAssignment.property?.value?.let {
296 if (BluePrintConstants.STATUS_SUCCESS == resourceAssignment.status)
297 JacksonUtils.getValue(it).toString()
300 resourceResolution.name = resourceAssignment.name
301 resourceResolution.dictionaryName = resourceAssignment.dictionaryName
302 resourceResolution.dictionaryVersion = resourceAssignment.version
303 resourceResolution.dictionarySource = resourceAssignment.dictionarySource
304 resourceResolution.status = resourceAssignment.status ?: BluePrintConstants.STATUS_FAILURE
307 resourceResolutionRepository.saveAndFlush(resourceResolution)
308 } catch (ex: Exception) {
309 throw BluePrintException("Failed to store resource resolution result.", ex)
314 * This method to deletes resources associated to a specific resolution-key
316 * @param blueprintName name of the CBA
317 * @param blueprintVersion version of the CBA
318 * @param artifactName name of the artifact
319 * @param resolutionKey value of the resolution-key
320 * @param lastNOccurrences number of occurrences to delete starting from the last,
321 * all occurrences will be deleted when null
323 * @return number of deleted rows
326 blueprintName: String,
327 blueprintVersion: String,
328 artifactName: String,
329 resolutionKey: String,
330 lastNOccurrences: Int?
331 ): Int = lastNOccurrences?.let {
332 if (lastNOccurrences < 0) {
333 throw IllegalArgumentException("last N occurrences must be a positive integer")
335 resourceResolutionRepository.deleteLastNOccurrences(
342 } ?: resourceResolutionRepository.deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKey(
350 * This method to deletes resources associated to a specific resourceType and resourceId
352 * @param blueprintName name of the CBA
353 * @param blueprintVersion version of the CBA
354 * @param artifactName name of the artifact
355 * @param resourceType value of the resourceType
356 * @param resourceId value of the resourceId
357 * @param lastNOccurrences number of occurrences to delete starting from the last,
358 * all occurrences will be deleted when null
360 * @return number of deleted rows
363 blueprintName: String,
364 blueprintVersion: String,
365 artifactName: String,
366 resourceType: String,
368 lastNOccurrences: Int?
369 ): Int = lastNOccurrences?.let {
370 if (lastNOccurrences < 0) {
371 throw IllegalArgumentException("last N occurrences must be a positive integer")
373 resourceResolutionRepository.deleteLastNOccurrences(
381 } ?: resourceResolutionRepository.deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceTypeAndResourceId(
389 suspend fun deleteResourceResolutionList(listResourceResolution: List<ResourceResolution>) = withContext(Dispatchers.IO) {
391 resourceResolutionRepository.deleteInBatch(listResourceResolution)
392 } catch (ex: Exception) {
393 throw BluePrintException("Failed to batch delete resource resolution", ex)
398 * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
399 * The 'occurrence' is used to persist new resource resolution in the DB.
401 * @param resolutionKey
402 * @param blueprintName
403 * @param blueprintVersion
404 * @param artifactPrefix
406 suspend fun findNextOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
407 resolutionKey: String,
408 blueprintName: String,
409 blueprintVersion: String,
410 artifactPrefix: String
411 ) = withContext(Dispatchers.IO) {
412 val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
418 maxOccurrence?.inc() ?: 1
422 * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
423 * The 'occurrence' is used to persist new resource resolution in the DB.
425 * @param blueprintName
426 * @param blueprintVersion
428 * @param resourceType
430 suspend fun findNextOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
431 blueprintName: String,
432 blueprintVersion: String,
435 ) = withContext(Dispatchers.IO) {
436 val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
442 maxOccurrence?.inc() ?: 1