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.slf4j.LoggerFactory
25 import org.springframework.dao.DataIntegrityViolationException
26 import org.springframework.dao.EmptyResultDataAccessException
27 import org.springframework.stereotype.Service
28 import java.lang.IllegalArgumentException
32 class TemplateResolutionService(private val templateResolutionRepository: TemplateResolutionRepository) {
34 private val log = LoggerFactory.getLogger(TemplateResolutionService::class.toString())
36 suspend fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
37 bluePrintRuntimeService: BluePrintRuntimeService<*>,
38 artifactPrefix: String,
41 withContext(Dispatchers.IO) {
43 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
45 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
46 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
48 findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
56 suspend fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
57 blueprintName: String,
58 blueprintVersion: String,
59 artifactPrefix: String,
60 resolutionKey: String,
63 withContext(Dispatchers.IO) {
65 templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
71 )?.result ?: throw EmptyResultDataAccessException(1)
74 suspend fun findResolutionKeysByBlueprintNameAndBlueprintVersionAndArtifactName(
75 bluePrintRuntimeService: BluePrintRuntimeService<*>,
76 artifactPrefix: String,
79 withContext(Dispatchers.IO) {
81 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
83 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
84 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
86 templateResolutionRepository.findResolutionKeysByBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
91 ) ?: throw EmptyResultDataAccessException(1)
94 suspend fun findArtifactNamesAndResolutionKeysByBlueprintNameAndBlueprintVersion(
95 bluePrintRuntimeService: BluePrintRuntimeService<*>,
97 ): Map<String, List<String>> =
98 withContext(Dispatchers.IO) {
100 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
102 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
103 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
105 val resultList = templateResolutionRepository.findArtifactNamesAndResolutionKeysByBlueprintNameAndBlueprintVersionAndOccurrence(
109 ) ?: throw EmptyResultDataAccessException(1)
111 var resultMap: MutableMap<String, MutableList<String>> = mutableMapOf()
113 resultList.forEach { it ->
114 if (!resultMap.containsKey(it.getArtifactName())) {
115 resultMap[it.getArtifactName()] = mutableListOf(it.getResolutionKey())
117 resultMap[it.getArtifactName()]!!.add(it.getResolutionKey())
121 .mapValues { it.value.toList() }
125 suspend fun findByResoureIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(
126 blueprintName: String,
127 blueprintVersion: String,
128 artifactPrefix: String,
130 resourceType: String,
133 withContext(Dispatchers.IO) {
135 templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
146 properties: Map<String, Any>,
148 bluePrintRuntimeService: BluePrintRuntimeService<*>,
149 artifactPrefix: String
150 ): TemplateResolution = withContext(Dispatchers.IO) {
152 val metadata = bluePrintRuntimeService.bluePrintContext().metadata!!
154 val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!!
155 val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!!
156 val resolutionKey = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_KEY] as String
157 val resourceId = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] as String
158 val resourceType = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] as String
159 val occurrence = properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE] as Int
173 blueprintName: String,
174 blueprintVersion: String,
175 artifactPrefix: String,
178 resolutionKey: String = "",
179 resourceId: String = "",
180 resourceType: String = ""
181 ): TemplateResolution =
182 withContext(Dispatchers.IO) {
184 val resourceResolutionResult = TemplateResolution()
185 resourceResolutionResult.id = UUID.randomUUID().toString()
186 resourceResolutionResult.artifactName = artifactPrefix
187 resourceResolutionResult.blueprintVersion = blueprintVersion
188 resourceResolutionResult.blueprintName = blueprintName
189 resourceResolutionResult.resolutionKey = resolutionKey
190 resourceResolutionResult.resourceId = resourceId
191 resourceResolutionResult.resourceType = resourceType
192 resourceResolutionResult.result = template
193 resourceResolutionResult.occurrence = occurrence
195 // Overwrite template resolution-key of resourceId/resourceType already existant
196 if (resolutionKey.isNotEmpty()) {
197 templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
198 resolutionKey, blueprintName, blueprintVersion, artifactPrefix, occurrence
201 "Overwriting template resolution for blueprintName=($blueprintVersion), blueprintVersion=($blueprintName), " +
202 "artifactName=($artifactPrefix) and resolutionKey=($resolutionKey)"
204 templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
212 } else if (resourceId.isNotEmpty() && resourceType.isNotEmpty()) {
213 templateResolutionRepository.findByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
214 resourceId, resourceType, blueprintName, blueprintVersion, artifactPrefix, occurrence
217 "Overwriting template resolution for blueprintName=($blueprintVersion), blueprintVersion=($blueprintName), " +
218 "artifactName=($artifactPrefix), resourceId=($resourceId) and resourceType=($resourceType)"
220 templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactNameAndOccurrence(
232 "Writing out template_resolution result: bpName: $blueprintName bpVer $blueprintVersion resKey:$resolutionKey" +
233 " (resourceId: $resourceId resourceType: $resourceType) occurrence:$occurrence"
235 templateResolutionRepository.saveAndFlush(resourceResolutionResult)
236 } catch (ex: DataIntegrityViolationException) {
238 "Error writing out template_resolution result: bpName: $blueprintName bpVer $blueprintVersion resKey:$resolutionKey" +
239 " (resourceId: $resourceId resourceType: $resourceType) occurrence:$occurrence error: {}",
242 throw BluePrintException("Failed to store resource api result.", ex)
246 * This returns the templates of first N 'occurrences'.
248 * @param blueprintName
249 * @param blueprintVersion
250 * @param artifactPrefix
251 * @param resolutionKey
254 suspend fun findFirstNOccurrences(
255 blueprintName: String,
256 blueprintVersion: String,
257 artifactPrefix: String,
258 resolutionKey: String,
260 ): Map<Int, List<TemplateResolution>> = withContext(Dispatchers.IO) {
262 templateResolutionRepository.findFirstNOccurrences(
268 ).groupBy(TemplateResolution::occurrence).toSortedMap(reverseOrder())
272 * This returns the templates of last N 'occurrences'.
274 * @param blueprintName
275 * @param blueprintVersion
276 * @param artifactPrefix
277 * @param resolutionKey
280 suspend fun findLastNOccurrences(
281 blueprintName: String,
282 blueprintVersion: String,
283 artifactPrefix: String,
284 resolutionKey: String,
286 ): Map<Int, List<TemplateResolution>> = withContext(Dispatchers.IO) {
288 templateResolutionRepository.findLastNOccurrences(
294 ).groupBy(TemplateResolution::occurrence).toSortedMap(reverseOrder())
298 * This returns the templates with 'occurrence' value between begin and end.
300 * @param blueprintName
301 * @param blueprintVersion
302 * @param artifactPrefix
303 * @param resolutionKey
307 suspend fun findOccurrencesWithinRange(
308 blueprintName: String,
309 blueprintVersion: String,
310 artifactPrefix: String,
311 resolutionKey: String,
314 ): Map<Int, List<TemplateResolution>> = withContext(Dispatchers.IO) {
316 templateResolutionRepository.findOccurrencesWithinRange(
323 ).groupBy(TemplateResolution::occurrence).toSortedMap(reverseOrder())
326 suspend fun readWithResolutionKey(
327 blueprintName: String,
328 blueprintVersion: String,
329 artifactPrefix: String,
330 resolutionKey: String
331 ): List<TemplateResolution> = withContext(Dispatchers.IO) {
333 templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
341 suspend fun deleteTemplates(
342 blueprintName: String,
343 blueprintVersion: String,
344 artifactPrefix: String,
345 resolutionKey: String,
346 lastNOccurrences: Int?
347 ): Int = lastNOccurrences?.let {
348 if (lastNOccurrences < 0) {
349 throw IllegalArgumentException("last N occurrences must be a positive integer")
351 templateResolutionRepository.deleteTemplates(
358 } ?: templateResolutionRepository.deleteByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
365 suspend fun deleteTemplates(
366 blueprintName: String,
367 blueprintVersion: String,
368 artifactPrefix: String,
369 resourceType: String,
371 lastNOccurrences: Int?
372 ): Int = lastNOccurrences?.let {
373 if (lastNOccurrences < 0) {
374 throw IllegalArgumentException("last N occurrences must be a positive integer")
376 templateResolutionRepository.deleteTemplates(
384 } ?: templateResolutionRepository.deleteByResourceIdAndResourceTypeAndBlueprintNameAndBlueprintVersionAndArtifactName(