2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2019 Bell Canada.
4 * Modifications Copyright © 2019 IBM.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler
21 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModel
22 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch
23 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelContentRepository
24 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelRepository
25 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelSearchRepository
26 import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils.BluePrintEnhancerUtils
27 import org.onap.ccsdk.cds.controllerblueprints.core.*
28 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
29 import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode
30 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
31 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService
32 import org.slf4j.LoggerFactory
33 import org.springframework.core.io.ByteArrayResource
34 import org.springframework.core.io.Resource
35 import org.springframework.http.HttpHeaders
36 import org.springframework.http.MediaType
37 import org.springframework.http.ResponseEntity
38 import org.springframework.http.codec.multipart.FilePart
39 import org.springframework.stereotype.Service
40 import org.springframework.transaction.annotation.Transactional
42 import java.io.IOException
46 * BlueprintModelHandler Purpose: Handler service to handle the request from BlurPrintModelRest
48 * @author Brinda Santh
53 open class BluePrintModelHandler(private val controllerBlueprintsCatalogService: BluePrintCatalogService,
54 private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
55 private val blueprintModelSearchRepository: BlueprintModelSearchRepository,
56 private val blueprintModelRepository: BlueprintModelRepository,
57 private val blueprintModelContentRepository: BlueprintModelContentRepository,
58 private val bluePrintEnhancerService: BluePrintEnhancerService) {
60 private val log = LoggerFactory.getLogger(BluePrintModelHandler::class.java)!!
63 * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
65 * @return List<BlueprintModelSearch> list of the controller blueprint archives
66 </BlueprintModelSearch> */
67 open fun allBlueprintModel(): List<BlueprintModelSearch> {
68 return blueprintModelSearchRepository.findAll()
72 * This is a saveBlueprintModel method
74 * @param filePart filePart
75 * @return Mono<BlueprintModelSearch>
76 * @throws BluePrintException BluePrintException
77 </BlueprintModelSearch> */
78 @Throws(BluePrintException::class)
79 open suspend fun saveBlueprintModel(filePart: FilePart): BlueprintModelSearch {
80 val saveId = UUID.randomUUID().toString()
81 val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, saveId)
84 normalizedFile(bluePrintLoadConfiguration.blueprintArchivePath, saveId).reCreateDirs()
85 val deCompressedFile = normalizedFile(blueprintArchive, "cba.zip")
86 // Copy the File Part to Local File
87 BluePrintEnhancerUtils.copyFromFilePart(filePart, deCompressedFile)
88 // Save the Copied file to Database
89 val blueprintId = controllerBlueprintsCatalogService.saveToDatabase(saveId, deCompressedFile, false)
90 // Check and Return the Saved File
91 val blueprintModelSearch = blueprintModelSearchRepository.findById(blueprintId)
92 ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
93 String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId))
95 log.info("Save($saveId) successful for blueprint(${blueprintModelSearch.artifactName}) " +
96 "version(${blueprintModelSearch.artifactVersion})")
97 return blueprintModelSearch
98 } catch (e: IOException) {
99 throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
100 "Error in Save CBA: ${e.message}", e)
102 deleteDir(blueprintArchive)
108 * This is a searchBlueprintModels method
111 * @return List<BlueprintModelSearch>
112 </BlueprintModelSearch> */
113 open fun searchBlueprintModels(tags: String): List<BlueprintModelSearch> {
114 return blueprintModelSearchRepository.findByTagsContainingIgnoreCase(tags)
118 * This is a getBlueprintModelSearchByNameAndVersion method
121 * @param version version
122 * @return BlueprintModelSearch
123 * @throws BluePrintException BluePrintException
125 @Throws(BluePrintException::class)
126 open fun getBlueprintModelSearchByNameAndVersion(name: String, version: String): BlueprintModelSearch {
127 return blueprintModelSearchRepository.findByArtifactNameAndArtifactVersion(name, version)
128 ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
129 String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version))
134 * This is a downloadBlueprintModelFileByNameAndVersion method to download a Blueprint by Name and Version
137 * @param version version
138 * @return ResponseEntity<Resource>
139 * @throws BluePrintException BluePrintException
141 @Throws(BluePrintException::class)
142 open fun downloadBlueprintModelFileByNameAndVersion(name: String,
143 version: String): ResponseEntity<Resource> {
144 val blueprintModel: BlueprintModel
146 blueprintModel = getBlueprintModelByNameAndVersion(name, version)
147 } catch (e: BluePrintException) {
148 throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
149 String.format("Error while " + "downloading the CBA file: %s", e.message), e)
152 val fileName = blueprintModel.id + ".zip"
153 val file = blueprintModel.blueprintModelContent?.content
154 ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
155 String.format("Error while downloading the CBA file: couldn't get model content"))
156 return prepareResourceEntity(fileName, file)
160 * This is a downloadBlueprintModelFile method to find the target file to download and return a file resource
162 * @return ResponseEntity<Resource>
163 * @throws BluePrintException BluePrintException
165 @Throws(BluePrintException::class)
166 open fun downloadBlueprintModelFile(id: String): ResponseEntity<Resource> {
167 val blueprintModel: BlueprintModel
169 blueprintModel = getBlueprintModel(id)
170 } catch (e: BluePrintException) {
171 throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, String.format("Error while " + "downloading the CBA file: %s", e.message), e)
174 val fileName = blueprintModel.id + ".zip"
175 val file = blueprintModel.blueprintModelContent?.content
176 ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
177 String.format("Error while downloading the CBA file: couldn't get model content"))
178 return prepareResourceEntity(fileName, file)
182 * @return ResponseEntity<Resource>
184 private fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity<Resource> {
185 return ResponseEntity.ok()
186 .contentType(MediaType.parseMediaType("text/plain"))
187 .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$fileName\"")
188 .body(ByteArrayResource(file))
192 * This is a getBlueprintModel method
195 * @return BlueprintModel
196 * @throws BluePrintException BluePrintException
198 @Throws(BluePrintException::class)
199 open fun getBlueprintModel(id: String): BlueprintModel {
200 val blueprintModel: BlueprintModel
201 val dbBlueprintModel = blueprintModelRepository.findById(id)
202 if (dbBlueprintModel.isPresent) {
203 blueprintModel = dbBlueprintModel.get()
205 val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
206 throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
208 return blueprintModel
212 * This is a getBlueprintModelByNameAndVersion method
215 * @param version version
216 * @return BlueprintModel
217 * @throws BluePrintException BluePrintException
219 @Throws(BluePrintException::class)
220 open fun getBlueprintModelByNameAndVersion(name: String, version: String): BlueprintModel {
221 val blueprintModel = blueprintModelRepository
222 .findByArtifactNameAndArtifactVersion(name, version)
223 if (blueprintModel != null) {
224 return blueprintModel
226 val msg = String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)
227 throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
232 * This is a getBlueprintModelSearch method
235 * @return BlueprintModelSearch
236 * @throws BluePrintException BluePrintException
238 @Throws(BluePrintException::class)
239 open fun getBlueprintModelSearch(id: String): BlueprintModelSearch {
240 return blueprintModelSearchRepository.findById(id)
241 ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
242 String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id))
246 * This is a deleteBlueprintModel method
249 * @throws BluePrintException BluePrintException
252 @Throws(BluePrintException::class)
253 open fun deleteBlueprintModel(id: String) {
254 val dbBlueprintModel = blueprintModelRepository.findById(id)
255 if (dbBlueprintModel != null && dbBlueprintModel.isPresent) {
256 blueprintModelContentRepository.deleteByBlueprintModel(dbBlueprintModel.get())
257 blueprintModelRepository.delete(dbBlueprintModel.get())
259 val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
260 throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
265 * This is a CBA enrichBlueprint method
266 * Save the Zip File in archive location and extract the cba content.
267 * Populate the Enhancement Location
268 * Enhance the CBA content
269 * Compress the Enhanced Content
270 * Return back the the compressed content back to the caller.
272 * @param filePart filePart
273 * @return ResponseEntity<Resource>
274 * @throws BluePrintException BluePrintException
276 @Throws(BluePrintException::class)
277 open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity<Resource> {
278 val enhanceId = UUID.randomUUID().toString()
279 val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, enhanceId)
280 val blueprintWorkingDir = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, enhanceId)
282 BluePrintEnhancerUtils.decompressFilePart(filePart, blueprintArchive, blueprintWorkingDir)
284 // Enhance the Blue Prints
285 bluePrintEnhancerService.enhance(blueprintWorkingDir)
287 return BluePrintEnhancerUtils.compressToFilePart(blueprintWorkingDir, blueprintArchive)
289 } catch (e: IOException) {
290 throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
291 "Error in Enriching CBA: ${e.message}", e)
293 BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
298 * This is a publishBlueprintModel method to change the status published to YES
300 * @param filePart filePart
301 * @return BlueprintModelSearch
302 * @throws BluePrintException BluePrintException
304 @Throws(BluePrintException::class)
305 open suspend fun publishBlueprint(filePart: FilePart): BlueprintModelSearch {
306 val publishId = UUID.randomUUID().toString()
307 val blueprintArchive = bluePrintLoadConfiguration.blueprintArchivePath.plus(File.separator).plus(publishId)
308 val blueprintWorkingDir = bluePrintLoadConfiguration.blueprintWorkingPath.plus(File.separator).plus(publishId)
310 val compressedFilePart = BluePrintEnhancerUtils
311 .extractCompressFilePart(filePart, blueprintArchive, blueprintWorkingDir)
313 val blueprintId = controllerBlueprintsCatalogService.saveToDatabase(publishId, compressedFilePart, true)
315 return blueprintModelSearchRepository.findById(blueprintId)
316 ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
317 String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId))
319 } catch (e: Exception) {
320 throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
321 "Error in Publishing CBA: ${e.message}", e)
323 BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
329 private const val BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%s) from repo"
330 private const val BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG = "failed to get blueprint model by name(%s)" + " and version(%s) from repo"