From 83eab67a658e57548f398a7ddd872de4ebab5ca3 Mon Sep 17 00:00:00 2001 From: Steve Alphonse Siani Date: Wed, 9 Jan 2019 14:34:06 -0500 Subject: Blueprint exception handler and REST responses Change-Id: I5727238cd4c3f3f5475c3f3022e56f1acc0d73bf Issue-ID: CCSDK-418 Signed-off-by: Steve Alphonse Siani Signed-off-by: Balazinski --- .../core/data/BlueprintErrorCode.kt | 97 ++++++++++++++++ .../core/utils/BluePrintFileUtils.kt | 24 +++- .../db/BlueprintProcessorCatalogServiceImpl.kt | 11 +- .../service/BlueprintModelService.java | 124 +++++++++++++++------ .../service/common/ErrorMessage.java | 4 + .../service/domain/BlueprintModel.java | 2 +- .../service/domain/BlueprintModelSearch.java | 4 + .../service/rs/BlueprintModelRest.java | 23 ++-- .../ControllerBlueprintExeptionHandler.kt | 50 +++++++++ .../load/ControllerBlueprintCatalogServiceImpl.kt | 13 ++- .../service/utils/BluePrintEnhancerUtils.kt | 3 +- 11 files changed, 304 insertions(+), 51 deletions(-) create mode 100644 components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BlueprintErrorCode.kt create mode 100644 ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BlueprintErrorCode.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BlueprintErrorCode.kt new file mode 100644 index 00000000..bef174b9 --- /dev/null +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BlueprintErrorCode.kt @@ -0,0 +1,97 @@ +/* + * Copyright © 2018-2019 Bell Canada 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. + */ +package org.onap.ccsdk.apps.controllerblueprints.core.data + +import java.util.HashMap + +/** + * ErrorCode.java Purpose: Maintain a list of HTTP status codes + * + * @author Steve Siani + * @version 1.0 + */ +enum class ErrorCode (val value: Int, val httpCode: Int) { + + /// TODO: Add more attribute for each needed application protocol + // TODO: Example: INVALID_FILE_EXTENSION(2, 415, 25) + GENERIC_FAILURE(1, 500) { + override fun message(detailMsg: String): String { + return "Generic failure. Details : {$detailMsg}" + } + }, + INVALID_FILE_EXTENSION(2, 415) { + override fun message(detailMsg: String): String { + return "Unexpected file extension. Details : {$detailMsg}" + } + }, + BLUEPRINT_PATH_MISSING(3, 503) { + override fun message(detailMsg: String): String { + return "Blueprint path missing or wrong. Details : {$detailMsg}" + } + }, + BLUEPRINT_WRITING_FAIL(4, 503) { + override fun message(detailMsg: String): String { + return "Fail to write blueprint files. Details : {$detailMsg}" + } + }, + IO_FILE_INTERRUPT(5, 503) { + override fun message(detailMsg: String): String { + return "IO file system interruption. Details : {$detailMsg}" + } + }, + INVALID_REQUEST_FORMAT(6, 400) { + override fun message(detailMsg: String): String { + return "Bad request. Details : {$detailMsg}" + } + }, + UNAUTHORIZED_REQUEST(7, 401) { + override fun message(detailMsg: String): String { + return "The request requires user authentication. Details : {$detailMsg}" + } + }, + REQUEST_NOT_FOUND(8, 404) { + override fun message(detailMsg: String): String { + return "Request mapping doesn't exist. Details : {$detailMsg}" + } + }, + RESOURCE_NOT_FOUND(9, 404) { + override fun message(detailMsg: String): String { + return "No response was found for this request in the server. Details : {$detailMsg}" + } + }, + CONFLICT_ADDING_RESOURCE(10, 409) { + override fun message(detailMsg: String): String { + return "Duplicated entry while saving Blueprint. Details : {$detailMsg}" + } + }; + + abstract fun message(detailMsg: String): String + + companion object { + + private val map = HashMap() + + init { + for (errorCode in ErrorCode.values()) { + map[errorCode.value] = errorCode + } + } + + fun valueOf(value: Int): ErrorCode? { + return if (map.containsKey(value)) map[value] else map[1] + } + } +} \ No newline at end of file diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintFileUtils.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintFileUtils.kt index 5a10e43f..9746bf57 100755 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintFileUtils.kt +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintFileUtils.kt @@ -24,6 +24,7 @@ import org.apache.commons.io.FileUtils import org.apache.commons.lang3.StringUtils import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode import org.onap.ccsdk.apps.controllerblueprints.core.data.ImportDefinition import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext @@ -105,7 +106,8 @@ class BluePrintFileUtils { val definitionDir = File(definitionPath) check(definitionDir.exists()) { - throw BluePrintException("couldn't get definition file under path(${definitionDir.absolutePath})") + throw BluePrintException(ErrorCode.BLUEPRINT_PATH_MISSING.value, "couldn't get definition file under " + + "path(${definitionDir.absolutePath})") } blueprintContext.serviceTemplate.dataTypes?.let { @@ -192,7 +194,8 @@ class BluePrintFileUtils { Files.write(definitionFile.toPath(), content.toByteArray(), StandardOpenOption.CREATE_NEW) check(definitionFile.exists()) { - throw BluePrintException("couldn't write definition file under path(${definitionFile.absolutePath})") + throw BluePrintException(ErrorCode.BLUEPRINT_WRITING_FAIL.value, "couldn't write definition file under " + + "path(${definitionFile.absolutePath})") } } @@ -201,7 +204,8 @@ class BluePrintFileUtils { Files.write(typeFile.toPath(), content.toByteArray(), StandardOpenOption.CREATE_NEW) check(typeFile.exists()) { - throw BluePrintException("couldn't write $type.json file under path(${typeFile.absolutePath})") + throw BluePrintException(ErrorCode.BLUEPRINT_WRITING_FAIL.value, "couldn't write $type.json file under " + + "path(${typeFile.absolutePath})") } } @@ -213,9 +217,21 @@ class BluePrintFileUtils { "\nTemplate-Tags: " } + + fun getBluePrintFile(fileName: String, targetPath: Path) : File { + val filePath = targetPath.resolve(fileName).toString() + val file = File(filePath) + check(file.exists()) { + throw BluePrintException(ErrorCode.BLUEPRINT_PATH_MISSING.value, "couldn't get definition file under " + + "path(${file.absolutePath})") + } + return file + } + fun getCbaStorageDirectory(path: String): Path { check(StringUtils.isNotBlank(path)) { - throw BluePrintException("CBA Path is missing.") + throw BluePrintException(ErrorCode.BLUEPRINT_PATH_MISSING.value, "couldn't get " + + "Blueprint folder under path($path)") } val fileStorageLocation = Paths.get(path).toAbsolutePath().normalize() diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt index 7c0eb6b6..89b7f649 100755 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/db/BlueprintProcessorCatalogServiceImpl.kt @@ -22,12 +22,15 @@ import org.onap.ccsdk.apps.blueprintsprocessor.db.primary.domain.BlueprintProces import org.onap.ccsdk.apps.blueprintsprocessor.db.primary.repository.BlueprintProcessorModelContentRepository import org.onap.ccsdk.apps.blueprintsprocessor.db.primary.repository.BlueprintProcessorModelRepository import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException import org.onap.ccsdk.apps.controllerblueprints.core.common.ApplicationConstants import org.onap.ccsdk.apps.controllerblueprints.core.config.BluePrintLoadConfiguration +import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintValidatorService import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintArchiveUtils import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils import org.onap.ccsdk.apps.controllerblueprints.db.resources.BlueprintCatalogServiceImpl +import org.springframework.dao.DataIntegrityViolationException import org.springframework.stereotype.Service import java.io.File import java.nio.file.Files @@ -38,7 +41,6 @@ Similar/Duplicate implementation in [org.onap.ccsdk.apps.controllerblueprints.se @Service class BlueprintProcessorCatalogServiceImpl(bluePrintLoadConfiguration: BluePrintLoadConfiguration, private val bluePrintValidatorService: BluePrintValidatorService, - private val blueprintModelContentRepository: BlueprintProcessorModelContentRepository, private val blueprintModelRepository: BlueprintProcessorModelRepository) : BlueprintCatalogServiceImpl(bluePrintLoadConfiguration) { @@ -80,7 +82,12 @@ class BlueprintProcessorCatalogServiceImpl(bluePrintLoadConfiguration: BluePrint // Set the Blueprint Model Content into blueprintModel blueprintModel.blueprintModelContent = blueprintModelContent - blueprintModelRepository.saveAndFlush(blueprintModel) + try { + blueprintModelRepository.saveAndFlush(blueprintModel) + } catch (ex: DataIntegrityViolationException) { + throw BluePrintException(ErrorCode.CONFLICT_ADDING_RESOURCE.value, "The blueprint entry " + + "is already exist in database: ${ex.message}", ex) + } } } } \ No newline at end of file diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BlueprintModelService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BlueprintModelService.java index ca0e2439..e80fa8cd 100644 --- a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BlueprintModelService.java +++ b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BlueprintModelService.java @@ -17,11 +17,11 @@ package org.onap.ccsdk.apps.controllerblueprints.service; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; import org.jetbrains.annotations.NotNull; import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException; +import org.onap.ccsdk.apps.controllerblueprints.core.common.ApplicationConstants; import org.onap.ccsdk.apps.controllerblueprints.core.config.BluePrintLoadConfiguration; +import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode; import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintCatalogService; import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintFileUtils; import org.onap.ccsdk.apps.controllerblueprints.service.domain.BlueprintModel; @@ -56,8 +56,6 @@ import java.util.Optional; @Service public class BlueprintModelService { - private static EELFLogger log = EELFManager.getInstance().getLogger(BlueprintModelService.class); - @Autowired private BluePrintLoadConfiguration bluePrintLoadConfiguration; @@ -73,9 +71,9 @@ public class BlueprintModelService { @Autowired private ControllerBlueprintModelContentRepository blueprintModelContentRepository; - private static final String BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%d) from repo"; - private static final String BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG = "failed to get blueprint model by name(%d)" + - " and version(%d) from repo"; + private static final String BLUEPRINT_MODEL_ID_FAILURE_MSG = "failed to get blueprint model id(%s) from repo"; + private static final String BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG = "failed to get blueprint model by name(%s)" + + " and version(%s) from repo"; /** * This is a saveBlueprintModel method @@ -87,28 +85,36 @@ public class BlueprintModelService { public Mono saveBlueprintModel(FilePart filePart) throws BluePrintException { try { Path cbaLocation = BluePrintFileUtils.Companion - .getCbaStorageDirectory(bluePrintLoadConfiguration.blueprintArchivePath); + .getCbaStorageDirectory(bluePrintLoadConfiguration.blueprintArchivePath); return BluePrintEnhancerUtils.Companion.saveCBAFile(filePart, cbaLocation).map(fileName -> { String blueprintId = bluePrintCatalogService - .uploadToDataBase(cbaLocation.resolve(fileName).toString(), false); + .uploadToDataBase(cbaLocation.resolve(fileName).toString(), false); return blueprintModelSearchRepository.findById(blueprintId).get(); }); - - } catch (IOException | BluePrintException e) { - return Mono.error(new BluePrintException("Error uploading the CBA file in channel.", e)); + } catch (IOException e) { + throw new BluePrintException(ErrorCode.IO_FILE_INTERRUPT.getValue(), + String.format("I/O Error while uploading the CBA file: %s", e.getMessage()), e); } } /** - * This is a publishBlueprintModel method + * This is a publishBlueprintModel method to change the status published to YES * * @param id id * @return BlueprintModelSearch * @throws BluePrintException BluePrintException */ public BlueprintModelSearch publishBlueprintModel(String id) throws BluePrintException { - // TODO Implement publish Functionality - return null; + BlueprintModelSearch blueprintModelSearch; + Optional dbBlueprintModel = blueprintModelSearchRepository.findById(id); + if (dbBlueprintModel.isPresent()) { + blueprintModelSearch = dbBlueprintModel.get(); + } else { + String msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), msg); + } + blueprintModelSearch.setPublished(ApplicationConstants.ACTIVE_Y); + return blueprintModelSearchRepository.saveAndFlush(blueprintModelSearch); } /** @@ -122,44 +128,78 @@ public class BlueprintModelService { } /** - * This is a getBlueprintModelByNameAndVersion method + * This is a getBlueprintModelSearchByNameAndVersion method * * @param name name * @param version version * @return BlueprintModelSearch + * @throws BluePrintException BluePrintException */ - public BlueprintModelSearch getBlueprintModelByNameAndVersion(@NotNull String name, @NotNull String version) - throws BluePrintException { + public BlueprintModelSearch getBlueprintModelSearchByNameAndVersion(@NotNull String name, @NotNull String version) + throws BluePrintException { BlueprintModelSearch blueprintModelSearch; Optional dbBlueprintModel = blueprintModelSearchRepository - .findByArtifactNameAndArtifactVersion(name, version); + .findByArtifactNameAndArtifactVersion(name, version); if (dbBlueprintModel.isPresent()) { blueprintModelSearch = dbBlueprintModel.get(); } else { - throw new BluePrintException(String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), + String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version)); } - return blueprintModelSearch; } /** - * This is a downloadBlueprintModelFile method to find the target file to download and return a file resource using MONO + * This is a downloadBlueprintModelFileByNameAndVersion method to download a Blueprint by Name and Version * + * @param name name + * @param version version * @return ResponseEntity + * @throws BluePrintException BluePrintException + */ + public ResponseEntity downloadBlueprintModelFileByNameAndVersion(@NotNull String name, @NotNull String version) + throws BluePrintException { + BlueprintModel blueprintModel; + try { + blueprintModel = getBlueprintModelByNameAndVersion(name, version); + } catch (BluePrintException e) { + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), String.format("Error while " + + "downloading the CBA file: %s", e.getMessage()), e); + } + String fileName = blueprintModel.getId() + ".zip"; + byte[] file = blueprintModel.getBlueprintModelContent().getContent(); + 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 */ public ResponseEntity downloadBlueprintModelFile(@NotNull String id) throws BluePrintException { BlueprintModel blueprintModel; try { blueprintModel = getBlueprintModel(id); } catch (BluePrintException e) { - throw new BluePrintException("Error uploading the CBA file in channel.", e); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), String.format("Error while " + + "downloading the CBA file: %s", e.getMessage()), e); } String fileName = blueprintModel.getId() + ".zip"; byte[] file = blueprintModel.getBlueprintModelContent().getContent(); + return prepareResourceEntity(fileName, file); + } + + /** + * + * @param (fileName, file) + * @return ResponseEntity + */ + private ResponseEntity prepareResourceEntity(String fileName, byte[] file) { return ResponseEntity.ok() - .contentType(MediaType.parseMediaType("text/plain")) - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"") - .body(new ByteArrayResource(file)); + .contentType(MediaType.parseMediaType("text/plain")) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"") + .body(new ByteArrayResource(file)); } /** @@ -175,9 +215,30 @@ public class BlueprintModelService { if (dbBlueprintModel.isPresent()) { blueprintModel = dbBlueprintModel.get(); } else { - throw new BluePrintException(String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)); + String msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), msg); } + return blueprintModel; + } + /** + * This is a getBlueprintModelByNameAndVersion method + * + * @param name name + * @param version version + * @return BlueprintModel + * @throws BluePrintException BluePrintException + */ + private BlueprintModel getBlueprintModelByNameAndVersion(@NotNull String name, @NotNull String version) + throws BluePrintException { + BlueprintModel blueprintModel; + Optional dbBlueprintModel = blueprintModelRepository.findByArtifactNameAndArtifactVersion(name, version); + if (dbBlueprintModel.isPresent()) { + blueprintModel = dbBlueprintModel.get(); + } else { + String msg = String.format(BLUEPRINT_MODEL_NAME_VERSION_FAILURE_MSG, name, version); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), msg); + } return blueprintModel; } @@ -194,7 +255,8 @@ public class BlueprintModelService { if (dbBlueprintModel.isPresent()) { blueprintModelSearch = dbBlueprintModel.get(); } else { - throw new BluePrintException(String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)); + String msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), msg); } return blueprintModelSearch; @@ -213,17 +275,17 @@ public class BlueprintModelService { blueprintModelContentRepository.deleteByBlueprintModel(dbBlueprintModel.get()); blueprintModelRepository.delete(dbBlueprintModel.get()); } else { - throw new BluePrintException(String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id)); + String msg = String.format(BLUEPRINT_MODEL_ID_FAILURE_MSG, id); + throw new BluePrintException(ErrorCode.RESOURCE_NOT_FOUND.getValue(), msg); } } /** * This is a getAllBlueprintModel method to retrieve all the BlueprintModel in Database * - * @return List list with the controller blueprint archives + * @return List list of the controller blueprint archives */ public List getAllBlueprintModel() { return blueprintModelSearchRepository.findAll(); } - } diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java index 43164126..5486262f 100644 --- a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java +++ b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java @@ -19,11 +19,15 @@ package org.onap.ccsdk.apps.controllerblueprints.service.common; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; import java.io.Serializable; import java.util.Date; @JsonInclude(Include.NON_NULL) +@JsonTypeName("errorMessage") +@JsonTypeInfo(include= JsonTypeInfo.As.WRAPPER_OBJECT, use=JsonTypeInfo.Id.NAME) public class ErrorMessage implements Serializable { private String message; private Integer code; diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModel.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModel.java index 93954daa..245e4a80 100755 --- a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModel.java +++ b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModel.java @@ -36,7 +36,7 @@ import java.util.Date; @EntityListeners({AuditingEntityListener.class}) @Entity -@Table(name = "CONFIG_MODEL") +@Table(name = "CONFIG_MODEL", uniqueConstraints=@UniqueConstraint(columnNames={"artifact_name","artifact_version"})) @Proxy(lazy=false) public class BlueprintModel implements Serializable { private static final long serialVersionUID = 1L; diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModelSearch.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModelSearch.java index 8b51bce3..33753b2f 100644 --- a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModelSearch.java +++ b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/BlueprintModelSearch.java @@ -18,6 +18,8 @@ package org.onap.ccsdk.apps.controllerblueprints.service.domain; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; import org.springframework.data.annotation.LastModifiedDate; import javax.persistence.*; @@ -26,6 +28,8 @@ import java.util.Date; @Entity @Table(name = "CONFIG_MODEL") +@JsonTypeName("blueprintModel") +@JsonTypeInfo(include= JsonTypeInfo.As.WRAPPER_OBJECT, use=JsonTypeInfo.Id.NAME) public class BlueprintModelSearch implements Serializable { private static final long serialVersionUID = 1L; diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/BlueprintModelRest.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/BlueprintModelRest.java index 9d0b1e3e..255137bf 100644 --- a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/BlueprintModelRest.java +++ b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/BlueprintModelRest.java @@ -42,31 +42,38 @@ public class BlueprintModelRest { @PostMapping(path = "", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public @ResponseBody - Mono saveBluePrint(@RequestPart("file") FilePart file) throws BluePrintException{ + Mono saveBlueprint(@RequestPart("file") FilePart file) throws BluePrintException{ return blueprintModelService.saveBlueprintModel(file); } @DeleteMapping(path = "/{id}") - public void deleteBluePrint(@PathVariable(value = "id") String id) throws BluePrintException { + public void deleteBlueprint(@PathVariable(value = "id") String id) throws BluePrintException { this.blueprintModelService.deleteBlueprintModel(id); } @GetMapping(path = "/by-name/{name}/version/{version}", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody - BlueprintModelSearch getBluePrintByNameAndVersion(@PathVariable(value = "name") String name, - @PathVariable(value = "version") String version) throws BluePrintException { - return this.blueprintModelService.getBlueprintModelByNameAndVersion(name, version); + BlueprintModelSearch getBlueprintByNameAndVersion(@PathVariable(value = "name") String name, + @PathVariable(value = "version") String version) throws BluePrintException { + return this.blueprintModelService.getBlueprintModelSearchByNameAndVersion(name, version); + } + + @GetMapping(path = "/download/by-name/{name}/version/{version}", produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody + ResponseEntity downloadBlueprintByNameAndVersion(@PathVariable(value = "name") String name, + @PathVariable(value = "version") String version) throws BluePrintException { + return this.blueprintModelService.downloadBlueprintModelFileByNameAndVersion(name, version); } @GetMapping(path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody - BlueprintModelSearch getCBA(@PathVariable(value = "id") String id) throws BluePrintException { + BlueprintModelSearch getBlueprintModel(@PathVariable(value = "id") String id) throws BluePrintException { return this.blueprintModelService.getBlueprintModelSearch(id); } @GetMapping(path = "", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody - List getAllCBA() { + List getAllBlueprintModel() { return this.blueprintModelService.getAllBlueprintModel(); } @@ -76,7 +83,7 @@ public class BlueprintModelRest { return this.blueprintModelService.downloadBlueprintModelFile(id); } - @GetMapping(path = "/publish/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @PutMapping(path = "/publish/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody BlueprintModelSearch publishBlueprintModel(@PathVariable(value = "id") String id) throws BluePrintException { return this.blueprintModelService.publishBlueprintModel(id); diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt new file mode 100644 index 00000000..a0e47d72 --- /dev/null +++ b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/controller/ControllerBlueprintExeptionHandler.kt @@ -0,0 +1,50 @@ +/* + * Copyright © 2018-2019 Bell Canada 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. + */ + +package org.onap.ccsdk.apps.controllerblueprints.service.controller + +import org.springframework.web.bind.annotation.RestControllerAdvice +import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode +import org.onap.ccsdk.apps.controllerblueprints.service.common.ErrorMessage +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.ExceptionHandler + +/** + * ControllerBlueprintExceptionHandler.java Purpose: Handle exceptions in controllerBlueprint API and provide the wright + * HTTP code status + * + * @author Vinal Patel + * @version 1.0 + */ +@RestControllerAdvice("org.onap.ccsdk.apps.controllerblueprints") +open class ControllerBlueprintExeptionHandler { + + @ExceptionHandler + fun ControllerBlueprintException(e: BluePrintException): ResponseEntity { + var errorCode = ErrorCode.valueOf(e.code) + val errorMessage = ErrorMessage(errorCode?.message(e.message!!), errorCode?.value, "ControllerBluePrint_Error_Message") + return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode!!.httpCode)) + } + + @ExceptionHandler + fun ControllerBlueprintException(e: Exception): ResponseEntity { + var errorCode = ErrorCode.GENERIC_FAILURE + val errorMessage = ErrorMessage(errorCode?.message(e.message!!), errorCode?.value, "ControllerBluePrint_Error_Message") + return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode!!.httpCode)) + } +} \ No newline at end of file diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/load/ControllerBlueprintCatalogServiceImpl.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/load/ControllerBlueprintCatalogServiceImpl.kt index ac81f8fa..6b367c4d 100755 --- a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/load/ControllerBlueprintCatalogServiceImpl.kt +++ b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/load/ControllerBlueprintCatalogServiceImpl.kt @@ -20,14 +20,16 @@ package org.onap.ccsdk.apps.controllerblueprints.service.load import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.apps.controllerblueprints.core.common.ApplicationConstants import org.onap.ccsdk.apps.controllerblueprints.core.config.BluePrintLoadConfiguration +import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintValidatorService import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintArchiveUtils import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils import org.onap.ccsdk.apps.controllerblueprints.db.resources.BlueprintCatalogServiceImpl import org.onap.ccsdk.apps.controllerblueprints.service.domain.BlueprintModel import org.onap.ccsdk.apps.controllerblueprints.service.domain.BlueprintModelContent -import org.onap.ccsdk.apps.controllerblueprints.service.repository.ControllerBlueprintModelContentRepository import org.onap.ccsdk.apps.controllerblueprints.service.repository.ControllerBlueprintModelRepository +import org.springframework.dao.DataIntegrityViolationException import org.springframework.stereotype.Service import java.io.File import java.nio.file.Files @@ -38,7 +40,6 @@ Similar implementation in [org.onap.ccsdk.apps.blueprintsprocessor.db.BlueprintP @Service class ControllerBlueprintCatalogServiceImpl(bluePrintLoadConfiguration: BluePrintLoadConfiguration, private val bluePrintValidatorService: BluePrintValidatorService, - private val blueprintModelContentRepository: ControllerBlueprintModelContentRepository, private val blueprintModelRepository: ControllerBlueprintModelRepository) : BlueprintCatalogServiceImpl(bluePrintLoadConfiguration) { @@ -56,7 +57,6 @@ class ControllerBlueprintCatalogServiceImpl(bluePrintLoadConfiguration: BluePrin if ((valid && checkValidity!!) || (!valid && !checkValidity!!)) { val metaData = bluePrintRuntimeService.bluePrintContext().metadata!! - // FIXME("Check Duplicate for Artifact Name and Artifact Version") val blueprintModel = BlueprintModel() blueprintModel.id = id blueprintModel.artifactType = ApplicationConstants.ASDC_ARTIFACT_TYPE_SDNC_MODEL @@ -80,7 +80,12 @@ class ControllerBlueprintCatalogServiceImpl(bluePrintLoadConfiguration: BluePrin // Set the Blueprint Model Content into blueprintModel blueprintModel.blueprintModelContent = blueprintModelContent - blueprintModelRepository.saveAndFlush(blueprintModel) + try { + blueprintModelRepository.saveAndFlush(blueprintModel) + } catch (ex: DataIntegrityViolationException) { + throw BluePrintException(ErrorCode.CONFLICT_ADDING_RESOURCE.value, "The blueprint entry " + + "is already exist in database: ${ex.message}", ex) + } } } } \ No newline at end of file diff --git a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt index c2d6f6aa..5e715f78 100644 --- a/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt +++ b/ms/controllerblueprints/modules/service/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/service/utils/BluePrintEnhancerUtils.kt @@ -20,6 +20,7 @@ package org.onap.ccsdk.apps.controllerblueprints.service.utils import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactType import org.onap.ccsdk.apps.controllerblueprints.core.data.DataType +import org.onap.ccsdk.apps.controllerblueprints.core.data.ErrorCode import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeType import org.onap.ccsdk.apps.controllerblueprints.core.data.RelationshipType import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintRepoService @@ -92,7 +93,7 @@ class BluePrintEnhancerUtils { // Check if the file's extension is "CBA" if (StringUtils.getFilenameExtension(fileName) != "zip") { - throw BluePrintException("Invalid file extension required ZIP") + throw BluePrintException(ErrorCode.INVALID_FILE_EXTENSION.value, "Invalid file extension required ZIP") } // Change file name to match a pattern -- cgit 1.2.3-korg