Add blueprint enrichment api 31/82831/2
authorMuthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
Wed, 20 Mar 2019 16:43:58 +0000 (12:43 -0400)
committerMuthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
Fri, 22 Mar 2019 15:11:04 +0000 (11:11 -0400)
Change-Id: Idf0f05a9462418a72c716d6b96c121cf223b56eb
Issue-ID: CCSDK-1173
Signed-off-by: Muthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctions.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/FileExtensionFunctions.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtils.kt
ms/controllerblueprints/modules/pom.xml
ms/controllerblueprints/modules/service/pom.xml
ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/BlueprintModelController.kt
ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/handler/BluePrintModelHandler.kt
ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt
ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/mock/MockFilePart.kt [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtilsTest.kt [new file with mode: 0644]

index 462935d..121dfa2 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,8 +21,6 @@ import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.node.*
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
 import org.slf4j.helpers.MessageFormatter
-import java.io.File
-import java.io.InputStream
 import kotlin.reflect.KClass
 
 /**
@@ -160,9 +159,3 @@ fun returnNotEmptyOrThrow(value: String?, lazyMessage: () -> Any): String {
     }
 }
 
-fun InputStream.toFile(path: String): File {
-    val file = File(path)
-    file.outputStream().use { this.copyTo(it) }
-    return file
-}
-
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/FileExtensionFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/FileExtensionFunctions.kt
new file mode 100644 (file)
index 0000000..a433a31
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.controllerblueprints.core
+
+import org.apache.commons.io.FileUtils
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintArchiveUtils
+import java.io.File
+import java.io.InputStream
+import java.nio.file.Paths
+
+fun InputStream.toFile(path: String): File {
+    val file = File(path)
+    file.outputStream().use { this.copyTo(it) }
+    return file
+}
+
+fun File.reCreateDirs(): File {
+    if (this.exists()) {
+        this.deleteRecursively()
+    }
+    // this.mkdirs()
+    FileUtils.forceMkdir(this)
+    check(this.exists()) {
+        throw BluePrintException("failed to re create dir(${this.absolutePath})")
+    }
+    return this
+}
+
+fun File.compress(targetZipFileName: String): File {
+    return this.compress(Paths.get(targetZipFileName).toFile())
+}
+
+/**
+ * Compress the current Dir to the target zip file and return the target zip file
+ */
+fun File.compress(targetZipFile: File): File {
+    BluePrintArchiveUtils.compress(this, targetZipFile, true)
+    return targetZipFile
+}
+
+fun File.deCompress(targetFileName: String): File {
+    return this.deCompress(Paths.get(targetFileName).toFile())
+}
+
+/**
+ * De-Compress the current zip file to the target file and return the target file
+ */
+fun File.deCompress(targetFile: File): File {
+    BluePrintArchiveUtils.deCompress(this, targetFile.path)
+    return targetFile
+}
+
+fun deleteDir(path: String) {
+    Paths.get(path).toFile().deleteRecursively()
+}
+
+
+fun normalizedFile(path: String): File {
+    return Paths.get(path).toFile().normalize()
+}
index f6bde1c..1176f71 100755 (executable)
 
 package org.onap.ccsdk.apps.controllerblueprints.core.utils
 
-import kotlinx.coroutines.async
-import kotlinx.coroutines.runBlocking
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
 import org.apache.commons.io.IOUtils
-import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
 import org.slf4j.LoggerFactory
 import java.io.BufferedInputStream
@@ -52,7 +49,7 @@ class BluePrintArchiveUtils {
                     recurseFiles(source, source, it, absolute)
                 }
             } catch (e: Exception) {
-                log.error("Fail to compress folder($source) to path(${destination.path}", e)
+                log.error("Fail to compress folder($source) to path(${destination.path})", e)
                 return false
             }
             return true
index c34a769..ce11d97 100644 (file)
@@ -21,7 +21,6 @@ package org.onap.ccsdk.apps.controllerblueprints.core.utils
 import com.att.eelf.configuration.EELFLogger
 import com.att.eelf.configuration.EELFManager
 import com.fasterxml.jackson.databind.JsonNode
-import org.apache.commons.io.FileUtils
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.apps.controllerblueprints.core.asJsonPrimitive
 import org.onap.ccsdk.apps.controllerblueprints.core.data.ToscaMetaData
@@ -31,6 +30,7 @@ import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeSer
 import org.onap.ccsdk.apps.controllerblueprints.core.service.DefaultBluePrintRuntimeService
 import java.io.File
 import java.nio.charset.Charset
