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