Merge "providing search packages functionalities"
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / inbounds / designer-api / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / designer / api / handler / BluePrintModelHandler.kt
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2019 Bell Canada.
4  * Modifications Copyright © 2019 IBM.
5  * Modifications Copyright © 2019 Orange.
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler
21
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.DesignerApiDomains
28 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.BootstrapRequest
29 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowSpecRequest
30 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowSpecResponse
31 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.WorkFlowData
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.logger
37 import org.onap.ccsdk.cds.controllerblueprints.core.httpProcessorException
38 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
39 import org.onap.ccsdk.cds.controllerblueprints.core.updateErrorMessage
40 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName
41 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
42 import org.onap.ccsdk.cds.controllerblueprints.core.deleteNBDir
43 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
44 import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
45 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
46 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
47 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService
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.utils.BluePrintFileUtils
51 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
52 import org.onap.ccsdk.cds.error.catalog.core.ErrorCatalogCodes
53 import org.onap.ccsdk.cds.error.catalog.core.utils.errorCauseOrDefault
54 import org.onap.ccsdk.cds.error.catalog.core.utils.errorMessageOrDefault
55 import org.springframework.core.io.ByteArrayResource
56 import org.springframework.core.io.Resource
57 import org.springframework.data.domain.Page
58 import org.springframework.data.domain.PageRequest
59 import org.springframework.data.domain.Pageable
60 import org.springframework.http.HttpHeaders
61 import org.springframework.http.MediaType
62 import org.springframework.http.ResponseEntity
63 import org.springframework.http.codec.multipart.FilePart
64 import org.springframework.stereotype.Service
65 import org.springframework.transaction.annotation.Transactional
66 import java.io.IOException
67 import java.util.UUID
68
69 /**
70  * BlueprintModelHandler Purpose: Handler service to handle the request from BlurPrintModelRest
71  *
72  * @author Brinda Santh
73  * @version 1.0
74  */
75
76 @Service
77 open class BluePrintModelHandler(
78     private val bluePrintDatabaseLoadService: BluePrintDatabaseLoadService,
79     private val blueprintsProcessorCatalogService: BluePrintCatalogService,
80     private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
81     private val blueprintModelSearchRepository: BlueprintModelSearchRepository,
82     private val blueprintModelRepository: BlueprintModelRepository,
83     private val blueprintModelContentRepository: BlueprintModelContentRepository,
84     private val bluePrintEnhancerService: BluePrintEnhancerService
85 ) {
86
87     private val log = logger(BluePrintModelHandler::class)
88
89     open suspend fun bootstrapBlueprint(bootstrapRequest: BootstrapRequest) {
90         log.info(
91             "Bootstrap request with type load(${bootstrapRequest.loadModelType}), " +
92                     "resource dictionary load(${bootstrapRequest.loadResourceDictionary}) and " +
93                     "cba load(${bootstrapRequest.loadCBA})"
94         )
95         if (bootstrapRequest.loadModelType) {
96             bluePrintDatabaseLoadService.initModelTypes()
97         }
98         if (bootstrapRequest.loadResourceDictionary) {
99             bluePrintDatabaseLoadService.initResourceDictionary()
100         }
101         if (bootstrapRequest.loadCBA) {
102             bluePrintDatabaseLoadService.initBluePrintCatalog()
103         }
104     }
105
106     @Throws(BluePrintException::class)
107     open suspend fun prepareWorkFlowSpec(req: WorkFlowSpecRequest):
108             WorkFlowSpecResponse {
109         val basePath = blueprintsProcessorCatalogService.getFromDatabase(req
110                 .blueprintName, req.version)
111         log.info("blueprint base path $basePath")
112
113         val blueprintContext = BluePrintMetadataUtils.getBluePrintContext(basePath.toString())
114         val workFlow = blueprintContext.workflowByName(req.workflowName)
115
116         val wfRes = WorkFlowSpecResponse()
117         wfRes.blueprintName = req.blueprintName
118         wfRes.version = req.version
119
120         val workFlowData = WorkFlowData()
121         workFlowData.workFlowName = req.workflowName
122         workFlowData.inputs = workFlow.inputs
123         workFlowData.outputs = workFlow.outputs
124
125         if (workFlow.inputs != null) {
126             for ((k, v) in workFlow.inputs!!) {
127                 addPropertyInfo(v, blueprintContext, wfRes)
128             }
129         }
130
131         if (workFlow.outputs != null) {
132             for ((k, v) in workFlow.outputs!!) {
133                 addPropertyInfo(v, blueprintContext, wfRes)
134             }
135         }
136
137         wfRes.workFlowData = workFlowData
138         return wfRes
139     }
140
141     private fun addPropertyInfo(prop: PropertyDefinition, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
142         addDataType(prop.type, ctx, res)
143         if (prop.entrySchema != null && prop.entrySchema!!.type != null) {
144             addDataType(prop.entrySchema!!.type, ctx, res)
145         }
146     }
147
148     private fun addDataType(name: String, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
149         var data = ctx.dataTypeByName(name)
150         if (data != null) {
151             res.dataTypes?.put(name, data)
152             addParentDataType(data, ctx, res)
153         }
154     }
155
156     private fun addParentDataType(data: DataType, ctx: BluePrintContext, res: WorkFlowSpecResponse) {
157         if (data.properties != null) {
158             for ((k, v) in data.properties!!) {
159                 addPropertyInfo(v, ctx, res)
160             }
161         }
162     }
163
164     @Throws(BluePrintException::class)
165     open suspend fun getWorkflowNames(name: String, version: String): WorkFlowsResponse {
166         val basePath = blueprintsProcessorCatalogService.getFromDatabase(
167                 name, version)
168         log.info("blueprint base path $basePath")
169
170         var res = WorkFlowsResponse()
171         res.blueprintName = name
172         res.version = version
173
174         val blueprintContext = BluePrintMetadataUtils.getBluePrintContext(
175                 basePath.toString())
176         if (blueprintContext.workflows() != null) {
177             res.workflows = blueprintContext.workflows()!!.keys
178         }
179         return res
180     }
181
182     /**
183      * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
184      *
185      * @return List<BlueprintModelSearch> list of the controller blueprint archives
186     </BlueprintModelSearch> */
187     open fun allBlueprintModel(): List<BlueprintModelSearch> {
188         return blueprintModelSearchRepository.findAll()
189     }
190
191     /**
192      * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
193      *
194      * @return List<BlueprintModelSearch> list of the controller blueprint archives
195     </BlueprintModelSearch> */
196     open fun allBlueprintModel(pageRequest: Pageable): Page<BlueprintModelSearch> {
197         return blueprintModelSearchRepository.findAll(pageRequest)
198     }
199
200     /**
201      * This is a saveBlueprintModel method
202      *
203      * @param filePart filePart
204      * @return Mono<BlueprintModelSearch>
205      * @throws BluePrintException BluePrintException
206     </BlueprintModelSearch> */
207     @Throws(BluePrintException::class)
208     open suspend fun saveBlueprintModel(filePart: FilePart): BlueprintModelSearch {
209         try {
210             return upload(filePart, false)
211         } catch (e: IOException) {
212             throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
213                     "Error in Save CBA: ${e.message}", e.errorCauseOrDefault())
214         }
215     }
216
217     /**
218      * This is a searchBlueprintModels method
219      *
220      * @param tags tags
221      * @return List<BlueprintModelSearch>
222     </BlueprintModelSearch> */
223     open fun searchBlueprintModels(tags: String): List<BlueprintModelSearch> {
224         return blueprintModelSearchRepository.findByTagsContainingIgnoreCase(tags)
225     }
226
227     /**
228      * This is a getBlueprintModelSearchByNameAndVersion method
229      *
230      * @param name name
231      * @param version version
232      * @return BlueprintModelSearch
233      * @throws BluePrintException BluePrintException
234      */
235     @Throws(BluePrintException::class)
236     open fun getBlueprintModelSearchByNameAndVersion(name: String, version: String): BlueprintModelSearch? {
237         return blueprintModelSearchRepository.findByArtifactNameAndArtifactVersion(name, version)
238             /*?: throw BluePrintException(
239                 ErrorCode.RESOURCE_NOT_FOUND.value,
240                 String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)
241             )*/
242     }
243
244     /**
245      * This is a downloadBlueprintModelFileByNameAndVersion method to download a Blueprint by Name and Version
246      *
247      * @param name name
248      * @param version version
249      * @return ResponseEntity<Resource>
250      * @throws BluePrintException BluePrintException
251     </Resource> */
252     @Throws(BluePrintException::class)
253     open fun downloadBlueprintModelFileByNameAndVersion(
254         name: String,
255         version: String
256     ): ResponseEntity<Resource> {
257         try {
258             val archiveByteArray = download(name, version)
259             val fileName = "${name}_$version.zip"
260             return prepareResourceEntity(fileName, archiveByteArray)
261         } catch (e: BluePrintProcessorException) {
262             e.http(ErrorCatalogCodes.RESOURCE_NOT_FOUND)
263             val errorMsg = "Error while downloading the CBA file by Blueprint Name ($name) and Version ($version)."
264             throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg,
265                     "Wrong resource definition or resolution failed.")
266         }
267     }
268
269     /**
270      * This is a downloadBlueprintModelFile method to find the target file to download and return a file resource
271      *
272      * @return ResponseEntity<Resource>
273      * @throws BluePrintException BluePrintException
274     </Resource> */
275     @Throws(BluePrintException::class)
276     open fun downloadBlueprintModelFile(id: String): ResponseEntity<Resource> {
277         val blueprintModel: BlueprintModel
278         try {
279             blueprintModel = getBlueprintModel(id)
280         } catch (e: BluePrintException) {
281             throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
282                     "Error while downloading the CBA file: couldn't get blueprint modelby ID ($id)",
283                     e.errorCauseOrDefault())
284         }
285
286         val fileName = "${blueprintModel.artifactName}_${blueprintModel.artifactVersion}.zip"
287         val file = blueprintModel.blueprintModelContent?.content
288             ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
289                     "Error while downloading the CBA file: couldn't get model content")
290         return prepareResourceEntity(fileName, file)
291     }
292
293     /**
294      * @return ResponseEntity<Resource>
295     </Resource> */
296     private fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity<Resource> {
297         return ResponseEntity.ok()
298             .contentType(MediaType.parseMediaType("text/plain"))
299             .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$fileName\"")
300             .body(ByteArrayResource(file))
301     }
302
303     /**
304      * This is a getBlueprintModel method
305      *
306      * @param id id
307      * @return BlueprintModel
308      * @throws BluePrintException BluePrintException
309      */
310     @Throws(BluePrintException::class)
311     open fun getBlueprintModel(id: String): BlueprintModel {
312         val blueprintModel: BlueprintModel
313         val dbBlueprintModel = blueprintModelRepository.findById(id)
314         if (dbBlueprintModel.isPresent) {
315             blueprintModel = dbBlueprintModel.get()
316         } else {
317             val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
318             throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg)
319         }
320         return blueprintModel
321     }
322
323     /**
324      * This is a getBlueprintModelByNameAndVersion method
325      *
326      * @param name name
327      * @param version version
328      * @return BlueprintModel
329      * @throws BluePrintException BluePrintException
330      */
331     @Throws(BluePrintException::class)
332     open fun getBlueprintModelByNameAndVersion(name: String, version: String): BlueprintModel {
333         val blueprintModel = blueprintModelRepository
334             .findByArtifactNameAndArtifactVersion(name, version)
335         if (blueprintModel != null) {
336             return blueprintModel
337         } else {
338             val msg = String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)
339             throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg)
340         }
341     }
342
343     /**
344      * This is a getBlueprintModelSearch method
345      *
346      * @param id id
347      * @return BlueprintModelSearch
348      * @throws BluePrintException BluePrintException
349      */
350     @Throws(BluePrintException::class)
351     open fun getBlueprintModelSearch(id: String): BlueprintModelSearch {
352         return blueprintModelSearchRepository.findById(id)
353             ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
354                     String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id))
355     }
356
357     /**
358      * This is a searchBluePrintModelsByKeyWord method to retrieve specific  BlueprintModel in Database
359      * where keyword equals updatedBy or tags or artifcat name or artifcat version or artifact type
360      * @author Shaaban Ebrahim
361      * @param keyWord
362      *
363      * @return List<BlueprintModelSearch> list of the controller blueprint
364     </BlueprintModelSearch> */
365     open fun searchBluePrintModelsByKeyWord(keyWord: String): List<BlueprintModelSearch> {
366         return blueprintModelSearchRepository.findByUpdatedByOrTagsOrOrArtifactNameOrOrArtifactVersionOrArtifactType(
367             keyWord, keyWord, keyWord, keyWord, keyWord
368         )
369     }
370
371     /**
372      * This is a searchBluePrintModelsByKeyWordPagebale method to retrieve specific  BlueprintModel in Database
373      * where keyword equals updatedBy or tags or artifcat name or artifcat version or artifact type and pageable
374      * @author Shaaban Ebrahim
375      * @param keyWord
376      *
377      * @return List<BlueprintModelSearch> list of the controller blueprint
378     </BlueprintModelSearch> */
379     open fun searchBluePrintModelsByKeyWordPaged(keyWord: String, pageRequest: PageRequest): Page<BlueprintModelSearch> {
380         return blueprintModelSearchRepository.findByUpdatedByContainingIgnoreCaseOrTagsContainingIgnoreCaseOrArtifactNameContainingIgnoreCaseOrArtifactVersionContainingIgnoreCaseOrArtifactTypeContainingIgnoreCase(
381             keyWord,
382             keyWord,
383             keyWord,
384             keyWord,
385             keyWord,
386             pageRequest
387         )
388     }
389
390     /**
391      * This is a deleteBlueprintModel method
392      *
393      * @param id id
394      * @throws BluePrintException BluePrintException
395      */
396     @Transactional
397     @Throws(BluePrintException::class)
398     open fun deleteBlueprintModel(id: String) {
399         val dbBlueprintModel = blueprintModelRepository.findById(id)
400         if (dbBlueprintModel.isPresent) {
401             blueprintModelContentRepository.deleteByBlueprintModel(dbBlueprintModel.get())
402             blueprintModelRepository.delete(dbBlueprintModel.get())
403         } else {
404             val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
405             throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API, msg)
406         }
407     }
408
409     open suspend fun deleteBlueprintModel(name: String, version: String) {
410         blueprintsProcessorCatalogService.deleteFromDatabase(name, version)
411     }
412
413     /**
414      * This is a CBA enrichBlueprint method
415      * Save the Zip File in archive location and extract the cba content.
416      * Populate the Enhancement Location
417      * Enhance the CBA content
418      * Compress the Enhanced Content
419      * Return back the the compressed content back to the caller.
420      *
421      * @param filePart filePart
422      * @return ResponseEntity<Resource>
423      * @throws BluePrintException BluePrintException
424      */
425     @Throws(BluePrintException::class)
426     open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity<Resource> {
427         try {
428             val enhancedByteArray = enrichBlueprintFileSource(filePart)
429             return BluePrintEnhancerUtils.prepareResourceEntity("enhanced-cba.zip", enhancedByteArray)
430         } catch (e: BluePrintProcessorException) {
431             e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
432             val errorMsg = "Error while enhancing the CBA package."
433             throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg,
434                     "Wrong CBA file provided, please verify and enrich Again.")
435         } catch (e: Exception) {
436             throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
437                     "EnrichBlueprint: ${e.message}", e.errorCauseOrDefault())
438         }
439     }
440
441     /**
442      * This is a publishBlueprintModel method to change the status published to YES
443      *
444      * @param filePart filePart
445      * @return BlueprintModelSearch
446      * @throws BluePrintException BluePrintException
447      */
448     @Throws(BluePrintException::class)
449     open suspend fun publishBlueprint(filePart: FilePart): BlueprintModelSearch {
450         try {
451             return upload(filePart, true)
452         } catch (e: BluePrintProcessorException) {
453             e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
454             val errorMsg = "Error in Publishing CBA."
455             throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg,
456                     "Wrong CBA provided, please verify and enrich your CBA.")
457         } catch (e: Exception) {
458             throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
459                     "Error in Publishing CBA: ${e.message}", e.errorCauseOrDefault())
460         }
461     }
462
463     /** Common CBA Save and Publish function for RestController and GRPC Handler, the [fileSource] may be
464      * byteArray or File Part type.*/
465     open suspend fun upload(fileSource: Any, validate: Boolean): BlueprintModelSearch {
466         val saveId = UUID.randomUUID().toString()
467         val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, saveId)
468         val blueprintWorking = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, saveId)
469         try {
470             val compressedFile = normalizedFile(blueprintArchive, "cba.zip")
471             when (fileSource) {
472                 is FilePart -> BluePrintEnhancerUtils.filePartAsFile(fileSource, compressedFile)
473                 is ByteArray -> BluePrintEnhancerUtils.byteArrayAsFile(fileSource, compressedFile)
474             }
475             // Save the Copied file to Database
476             val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(saveId, compressedFile, validate)
477
478             return blueprintModelSearchRepository.findById(blueprintId)
479                 ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
480                         String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId))
481         } catch (e: BluePrintException) {
482             e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
483             val errorMsg = "Error in Upload CBA."
484             throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg,
485                     "Wrong enriched CBA.")
486         } catch (e: IOException) {
487             throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
488                     "Error in Upload CBA: ${e.errorMessageOrDefault()}", e.errorCauseOrDefault())
489         } finally {
490             // Clean blueprint script cache
491             val cacheKey = BluePrintFileUtils
492                 .compileCacheKey(normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, saveId))
493             BluePrintCompileCache.cleanClassLoader(cacheKey)
494             deleteNBDir(blueprintArchive)
495             deleteNBDir(blueprintWorking)
496         }
497     }
498
499     /** Common CBA download function for RestController and GRPC Handler, the [fileSource] may be
500      * byteArray or File Part type.*/
501     open fun download(name: String, version: String): ByteArray {
502         try {
503             val blueprintModel = getBlueprintModelByNameAndVersion(name, version)
504             return blueprintModel.blueprintModelContent?.content
505                 ?: throw httpProcessorException(ErrorCatalogCodes.RESOURCE_NOT_FOUND, DesignerApiDomains.DESIGNER_API,
506                         "Error while downloading the CBA file: couldn't get model content")
507         } catch (e: BluePrintException) {
508             e.http(ErrorCatalogCodes.RESOURCE_NOT_FOUND)
509             val errorMsg = "Fail to get Blueprint Model content."
510             throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg,
511                     "Wrong name and version was provide.")
512         }
513     }
514
515     /** Common CBA Enrich function for RestController and GRPC Handler, the [fileSource] may be
516      * byteArray or File Part type.*/
517     open suspend fun enrichBlueprintFileSource(fileSource: Any): ByteArray {
518         val enhanceId = UUID.randomUUID().toString()
519         val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, enhanceId)
520         val blueprintWorkingDir = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, enhanceId)
521         try {
522             when (fileSource) {
523                 is FilePart -> BluePrintEnhancerUtils
524                     .copyFilePartToEnhanceDir(fileSource, blueprintArchive, blueprintWorkingDir)
525                 is ByteArray -> BluePrintEnhancerUtils
526                     .copyByteArrayToEnhanceDir(fileSource, blueprintArchive, blueprintWorkingDir)
527             } // Enhance the Blue Prints
528             bluePrintEnhancerService.enhance(blueprintWorkingDir)
529
530             return BluePrintEnhancerUtils.compressEnhanceDirAndReturnByteArray(blueprintWorkingDir, blueprintArchive)
531         } catch (e: BluePrintException) {
532             e.http(ErrorCatalogCodes.IO_FILE_INTERRUPT)
533             val errorMsg = "Fail Enriching the CBA."
534             throw e.updateErrorMessage(DesignerApiDomains.DESIGNER_API, errorMsg)
535         } catch (e: IOException) {
536             throw httpProcessorException(ErrorCatalogCodes.IO_FILE_INTERRUPT, DesignerApiDomains.DESIGNER_API,
537                     "Error while Enriching the CBA file.", e.errorCauseOrDefault())
538         } finally {
539             BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
540         }
541     }
542
543     companion object {
544
545         private const val BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%s) from repo"
546         private const val BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG = "failed to get blueprint model by name(%s)" + " and version(%s) from repo"
547     }
548 }