+import java.nio.file.Paths
 import java.util.*
 
 class BluePrintMetadataUtils {
@@ -73,7 +73,7 @@ class BluePrintMetadataUtils {
 
         fun toscaMetaDataFromMetaFile(metaFilePath: String): ToscaMetaData {
             val toscaMetaData = ToscaMetaData()
-            val lines: MutableList<String> = FileUtils.readLines(File(metaFilePath), Charset.defaultCharset())
+            val lines = Paths.get(metaFilePath).toFile().readLines(Charset.defaultCharset())
             lines.forEach { line ->
                 if (line.contains(":")) {
                     val keyValue = line.split(":")
@@ -118,8 +118,8 @@ class BluePrintMetadataUtils {
         fun getBluePrintRuntime(id: String, blueprintBasePath: String, executionContext: MutableMap<String, JsonNode>): BluePrintRuntimeService<MutableMap<String, JsonNode>> {
             val bluePrintContext: BluePrintContext = getBluePrintContext(blueprintBasePath)
             val bluePrintRuntimeService = DefaultBluePrintRuntimeService(id, bluePrintContext)
-            executionContext.forEach{
-                bluePrintRuntimeService.put(it.key,it.value)
+            executionContext.forEach {
+                bluePrintRuntimeService.put(it.key, it.value)
             }
 
             bluePrintRuntimeService.setExecutionContext(executionContext)
index 9275921..8263f88 100644 (file)
@@ -15,7 +15,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId>
         <module>service</module>
     </modules>
 
+    <dependencies>
+        <!-- Test Dependencies -->
+        <dependency>
+            <groupId>io.mockk</groupId>
+            <artifactId>mockk</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-test-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains.kotlinx</groupId>
+            <artifactId>kotlinx-coroutines-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.projectreactor</groupId>
+            <artifactId>reactor-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
     <build>
         <plugins>
             <plugin>
index 7ca7e0d..cb2cf6a 100644 (file)
@@ -16,7 +16,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId>
     </properties>
 
     <dependencies>
+        <dependency>
+            <groupId>org.jetbrains.kotlinx</groupId>
+            <artifactId>kotlinx-coroutines-reactor</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId>
             <artifactId>db-resources</artifactId>
             <groupId>org.mariadb.jdbc</groupId>
             <artifactId>mariadb-java-client</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-api-mockito2</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.jetbrains.kotlin</groupId>
-            <artifactId>kotlin-test-junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.projectreactor</groupId>
-            <artifactId>reactor-test</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 </project>
index 60c07ad..d6ce286 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.onap.ccsdk.apps.controllerblueprints.service.controller
 
+import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
 import org.onap.ccsdk.apps.controllerblueprints.service.domain.BlueprintModelSearch
 import org.onap.ccsdk.apps.controllerblueprints.service.handler.BluePrintModelHandler
@@ -86,6 +87,14 @@ open class BlueprintModelController(private val bluePrintModelHandler: BluePrint
         return this.bluePrintModelHandler.downloadBlueprintModelFile(id)
     }
 
+    @PostMapping("/enrich", produces = [MediaType.APPLICATION_JSON_VALUE], consumes = [MediaType
+            .MULTIPART_FORM_DATA_VALUE])
+    @ResponseBody
+    @Throws(BluePrintException::class)
+    fun enrichBlueprint(@RequestPart("file") file: FilePart): ResponseEntity<Resource> = runBlocking {
+        bluePrintModelHandler.enrichBlueprint(file)
+    }
+
     @PutMapping("/publish/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
     @ResponseBody
     @Throws(BluePrintException::class)
index 907566c..4239abb 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  * Modifications Copyright © 2019 Bell Canada.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +23,7 @@ import org.onap.ccsdk.apps.controllerblueprints.core.common.ApplicationConstants
 import org.onap.ccsdk.apps.controllerblueprints.core.config.BluePrintLoadConfiguration
 import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode
 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintCatalogService
+import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintEnhancerService
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintFileUtils
 import org.onap.ccsdk.apps.controllerblueprints.service.domain.BlueprintModel
 import org.onap.ccsdk.apps.controllerblueprints.service.domain.BlueprintModelSearch
@@ -38,7 +40,9 @@ import org.springframework.http.codec.multipart.FilePart
 import org.springframework.stereotype.Service
 import org.springframework.transaction.annotation.Transactional
 import reactor.core.publisher.Mono
+import java.io.File
 import java.io.IOException
+import java.util.*
 
 /**
  * BlueprintModelHandler Purpose: Handler service to handle the request from BlurPrintModelRest
@@ -48,10 +52,12 @@ import java.io.IOException
  */
 
 @Service
-open class BluePrintModelHandler(private val bluePrintCatalogService: BluePrintCatalogService, private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
+open class BluePrintModelHandler(private val bluePrintCatalogService: BluePrintCatalogService,
+                                 private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
                                  private val blueprintModelSearchRepository: ControllerBlueprintModelSearchRepository,
                                  private val blueprintModelRepository: ControllerBlueprintModelRepository,
-                                 private val blueprintModelContentRepository: ControllerBlueprintModelContentRepository) {
+                                 private val blueprintModelContentRepository: ControllerBlueprintModelContentRepository,
+                                 private val bluePrintEnhancerService: BluePrintEnhancerService) {
 
     /**
      * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
@@ -275,6 +281,40 @@ open class BluePrintModelHandler(private val bluePrintCatalogService: BluePrintC
         }
     }
 
+    /**
+     * This is a CBA enrichBlueprint method
+     * Save the Zip File in archive location and extract the cba content.
+     * Populate the Enhancement Location
+     * Enhance the CBA content
+     * Compress the Enhanced Content
+     * Return back the the compressed content back to the caller.
+     *
+     * @param filePart filePart
+     * @return ResponseEntity<Resource>
+     * @throws BluePrintException BluePrintException
+     */
+    @Throws(BluePrintException::class)
+    open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity<Resource> {
+        val enhanceId = UUID.randomUUID().toString()
+        val blueprintArchive = bluePrintLoadConfiguration.blueprintArchivePath.plus(File.separator).plus(enhanceId)
+        val blueprintEnrichmentDir = bluePrintLoadConfiguration.blueprintEnrichmentPath.plus(File.separator).plus(enhanceId)
+
+        try {
+            BluePrintEnhancerUtils.decompressFilePart(filePart, blueprintArchive, blueprintEnrichmentDir)
+
+            // Enhance the Blue Prints
+            bluePrintEnhancerService.enhance(blueprintEnrichmentDir)
+
+            return BluePrintEnhancerUtils.compressToFilePart(blueprintEnrichmentDir, blueprintArchive)
+
+        } catch (e: IOException) {
+            throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
+                    String.format("I/O Error while uploading the CBA file: %s", e.message), e)
+        } finally {
+            BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintEnrichmentDir)
+        }
+    }
+
     companion object {
 
         private const val BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%s) from repo"
index 5e715f7..02140eb 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  * Modifications Copyright © 2019 Bell Canada.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.ccsdk.apps.controllerblueprints.service.utils
 
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.reactive.awaitSingle
+import kotlinx.coroutines.withContext
+import org.apache.commons.io.FileUtils
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
-import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactType
-import org.onap.ccsdk.apps.controllerblueprints.core.data.DataType
-import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode
-import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeType
-import org.onap.ccsdk.apps.controllerblueprints.core.data.RelationshipType
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*
+import org.onap.ccsdk.apps.controllerblueprints.core.deCompress
 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintRepoService
+import org.onap.ccsdk.apps.controllerblueprints.core.reCreateDirs
 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintArchiveUtils
+import org.springframework.core.io.ByteArrayResource
+import org.springframework.core.io.Resource
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
 import org.springframework.http.codec.multipart.FilePart
 import org.springframework.util.StringUtils
 import reactor.core.publisher.Mono
 import java.io.File
 import java.io.IOException
 import java.nio.file.Path
+import java.nio.file.Paths
 import java.util.*
 
 
@@ -47,7 +57,7 @@ class BluePrintEnhancerUtils {
         }
 
         fun populateRelationshipType(bluePrintContext: BluePrintContext, bluePrintRepoService: BluePrintRepoService,
-                             relationshipName: String): RelationshipType {
+                                     relationshipName: String): RelationshipType {
 
             val relationshipType = bluePrintContext.serviceTemplate.relationshipTypes?.get(relationshipName)
                     ?: bluePrintRepoService.getRelationshipType(relationshipName)
@@ -77,6 +87,47 @@ class BluePrintEnhancerUtils {
             return artifactType
         }
 
+        suspend fun copyFromFilePart(filePart: FilePart, targetFile: File): File {
+            // Delete the Directory
+            targetFile.deleteRecursively()
+            return filePart.transferTo(targetFile)
+                    .thenReturn(targetFile)
+                    .awaitSingle()
+        }
+
+        suspend fun decompressFilePart(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
+            //Recreate the Base Directories
+            Paths.get(archiveDir).toFile().reCreateDirs()
+            Paths.get(enhanceDir).toFile().reCreateDirs()
+
+            val filePartFile = Paths.get(archiveDir, "cba.zip").toFile()
+            // Copy the File Part to ZIP
+            copyFromFilePart(filePart, filePartFile)
+            val deCompressFileName = Paths.get(enhanceDir).toUri().path
+            return filePartFile.deCompress(deCompressFileName)
+        }
+
+        suspend fun compressToFilePart(enhanceDir: String, archiveDir: String): ResponseEntity<Resource> {
+            val compressedFile = Paths.get(archiveDir, "enhanced-cba.zip").toFile()
+            BluePrintArchiveUtils.compress(Paths.get(enhanceDir).toFile(), compressedFile, true)
+            return prepareResourceEntity(compressedFile.name, compressedFile.readBytes())
+        }
+
+        suspend fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity<Resource> {
+            return ResponseEntity.ok()
+                    .contentType(MediaType.parseMediaType("text/plain"))
+                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$fileName\"")
+                    .body(ByteArrayResource(file))
+        }
+
+        suspend fun cleanEnhancer(archiveLocation: String, enhancementLocation: String) = withContext(Dispatchers.Default) {
+            val enrichDir = File(enhancementLocation)
+            FileUtils.forceDeleteOnExit(enrichDir)
+
+            val archiveDir = File(archiveLocation)
+            FileUtils.forceDeleteOnExit(archiveDir)
+        }
+
         /**
          * This is a saveCBAFile method
          * take a [FilePart], transfer it to disk using a Flux of FilePart and return a [Mono] representing the CBA file name
diff --git a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/mock/MockFilePart.kt b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/mock/MockFilePart.kt
new file mode 100644 (file)
index 0000000..60420aa
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.controllerblueprints.service.controller.mock
+
+import org.apache.commons.io.FilenameUtils
+import org.slf4j.LoggerFactory
+import org.springframework.core.io.buffer.DataBuffer
+import org.springframework.http.HttpHeaders
+import org.springframework.http.codec.multipart.FilePart
+import org.springframework.util.FileCopyUtils
+import reactor.core.publisher.Flux
+import reactor.core.publisher.Mono
+import java.io.File
+import java.nio.file.Path
+
+class MockFilePart(private val fileName: String) : FilePart {
+    val log = LoggerFactory.getLogger(MockFilePart::class.java)!!
+    override fun content(): Flux<DataBuffer> {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun headers(): HttpHeaders {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun filename(): String {
+        return FilenameUtils.getName(fileName)
+    }
+
+    override fun name(): String {
+        return FilenameUtils.getBaseName(fileName)
+    }
+
+    override fun transferTo(path: Path): Mono<Void> {
+        log.info("Copying file($fileName to ${path}")
+        FileCopyUtils.copy(File(fileName), path.toFile())
+        return Mono.empty()
+    }
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtilsTest.kt b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtilsTest.kt
new file mode 100644 (file)
index 0000000..2e7ca2c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.controllerblueprints.service.utils
+
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.onap.ccsdk.apps.controllerblueprints.core.compress
+import org.onap.ccsdk.apps.controllerblueprints.core.deleteDir
+import org.onap.ccsdk.apps.controllerblueprints.core.normalizedFile
+import org.onap.ccsdk.apps.controllerblueprints.core.reCreateDirs
+import org.onap.ccsdk.apps.controllerblueprints.service.controller.mock.MockFilePart
+import java.nio.file.Paths
+import java.util.*
+import kotlin.test.assertTrue
+
+class BluePrintEnhancerUtilsTest {
+
+    private val blueprintDir = "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
+    private val blueprintArchivePath: String = "./target/blueprints/archive"
+    private val blueprintEnrichmentPath: String = "./target/blueprints/enrichment"
+    private var zipBlueprintFileName = Paths.get(blueprintArchivePath, "test.zip").toFile().normalize().absolutePath
+
+    @Before
+    @Throws(Exception::class)
+    fun setUp() {
+        val archiveDir = normalizedFile(blueprintArchivePath).reCreateDirs()
+        assertTrue(archiveDir.exists(), "failed to create archiveDir(${archiveDir.absolutePath}")
+        val enhancerDir = normalizedFile(blueprintEnrichmentPath).reCreateDirs()
+        assertTrue(enhancerDir.exists(), "failed to create enhancerDir(${enhancerDir.absolutePath}")
+        val blueprintFile = Paths.get(blueprintDir).toFile().normalize()
+        val testZipFile = blueprintFile.compress(zipBlueprintFileName)
+        assertTrue(testZipFile.exists(), "Failed to create blueprint test zip(${testZipFile.absolutePath}")
+    }
+
+    @After
+    @Throws(Exception::class)
+    fun tearDown() {
+        deleteDir(blueprintArchivePath)
+        deleteDir(blueprintEnrichmentPath)
+    }
+
+    @Test
+    fun testDecompressFilePart() {
+        val filePart = MockFilePart(zipBlueprintFileName)
+
+        runBlocking {
+            val enhanceId = UUID.randomUUID().toString()
+            val blueprintArchiveLocation = "$blueprintArchivePath/$enhanceId"
+            val blueprintEnrichmentLocation = "$blueprintEnrichmentPath/$enhanceId"
+            BluePrintEnhancerUtils.decompressFilePart(filePart, blueprintArchiveLocation, blueprintEnrichmentLocation)
+            BluePrintEnhancerUtils.compressToFilePart(blueprintEnrichmentLocation, blueprintArchiveLocation)
+        }
+    }
+}
+