Implement GRPC enrich rpc. 76/95176/1
authorBrinda Santh <brindasanth@in.ibm.com>
Fri, 6 Sep 2019 16:35:39 +0000 (12:35 -0400)
committerBrinda Santh <brindasanth@in.ibm.com>
Fri, 6 Sep 2019 16:35:39 +0000 (12:35 -0400)
Change-Id: I51d3b93a1a48677339e371a8cec7d2fd63811140
Issue-ID: CCSDK-1682
Signed-off-by: Brinda Santh <brindasanth@in.ibm.com>
components/model-catalog/proto-definition/proto/BluePrintCommon.proto
ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandler.kt
ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/handler/BluePrintModelHandler.kt
ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/service/AutoResourceMappingService.kt [deleted file]
ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/utils/BluePrintEnhancerUtils.kt
ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintManagementGRPCHandlerTest.kt
ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt
ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/utils/BluePrintEnhancerUtilsTest.kt

index 5d1efbd..9b24c50 100644 (file)
@@ -24,7 +24,9 @@ message ActionIdentifiers {
 
 message Status {
   int32 code = 1;
+  // present only if message is failure
   string errorMessage = 2;
+  // This will be success or failure
   string message = 3;
   EventType eventType = 4;
   string timestamp = 5;
index b7badb5..c48f1dd 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api
 
+import com.google.protobuf.ByteString
 import io.grpc.StatusException
 import io.grpc.stub.StreamObserver
 import kotlinx.coroutines.runBlocking
+import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler.BluePrintModelHandler
 import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader
 import org.onap.ccsdk.cds.controllerblueprints.common.api.Status
-import org.onap.ccsdk.cds.controllerblueprints.core.*
-import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
-import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
-import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache
-import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.emptyTONull
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.currentTimestamp
 import org.onap.ccsdk.cds.controllerblueprints.management.api.*
 import org.slf4j.LoggerFactory
 import org.springframework.security.access.prepost.PreAuthorize
 import org.springframework.stereotype.Service
-import java.io.File
-import java.util.*
 
 @Service
-open class BluePrintManagementGRPCHandler(private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
-                                          private val blueprintsProcessorCatalogService: BluePrintCatalogService)
+open class BluePrintManagementGRPCHandler(private val bluePrintModelHandler: BluePrintModelHandler)
     : BluePrintManagementServiceGrpc.BluePrintManagementServiceImplBase() {
 
     private val log = LoggerFactory.getLogger(BluePrintManagementGRPCHandler::class.java)
@@ -46,30 +43,24 @@ open class BluePrintManagementGRPCHandler(private val bluePrintLoadConfiguration
     @PreAuthorize("hasRole('USER')")
     override fun uploadBlueprint(request: BluePrintUploadInput, responseObserver:
     StreamObserver<BluePrintManagementOutput>) {
-        runBlocking {
 
+        runBlocking {
             log.info("request(${request.commonHeader.requestId})")
-            val uploadId = UUID.randomUUID().toString()
-            val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, uploadId)
-            val blueprintWorking = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, uploadId)
             try {
-                val cbaFile = normalizedFile(blueprintArchive, "cba.zip")
-
-                saveToDisk(request, cbaFile)
-
+                /** Get the file byte array */
+                val byteArray = request.fileChunk.chunk.toByteArray()
+                /** Get the Upload Action */
                 val uploadAction = request.actionIdentifiers?.actionName.emptyTONull()
                         ?: UploadAction.DRAFT.toString()
 
                 when (uploadAction) {
                     UploadAction.DRAFT.toString() -> {
-                        val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(uploadId, cbaFile, false)
-                        responseObserver.onNext(successStatus("Successfully uploaded CBA($blueprintId)...",
-                                request.commonHeader))
+                        val blueprintModel = bluePrintModelHandler.upload(byteArray, false)
+                        responseObserver.onNext(successStatus(request.commonHeader))
                     }
                     UploadAction.PUBLISH.toString() -> {
-                        val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(uploadId, cbaFile, true)
-                        responseObserver.onNext(successStatus("Successfully uploaded CBA($blueprintId)...",
-                                request.commonHeader))
+                        val blueprintModel = bluePrintModelHandler.upload(byteArray, true)
+                        responseObserver.onNext(successStatus(request.commonHeader))
                     }
                     UploadAction.VALIDATE.toString() -> {
                         //TODO("Not Implemented")
@@ -77,21 +68,17 @@ open class BluePrintManagementGRPCHandler(private val bluePrintLoadConfiguration
                                 BluePrintProcessorException("Not Implemented")))
                     }
                     UploadAction.ENRICH.toString() -> {
-                        //TODO("Not Implemented")
-                        responseObserver.onError(failStatus("Not Implemented",
-                                BluePrintProcessorException("Not Implemented")))
+                        val enrichedByteArray = bluePrintModelHandler.enrichBlueprintFileSource(byteArray)
+                        responseObserver.onNext(enrichmentStatus(request.commonHeader, enrichedByteArray))
+                    }
+                    else -> {
+                        responseObserver.onError(failStatus("Upload action($uploadAction) not implemented",
+                                BluePrintProcessorException("Upload action($uploadAction) not implemented")))
                     }
                 }
                 responseObserver.onCompleted()
             } catch (e: Exception) {
                 responseObserver.onError(failStatus("request(${request.commonHeader.requestId}): Failed to upload CBA", e))
-            } finally {
-                // Clean blueprint script cache
-                val cacheKey = BluePrintFileUtils
-                        .compileCacheKey(normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, uploadId))
-                BluePrintCompileCache.cleanClassLoader(cacheKey)
-                deleteNBDir(blueprintArchive)
-                deleteNBDir(blueprintWorking)
             }
         }
     }
@@ -106,11 +93,9 @@ open class BluePrintManagementGRPCHandler(private val bluePrintLoadConfiguration
             val blueprint = "blueprint $blueprintName:$blueprintVersion"
 
             log.info("request(${request.commonHeader.requestId}): Received delete $blueprint")
-
-
             try {
-                blueprintsProcessorCatalogService.deleteFromDatabase(blueprintName, blueprintVersion)
-                responseObserver.onNext(successStatus("Successfully deleted $blueprint", request.commonHeader))
+                bluePrintModelHandler.deleteBlueprintModel(blueprintName, blueprintVersion)
+                responseObserver.onNext(successStatus(request.commonHeader))
                 responseObserver.onCompleted()
             } catch (e: Exception) {
                 responseObserver.onError(failStatus("request(${request.commonHeader.requestId}): Failed to delete $blueprint", e))
@@ -118,25 +103,23 @@ open class BluePrintManagementGRPCHandler(private val bluePrintLoadConfiguration
         }
     }
 
-    private fun saveToDisk(request: BluePrintUploadInput, cbaFile: File) {
-        log.info("request(${request.commonHeader.requestId}): Writing CBA File under :${cbaFile.absolutePath}")
-
-        // Recreate Folder
-        cbaFile.parentFile.reCreateDirs()
-
-        // Write the File
-        cbaFile.writeBytes(request.fileChunk.chunk.toByteArray()).apply {
-            log.info("request(${request.commonHeader.requestId}): CBA file(${cbaFile.absolutePath} written successfully")
-        }
-
-    }
+    private fun enrichmentStatus(header: CommonHeader, byteArray: ByteArray): BluePrintManagementOutput =
+            BluePrintManagementOutput.newBuilder()
+                    .setCommonHeader(header)
+                    .setFileChunk(FileChunk.newBuilder().setChunk(ByteString.copyFrom(byteArray)))
+                    .setStatus(Status.newBuilder()
+                            .setTimestamp(currentTimestamp())
+                            .setMessage(BluePrintConstants.STATUS_SUCCESS)
+                            .setCode(200)
+                            .build())
+                    .build()
 
-    private fun successStatus(message: String, header: CommonHeader): BluePrintManagementOutput =
+    private fun successStatus(header: CommonHeader): BluePrintManagementOutput =
             BluePrintManagementOutput.newBuilder()
                     .setCommonHeader(header)
                     .setStatus(Status.newBuilder()
                             .setTimestamp(currentTimestamp())
-                            .setMessage(message)
+                            .setMessage(BluePrintConstants.STATUS_SUCCESS)
                             .setCode(200)
                             .build())
                     .build()
index af7b3fe..212ffd9 100644 (file)
@@ -18,7 +18,6 @@
 
 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.handler
 
-import kotlinx.coroutines.reactive.awaitSingle
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModel
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.repository.BlueprintModelContentRepository
@@ -32,7 +31,6 @@ import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogS
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService
 import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintCompileCache
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintFileUtils
-import org.slf4j.LoggerFactory
 import org.springframework.core.io.ByteArrayResource
 import org.springframework.core.io.Resource
 import org.springframework.http.HttpHeaders
@@ -41,7 +39,6 @@ import org.springframework.http.ResponseEntity
 import org.springframework.http.codec.multipart.FilePart
 import org.springframework.stereotype.Service
 import org.springframework.transaction.annotation.Transactional
-import java.io.File
 import java.io.IOException
 import java.util.*
 
@@ -60,7 +57,7 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService:
                                  private val blueprintModelContentRepository: BlueprintModelContentRepository,
                                  private val bluePrintEnhancerService: BluePrintEnhancerService) {
 
-    private val log = LoggerFactory.getLogger(BluePrintModelHandler::class.java)!!
+    private val log = logger(BluePrintModelHandler::class)
 
     /**
      * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
@@ -81,15 +78,7 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService:
     @Throws(BluePrintException::class)
     open suspend fun saveBlueprintModel(filePart: FilePart): BlueprintModelSearch {
         try {
-            val blueprintId = upload(filePart, false)
-            // Check and Return the Saved File
-            val blueprintModelSearch = blueprintModelSearchRepository.findById(blueprintId)
-                    ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
-                            String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId))
-
-            log.info("Save successful for blueprint(${blueprintModelSearch.artifactName}) " +
-                    "version(${blueprintModelSearch.artifactVersion})")
-            return blueprintModelSearch
+            return upload(filePart, false)
         } catch (e: IOException) {
             throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
                     "Error in Save CBA: ${e.message}", e)
@@ -272,22 +261,12 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService:
      */
     @Throws(BluePrintException::class)
     open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity<Resource> {
-        val enhanceId = UUID.randomUUID().toString()
-        val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, enhanceId)
-        val blueprintWorkingDir = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, enhanceId)
         try {
-            BluePrintEnhancerUtils.decompressFilePart(filePart, blueprintArchive, blueprintWorkingDir)
-
-            // Enhance the Blue Prints
-            bluePrintEnhancerService.enhance(blueprintWorkingDir)
-
-            return BluePrintEnhancerUtils.compressToFilePart(blueprintWorkingDir, blueprintArchive)
-
+            val enhancedByteArray = enrichBlueprintFileSource(filePart)
+            return BluePrintEnhancerUtils.prepareResourceEntity("enhanced-cba.zip", enhancedByteArray)
         } catch (e: IOException) {
             throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
                     "Error in Enriching CBA: ${e.message}", e)
-        } finally {
-            BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
         }
     }
 
