summaryrefslogtreecommitdiffstats
path: root/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main
diff options
context:
space:
mode:
authorSerge Simard <serge@agilitae.com>2019-06-18 10:36:57 -0400
committerSerge Simard <serge@agilitae.com>2019-06-18 10:36:57 -0400
commitd1e26003105404f974f9fa45d542f658706ad3cb (patch)
tree154fbabc9232146e518a25dee845ee16ec4f2405 /ms/blueprintsprocessor/modules/inbounds/resource-api/src/main
parent39167cccae3271603819aa39c6476e434c759533 (diff)
Create REST API layer for resource resolution stored configlet
Issue-ID: CCSDK-1407 Signed-off-by: Serge Simard <serge@agilitae.com> Change-Id: I18db6b654cbf4f416af54596ee71f56eaa860d32
Diffstat (limited to 'ms/blueprintsprocessor/modules/inbounds/resource-api/src/main')
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt104
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.kt97
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt71
3 files changed, 272 insertions, 0 deletions
diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt
new file mode 100644
index 000000000..61a9541d3
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.cds.blueprintsprocessor.resolutionresults.api
+
+import io.swagger.annotations.ApiOperation
+import kotlinx.coroutines.runBlocking
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.security.access.prepost.PreAuthorize
+import org.springframework.web.bind.annotation.*
+
+/**
+ * Exposes Resolution Results API to store and retrieve resource resolution results from external processes,
+ * like python or ansible scripts
+ *
+ * @author Serge Simard
+ * @version 1.0
+ */
+@RestController
+@RequestMapping("/api/v1/resolution-results")
+open class ResolutionResultsServiceController {
+
+ @Autowired
+ lateinit var resolutionResultsServiceHandler: ResolutionResultsServiceHandler
+
+ @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ fun ping(): String = runBlocking {
+ "Success"
+ }
+
+ @RequestMapping(path = ["/{resolution_result_id}"], method = [RequestMethod.GET], produces = [MediaType.TEXT_PLAIN_VALUE])
+ @ApiOperation(value = "Fetch a stored result by ID",
+ notes = "Loads a stored result using the resolution_result_id primary key")
+ @ResponseBody
+ @PreAuthorize("hasRole('USER')")
+ fun getStoredResultById(@PathVariable(value = "resolution_result_id") resolutionResultId: String)
+ : String = runBlocking {
+ resolutionResultsServiceHandler.loadStoredResultById(resolutionResultId)
+ }
+
+ @RequestMapping(path = ["/"], method = [RequestMethod.GET], produces = [MediaType.TEXT_PLAIN_VALUE])
+ @ApiOperation(value = "Fetch a stored result ",
+ notes = "Loads a stored result using the blueprint metadata, artifact name and resolution-key")
+ @ResponseBody
+ @PreAuthorize("hasRole('USER')")
+ fun getStoredResult(@RequestParam(value = "bpName") bpName: String,
+ @RequestParam(value = "bpVersion") bpVersion: String,
+ @RequestParam(value = "artifactName") artifactName: String,
+ @RequestParam(value = "resolutionKey") resolutionKey: String,
+ @RequestParam(value = "format", required = false, defaultValue = "text/plain") format: String)
+ : ResponseEntity<String> = runBlocking {
+
+ val payload = resolutionResultsServiceHandler.loadStoredResult(bpName, bpVersion, artifactName, resolutionKey)
+
+ var expectedContentType = format
+ if (expectedContentType.indexOf('/') < 0) {
+ expectedContentType = "application/$expectedContentType"
+ }
+ val expectedMediaType : MediaType = MediaType.valueOf(expectedContentType)
+
+ ResponseEntity.ok().contentType(expectedMediaType).body(payload)
+ }
+
+
+ @PostMapping("/{bpName}/{bpVersion}/{artifactName}/{resolutionKey}", produces = [MediaType.TEXT_PLAIN_VALUE])
+ @ApiOperation(value = "Store result ",
+ notes = "Store result under resolution-key for the specified blueprint/version/artifact.")
+ @ResponseBody
+ @PreAuthorize("hasRole('USER')")
+ fun putStoredResult(@PathVariable(value = "bpName") bpName: String,
+ @PathVariable(value = "bpVersion") bpVersion: String,
+ @PathVariable(value = "artifactName") artifactName: String,
+ @PathVariable(value = "resolutionKey") resolutionKey: String,
+ @RequestBody result : String): String? = runBlocking {
+ resolutionResultsServiceHandler.saveNewStoredResult(bpName, bpVersion, artifactName, resolutionKey, result).id
+ }
+
+
+ @DeleteMapping(path = ["/{resolution_result_id}"])
+ @ApiOperation(value = "Deletes a stored result by ID",
+ notes = "Removes a stored result, using the resolution_result_id primary key")
+ @ResponseBody
+ @PreAuthorize("hasRole('USER')")
+ fun deleteStoredResult(@PathVariable(value = "resolution_result_id") resolutionResultId: String) = runBlocking {
+ resolutionResultsServiceHandler.removeStoredResultById(resolutionResultId)
+ }
+
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.kt
new file mode 100644
index 000000000..69641c628
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.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.cds.blueprintsprocessor.resolutionresults.api
+
+import com.fasterxml.jackson.annotation.JsonFormat
+import com.fasterxml.jackson.annotation.JsonInclude
+import com.fasterxml.jackson.annotation.JsonTypeInfo
+import com.fasterxml.jackson.annotation.JsonTypeName
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ErrorCode
+import org.slf4j.LoggerFactory
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+import org.springframework.orm.jpa.JpaObjectRetrievalFailureException
+import org.springframework.dao.EmptyResultDataAccessException
+import org.springframework.web.server.ServerWebInputException
+import org.springframework.web.bind.annotation.ExceptionHandler
+import org.springframework.web.bind.annotation.RestControllerAdvice
+import java.io.Serializable
+import java.util.*
+
+/**
+ * Handle exceptions in Resolution Results API and provide relevant HTTP status codes and messages
+ *
+ * @author Serge Simard
+ * @version 1.0
+ */
+@RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.resolutionresults")
+open class ResolutionResultsServiceExceptionHandler {
+
+ private val log = LoggerFactory.getLogger(ResolutionResultsServiceExceptionHandler::class.toString())
+
+ private val debugMsg = "ResolutionResultsService_Error_Message"
+
+ @ExceptionHandler
+ fun ResolutionResultsServiceExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> {
+ log.error(e.message)
+ val errorCode = ErrorCode.BLUEPRINT_PATH_MISSING
+ val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
+ return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode))
+ }
+
+ @ExceptionHandler
+ fun ResolutionResultsServiceExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> {
+ log.error(e.message)
+ val errorCode = ErrorCode.INVALID_REQUEST_FORMAT
+ val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
+ return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode))
+ }
+
+ @ExceptionHandler
+ fun ResolutionResultsServiceExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> {
+ log.error(e.message)
+ var errorCode = ErrorCode.RESOURCE_NOT_FOUND
+ val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
+ return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode))
+ }
+
+ @ExceptionHandler
+ fun ResolutionResultsServiceExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorMessage> {
+ log.error(e.message)
+
+ var errorCode = ErrorCode.RESOURCE_NOT_FOUND
+ val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
+ return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode))
+ }
+
+ @ExceptionHandler
+ fun ResolutionResultsServiceExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> {
+ log.error(e.message, e)
+ var errorCode = ErrorCode.GENERIC_FAILURE
+ val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
+ return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode))
+ }
+}
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonTypeName("errorMessage")
+@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
+class ErrorMessage(var message: String?, var code: Int?, var debugMessage: String?) : Serializable {
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+ var timestamp = Date()
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt
new file mode 100644
index 000000000..1fb34d789
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.cds.blueprintsprocessor.resolutionresults.api
+
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionResult
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionResultService
+import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.springframework.stereotype.Service
+import java.util.*
+
+/**
+ * Process Resolution Results API request to store and retrieve resource resolution results using database acess layer
+ * ResourceResolutionResultService and corresponding entities
+ *
+ * @author Serge Simard
+ * @version 1.0
+ */
+@Service
+class ResolutionResultsServiceHandler(private val bluePrintCatalogService: BluePrintCatalogService,
+ private var resolutionResultService: ResourceResolutionResultService) {
+
+ suspend fun loadStoredResultById(resolutionResultId: String): String {
+
+ return resolutionResultService.readByKey(resolutionResultId)
+ }
+
+ suspend fun loadStoredResult(blueprintName : String, blueprintVersion : String, artifactTemplate: String,
+ resolutionKey: String): String {
+
+ val basePath = bluePrintCatalogService.getFromDatabase(blueprintName, blueprintVersion)
+ val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(UUID.randomUUID().toString(),
+ basePath.toString())
+
+ return resolutionResultService.read(blueprintRuntimeService, artifactTemplate, resolutionKey)
+ }
+
+ suspend fun saveNewStoredResult(blueprintName : String, blueprintVersion : String, artifactTemplate: String,
+ resolutionKey: String, result: String): ResourceResolutionResult {
+
+ val basePath = bluePrintCatalogService.getFromDatabase(blueprintName, blueprintVersion)
+ val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(UUID.randomUUID().toString(),
+ basePath.toString())
+
+ val properties = mapOf(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY to resolutionKey)
+
+ val resultStored = resolutionResultService.write(properties, result, blueprintRuntimeService, artifactTemplate)
+
+ return resultStored
+ }
+
+ suspend fun removeStoredResultById(resolutionResultId: String): Unit {
+
+ return resolutionResultService.deleteByKey(resolutionResultId)
+ }
+} \ No newline at end of file