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 with 'occurrence' value between begin and end.
175 * @param blueprintName
176 * @param blueprintVersion
177 * @param artifactPrefix
178 * @param resolutionKey
182 suspend fun findOccurrencesWithinRange(
183 blueprintName: String,
184 blueprintVersion: String,
185 artifactPrefix: String,
186 resolutionKey: String,
189 ): Map<Int, List<ResourceResolution>> = withContext(Dispatchers.IO) {
191 resourceResolutionRepository.findOccurrencesWithinRange(
198 ).groupBy(ResourceResolution::occurrence).toSortedMap(reverseOrder())
201 suspend fun readWithResourceIdAndResourceType(
202 blueprintName: String,
203 blueprintVersion: String,
206 ): List<ResourceResolution> =
207 withContext(Dispatchers.IO) {
209 resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
218 properties: Map<String, Any>,
219 bluePrintRuntimeService: BluePrintRuntimeService<*>,
220 artifactPrefix: String,
221 resourceAssignment: ResourceAssignment
222 ): ResourceResolution = withContext(Dispatchers.IO) {
224 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
226 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
227 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
229 val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String
230 val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
231 val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
232 val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
247 blueprintName: String,
248 blueprintVersion: String,
249 resolutionKey: String,
251 resourceType: String,
252 artifactPrefix: String,
253 resourceAssignment: ResourceAssignment,
255 ): ResourceResolution = withContext(Dispatchers.IO) {
257 val resourceResolution = ResourceResolution()
258 resourceResolution.id = UUID.randomUUID().toString()
259 resourceResolution.artifactName = artifactPrefix
260 resourceResolution.occurrence = occurrence
261 resourceResolution.blueprintVersion = blueprintVersion
262 resourceResolution.blueprintName = blueprintName
263 resourceResolution.resolutionKey = resolutionKey
264 resourceResolution.resourceType = resourceType
265 resourceResolution.resourceId = resourceId
266 resourceResolution.value = resourceAssignment.property?.value?.let {
267 if (BluePrintConstants.STATUS_SUCCESS == resourceAssignment.status)
268 JacksonUtils.getValue(it).toString()
271 resourceResolution.name = resourceAssignment.name
272 resourceResolution.dictionaryName = resourceAssignment.dictionaryName
273 resourceResolution.dictionaryVersion = resourceAssignment.version
274 resourceResolution.dictionarySource = resourceAssignment.dictionarySource
275 resourceResolution.status = resourceAssignment.status ?: BluePrintConstants.STATUS_FAILURE
278 resourceResolutionRepository.saveAndFlush(resourceResolution)
279 } catch (ex: Exception) {
280 throw BluePrintException("Failed to store resource resolution result.", ex)
285 * This method to deletes resources associated to a specific resolution-key
287 * @param blueprintName name of the CBA
288 * @param blueprintVersion version of the CBA
289 * @param artifactName name of the artifact
290 * @param resolutionKey value of the resolution-key
291 * @param lastNOccurrences number of occurrences to delete starting from the last,
292 * all occurrences will be deleted when null
294 * @return number of deleted rows
297 blueprintName: String,
298 blueprintVersion: String,
299 artifactName: String,
300 resolutionKey: String,
301 lastNOccurrences: Int?
302 ): Int = lastNOccurrences?.let {
303 if (lastNOccurrences < 0) {
304 throw IllegalArgumentException("last N occurrences must be a positive integer")
306 resourceResolutionRepository.deleteLastNOccurrences(
313 } ?: resourceResolutionRepository.deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResolutionKey(
321 * This method to deletes resources associated to a specific resourceType and resourceId
323 * @param blueprintName name of the CBA
324 * @param blueprintVersion version of the CBA
325 * @param artifactName name of the artifact
326 * @param resourceType value of the resourceType
327 * @param resourceId value of the resourceId
328 * @param lastNOccurrences number of occurrences to delete starting from the last,
329 * all occurrences will be deleted when null
331 * @return number of deleted rows
334 blueprintName: String,
335 blueprintVersion: String,
336 artifactName: String,
337 resourceType: String,
339 lastNOccurrences: Int?
340 ): Int = lastNOccurrences?.let {
341 if (lastNOccurrences < 0) {
342 throw IllegalArgumentException("last N occurrences must be a positive integer")
344 resourceResolutionRepository.deleteLastNOccurrences(
352 } ?: resourceResolutionRepository.deleteByBlueprintNameAndBlueprintVersionAndArtifactNameAndResourceTypeAndResourceId(
360 suspend fun deleteResourceResolutionList(listResourceResolution: List<ResourceResolution>) = withContext(Dispatchers.IO) {
362 resourceResolutionRepository.deleteInBatch(listResourceResolution)
363 } catch (ex: Exception) {
364 throw BluePrintException("Failed to batch delete resource resolution", ex)
369 * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
370 * The 'occurrence' is used to persist new resource resolution in the DB.
372 * @param resolutionKey
373 * @param blueprintName
374 * @param blueprintVersion
375 * @param artifactPrefix
377 suspend fun findNextOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
378 resolutionKey: String,
379 blueprintName: String,
380 blueprintVersion: String,
381 artifactPrefix: String
382 ) = withContext(Dispatchers.IO) {
383 val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
389 maxOccurrence?.inc() ?: 1
393 * This method returns the (highest occurrence + 1) of resource resolutions if present in DB, returns 1 otherwise.
394 * The 'occurrence' is used to persist new resource resolution in the DB.
396 * @param blueprintName
397 * @param blueprintVersion
399 * @param resourceType
401 suspend fun findNextOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
402 blueprintName: String,
403 blueprintVersion: String,
406 ) = withContext(Dispatchers.IO) {
407 val maxOccurrence = resourceResolutionRepository.findMaxOccurrenceByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
413 maxOccurrence?.inc() ?: 1