@@ -301,30 +280,32 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService:
     @Throws(BluePrintException::class)
     open suspend fun publishBlueprint(filePart: FilePart): BlueprintModelSearch {
         try {
-            val blueprintId = upload(filePart, true)
-
-            return blueprintModelSearchRepository.findById(blueprintId)
-                    ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
-                            String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId))
-
+            return upload(filePart, true)
         } catch (e: Exception) {
             throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
                     "Error in Publishing CBA: ${e.message}", e)
         }
     }
 
-    //TODO("Combine Rest and GRPC Handler")
-    suspend fun upload(filePart: FilePart, validate: Boolean): String {
+    /** Common CBA Save and Publish function for RestController and GRPC Handler, the [fileSource] may be
+     * byteArray or File Part type.*/
+    open suspend fun upload(fileSource: Any, validate: Boolean): BlueprintModelSearch {
         val saveId = UUID.randomUUID().toString()
         val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, saveId)
         val blueprintWorking = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, saveId)
         try {
             val compressedFile = normalizedFile(blueprintArchive, "cba.zip")
-            compressedFile.parentFile.reCreateNBDirs()
-            // Copy the File Part to Local File
-            copyFromFilePart(filePart, compressedFile)
+            when (fileSource) {
+                is FilePart -> BluePrintEnhancerUtils.filePartAsFile(fileSource, compressedFile)
+                is ByteArray -> BluePrintEnhancerUtils.byteArrayAsFile(fileSource, compressedFile)
+            }
             // Save the Copied file to Database
-            return blueprintsProcessorCatalogService.saveToDatabase(saveId, compressedFile, validate)
+            val blueprintId = blueprintsProcessorCatalogService.saveToDatabase(saveId, compressedFile, validate)
+
+            return blueprintModelSearchRepository.findById(blueprintId)
+                    ?: throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
+                            String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, blueprintId))
+
         } catch (e: IOException) {
             throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
                     "Error in Upload CBA: ${e.message}", e)
