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.controllerblueprints.service.utils
21 import kotlinx.coroutines.Dispatchers
22 import kotlinx.coroutines.reactive.awaitSingle
23 import kotlinx.coroutines.withContext
24 import org.onap.ccsdk.cds.controllerblueprints.core.*
25 import org.onap.ccsdk.cds.controllerblueprints.core.data.*
26 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintRepoService
27 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
28 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintArchiveUtils
29 import org.springframework.core.io.ByteArrayResource
30 import org.springframework.core.io.Resource
31 import org.springframework.http.HttpHeaders
32 import org.springframework.http.MediaType
33 import org.springframework.http.ResponseEntity
34 import org.springframework.http.codec.multipart.FilePart
35 import org.springframework.util.StringUtils
36 import reactor.core.publisher.Mono
38 import java.io.IOException
39 import java.nio.file.Path
40 import java.nio.file.Paths
44 class BluePrintEnhancerUtils {
47 fun populateDataTypes(bluePrintContext: BluePrintContext, bluePrintRepoService: BluePrintRepoService,
48 dataTypeName: String): DataType {
49 val dataType = bluePrintContext.serviceTemplate.dataTypes?.get(dataTypeName)
50 ?: bluePrintRepoService.getDataType(dataTypeName)
51 ?: throw BluePrintException("couldn't get DataType($dataTypeName) from repo.")
52 bluePrintContext.serviceTemplate.dataTypes?.put(dataTypeName, dataType)
56 fun populateRelationshipType(bluePrintContext: BluePrintContext, bluePrintRepoService: BluePrintRepoService,
57 relationshipName: String): RelationshipType {
59 val relationshipType = bluePrintContext.serviceTemplate.relationshipTypes?.get(relationshipName)
60 ?: bluePrintRepoService.getRelationshipType(relationshipName)
61 ?: throw BluePrintException("couldn't get RelationshipType($relationshipName) from repo.")
62 bluePrintContext.serviceTemplate.relationshipTypes?.put(relationshipName, relationshipType)
63 return relationshipType
67 fun populateNodeType(bluePrintContext: BluePrintContext, bluePrintRepoService: BluePrintRepoService,
68 nodeTypeName: String): NodeType {
70 val nodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(nodeTypeName)
71 ?: bluePrintRepoService.getNodeType(nodeTypeName)
72 ?: throw BluePrintException("couldn't get NodeType($nodeTypeName) from repo.")
73 bluePrintContext.serviceTemplate.nodeTypes?.put(nodeTypeName, nodeType)
77 fun populateArtifactType(bluePrintContext: BluePrintContext, bluePrintRepoService: BluePrintRepoService,
78 artifactTypeName: String): ArtifactType {
80 val artifactType = bluePrintContext.serviceTemplate.artifactTypes?.get(artifactTypeName)
81 ?: bluePrintRepoService.getArtifactType(artifactTypeName)
82 ?: throw BluePrintException("couldn't get ArtifactType($artifactTypeName) from repo.")
83 bluePrintContext.serviceTemplate.artifactTypes?.put(artifactTypeName, artifactType)
87 private suspend fun copyFromFilePart(filePart: FilePart, targetFile: File): File {
88 // Delete the Directory
89 targetFile.deleteRecursively()
90 return filePart.transferTo(targetFile)
91 .thenReturn(targetFile)
95 suspend fun extractCompressFilePart(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
96 //Recreate the Base Directories
97 normalizedFile(archiveDir).reCreateDirs()
98 normalizedFile(enhanceDir).reCreateDirs()
99 val filePartFile = normalizedFile(archiveDir, "cba.zip")
100 // Copy the File Part to ZIP
101 return copyFromFilePart(filePart, filePartFile)
104 suspend fun decompressFilePart(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
105 val filePartFile = extractCompressFilePart(filePart, archiveDir, enhanceDir)
106 val deCompressFileName = normalizedPathName(enhanceDir)
107 return filePartFile.deCompress(deCompressFileName)
110 suspend fun compressToFilePart(enhanceDir: String, archiveDir: String): ResponseEntity<Resource> {
111 val compressedFile = normalizedFile(archiveDir, "enhanced-cba.zip")
112 BluePrintArchiveUtils.compress(Paths.get(enhanceDir).toFile(), compressedFile, true)
113 return prepareResourceEntity(compressedFile.name, compressedFile.readBytes())
116 suspend fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity<Resource> {
117 return ResponseEntity.ok()
118 .contentType(MediaType.parseMediaType("text/plain"))
119 .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$fileName\"")
120 .body(ByteArrayResource(file))
123 suspend fun cleanEnhancer(archiveLocation: String, enhancementLocation: String) = withContext(Dispatchers.Default) {
124 deleteDir(archiveLocation)
125 deleteDir(enhancementLocation)
129 * This is a saveCBAFile method
130 * take a [FilePart], transfer it to disk using a Flux of FilePart and return a [Mono] representing the CBA file name
132 * @param (filePart, targetDirectory) - the request part containing the file to be saved and the default directory where to save
133 * @return a [Mono] String representing the result of the operation
134 * @throws (BluePrintException, IOException) BluePrintException, IOException
136 @Throws(BluePrintException::class, IOException::class)
137 fun saveCBAFile(filePart: FilePart, targetDirectory: Path): Mono<String> {
139 // Normalize file name
140 val fileName = StringUtils.cleanPath(filePart.filename())
142 // Check if the file's extension is "CBA"
143 if (StringUtils.getFilenameExtension(fileName) != "zip") {
144 throw BluePrintException(ErrorCode.INVALID_FILE_EXTENSION.value, "Invalid file extension required ZIP")
147 // Change file name to match a pattern
148 val changedFileName = UUID.randomUUID().toString() + ".zip"
149 //String changedFileName = BluePrintFileUtils.Companion.getCBAGeneratedFileName(fileName, this.CBA_FILE_NAME_PATTERN);
151 // Copy file to the target location (Replacing existing file with the same name)
152 val targetLocation = targetDirectory.resolve(changedFileName)
154 // if a file with the same name already exists in a repository, delete and recreate it
155 val file = File(targetLocation.toString())
160 return filePart.transferTo(file).thenReturn(changedFileName)