From b8539cca6f2bc572801640b3fcefe83dcecf5ef5 Mon Sep 17 00:00:00 2001 From: Brinda Santh Date: Thu, 29 Aug 2019 16:46:22 -0400 Subject: Refactor Blueprint model controller to designer api. Change-Id: I6e729aab24262f6bdef4b92febf9f65a4819d142 Issue-ID: CCSDK-1663 Signed-off-by: Brinda Santh --- .../modules/inbounds/designer-api/pom.xml | 8 +- .../designer/api/BluePrintModelHandler.kt | 335 +++++++++++++++++++++ .../designer/api/BlueprintModelController.kt | 108 +++++++ .../designer/api/BlueprintModelControllerTest.kt | 223 ++++++++++++++ .../designer/api/DesignerApiTestConfiguration.kt | 27 ++ .../src/test/resources/application-test.properties | 41 +++ .../src/test/resources/logback-test.xml | 39 +++ .../service/controller/BlueprintModelController.kt | 109 ------- .../service/handler/BluePrintModelHandler.kt | 335 --------------------- .../controller/BlueprintModelControllerTest.kt | 224 -------------- 10 files changed, 775 insertions(+), 674 deletions(-) create mode 100644 ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BluePrintModelHandler.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelController.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/BlueprintModelControllerTest.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/DesignerApiTestConfiguration.kt create mode 100755 ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/application-test.properties create mode 100644 ms/blueprintsprocessor/modules/inbounds/designer-api/src/test/resources/logback-test.xml delete mode 100644 ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelController.kt delete mode 100644 ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/handler/BluePrintModelHandler.kt delete mode 100644 ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelControllerTest.kt 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 @@ 4.0.0 designer-api jar - Blueprints Designer API - Blueprints Designer API - - - true - + Blueprints Processor Designer API + Blueprints Processor Designer API 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 list of the controller blueprint archives + */ + open fun allBlueprintModel(): List { + return blueprintModelSearchRepository.findAll() + } + + /** + * This is a saveBlueprintModel method + * + * @param filePart filePart + * @return Mono + * @throws BluePrintException BluePrintException + */ + @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 + */ + open fun searchBlueprintModels(tags: String): List { + 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 + * @throws BluePrintException BluePrintException + */ + @Throws(BluePrintException::class) + open fun downloadBlueprintModelFileByNameAndVersion(name: String, + version: String): ResponseEntity { + 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 + * @throws BluePrintException BluePrintException + */ + @Throws(BluePrintException::class) + open fun downloadBlueprintModelFile(id: String): ResponseEntity { + 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 + */ + private fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity { + 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 + * @throws BluePrintException BluePrintException + */ + @Throws(BluePrintException::class) + open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity { + 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 { + 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 { + 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 { + 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 = 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 { + 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() + .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 @@ + + + + + + + + %d{HH:mm:ss.SSS} %-5level [%thread] %logger{50} - %msg%n + + + + + + + + + + + + + + + diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelController.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelController.kt deleted file mode 100644 index a214f961e..000000000 --- a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelController.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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.controllerblueprints.service.controller - -import kotlinx.coroutines.runBlocking -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException -import org.onap.ccsdk.cds.controllerblueprints.service.domain.BlueprintModelSearch -import org.onap.ccsdk.cds.controllerblueprints.service.handler.BluePrintModelHandler -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 { - 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 { - 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 { - 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 = 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 { - return this.bluePrintModelHandler.searchBlueprintModels(tags) - } -} diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/handler/BluePrintModelHandler.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/handler/BluePrintModelHandler.kt deleted file mode 100644 index f40da68f6..000000000 --- a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/handler/BluePrintModelHandler.kt +++ /dev/null @@ -1,335 +0,0 @@ -/* - * 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.controllerblueprints.service.handler - -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 list of the controller blueprint archives - */ - open fun allBlueprintModel(): List { - return blueprintModelSearchRepository.findAll() - } - - /** - * This is a saveBlueprintModel method - * - * @param filePart filePart - * @return Mono - * @throws BluePrintException BluePrintException - */ - @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 - */ - open fun searchBlueprintModels(tags: String): List { - 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 - * @throws BluePrintException BluePrintException - */ - @Throws(BluePrintException::class) - open fun downloadBlueprintModelFileByNameAndVersion(name: String, - version: String): ResponseEntity { - 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 - * @throws BluePrintException BluePrintException - */ - @Throws(BluePrintException::class) - open fun downloadBlueprintModelFile(id: String): ResponseEntity { - 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 - */ - private fun prepareResourceEntity(fileName: String, file: ByteArray): ResponseEntity { - 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 - * @throws BluePrintException BluePrintException - */ - @Throws(BluePrintException::class) - open suspend fun enrichBlueprint(filePart: FilePart): ResponseEntity { - 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/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelControllerTest.kt b/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelControllerTest.kt deleted file mode 100644 index 1ef717a5c..000000000 --- a/ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/controller/BlueprintModelControllerTest.kt +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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.controllerblueprints.service.controller - -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.controllerblueprints.TestApplication -import org.onap.ccsdk.cds.controllerblueprints.core.* -import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration -import org.onap.ccsdk.cds.controllerblueprints.service.BluePrintDesignerCoreConfiguration -import org.onap.ccsdk.cds.controllerblueprints.service.domain.BlueprintModelSearch -import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.context.annotation.ComponentScan -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.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 java.nio.file.Paths -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 = [TestApplication::class, BluePrintDesignerCoreConfiguration::class]) -@ComponentScan(basePackages = ["org.onap.ccsdk.cds.controllerblueprints"]) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@EnableAutoConfiguration -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 = Paths.get(blueprintDir).toFile().normalize() - 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() - .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 -- cgit 1.2.3-korg