@@ -338,10 +319,29 @@ open class BluePrintModelHandler(private val blueprintsProcessorCatalogService:
         }
     }
 
-    private suspend fun copyFromFilePart(filePart: FilePart, targetFile: File): File {
-        return filePart.transferTo(targetFile)
-                .thenReturn(targetFile)
-                .awaitSingle()
+    /** Common CBA Enrich function for RestController and GRPC Handler, the [fileSource] may be
+     * byteArray or File Part type.*/
+    open suspend fun enrichBlueprintFileSource(fileSource: Any): ByteArray {
+        val enhanceId = UUID.randomUUID().toString()
+        val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, enhanceId)
+        val blueprintWorkingDir = normalizedPathName(bluePrintLoadConfiguration.blueprintWorkingPath, enhanceId)
+        try {
+            when (fileSource) {
+                is FilePart -> BluePrintEnhancerUtils
+                        .copyFilePartToEnhanceDir(fileSource, blueprintArchive, blueprintWorkingDir)
+                is ByteArray -> BluePrintEnhancerUtils
+                        .copyByteArrayToEnhanceDir(fileSource, blueprintArchive, blueprintWorkingDir)
+            }            // Enhance the Blue Prints
+            bluePrintEnhancerService.enhance(blueprintWorkingDir)
+
+            return BluePrintEnhancerUtils.compressEnhanceDirAndReturnByteArray(blueprintWorkingDir, blueprintArchive)
+
+        } catch (e: IOException) {
+            throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
+                    "Error in Enriching CBA: ${e.message}", e)
+        } finally {
+            BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
+        }
     }
 
     companion object {
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/service/AutoResourceMappingService.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/service/AutoResourceMappingService.kt
deleted file mode 100644 (file)
index be56264..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright Â© 2017-2018 AT&T Intellectual Property.
- * Modifications Copyright Â© 2019 Huawei.
- *
- * 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.cds.blueprintsprocessor.designer.api.service
-
-import com.google.common.base.Preconditions
-import org.apache.commons.collections.CollectionUtils
-import org.apache.commons.lang3.StringUtils
-import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.AutoMapResponse
-import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.domain.ResourceDictionary
-import org.onap.ccsdk.cds.blueprintsprocessor.designer.api.repository.ResourceDictionaryRepository
-import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
-import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
-import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
-import org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils.ResourceDictionaryUtils
-import org.slf4j.LoggerFactory
-import org.springframework.stereotype.Service
-import java.util.*
-
-@Service
-open class AutoResourceMappingService(private val dataDictionaryRepository: ResourceDictionaryRepository) {
-
-    private val log = LoggerFactory.getLogger(AutoResourceMappingService::class.java)
-
-    @Throws(BluePrintException::class)
-    fun autoMap(resourceAssignments: MutableList<ResourceAssignment>):
-            AutoMapResponse {
-        val autoMapResponse = AutoMapResponse()
-        try {
-            if (CollectionUtils.isNotEmpty(resourceAssignments)) {
-                // Create the Dictionary definitions for the ResourceAssignment Names
-                val dictionaryMap = getDictionaryDefinitions(resourceAssignments)
-
-                for (resourceAssignment in resourceAssignments) {
-                    if (StringUtils.isNotBlank(resourceAssignment.name)
-                            && StringUtils.isBlank(resourceAssignment.dictionaryName)) {
-                        populateDictionaryMapping(dictionaryMap, resourceAssignment)
-                        log.info("Mapped Resource : {}", resourceAssignment)
-                    }
-                }
-            }
-            val dictionaries = getDictionaryDefinitionsList(resourceAssignments)
-            val resourceAssignmentsFinal = getAllAutoMapResourceAssignments(resourceAssignments)
-            autoMapResponse.dataDictionaries = dictionaries
-            autoMapResponse.resourceAssignments = resourceAssignmentsFinal
-        } catch (e: Exception) {
-            log.error(String.format("Failed in auto process %s", e.message))
-            throw BluePrintException(e, e.message!!)
-        }
-
-        return autoMapResponse
-    }
-
-    private fun populateDictionaryMapping(dictionaryMap: Map<String, ResourceDictionary>, resourceAssignment: ResourceAssignment) {
-        val dbDataDictionary = dictionaryMap[resourceAssignment.name]
-        if (dbDataDictionary != null && dbDataDictionary.definition != null) {
-
-            val dictionaryDefinition = dbDataDictionary.definition
-
-            if (dictionaryDefinition != null && StringUtils.isNotBlank(dictionaryDefinition.name)
-                    && StringUtils.isBlank(resourceAssignment.dictionaryName)) {
-
-                resourceAssignment.dictionaryName = dbDataDictionary.name
-                ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition)
-            }
-        }
-    }
-
-    private fun getDictionaryDefinitions(resourceAssignments: List<ResourceAssignment>): Map<String, ResourceDictionary> {
-        val dictionaryMap = HashMap<String, ResourceDictionary>()
-        val names = ArrayList<String>()
-        for (resourceAssignment in resourceAssignments) {
-            if (StringUtils.isNotBlank(resourceAssignment.name)) {
-                names.add(resourceAssignment.name)
-            }
-        }
-        if (CollectionUtils.isNotEmpty(names)) {
-
-            val dictionaries = dataDictionaryRepository.findByNameIn(names)
-            if (CollectionUtils.isNotEmpty(dictionaries)) {
-                for (dataDictionary in dictionaries) {
-                    if (StringUtils.isNotBlank(dataDictionary.name)) {
-                        dictionaryMap[dataDictionary.name] = dataDictionary
-                    }
-                }
-            }
-        }
-        return dictionaryMap
-
-    }
-    private fun getDictionaryDefinitionsList(resourceAssignments: List<ResourceAssignment>): List<ResourceDictionary>? {
-        var dictionaries: List<ResourceDictionary>? = null
-        val names = ArrayList<String>()
-        for (resourceAssignment in resourceAssignments) {
-            if (StringUtils.isNotBlank(resourceAssignment.dictionaryName)) {
-
-                if (!names.contains(resourceAssignment.dictionaryName)) {
-                    names.add(resourceAssignment.dictionaryName!!)
-                }
-
-                if (resourceAssignment.dependencies != null && !resourceAssignment.dependencies!!.isEmpty()) {
-                    val dependencyNames = resourceAssignment.dependencies
-                    for (dependencyName in dependencyNames!!) {
-                        if (StringUtils.isNotBlank(dependencyName) && !names.contains(dependencyName)) {
-                            names.add(dependencyName)
-                        }
-                    }
-                }
-            }
-        }
-        if (CollectionUtils.isNotEmpty(names)) {
-            dictionaries = dataDictionaryRepository.findByNameIn(names)
-        }
-        return dictionaries
-
-    }
-
-    private fun getAllAutoMapResourceAssignments(resourceAssignments: MutableList<ResourceAssignment>): List<ResourceAssignment> {
-        var dictionaries: List<ResourceDictionary>? = null
-        val names = ArrayList<String>()
-        for (resourceAssignment in resourceAssignments) {
-            if (StringUtils.isNotBlank(resourceAssignment.dictionaryName)) {
-                if (resourceAssignment.dependencies != null && !resourceAssignment.dependencies!!.isEmpty()) {
-                    val dependencyNames = resourceAssignment.dependencies
-                    for (dependencyName in dependencyNames!!) {
-                        if (StringUtils.isNotBlank(dependencyName) && !names.contains(dependencyName)
-                                && !checkAssignmentsExists(resourceAssignments, dependencyName)) {
-                            names.add(dependencyName)
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!names.isEmpty()) {
-            dictionaries = dataDictionaryRepository.findByNameIn(names)
-        }
-        if (dictionaries != null) {
-            for (rscDictionary in dictionaries) {
-                val dictionaryDefinition = rscDictionary.definition
-                Preconditions.checkNotNull(dictionaryDefinition, "failed to get Resource Definition from dictionary definition")
-                val property = PropertyDefinition()
-                property.required = true
-                val resourceAssignment = ResourceAssignment()
-                resourceAssignment.name = rscDictionary.name
-                resourceAssignment.dictionaryName = rscDictionary.name
-                resourceAssignment.version = 0
-                resourceAssignment.property = property
-                ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition)
-                resourceAssignments.add(resourceAssignment)
-            }
-        }
-        return resourceAssignments
-    }
-
-
-    private fun checkAssignmentsExists(resourceAssignmentsWithDepencies: List<ResourceAssignment>, resourceName: String): Boolean {
-        return resourceAssignmentsWithDepencies.stream().anyMatch { names -> names.name.equals(resourceName, ignoreCase = true) }
-    }
-}
\ No newline at end of file
index 6eab5cd..c79d1b5 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.designer.api.utils
 
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.reactive.awaitSingle
-import kotlinx.coroutines.withContext
 import org.onap.ccsdk.cds.controllerblueprints.core.*
-import org.onap.ccsdk.cds.controllerblueprints.core.data.*
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.RelationshipType
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintRepoService
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintArchiveUtils
@@ -32,17 +33,13 @@ 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.*
 
 
 class BluePrintEnhancerUtils {
     companion object {
+        val log = logger(BluePrintEnhancerUtils)
 
         fun populateDataTypes(bluePrintContext: BluePrintContext, bluePrintRepoService: BluePrintRepoService,
                               dataTypeName: String): DataType {
@@ -84,81 +81,88 @@ class BluePrintEnhancerUtils {
             return artifactType
         }
 
-        suspend fun copyFromFilePart(filePart: FilePart, targetFile: File): File {
+        suspend fun byteArrayAsFile(byteArray: ByteArray, targetFile: File): File {
+            // Recreate Folder
+            targetFile.parentFile.reCreateNBDirs()
+            targetFile.writeBytes(byteArray).apply {
+                log.info("CBA file(${targetFile.absolutePath} written successfully")
+            }
+            return targetFile
+        }
+
+
+        suspend fun filePartAsFile(filePart: FilePart, targetFile: File): File {
             // Delete the Directory
-            targetFile.deleteRecursively()
+            targetFile.parentFile.reCreateNBDirs()
             return filePart.transferTo(targetFile)
                     .thenReturn(targetFile)
                     .awaitSingle()
         }
 
-        suspend fun extractCompressFilePart(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
+        private suspend fun byteArrayAsArchiveFile(byteArray: ByteArray, archiveDir: String, enhanceDir: String): File {
+            //Recreate the Base Directories
+            normalizedFile(archiveDir).reCreateNBDirs()
+            normalizedFile(enhanceDir).reCreateNBDirs()
+            val archiveFile = normalizedFile(archiveDir, "cba.zip")
+            // Copy the File Part to ZIP
+            return byteArrayAsFile(byteArray, archiveFile)
+        }
+
+        private suspend fun filePartAsArchiveFile(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
             //Recreate the Base Directories
-            normalizedFile(archiveDir).reCreateDirs()
-            normalizedFile(enhanceDir).reCreateDirs()
-            val filePartFile = normalizedFile(archiveDir, "cba.zip")
+            normalizedFile(archiveDir).reCreateNBDirs()
+            normalizedFile(enhanceDir).reCreateNBDirs()
+            val archiveFile = normalizedFile(archiveDir, "cba.zip")
             // Copy the File Part to ZIP
-            return copyFromFilePart(filePart, filePartFile)
+            return filePartAsFile(filePart, archiveFile)
+        }
+
+        /** copy the [byteArray] zip file to [archiveDir] and then decompress to [enhanceDir] */
+        suspend fun copyByteArrayToEnhanceDir(byteArray: ByteArray, archiveDir: String, enhanceDir: String): File {
+            val archiveFile = byteArrayAsArchiveFile(byteArray, archiveDir, enhanceDir)
+            val deCompressFileName = normalizedPathName(enhanceDir)
+            return archiveFile.deCompress(deCompressFileName)
         }
 
-        suspend fun decompressFilePart(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
-            val filePartFile = extractCompressFilePart(filePart, archiveDir, enhanceDir)
+        /** copy the [filePart] zip file to [archiveDir] and then decompress to [enhanceDir] */
+        suspend fun copyFilePartToEnhanceDir(filePart: FilePart, archiveDir: String, enhanceDir: String): File {
+            val filePartFile = filePartAsArchiveFile(filePart, archiveDir, enhanceDir)
             val deCompressFileName = normalizedPathName(enhanceDir)
             return filePartFile.deCompress(deCompressFileName)
         }
 
-        suspend fun compressToFilePart(enhanceDir: String, archiveDir: String,
-                                       outputFileName:String="enhanced-cba.zip"): ResponseEntity<Resource> {
+        /** compress [enhanceDir] to [archiveDir] and return ByteArray */
+        suspend fun compressEnhanceDirAndReturnByteArray(enhanceDir: String, archiveDir: String,
+                                                         outputFileName: String = "enhanced-cba.zip"): ByteArray {
             val compressedFile = normalizedFile(archiveDir, outputFileName)
             BluePrintArchiveUtils.compress(Paths.get(enhanceDir).toFile(), compressedFile)
-            return prepareResourceEntity(compressedFile.name, compressedFile.readBytes())
+            return compressedFile.readBytes()
         }
 
-        suspend fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity<Resource> {
+        /** compress [enhanceDir] to [archiveDir] and return ResponseEntity */
+        suspend fun compressEnhanceDirAndReturnFilePart(enhanceDir: String, archiveDir: String,
+                                                        outputFileName: String = "enhanced-cba.zip")
+                : ResponseEntity<Resource> {
+            val compressedFile = normalizedFile(archiveDir, outputFileName)
+            BluePrintArchiveUtils.compress(Paths.get(enhanceDir).toFile(), compressedFile)
+            return prepareResourceEntity(compressedFile)
+        }
+
+        /** convert [file] to ResourceEntity */
+        suspend fun prepareResourceEntity(file: File): ResponseEntity<Resource> {
+            return prepareResourceEntity(file.name, file.readBytes())
+        }
+        /** convert [byteArray] to ResourceEntity with [fileName]*/
+        fun prepareResourceEntity(fileName: String, byteArray: 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) {
-            deleteDir(archiveLocation)
-            deleteDir(enhancementLocation)
+                    .body(ByteArrayResource(byteArray))
         }
 
-        /**
-         * 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
-         *
-         * @param (filePart, targetDirectory) - the request part containing the file to be saved and the default directory where to save
-         * @return a [Mono] String representing the result of the operation
-         * @throws (BluePrintException, IOException) BluePrintException, IOException
-         */
-        @Throws(BluePrintException::class, IOException::class)
-        fun saveCBAFile(filePart: FilePart, targetDirectory: Path): Mono<String> {
-
-            // Normalize file name
-            val fileName = StringUtils.cleanPath(filePart.filename())
-
-            // Check if the file's extension is "CBA"
-            if (StringUtils.getFilenameExtension(fileName) != "zip") {
-                throw BluePrintException(ErrorCode.INVALID_FILE_EXTENSION.value, "Invalid file extension required ZIP")
-            }
-
-            // Change file name to match a pattern
-            val changedFileName = UUID.randomUUID().toString() + ".zip"
-            //String changedFileName = BluePrintFileUtils.Companion.getCBAGeneratedFileName(fileName, this.CBA_FILE_NAME_PATTERN);
-
-            // Copy file to the target location (Replacing existing file with the same name)
-            val targetLocation = targetDirectory.resolve(changedFileName)
-
-            // if a file with the same name already exists in a repository, delete and recreate it
-            val file = File(targetLocation.toString())
-            if (file.exists())
-                file.delete()
-            file.createNewFile()
-
-            return filePart.transferTo(file).thenReturn(changedFileName)
+        suspend fun cleanEnhancer(archiveLocation: String, enhancementLocation: String) {
+            deleteNBDir(archiveLocation)
+            deleteNBDir(enhancementLocation)
         }
     }
 }
index f0411b0..6e4e91a 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.controllerblueprints.common.api.ActionIdentifiers
 import org.onap.ccsdk.cds.controllerblueprints.common.api.CommonHeader
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir
 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
 import org.onap.ccsdk.cds.controllerblueprints.management.api.*
@@ -42,7 +43,8 @@ import kotlin.test.assertTrue
 @RunWith(SpringRunner::class)
 @EnableAutoConfiguration
 @DirtiesContext
-@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"])
+@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor",
+    "org.onap.ccsdk.cds.controllerblueprints"])
 @TestPropertySource(locations = ["classpath:application-test.properties"])
 class BluePrintManagementGRPCHandlerTest {
 
@@ -72,7 +74,8 @@ class BluePrintManagementGRPCHandlerTest {
         val output = blockingStub.uploadBlueprint(req)
 
         assertEquals(200, output.status.code)
-        assertTrue(output.status.message.contains("Successfully uploaded CBA"))
+        assertTrue(output.status.message.contentEquals(BluePrintConstants.STATUS_SUCCESS),
+                "failed to get success status")
         assertEquals(id, output.commonHeader.requestId)
     }
 
@@ -84,7 +87,8 @@ class BluePrintManagementGRPCHandlerTest {
 
         var output = blockingStub.uploadBlueprint(req)
         assertEquals(200, output.status.code)
-        assertTrue(output.status.message.contains("Successfully uploaded CBA"))
+        assertTrue(output.status.message.contentEquals(BluePrintConstants.STATUS_SUCCESS),
+                "failed to get success status")
         assertEquals(id, output.commonHeader.requestId)
 
         val removeReq = createRemoveInputRequest(id)
index 1491080..0d834d2 100644 (file)
@@ -32,7 +32,6 @@ import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration
 import org.onap.ccsdk.cds.blueprintsprocessor.db.primary.domain.BlueprintModelSearch
 import org.onap.ccsdk.cds.controllerblueprints.core.*
 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
-import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.boot.test.context.SpringBootTest
 import org.springframework.core.io.ByteArrayResource
@@ -67,7 +66,7 @@ import kotlin.test.assertTrue
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class BlueprintModelControllerTest {
 
-    private val log = LoggerFactory.getLogger(BlueprintModelControllerTest::class.java)!!
+    private val log = logger(BlueprintModelControllerTest::class)
 
     companion object {
         private var bp: BlueprintModelSearch? = null
index e34238e..5999873 100644 (file)
@@ -58,8 +58,8 @@ class BluePrintEnhancerUtilsTest {
             val enhanceId = UUID.randomUUID().toString()
             val blueprintArchiveLocation = normalizedPathName(blueprintArchivePath, enhanceId)
             val blueprintEnrichmentLocation = normalizedPathName(blueprintEnrichmentPath, enhanceId)
-            BluePrintEnhancerUtils.decompressFilePart(filePart, blueprintArchiveLocation, blueprintEnrichmentLocation)
-            BluePrintEnhancerUtils.compressToFilePart(blueprintEnrichmentLocation, blueprintArchiveLocation)
+            BluePrintEnhancerUtils.copyFilePartToEnhanceDir(filePart, blueprintArchiveLocation, blueprintEnrichmentLocation)
+            BluePrintEnhancerUtils.compressEnhanceDirAndReturnFilePart(blueprintEnrichmentLocation, blueprintArchiveLocation)
         }
     }
 }