2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2019 Bell Canada.
4 * Modifications Copyright © 2019 IBM.
5 * Modifications Copyright © 2019 Orange.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler
22 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModel
23 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch
24 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelContentRepository
25 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelRepository
26 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelSearchRepository
27 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.BootstrapRequest
28 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.DesignerApiDomains
29 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowData
30 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowSpecRequest
31 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowSpecResponse
32 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowsResponse
33 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.load.BluePrintDatabaseLoadService
34 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils.BluePrintEnhancerUtils
35 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
36 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
37 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
38 import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
39 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
40 import org.onap.ccsdk.cds.controllerblueprints.core.deleteNBDir
41 import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException
42 import org.onap.ccsdk.cds.controllerblueprints.core.data.Workflow
43 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
44 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService
45 import org.onap.ccsdk.cds.controllerblueprints.core.logger
46 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
47 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName
48 import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache
49 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
50 import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage
51 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils
52 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
53 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
54 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
55 import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes
56 import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault
57 import org.onap.ccsdk.cds.error.catalog.core.utils.errorMessageOrDefault
58 import org.springframework.core.io.ByteArrayResource
59 import org.springframework.core.io.Resource
60 import org.springframework.data.domain.Page
61 import org.springframework.data.domain.PageRequest
62 import org.springframework.data.domain.Pageable
63 import org.springframework.http.HttpHeaders
64 import org.springframework.http.MediaType
65 import org.springframework.http.ResponseEntity
66 import org.springframework.http.codec.multipart.FilePart
67 import org.springframework.stereotype.Service
68 import org.springframework.transaction.annotation.Transactional
70 import java.io.IOException
74 * BlueprintModelHandler Purpose: Handler service to handle the request from BlurPrintModelRest
76 * @author Brinda Santh
81 open class BluePrintModelHandler(
82 private val bluePrintDatabaseLoadService: BluePrintDatabaseLoadService,
83 private val blueprintsProcessorCatalogService: BluePrintCatalogService,
84 private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
85 private val blueprintModelSearchRepository: BlueprintModelSearchRepository,
86 private val blueprintModelRepository: BlueprintModelRepository,
87 private val blueprintModelContentRepository: BlueprintModelContentRepository,
88 private val bluePrintEnhancerService: BluePrintEnhancerService
91 private val log = logger(BluePrintModelHandler::class)
93 open suspend fun bootstrapBlueprint(bootstrapRequest: BootstrapRequest) {
95 "Bootstrap request with type load(${bootstrapRequest.loadModelType}), " +
96 "resource dictionary load(${bootstrapRequest.loadResourceDictionary}) and " +
97 "cba load(${bootstrapRequest.loadCBA})"
99 if (bootstrapRequest.loadModelType) {
100 bluePrintDatabaseLoadService.initModelTypes()
102 if (bootstrapRequest.loadResourceDictionary) {
103 bluePrintDatabaseLoadService.initResourceDictionary()
105 if (bootstrapRequest.loadCBA) {
106 bluePrintDatabaseLoadService.initBluePrintCatalog()
110 @Throws(BluePrintException::class)
111 private suspend fun getBlueprintCtxByNameAndVersion(blueprintName: String, version: String): BluePrintContext {
112 val basePath = blueprintsProcessorCatalogService.getFromDatabase(blueprintName, version)
113 log.info("blueprint base path $basePath for blueprint: $blueprintName version:$version")
114 return BluePrintMetadataUtils.getBluePrintContext(basePath.toString())
117 @Throws(BluePrintException::class)
119 * Try to get workflows cached from the BLUEPRINT_MODEL table first,
120 * failing that, load the CBA from the filesystem and extract workflows.
121 * The second case is possible during update scenario - current CDS DB already contains desired CBAs and reupload
124 open suspend fun getWorkflowsFromRepository(name: String, version: String): Map<String, Workflow> {
125 var workflowsFromCache: Map<String, Workflow>
127 workflowsFromCache = blueprintModelRepository.findByArtifactNameAndArtifactVersion(name, version)?.workflows!!
128 if (workflowsFromCache.isEmpty()) {
129 log.info("findByArtifactNameAndArtifactVersion did not return list of workflows for blueprintName:($name) version:($version), falling back to loading CBA from filesystem.")
130 workflowsFromCache = getBlueprintCtxByNameAndVersion(name, version).workflows()!!
131 // TODO: does it make sense to update the BLUEPRINT_MODEL workflows in this case or just wait for CBA reupload?
133 } catch (e: Exception) {
134 throw BluePrintException("Failed to get workflows from DB cache or by reading CBA", e)
136 return workflowsFromCache
139 // lookup workflows list from field.
140 open suspend fun getWorkflowNamesFromRepository(name: String, version: String): Set<String> {
141 return getWorkflowsFromRepository(name, version).keys
144 @Throws(BluePrintException::class)
145 open suspend fun prepareWorkFlowSpec(req: WorkFlowSpecRequest): WorkFlowSpecResponse {
146 val basePath = blueprintsProcessorCatalogService.getFromDatabase(req.blueprintName, req.version)
147 log.info("blueprint base path $basePath")
149 val blueprintContext = BluePrintMetadataUtils.getBluePrintContext(basePath.toString())
150 val workFlow = blueprintContext.workflowByName(req.workflowName)
152 val wfRes = WorkFlowSpecResponse()
153 wfRes.blueprintName = req.blueprintName
154 wfRes.version = req.version
156 val workFlowData = WorkFlowData()
157 workFlowData.workFlowName = req.workflowName
158 workFlowData.inputs = workFlow.inputs
159 workFlowData.outputs = workFlow.outputs
161 if (workFlow.inputs != null) {
162 for ((k, v) in workFlow.inputs!!) {
163 addPropertyInfo(k, v, blueprintContext, wfRes)
167 if (workFlow.outputs != null) {
168 for ((k, v) in workFlow.outputs!!) {
169 addPropertyInfo(k, v, blueprintContext, wfRes)
173 wfRes.workFlowData = workFlowData
177 private fun addPropertyInfo(propName: String, prop: PropertyDefinition, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
178 updatePropertyInfo(propName, prop, ctx, res)
179 addDataType(prop.type, ctx, res)
180 if (prop.entrySchema != null && prop.entrySchema!!.type != null) {
181 addDataType(prop.entrySchema!!.type, ctx, res)
185 private fun updatePropertyInfo(name: String, prop: PropertyDefinition, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
186 if (prop.inputparam == null || prop.inputparam == false) {
187 var workflow = ctx.workflowByName(res.workFlowData.workFlowName)
188 for ((k, v) in workflow.steps!!) {
189 var arts = ctx.nodeTemplateArtifacts(v.target!!)
191 for ((k, v) in arts.entries!!) {
192 if (v.type == "artifact-mapping-resource") {
193 val file: String = v.file
194 val completePath = ctx.rootPath.plus(File.separator).plus(file)
195 val resourceAssignment = JacksonUtils.getListFromFile(completePath, ResourceAssignment::class.java)
196 for (res in resourceAssignment) {
197 if (res.name == name && res.inputParameter) {
198 prop.inputparam = true
209 private fun addDataType(name: String, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
210 var data = ctx.dataTypeByName(name)
212 res.dataTypes?.put(name, data)
213 addParentDataType(data, ctx, res)
217 private fun addParentDataType(data: DataType, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
218 if (data.properties != null) {
219 for ((k, v) in data.properties!!) {
220 addPropertyInfo(k, v, ctx, res)
225 // wrap CBA workflows list in WorkflowsResponse object
226 @Throws(BluePrintException::class)
227 open suspend fun getWorkflowNames(name: String, version: String): WorkFlowsResponse {
228 var workflows = getWorkflowsFromRepository(name, version)
229 if (workflows == null) throw httpProcessorException(
230 ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
231 "Failed to find workflows list for blueprint: ($name) version: ($version) from filesystem."
234 var res = WorkFlowsResponse()
235 res.blueprintName = name
236 res.version = version
237 res.workflows = workflows.keys.toMutableSet()
242 * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
244 * @return List<BlueprintModelSearch> list of the controller blueprint archives
245 </BlueprintModelSearch> */
246 open fun allBlueprintModel(): List<BlueprintModelSearch> {
247 return blueprintModelSearchRepository.findAll()
251 * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
253 * @return List<BlueprintModelSearch> list of the controller blueprint archives
254 </BlueprintModelSearch> */
255 open fun allBlueprintModel(pageRequest: Pageable): Page<BlueprintModelSearch> {
256 return blueprintModelSearchRepository.findAll(pageRequest)
260 * This is a saveBlueprintModel method
262 * @param filePart filePart
263 * @return Mono<BlueprintModelSearch>
264 * @throws BluePrintException BluePrintException
265 </BlueprintModelSearch> */
266 @Throws(BluePrintException::class)
267 open suspend fun saveBlueprintModel(filePart: FilePart): BlueprintModelSearch {
269 return upload(filePart, false)
270 } catch (e: IOException) {
271 log.error("saveBlueprintModel fails ${e.message}", e)
272 throw httpProcessorException(
273 ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
274 "Error in Save CBA: ${e.message}", e.errorCauseOrDefault()
280 * This is a searchBlueprintModels method
283 * @return List<BlueprintModelSearch>
284 </BlueprintModelSearch> */
285 open fun searchBlueprintModels(tags: String): List<BlueprintModelSearch> {
286 return blueprintModelSearchRepository.findByTagsContainingIgnoreCase(tags)
290 * This is a getBlueprintModelSearchByNameAndVersion method
293 * @param version version
294 * @return BlueprintModelSearch
295 * @throws BluePrintException BluePrintException
297 @Throws(BluePrintException::class)
298 open fun getBlueprintModelSearchByNameAndVersion(name: String, version: String): BlueprintModelSearch? {
299 return blueprintModelSearchRepository.findByArtifactNameAndArtifactVersion(name, version)
300 /*?: throw BluePrintException(
301 ErrorCode.RESOURCE_NOT_FOUND.value,
302 String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)
307 * This is a downloadBlueprintModelFileByNameAndVersion method to download a Blueprint by Name and Version
310 * @param version version
311 * @return ResponseEntity<Resource>
312 * @throws BluePrintException BluePrintException
314 @Throws(BluePrintException::class)
315 open fun downloadBlueprintModelFileByNameAndVersion(
318 ): ResponseEntity<Resource> {
320 val archiveByteArray = download(name, version)
321 val fileName = "${name}_$version.zip"
322 return prepareResourceEntity(fileName, archiveByteArray)
323 } catch (e: BluePrintProcessorException) {
324 e.http(ErrorCatalogCodes.RESOURCE_NOT_FOUND)
325 val errorMsg = "Error while downloading the CBA file by Blueprint Name ($name) and Version ($version)."
326 throw e.updateErrorMessage(
327 DesignerApiDomains.DESIGNER_API, errorMsg,
328 "Wrong resource definition or resolution failed."
334 * This is a downloadBlueprintModelFile method to find the target file to download and return a file resource
336 * @return ResponseEntity<Resource>
337 * @throws BluePrintException BluePrintException
339 @Throws(BluePrintException::class)
340 open fun downloadBlueprintModelFile(id: String): ResponseEntity<Resource> {
341 val blueprintModel: BlueprintModel
343 blueprintModel = getBlueprintModel(id)
344 } catch (e: BluePrintException) {
345 throw httpProcessorException(
346 ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
347 "Error while downloading the CBA file: couldn't get blueprint modelby ID ($id)",
348 e.errorCauseOrDefault()
352 val fileName = "${blueprintModel.artifactName}_${blueprintModel.artifactVersion}.zip"
353 val file = blueprintModel.blueprintModelContent?.content
354 ?: throw httpProcessorException(
355 ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
356 "Error while downloading the CBA file: couldn't get model content"
358 return prepareResourceEntity(fileName, file)
362 * @return ResponseEntity<Resource>
364 private fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity<Resource> {
365 return ResponseEntity.ok()
366 .contentType(MediaType.parseMediaType("text/plain"))
367 .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$fileName\"")
368 .body(ByteArrayResource(file))
372 * This is a getBlueprintModel method
375 * @return BlueprintModel
376 * @throws BluePrintException BluePrintException
378 @Throws(BluePrintException::class)
379 open fun getBlueprintModel(id: String): BlueprintModel {
380 val blueprintModel: BlueprintModel
381 val dbBlueprintModel = blueprintModelRepository.findById(id)
382 if (dbBlueprintModel.isPresent) {
383 blueprintModel = dbBlueprintModel.get()
385 val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
386 throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg)
388 return blueprintModel
392 * This is a getBlueprintModelByNameAndVersion method
395 * @param version version
396 * @return BlueprintModel
397 * @throws BluePrintException BluePrintException
399 @Throws(BluePrintException::class)
400 open fun getBlueprintModelByNameAndVersion(name: String, version: String): BlueprintModel {
401 val blueprintModel = blueprintModelRepository
402 .findByArtifactNameAndArtifactVersion(name, version)
403 if (blueprintModel != null) {
404 return blueprintModel
406 val msg = String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)
407 throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg)
412 * This is a getBlueprintModelSearch method
415 * @return BlueprintModelSearch
416 * @throws BluePrintException BluePrintException
418 @Throws(BluePrintException::class)
419 open fun getBlueprintModelSearch(id: String): BlueprintModelSearch {
420 return blueprintModelSearchRepository.findById(id)
421 ?: throw httpProcessorException(
422 ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
423 String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
428 * This is a searchBluePrintModelsByKeyWord method to retrieve specific BlueprintModel in Database
429 * where keyword equals updatedBy or tags or artifcat name or artifcat version or artifact type
430 * @author Shaaban Ebrahim
433 * @return List<BlueprintModelSearch> list of the controller blueprint
434 </BlueprintModelSearch> */
435 open fun searchBluePrintModelsByKeyWord(keyWord: String): List<BlueprintModelSearch> {
436 return blueprintModelSearchRepository.findByUpdatedByOrTagsOrOrArtifactNameOrOrArtifactVersionOrArtifactType(
437 keyWord, keyWord, keyWord, keyWord, keyWord
442 * This is a searchBluePrintModelsByKeyWordPagebale method to retrieve specific BlueprintModel in Database
443 * where keyword equals updatedBy or tags or artifcat name or artifcat version or artifact type and pageable
444 * @author Shaaban Ebrahim
447 * @return List<BlueprintModelSearch> list of the controller blueprint
448 </BlueprintModelSearch> */
449 open fun searchBluePrintModelsByKeyWordPaged(keyWord: String, pageRequest: PageRequest): Page<BlueprintModelSearch> {
450 return blueprintModelSearchRepository.findByUpdatedByContainingIgnoreCaseOrTagsContainingIgnoreCaseOrArtifactNameContainingIgnoreCaseOrArtifactVersionContainingIgnoreCaseOrArtifactTypeContainingIgnoreCase(
461 * This is a deleteBlueprintModel method
464 * @throws BluePrintException BluePrintException
467 @Throws(BluePrintException::class)
468 open fun deleteBlueprintModel(id: String) {
469 val dbBlueprintModel = blueprintModelRepository.findById(id)
470 if (dbBlueprintModel.isPresent) {
471 blueprintModelContentRepository.deleteByBlueprintModel(dbBlueprintModel.get())
472 blueprintModelRepository.delete(dbBlueprintModel.get())
474 val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
475 throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg)
479 open suspend fun deleteBlueprintModel(name: String, version: String) {
480 blueprintsProcessorCatalogService.deleteFromDatabase(name, version)
484 * This is a CBA enrichBlueprint method
485 * Save the Zip File in archive location and extract the cba content.
486 * Populate the Enhancement Location
487 * Enhance the CBA content
488 * Compress the Enhanced Content
489 * Return back the the compressed content back to the caller.
491 * @param filePart filePart
492 * @return ResponseEntity<Resource>
493 * @throws BluePrintException BluePrintException
495 @Throws(BluePrintException::class)
496 open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity<Resource> {
498 val enhancedByteArray = enrichBlueprintFileSource(filePart)
499 return BluePrintEnhancerUtils.prepareResourceEntity("enhanced-cba.zip", enhancedByteArray)
500 } catch (e: BluePrintProcessorException) {
501 e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
502 val errorMsg = "Error while enhancing the CBA package."
503 throw e.updateErrorMessage(
504 DesignerApiDomains.DESIGNER_API, errorMsg,
505 "Wrong CBA file provided, please verify and enrich Again."
507 } catch (e: Exception) {
508 throw httpProcessorException(
509 ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
510 "EnrichBlueprint: ${e.message}", e.errorCauseOrDefault()
516 * This is a publishBlueprintModel method to change the status published to YES
517 * NOTE: this method is meant for enriched blueprints only.
519 * @param filePart filePart
520 * @return BlueprintModelSearch
521 * @throws BluePrintException BluePrintException
523 @Throws(BluePrintException::class)
524 open suspend fun publishBlueprint(filePart: FilePart): BlueprintModelSearch {
526 return upload(filePart, true)
527 } catch (e: BluePrintProcessorException) {
528 e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
529 val errorMsg = "Error in Publishing CBA."
530 throw e.updateErrorMessage(
531 DesignerApiDomains.DESIGNER_API, errorMsg,
532 "Wrong CBA provided, please verify and enrich your CBA."
534 } catch (e: Exception) {
535 throw httpProcessorException(
536 ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
537 "Error in Publishing CBA: ${e.message}", e.errorCauseOrDefault()
543 * Enrich and publish the blueprint.
544 * NOTE: this method is meant for the unenriched vs publishBlueprint(filePart)
545 * which is used for enriched blueprints.
547 * @param filePart filePart
548 * @return BlueprintModelSearch
549 * @throws BluePrintException BluePrintException
551 @Throws(BluePrintException::class)
552 open suspend fun enrichAndPublishBlueprint(filePart: FilePart): BlueprintModelSearch {
554 val enhancedByteArray = enrichBlueprintFileSource(filePart)
555 return upload(enhancedByteArray, true)
556 } catch (e: BluePrintProcessorException) {
557 val errorMsg = "Error while enhancing and uploading the CBA package."
558 log.error(errorMsg, e)
559 e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
560 throw e.updateErrorMessage(
561 DesignerApiDomains.DESIGNER_API, errorMsg,
562 "Wrong CBA file provided, please verify the source CBA."
564 } catch (e: Exception) {
565 log.error("Error enriching/uploading CBA", e)
566 throw httpProcessorException(
567 ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
568 "EnrichBlueprint: ${e.message}", e.errorCauseOrDefault()
573 /** Common CBA Save and Publish function for RestController and GRPC Handler, the [fileSource] may be
574 * byteArray or File Part type.*/
575 open suspend fun upload(fileSource: Any, validate: Boolean): BlueprintModelSearch {
576 val saveId = UUID.randomUUID().toString()
577 val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, saveId)
578 val blueprintWorking = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, saveId)
580 val compressedFile = normalizedFile(blueprintArchive, "cba.zip")
582 is FilePart -> BluePrintEnhancerUtils.filePartAsFile(fileSource, compressedFile)
583 is ByteArray -> BluePrintEnhancerUtils.byteArrayAsFile(fileSource, compressedFile)
585 // Save the Copied file to Database
586 val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(saveId, compressedFile, validate)
588 return blueprintModelSearchRepository.findById(blueprintId)
589 ?: throw httpProcessorException(
590 ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
591 String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId)
593 } catch (e: BluePrintException) {
594 e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
595 val errorMsg = "Error in Upload CBA."
596 throw e.updateErrorMessage(
597 DesignerApiDomains.DESIGNER_API, errorMsg,
598 "Wrong enriched CBA."
600 } catch (e: IOException) {
601 throw httpProcessorException(
602 ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
603 "Error in Upload CBA: ${e.errorMessageOrDefault()}", e.errorCauseOrDefault()
606 // Clean blueprint script cache
607 val cacheKey = BluePrintFileUtils
608 .compileCacheKey(normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, saveId))
609 BluePrintCompileCache.cleanClassLoader(cacheKey)
610 deleteNBDir(blueprintArchive)
611 deleteNBDir(blueprintWorking)
615 /** Common CBA download function for RestController and GRPC Handler, the [fileSource] may be
616 * byteArray or File Part type.*/
617 open fun download(name: String, version: String): ByteArray {
619 val blueprintModel = getBlueprintModelByNameAndVersion(name, version)
620 return blueprintModel.blueprintModelContent?.content
621 ?: throw httpProcessorException(
622 ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
623 "Error while downloading the CBA file: couldn't get model content"
625 } catch (e: BluePrintException) {
626 e.http(ErrorCatalogCodes.RESOURCE_NOT_FOUND)
627 val errorMsg = "Fail to get Blueprint Model content."
628 throw e.updateErrorMessage(
629 DesignerApiDomains.DESIGNER_API, errorMsg,
630 "Wrong name and version was provide."
635 /** Common CBA Enrich function for RestController and GRPC Handler, the [fileSource] may be
636 * byteArray or File Part type.*/
637 open suspend fun enrichBlueprintFileSource(fileSource: Any): ByteArray {
638 val enhanceId = UUID.randomUUID().toString()
639 val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, enhanceId)
640 val blueprintWorkingDir = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, enhanceId)
644 BluePrintEnhancerUtils
645 .copyFilePartToEnhanceDir(fileSource, blueprintArchive, blueprintWorkingDir)
647 BluePrintEnhancerUtils
648 .copyByteArrayToEnhanceDir(fileSource, blueprintArchive, blueprintWorkingDir)
649 } // Enhance the Blue Prints
650 bluePrintEnhancerService.enhance(blueprintWorkingDir)
652 return BluePrintEnhancerUtils.compressEnhanceDirAndReturnByteArray(blueprintWorkingDir, blueprintArchive)
653 } catch (e: BluePrintException) {
654 e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
655 val errorMsg = "Fail Enriching the CBA."
656 throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg)
657 } catch (e: IOException) {
658 throw httpProcessorException(
659 ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
660 "Error while Enriching the CBA file.", e.errorCauseOrDefault()
663 BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
669 private const val BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%s) from repo"
670 private const val BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG = "failed to get blueprint model by name(%s)" + " and version(%s) from repo"