summaryrefslogtreecommitdiffstats
path: root/ms/blueprintsprocessor
diff options
context:
space:
mode:
authorBrinda Santh <brindasanth@in.ibm.com>2019-08-29 16:46:22 -0400
committerBrinda Santh <brindasanth@in.ibm.com>2019-08-29 23:43:47 -0400
commitb8539cca6f2bc572801640b3fcefe83dcecf5ef5 (patch)
tree73fd650fa51807d664528ba53f53a4602aec2c30 /ms/blueprintsprocessor
parent0fbfc6eab2d42c8ee2f8601db43813a4e33ffc4d (diff)
Refactor Blueprint model controller to designer api.
Change-Id: I6e729aab24262f6bdef4b92febf9f65a4819d142 Issue-ID: CCSDK-1663 Signed-off-by: Brinda Santh <brindasanth@in.ibm.com>
Diffstat (limited to 'ms/blueprintsprocessor')
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml8
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintModelHandler.kt335
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt108
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt223
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiTestConfiguration.kt27
-rwxr-xr-xms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties41
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/logback-test.xml39
7 files changed, 775 insertions, 6 deletions
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml
index 2586be255..7c1576e95 100644
--- a/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/pom.xml
@@ -23,12 +23,8 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>designer-api</artifactId>
<packaging>jar</packaging>
- <name>Blueprints Designer API</name>
- <description>Blueprints Designer API</description>
-
- <properties>
- <sonar.skip>true</sonar.skip>
- </properties>
+ <name>Blueprints Processor Designer API</name>
+ <description>Blueprints Processor Designer API</description>
<dependencies>
<dependency>
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintModelHandler.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintModelHandler.kt
new file mode 100644
index 000000000..d4bcd8e94
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintModelHandler.kt
@@ -0,0 +1,335 @@
+/*
+ * 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.
+ * 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
+
+import org.onap.ccsdk.cds.controllerblueprints.core.*
+import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode
+import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
+import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService
+import org.onap.ccsdk.cds.controllerblueprints.service.domain.BlueprintModel
+import org.onap.ccsdk.cds.controllerblueprints.service.domain.BlueprintModelSearch
+import org.onap.ccsdk.cds.controllerblueprints.service.repository.ControllerBlueprintModelContentRepository
+import org.onap.ccsdk.cds.controllerblueprints.service.repository.ControllerBlueprintModelRepository
+import org.onap.ccsdk.cds.controllerblueprints.service.repository.ControllerBlueprintModelSearchRepository
+import org.onap.ccsdk.cds.controllerblueprints.service.utils.BluePrintEnhancerUtils
+import org.slf4j.LoggerFactory
+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.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
+import java.io.File
+import java.io.IOException
+import java.util.*
+
+/**
+ * BlueprintModelHandler Purpose: Handler service to handle the request from BlurPrintModelRest
+ *
+ * @author Brinda Santh
+ * @version 1.0
+ */
+
+@Service
+open class BluePrintModelHandler(private val controllerBlueprintsCatalogService: BluePrintCatalogService,
+ private val bluePrintLoadConfiguration: BluePrintLoadConfiguration,
+ private val blueprintModelSearchRepository: ControllerBlueprintModelSearchRepository,
+ private val blueprintModelRepository: ControllerBlueprintModelRepository,
+ private val blueprintModelContentRepository: ControllerBlueprintModelContentRepository,
+ private val bluePrintEnhancerService: BluePrintEnhancerService) {
+
+ private val log = LoggerFactory.getLogger(BluePrintModelHandler::class.java)!!
+
+ /**
+ * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database
+ *
+ * @return List<BlueprintModelSearch> list of the controller blueprint archives
+ </BlueprintModelSearch> */
+ open fun allBlueprintModel(): List<BlueprintModelSearch> {
+ return blueprintModelSearchRepository.findAll()
+ }
+
+ /**
+ * This is a saveBlueprintModel method
+ *
+ * @param filePart filePart
+ * @return Mono<BlueprintModelSearch>
+ * @throws BluePrintException BluePrintException
+ </BlueprintModelSearch> */
+ @Throws(BluePrintException::class)
+ open suspend fun saveBlueprintModel(filePart: FilePart): BlueprintModelSearch {
+ val saveId = UUID.randomUUID().toString()
+ val blueprintArchive = normalizedPathName(bluePrintLoadConfiguration.blueprintArchivePath, saveId)
+ try {
+ //Recreate the Dir
+ normalizedFile(bluePrintLoadConfiguration.blueprintArchivePath, saveId).reCreateDirs()
+ val deCompressedFile = normalizedFile(blueprintArchive, "cba.zip")
+ // Copy the File Part to Local File
+ BluePrintEnhancerUtils.copyFromFilePart(filePart, deCompressedFile)
+ // Save the Copied file to Database
+ val blueprintId = controllerBlueprintsCatalogService.saveToDatabase(saveId, deCompressedFile, false)
+ // Check and Return the Saved File
+ val blueprintModelSearch = blueprintModelSearchRepository.findById(blueprintId).get()
+ log.info("Save($saveId) successful for blueprint(${blueprintModelSearch.artifactName}) " +
+ "version(${blueprintModelSearch.artifactVersion})")
+ return blueprintModelSearch
+ } catch (e: IOException) {
+ throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
+ "Error in Save CBA: ${e.message}", e)
+ } finally {
+ deleteDir(blueprintArchive)
+ }
+ }
+
+
+ /**
+ * This is a searchBlueprintModels method
+ *
+ * @param tags tags
+ * @return List<BlueprintModelSearch>
+ </BlueprintModelSearch> */
+ open fun searchBlueprintModels(tags: String): List<BlueprintModelSearch> {
+ return blueprintModelSearchRepository.findByTagsContainingIgnoreCase(tags)
+ }
+
+ /**
+ * This is a getBlueprintModelSearchByNameAndVersion method
+ *
+ * @param name name
+ * @param version version
+ * @return BlueprintModelSearch
+ * @throws BluePrintException BluePrintException
+ */
+ @Throws(BluePrintException::class)
+ open fun getBlueprintModelSearchByNameAndVersion(name: String, version: String): BlueprintModelSearch {
+ val blueprintModelSearch: BlueprintModelSearch
+ val dbBlueprintModel = blueprintModelSearchRepository
+ .findByArtifactNameAndArtifactVersion(name, version)
+ if (dbBlueprintModel.isPresent) {
+ blueprintModelSearch = dbBlueprintModel.get()
+ } else {
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value,
+ String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version))
+ }
+ return blueprintModelSearch
+ }
+
+ /**
+ * This is a downloadBlueprintModelFileByNameAndVersion method to download a Blueprint by Name and Version
+ *
+ * @param name name
+ * @param version version
+ * @return ResponseEntity<Resource>
+ * @throws BluePrintException BluePrintException
+ </Resource> */
+ @Throws(BluePrintException::class)
+ open fun downloadBlueprintModelFileByNameAndVersion(name: String,
+ version: String): ResponseEntity<Resource> {
+ val blueprintModel: BlueprintModel
+ try {
+ blueprintModel = getBlueprintModelByNameAndVersion(name, version)
+ } catch (e: BluePrintException) {
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, String.format("Error while " + "downloading the CBA file: %s", e.message), e)
+ }
+
+ val fileName = blueprintModel.id + ".zip"
+ val file = blueprintModel.blueprintModelContent.content
+ return prepareResourceEntity(fileName, file)
+ }
+
+ /**
+ * This is a downloadBlueprintModelFile method to find the target file to download and return a file resource
+ *
+ * @return ResponseEntity<Resource>
+ * @throws BluePrintException BluePrintException
+ </Resource> */
+ @Throws(BluePrintException::class)
+ open fun downloadBlueprintModelFile(id: String): ResponseEntity<Resource> {
+ val blueprintModel: BlueprintModel
+ try {
+ blueprintModel = getBlueprintModel(id)
+ } catch (e: BluePrintException) {
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, String.format("Error while " + "downloading the CBA file: %s", e.message), e)
+ }
+
+ val fileName = blueprintModel.id + ".zip"
+ val file = blueprintModel.blueprintModelContent.content
+ return prepareResourceEntity(fileName, file)
+ }
+
+ /**
+ * @return ResponseEntity<Resource>
+ </Resource> */
+ private 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))
+ }
+
+ /**
+ * This is a getBlueprintModel method
+ *
+ * @param id id
+ * @return BlueprintModel
+ * @throws BluePrintException BluePrintException
+ */
+ @Throws(BluePrintException::class)
+ open fun getBlueprintModel(id: String): BlueprintModel {
+ val blueprintModel: BlueprintModel
+ val dbBlueprintModel = blueprintModelRepository.findById(id)
+ if (dbBlueprintModel.isPresent) {
+ blueprintModel = dbBlueprintModel.get()
+ } else {
+ val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
+ }
+ return blueprintModel
+ }
+
+ /**
+ * This is a getBlueprintModelByNameAndVersion method
+ *
+ * @param name name
+ * @param version version
+ * @return BlueprintModel
+ * @throws BluePrintException BluePrintException
+ */
+ @Throws(BluePrintException::class)
+ open fun getBlueprintModelByNameAndVersion(name: String, version: String): BlueprintModel {
+ val blueprintModel = blueprintModelRepository
+ .findByArtifactNameAndArtifactVersion(name, version)
+ if (blueprintModel != null) {
+ return blueprintModel
+ } else {
+ val msg = String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
+ }
+ }
+
+ /**
+ * This is a getBlueprintModelSearch method
+ *
+ * @param id id
+ * @return BlueprintModelSearch
+ * @throws BluePrintException BluePrintException
+ */
+ @Throws(BluePrintException::class)
+ open fun getBlueprintModelSearch(id: String): BlueprintModelSearch {
+ val blueprintModelSearch: BlueprintModelSearch
+ val dbBlueprintModel = blueprintModelSearchRepository.findById(id)
+ if (dbBlueprintModel.isPresent) {
+ blueprintModelSearch = dbBlueprintModel.get()
+ } else {
+ val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
+ }
+
+ return blueprintModelSearch
+ }
+
+ /**
+ * This is a deleteBlueprintModel method
+ *
+ * @param id id
+ * @throws BluePrintException BluePrintException
+ */
+ @Transactional
+ @Throws(BluePrintException::class)
+ open fun deleteBlueprintModel(id: String) {
+ val dbBlueprintModel = blueprintModelRepository.findById(id)
+ if (dbBlueprintModel.isPresent) {
+ blueprintModelContentRepository.deleteByBlueprintModel(dbBlueprintModel.get())
+ blueprintModelRepository.delete(dbBlueprintModel.get())
+ } else {
+ val msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)
+ throw BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.value, msg)
+ }
+ }
+
+ /**
+ * 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 = 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)
+
+ } catch (e: IOException) {
+ throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
+ "Error in Enriching CBA: ${e.message}", e)
+ } finally {
+ BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
+ }
+ }
+
+ /**
+ * This is a publishBlueprintModel method to change the status published to YES
+ *
+ * @param filePart filePart
+ * @return BlueprintModelSearch
+ * @throws BluePrintException BluePrintException
+ */
+ @Throws(BluePrintException::class)
+ open suspend fun publishBlueprint(filePart: FilePart): BlueprintModelSearch {
+ val publishId = UUID.randomUUID().toString()
+ val blueprintArchive = bluePrintLoadConfiguration.blueprintArchivePath.plus(File.separator).plus(publishId)
+ val blueprintWorkingDir = bluePrintLoadConfiguration.blueprintWorkingPath.plus(File.separator).plus(publishId)
+ try {
+ val compressedFilePart = BluePrintEnhancerUtils
+ .extractCompressFilePart(filePart, blueprintArchive, blueprintWorkingDir)
+
+ val blueprintId = controllerBlueprintsCatalogService.saveToDatabase(publishId, compressedFilePart, true)
+
+ return blueprintModelSearchRepository.findById(blueprintId).get()
+
+ } catch (e: Exception) {
+ throw BluePrintException(ErrorCode.IO_FILE_INTERRUPT.value,
+ "Error in Publishing CBA: ${e.message}", e)
+ } finally {
+ BluePrintEnhancerUtils.cleanEnhancer(blueprintArchive, blueprintWorkingDir)
+ }
+ }
+
+ companion object {
+
+ private const val BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%s) from repo"
+ private const val BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG = "failed to get blueprint model by name(%s)" + " and version(%s) from repo"
+ }
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
new file mode 100644
index 000000000..98f521222
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2019 Bell Canada 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.
+ * 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
+
+import kotlinx.coroutines.runBlocking
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
+import org.onap.ccsdk.cds.controllerblueprints.service.domain.BlueprintModelSearch
+import org.springframework.core.io.Resource
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.http.codec.multipart.FilePart
+import org.springframework.web.bind.annotation.*
+
+/**
+ * BlueprintModelController Purpose: Handle controllerBlueprint API request
+ *
+ * @author Vinal Patel
+ * @version 1.0
+ */
+@RestController
+@RequestMapping("/api/v1/blueprint-model")
+open class BlueprintModelController(private val bluePrintModelHandler: BluePrintModelHandler) {
+
+ @PostMapping("", produces = [MediaType.APPLICATION_JSON_VALUE], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
+ @ResponseBody
+ @Throws(BluePrintException::class)
+ fun saveBlueprint(@RequestPart("file") filePart: FilePart): BlueprintModelSearch = runBlocking {
+ bluePrintModelHandler.saveBlueprintModel(filePart)
+ }
+
+ @GetMapping("", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ fun allBlueprintModel(): List<BlueprintModelSearch> {
+ return this.bluePrintModelHandler.allBlueprintModel()
+ }
+
+ @DeleteMapping("/{id}")
+ @Throws(BluePrintException::class)
+ fun deleteBlueprint(@PathVariable(value = "id") id: String) {
+ this.bluePrintModelHandler.deleteBlueprintModel(id)
+ }
+
+ @GetMapping("/by-name/{name}/version/{version}", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ @Throws(BluePrintException::class)
+ fun getBlueprintByNameAndVersion(@PathVariable(value = "name") name: String,
+ @PathVariable(value = "version") version: String): BlueprintModelSearch {
+ return this.bluePrintModelHandler.getBlueprintModelSearchByNameAndVersion(name, version)
+ }
+
+ @GetMapping("/download/by-name/{name}/version/{version}", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ @Throws(BluePrintException::class)
+ fun downloadBlueprintByNameAndVersion(@PathVariable(value = "name") name: String,
+ @PathVariable(value = "version") version: String): ResponseEntity<Resource> {
+ return this.bluePrintModelHandler.downloadBlueprintModelFileByNameAndVersion(name, version)
+ }
+
+ @GetMapping("/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ @Throws(BluePrintException::class)
+ fun getBlueprintModel(@PathVariable(value = "id") id: String): BlueprintModelSearch {
+ return this.bluePrintModelHandler.getBlueprintModelSearch(id)
+ }
+
+ @GetMapping("/download/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ @Throws(BluePrintException::class)
+ fun downloadBluePrint(@PathVariable(value = "id") id: String): ResponseEntity<Resource> {
+ 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)
+ }
+
+ @PostMapping("/publish", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ @Throws(BluePrintException::class)
+ fun publishBlueprint(@RequestPart("file") file: FilePart): BlueprintModelSearch = runBlocking {
+ bluePrintModelHandler.publishBlueprint(file)
+ }
+
+ @GetMapping("/search/{tags}", produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ fun searchBlueprintModels(@PathVariable(value = "tags") tags: String): List<BlueprintModelSearch> {
+ return this.bluePrintModelHandler.searchBlueprintModels(tags)
+ }
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt
new file mode 100644
index 000000000..cd49870ae
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt
@@ -0,0 +1,223 @@
+/*
+ * Copyright © 2019 Bell Canada 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.
+ * 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
+
+import kotlinx.coroutines.reactive.awaitSingle
+import kotlinx.coroutines.runBlocking
+import org.json.JSONException
+import org.junit.After
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
+import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration
+import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.*
+import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.service.domain.BlueprintModelSearch
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.core.io.ByteArrayResource
+import org.springframework.http.HttpMethod
+import org.springframework.http.HttpStatus
+import org.springframework.http.client.MultipartBodyBuilder
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.TestPropertySource
+import org.springframework.test.context.junit4.SpringRunner
+import org.springframework.test.web.reactive.server.WebTestClient
+import org.springframework.test.web.reactive.server.returnResult
+import org.springframework.util.Base64Utils
+import org.springframework.web.reactive.function.BodyInserters
+import java.io.File
+import java.nio.charset.StandardCharsets.UTF_8
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
+
+/**
+ * BlueprintModelControllerTest Purpose: Integration test at API level
+ *
+ * @author Vinal Patel
+ * @version 1.0
+ */
+
+@RunWith(SpringRunner::class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ContextConfiguration(classes = [DesignerApiTestConfiguration::class,
+ BlueprintPropertyConfiguration::class, BluePrintProperties::class, BluePrintDBLibConfiguration::class])
+@TestPropertySource(locations = ["classpath:application-test.properties"])
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class BlueprintModelControllerTest {
+
+ private val log = LoggerFactory.getLogger(BlueprintModelControllerTest::class.java)!!
+
+ companion object {
+ private var bp: BlueprintModelSearch? = null
+ }
+
+ @Autowired
+ lateinit var webTestClient: WebTestClient
+
+ private var bluePrintLoadConfiguration: BluePrintLoadConfiguration? = null
+
+ private val blueprintDir = "./../../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
+ private var zipBlueprintFileName: String? = null
+
+ private var testZipFile: File? = null
+
+
+ @Before
+ fun setUp() {
+ assertNotNull(webTestClient, " Failed to create WebTestClient")
+
+ bluePrintLoadConfiguration = BluePrintLoadConfiguration().apply {
+ blueprintArchivePath = "./target/blueprints/archive"
+ blueprintWorkingPath = "./target/blueprints/work"
+ blueprintDeployPath = "./target/blueprints/deploy"
+ }
+ zipBlueprintFileName = normalizedPathName(bluePrintLoadConfiguration!!.blueprintArchivePath, "test.zip")
+
+ val archiveDir = normalizedFile(bluePrintLoadConfiguration!!.blueprintArchivePath).reCreateDirs()
+ assertTrue(archiveDir.exists(), "failed to create archiveDir(${archiveDir.absolutePath}")
+
+ val blueprintFile = normalizedFile(blueprintDir)
+ testZipFile = blueprintFile.compress(zipBlueprintFileName!!)
+ assertNotNull(testZipFile, "test zip is null")
+ assertTrue(testZipFile!!.exists(), "Failed to create blueprint test zip(${testZipFile!!.absolutePath}")
+ }
+
+ @After
+ fun tearDown() {
+ deleteDir(bluePrintLoadConfiguration!!.blueprintArchivePath)
+ deleteDir(bluePrintLoadConfiguration!!.blueprintWorkingPath)
+ }
+
+ @Test
+ fun test01_saveBluePrint() {
+ bp = runBlocking {
+ val body = MultipartBodyBuilder().apply {
+ part("file", object : ByteArrayResource(testZipFile!!.readBytes()) {
+ override fun getFilename(): String {
+ return "test.zip"
+ }
+ })
+ }.build()
+
+ val saveBP = webTestClient
+ .post()
+ .uri("/api/v1/blueprint-model")
+ .body(BodyInserters.fromMultipartData(body))
+ .exchange()
+ .expectStatus().isOk
+ .returnResult<BlueprintModelSearch>()
+ .responseBody
+ .awaitSingle()
+
+ assertNotNull(saveBP, "failed to get response")
+ assertEquals("baseconfiguration", saveBP.artifactName, "mismatch artifact name")
+ assertEquals("1.0.0", saveBP.artifactVersion, "mismatch artifact version")
+ assertEquals("N", saveBP.published, "mismatch publish")
+ saveBP
+ }
+ }
+
+ @Test
+ @Throws(JSONException::class)
+ fun test02_getBluePrintByNameAndVersion() {
+ webTestClient(HttpMethod.GET, null,
+ "/api/v1/blueprint-model/by-name/${bp!!.artifactName}/version/${bp!!.artifactVersion}",
+ HttpStatus.OK, false)
+ }
+
+
+ @Test
+ @Throws(JSONException::class)
+ fun test03_getBlueprintModel() {
+ webTestClient(HttpMethod.GET, null,
+ "/api/v1/blueprint-model/${bp!!.id}",
+ HttpStatus.OK, false)
+ }
+
+ @Test
+ @Throws(JSONException::class)
+ fun test04_getAllBlueprintModel() {
+ webTestClient(HttpMethod.GET, null, "/api/v1/blueprint-model", HttpStatus.OK, false)
+ }
+
+ @Test
+ @Throws(JSONException::class)
+ fun test05_downloadBluePrint() {
+ webTestClient(HttpMethod.GET, null,
+ "/api/v1/blueprint-model/download/${bp!!.id}",
+ HttpStatus.OK, false)
+ }
+
+ @Test
+ fun test06_enrichBlueprintModel() {
+ }
+
+ @Test
+ fun test07_publishBlueprintModel() {
+ }
+
+ @Test
+ @Throws(JSONException::class)
+ fun test08_searchBlueprintModels() {
+ webTestClient(HttpMethod.GET, null,
+ "/api/v1/blueprint-model/search/${bp!!.artifactName}",
+ HttpStatus.OK, false)
+ }
+
+ @Test
+ @Throws(JSONException::class)
+ fun test09_downloadBlueprintByNameAndVersion() {
+ webTestClient(HttpMethod.GET, null,
+ "/api/v1/blueprint-model/download/by-name/${bp!!.artifactName}/version/${bp!!.artifactVersion}",
+ HttpStatus.OK, false)
+ }
+
+ @Test
+ fun test10_deleteBluePrint() {
+ webTestClient.delete().uri("/api/v1/blueprint-model/${bp!!.id}")
+ .header("Authorization", "Basic " + Base64Utils
+ .encodeToString(("ccsdkapps" + ":" + "ccsdkapps").toByteArray(UTF_8)))
+ .exchange()
+ .expectStatus().is2xxSuccessful
+ }
+
+ @Throws(JSONException::class)
+ private fun webTestClient(requestMethod: HttpMethod, body: BodyInserters.MultipartInserter?, uri: String,
+ expectedResponceStatus: HttpStatus, setParam: Boolean) {
+
+ log.info("Requesting($uri): Method(${requestMethod.name})")
+
+ webTestClient.method(requestMethod).uri(uri)
+ .header("Authorization", "Basic " + Base64Utils
+ .encodeToString(("ccsdkapps" + ":" + "ccsdkapps").toByteArray(UTF_8)))
+ .body(body)
+ .exchange()
+ .expectStatus().isEqualTo(expectedResponceStatus)
+ .expectBody()
+ .returnResult().responseBody!!
+
+ }
+
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiTestConfiguration.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiTestConfiguration.kt
new file mode 100644
index 000000000..03e016b8e
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiTestConfiguration.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.cds.blueprintsprocessor.designer.api
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan(basePackages = ["org.onap.ccsdk.cds.controllerblueprints",
+ "org.onap.ccsdk.cds.blueprintsprocessor"])
+@EnableAutoConfiguration
+open class DesignerApiTestConfiguration
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties
new file mode 100755
index 000000000..e22e522ee
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+spring.main.banner-mode=off
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
+logging.level.org.springframework.web=INFO
+logging.level.org.hibernate.SQL=warn
+logging.level.org.hibernate.type.descriptor.sql=debug
+
+blueprintsprocessor.db.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
+blueprintsprocessor.db.username=sa
+blueprintsprocessor.db.password=
+blueprintsprocessor.db.driverClassName=org.h2.Driver
+blueprintsprocessor.db.hibernateHbm2ddlAuto=create-drop
+blueprintsprocessor.db.hibernateDDLAuto=update
+blueprintsprocessor.db.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy
+blueprintsprocessor.db.hibernateDialect=org.hibernate.dialect.H2Dialect
+
+# Load Resource Source Mappings
+resourceSourceMappings=processor-db=source-db,input=source-input,default=source-default,sdnc=source-rest,aai-data=source-rest,capability=source-capability
+# Controller Blueprints Core Configuration
+blueprintsprocessor.blueprintDeployPath=./target/blueprints/deploy
+blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive
+blueprintsprocessor.blueprintWorkingPath=./target/blueprints/work
+
+# Python executor
+blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints
+blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints
diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..feb4514d6
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/logback-test.xml
@@ -0,0 +1,39 @@
+<!--
+ ~ Copyright © 2018 IBM.
+ ~ Modifications Copyright © 2017-2018 AT&T Intellectual Property.
+ ~
+ ~ 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.
+ -->
+
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{50} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <logger name="org.springframework" level="warn"/>
+ <logger name="org.springframework.web" level="warn"/>
+ <logger name="org.hibernate" level="error"/>
+ <logger name="org.onap.ccsdk.cds.controllerblueprints.core" level="warn"/>
+ <logger name="org.onap.ccsdk.cds.controllerblueprints" level="info"/>
+
+ <root level="warn">
+ <appender-ref ref="STDOUT"/>
+ </root>
+
+</configuration>