diff options
author | Alexis de Talhouët <adetalhouet89@gmail.com> | 2019-06-20 22:48:12 -0400 |
---|---|---|
committer | Alexis de Talhouët <adetalhouet89@gmail.com> | 2019-07-04 15:53:42 -0400 |
commit | c5276ff19122435871c3deedbf0d983962ac2537 (patch) | |
tree | 6a96054ac6863d641c836e14e76fb3fc7f3a1ece /ms | |
parent | d4b56bc36db1169024fef1f54f924bf3b8f351b6 (diff) |
Refactor resolution controllers
tempalte and resources for get/put API
Change-Id: Ia00bdb08f5f52231481edc6de232f850c66874e9
Issue-ID: CCSDK-1423
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
Diffstat (limited to 'ms')
17 files changed, 410 insertions, 532 deletions
diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java index 2b6f8bcf1..a27e079c7 100644 --- a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/BlueprintProcessorApplication.java @@ -35,7 +35,7 @@ public class BlueprintProcessorApplication { public static void main(String[] args) { - // This is required for ResolutionResultsServiceController.getStoredResult to accept a content-type value + // This is required for TemplateController.getStoredResult to accept a content-type value // as a request parameter, e.g. &format=application%2Fxml is accepted System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true"); diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index b1482934f..96c3f644c 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -21,7 +21,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionResultService +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException @@ -58,7 +58,7 @@ interface ResourceResolutionService { @Service(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION) open class ResourceResolutionServiceImpl(private var applicationContext: ApplicationContext, - private var resolutionResultService: ResourceResolutionResultService, + private var resolutionResultService: TemplateResolutionService, private var blueprintTemplateService: BluePrintTemplateService, private var resourceResolutionDBService: ResourceResolutionDBService) : ResourceResolutionService { @@ -181,7 +181,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica blueprintRuntimeService, artifactPrefix, resourceAssignment) - log.info("resolution saved into database successfully : ($resourceAssignment)") + log.info("Resource resolution saved into database successfully : ($resourceAssignment)") } // Set errors from RA diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt deleted file mode 100644 index ebb34ba4a..000000000 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 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.functions.resource.resolution.db - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants -import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException -import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService -import org.springframework.dao.DataIntegrityViolationException -import org.springframework.stereotype.Service -import java.util.* - -@Service -class ResourceResolutionResultService(private val resourceResolutionRepository: ResourceResolutionResultRepository) { - - suspend fun read(bluePrintRuntimeService: BluePrintRuntimeService<*>, artifactPrefix: String, - resolutionKey: String): String = withContext(Dispatchers.IO) { - - val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! - - val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION] - val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME] - - resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( - resolutionKey, - blueprintName, - blueprintVersion, - artifactPrefix).result!! - } - - suspend fun write(properties: Map<String, Any>, result: String, bluePrintRuntimeService: BluePrintRuntimeService<*>, - artifactPrefix: String) = withContext(Dispatchers.IO) { - - val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! - - val resourceResolutionResult = ResourceResolutionResult() - resourceResolutionResult.id = UUID.randomUUID().toString() - resourceResolutionResult.artifactName = artifactPrefix - resourceResolutionResult.blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION] - resourceResolutionResult.blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME] - resourceResolutionResult.resolutionKey = - properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY].toString() - resourceResolutionResult.result = result - - try { - resourceResolutionRepository.saveAndFlush(resourceResolutionResult) - } catch (ex: DataIntegrityViolationException) { - throw BluePrintException("Failed to store resource resolution result.", ex) - } - } - - suspend fun readByKey(resolutionResultId: String): String = withContext(Dispatchers.IO) { - - resourceResolutionRepository.getOne(resolutionResultId).result!! - } - - suspend fun deleteByKey(resolutionResultId: String): Unit = withContext(Dispatchers.IO) { - - val row = resourceResolutionRepository.getOne(resolutionResultId) - resourceResolutionRepository.delete(row) - resourceResolutionRepository.flush() - } -}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResult.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt index c9b747e59..ea5626a80 100755 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResult.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt @@ -33,12 +33,12 @@ import javax.persistence.TemporalType @EntityListeners(AuditingEntityListener::class) @Entity -@Table(name = "RESOURCE_RESOLUTION_RESULT") +@Table(name = "TEMPLATE_RESOLUTION") @Proxy(lazy = false) -class ResourceResolutionResult : Serializable { +class TemplateResolution : Serializable { @Id - @Column(name = "resource_resolution_result_id") + @Column(name = "template_resolution_id") var id: String? = null @Column(name = "resolution_key", nullable = false) diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt index efc130a84..136b5e952 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt @@ -17,9 +17,9 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db import org.springframework.data.jpa.repository.JpaRepository -interface ResourceResolutionResultRepository : JpaRepository<ResourceResolutionResult, String> { +interface TemplateResolutionRepository : JpaRepository<TemplateResolution, String> { fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?, blueprintVersion: String?, - artifactName: String): ResourceResolutionResult + artifactName: String): TemplateResolution } diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt new file mode 100644 index 000000000..c4e36401f --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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.functions.resource.resolution.db + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException +import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService +import org.springframework.dao.DataIntegrityViolationException +import org.springframework.stereotype.Service +import java.util.* + +@Service +class TemplateResolutionService(private val templateResolutionRepository: TemplateResolutionRepository) { + + suspend fun read(bluePrintRuntimeService: BluePrintRuntimeService<*>, + artifactPrefix: String, + resolutionKey: String): String = withContext(Dispatchers.IO) { + + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + + read(blueprintName, blueprintVersion, artifactPrefix, resolutionKey) + } + + suspend fun read(blueprintName: String, + blueprintVersion: String, + artifactPrefix: String, + resolutionKey: String): String = withContext(Dispatchers.IO) { + + templateResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName( + resolutionKey, + blueprintName, + blueprintVersion, + artifactPrefix).result!! + } + + suspend fun write(properties: Map<String, Any>, + result: String, bluePrintRuntimeService: BluePrintRuntimeService<*>, + artifactPrefix: String): TemplateResolution = withContext(Dispatchers.IO) { + + val metadata = bluePrintRuntimeService.bluePrintContext().metadata!! + + val blueprintVersion = metadata[BluePrintConstants.METADATA_TEMPLATE_VERSION]!! + val blueprintName = metadata[BluePrintConstants.METADATA_TEMPLATE_NAME]!! + val resolutionKey = + properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY].toString() + + write(blueprintName, blueprintVersion, resolutionKey, artifactPrefix, result) + } + + suspend fun write(blueprintName: String, + blueprintVersion: String, + resolutionKey: String, + artifactPrefix: String, + template: String): TemplateResolution = withContext(Dispatchers.IO) { + + val resourceResolutionResult = TemplateResolution() + resourceResolutionResult.id = UUID.randomUUID().toString() + resourceResolutionResult.artifactName = artifactPrefix + resourceResolutionResult.blueprintVersion = blueprintVersion + resourceResolutionResult.blueprintName = blueprintName + resourceResolutionResult.resolutionKey = resolutionKey + resourceResolutionResult.result = template + + try { + templateResolutionRepository.saveAndFlush(resourceResolutionResult) + } catch (ex: DataIntegrityViolationException) { + throw BluePrintException("Failed to store resource api result.", ex) + } + } +}
\ 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/ResolutionResultsServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt deleted file mode 100644 index 61a9541d3..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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/ResolutionResultsServiceHandler.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt deleted file mode 100644 index 1fb34d789..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt index 40aa1a3e6..c50853ff2 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.resolutionresults.api +package org.onap.ccsdk.cds.blueprintsprocessor.resource.api import io.swagger.annotations.ApiOperation import kotlinx.coroutines.runBlocking diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceException.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceException.kt index 6815c05ef..19c42f2ea 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceException.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceException.kt @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.resolutionresults.api +package org.onap.ccsdk.cds.blueprintsprocessor.resource.api class ResourceException(message: String) : RuntimeException(message) { var code: Int = 404 } - 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/resource/api/ResourceExceptionHandler.kt index 7f8f7da79..f01dccff7 100644 --- 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/resource/api/ResourceExceptionHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2018-2019 Bell Canada Intellectual Property. + * Copyright © 2019 Bell Canada * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.onap.ccsdk.cds.blueprintsprocessor.resolutionresults.api +package org.onap.ccsdk.cds.blueprintsprocessor.resource.api import com.fasterxml.jackson.annotation.JsonFormat import com.fasterxml.jackson.annotation.JsonInclude @@ -27,6 +27,7 @@ import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.orm.jpa.JpaObjectRetrievalFailureException import org.springframework.dao.EmptyResultDataAccessException +import org.springframework.dao.IncorrectResultSizeDataAccessException import org.springframework.web.server.ServerWebInputException import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.RestControllerAdvice @@ -34,57 +35,61 @@ import java.io.Serializable import java.util.* /** - * Handle exceptions in Resolution Results API and provide relevant HTTP status codes and messages + * Handle exceptions in Resolution 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 { +@RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.resource.api") +open class ResourceExceptionHandler { - private val log = LoggerFactory.getLogger(ResolutionResultsServiceExceptionHandler::class.toString()) + private val log = LoggerFactory.getLogger(ExceptionHandler::class.toString()) - private val debugMsg = "ResolutionResultsService_Error_Message" + private val debugMsg = "Resolution_Service_Error_Message" @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> { - log.error(e.message, e) + fun resolutionResultsServiceExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> { val errorCode = ErrorCode.BLUEPRINT_PATH_MISSING - val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg) - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)) + return returnError(e, errorCode) } @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> { - log.error(e.message, e) + fun resolutionResultsServiceExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> { val errorCode = ErrorCode.INVALID_REQUEST_FORMAT - val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg) - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)) + return returnError(e, errorCode) } @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> { - log.error(e.message, e) - var errorCode = ErrorCode.RESOURCE_NOT_FOUND - val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg) - return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)) + fun resolutionResultsServiceExceptionHandler(e: IncorrectResultSizeDataAccessException): ResponseEntity<ErrorMessage> { + val errorCode = ErrorCode.DUPLICATE_DATA + return returnError(e, errorCode) } @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorMessage> { - log.error(e.message, e) + fun resolutionResultsServiceExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> { + val errorCode = ErrorCode.RESOURCE_NOT_FOUND + return returnError(e, errorCode) + } - 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> { + val errorCode = ErrorCode.RESOURCE_NOT_FOUND + return returnError(e, errorCode) } @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> { + fun resolutionResultsServiceExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> { + val errorCode = ErrorCode.GENERIC_FAILURE + return returnError(e, errorCode) + } + + fun returnError(e: Exception, errorCode: ErrorCode): 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)) + val errorMessage = + ErrorMessage(errorCode.message(e.message!!), + errorCode.value, + debugMsg) + return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)!!) } @ExceptionHandler diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt new file mode 100644 index 000000000..d3ebd5c49 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt @@ -0,0 +1,87 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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.resource.api + +import io.swagger.annotations.ApiOperation +import kotlinx.coroutines.runBlocking +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolution +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.* + +/** + * Exposes Template Resolution API to store and retrieve rendered template results. + * + * @author Serge Simard + * @version 1.0 + */ +@RestController +@RequestMapping("/api/v1/template") +open class TemplateController(private val templateResolutionService: TemplateResolutionService) { + + @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE]) + @ResponseBody + fun ping(): String = runBlocking { + "Success" + } + + @RequestMapping(path = [""], method = [RequestMethod.GET], produces = [MediaType.TEXT_PLAIN_VALUE]) + @ApiOperation(value = "Retrieve a meshed template.", + notes = "Retrieve a meshed template for a given CBA's action, identified by its blueprint name, blueprint version, " + + "artifact name and resolution key. And extra 'format' parameter can be passed to tell what content-type" + + " to expect in return") + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun get(@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 result = templateResolutionService.read(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(result) + } + + + @PostMapping("/{bpName}/{bpVersion}/{artifactName}/{resolutionKey}", produces = [MediaType.APPLICATION_JSON_VALUE]) + @ApiOperation(value = "Store a meshed template", + notes = "Store a meshed template for a given CBA's action, identified by its blueprint name, blueprint version, " + + "artifact name and resolution key.") + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun post(@PathVariable(value = "bpName") bpName: String, + @PathVariable(value = "bpVersion") bpVersion: String, + @PathVariable(value = "artifactName") artifactName: String, + @PathVariable(value = "resolutionKey") resolutionKey: String, + @RequestBody result: String): ResponseEntity<TemplateResolution> = runBlocking { + + val resultStored = + templateResolutionService.write(bpName, bpVersion, resolutionKey, artifactName, result) + + ResponseEntity.ok().body(resultStored) + } +} diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionControllerTest.java b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionControllerTest.java deleted file mode 100644 index f8c37f828..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionControllerTest.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2019 Bell Canada - * - * 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.resource.api; - -// TODO -public class ResourceResolutionControllerTest { - -} diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandlerTest.kt deleted file mode 100644 index 813c900d7..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandlerTest.kt +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright © 2019 Bell Canada. - * - * 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 kotlinx.coroutines.runBlocking -import org.junit.Test -import org.junit.runner.RunWith -import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintCoreConfiguration -import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir -import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService -import org.slf4j.LoggerFactory -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.security.SecurityProperties -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest -import org.springframework.context.annotation.ComponentScan -import org.springframework.http.HttpStatus -import org.springframework.http.MediaType -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.web.reactive.function.BodyInserters -import java.io.File -import java.nio.file.Paths -import java.util.* -import kotlin.test.AfterTest -import kotlin.test.BeforeTest -import kotlin.test.assertTrue - -@RunWith(SpringRunner::class) -@WebFluxTest -@ContextConfiguration(classes = [ResolutionResultsServiceHandler::class, BluePrintCoreConfiguration::class, - BluePrintCatalogService::class, SecurityProperties::class]) -@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) -@TestPropertySource(locations = ["classpath:application-test.properties"]) -class ResolutionResultsServiceHandlerTest { - - private val log = LoggerFactory.getLogger(ResolutionResultsServiceHandlerTest::class.toString()) - - @Autowired - lateinit var blueprintCatalog: BluePrintCatalogService - @Autowired - lateinit var webTestClient: WebTestClient - - var resolutionKey = "7cafa9f3-bbc8-49ec-8f25-fcaa6ac3ff08" - val blueprintName = "baseconfiguration" - val blueprintVersion = "1.0.0" - val templatePrefix = "activate" - val payloadDummyTemplateData = "PAYLOAD DATA" - - @BeforeTest - fun init() { - runBlocking { - deleteDir("target", "blueprints") - blueprintCatalog.saveToDatabase(UUID.randomUUID().toString(), loadTestCbaFile()) - } - } - - @AfterTest - fun cleanDir() { - deleteDir("target", "blueprints") - } - - @Test - fun `ping return Success`() { - runBlocking { - - webTestClient.get().uri("/api/v1/resolution-results/ping") - .exchange() - .expectStatus().isOk - .expectBody().equals("Success") - } - } - - @Test - fun `store-retrieve-delete result by path or UUID`() { - runBlocking { - createRetrieveDelete() - } - } - - @Test - fun `get returns requested JSON content-type`() { - runBlocking { - createRetrieveDelete("json") - } - } - - @Test - fun `get returns requested XML content-type`() { - runBlocking { - createRetrieveDelete("xml") - } - } - - private fun createRetrieveDelete(expectedType : String? = null): WebTestClient.ResponseSpec { - var uuid = "MISSING" - - // Store new result for blueprint/artifact/resolutionkey - webTestClient - .post() - .uri("/api/v1/resolution-results/$blueprintName/$blueprintVersion/$templatePrefix/$resolutionKey/") - .body(BodyInserters.fromObject(payloadDummyTemplateData)) - .exchange() - .expectStatus().is2xxSuccessful - .expectBody() - .consumeWith { - uuid = String(it.responseBody) - log.info("Stored result under UUID $uuid") - } - // Retrieve same payload - var requestArguments = "bpName=$blueprintName&bpVersion=$blueprintVersion" + - "&artifactName=$templatePrefix&resolutionKey=$resolutionKey" - if (expectedType != null) { - requestArguments = "$requestArguments&format=$expectedType" - webTestClient - .get() - .uri("/api/v1/resolution-results/?$requestArguments") - .exchange() - .expectStatus().is2xxSuccessful - .expectHeader().contentType(MediaType.valueOf("application/$expectedType")) - .expectBody().equals(payloadDummyTemplateData) - } else { - webTestClient - .get() - .uri("/api/v1/resolution-results/?$requestArguments") - .exchange() - .expectStatus().is2xxSuccessful - .expectHeader().contentType(MediaType.TEXT_PLAIN) - .expectBody().equals(payloadDummyTemplateData) - } - // And delete by UUID - return webTestClient - .delete() - .uri("/api/v1/resolution-results/$uuid/") - .exchange() - .expectStatus().is2xxSuccessful - } - - /* - * Error cases - */ - @Test - fun `get returns 400 error if missing arg`() { - runBlocking { - val arguments = "bpBADName=$blueprintName" + - "&bpBADVersion=$blueprintVersion" + - "&artifactName=$templatePrefix" + - "&resolutionKey=$resolutionKey" - - webTestClient.get().uri("/api/v1/resolution-results/?$arguments") - .exchange() - .expectStatus().isBadRequest - } - } - - @Test - fun `get returns 503 error if Blueprint not found`() { - runBlocking { - val arguments = "bpName=BAD_BP_NAME" + - "&bpVersion=BAD_BP_VERSION" + - "&artifactName=$templatePrefix" + - "&resolutionKey=$resolutionKey" - - webTestClient.get().uri("/api/v1/resolution-results/?$arguments") - .exchange() - .expectStatus().isEqualTo(HttpStatus.SERVICE_UNAVAILABLE) - } - } - - @Test - fun `get returns 404 if entry not found`() { - runBlocking { - - webTestClient - .get() - .uri("/api/v1/resolution-results/?bpName=$blueprintName&bpVersion=$blueprintVersion" + - "&artifactName=$templatePrefix&resolutionKey=$resolutionKey") - .exchange() - .expectStatus().isNotFound - } - } - - @Test - fun `get returns 404 if UUID not found`() { - runBlocking { - - webTestClient - .get() - .uri("/api/v1/resolution-results/234234234234/") - .exchange() - .expectStatus().isNotFound - } - } - - private fun loadTestCbaFile(): File { - val testCbaFile = Paths.get("./src/test/resources/test-cba.zip").toFile() - assertTrue(testCbaFile.exists(), "couldn't get file ${testCbaFile.absolutePath}") - return testCbaFile - } -}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt index fa8bf4459..cde71d86c 100644 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt @@ -51,6 +51,8 @@ import java.util.* import org.h2.value.DataType.readValue import org.python.bouncycastle.asn1.x500.style.RFC4519Style.l import org.h2.value.DataType.readValue +import org.onap.ccsdk.cds.blueprintsprocessor.resource.api.ErrorMessage +import org.onap.ccsdk.cds.blueprintsprocessor.resource.api.ResourceController import java.lang.reflect.Array diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt new file mode 100644 index 000000000..d12d05804 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt @@ -0,0 +1,182 @@ +/* + * Copyright © 2019 Bell Canada. + * + * 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.resource.api + +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintCoreConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.TemplateResolutionService +import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir +import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.security.SecurityProperties +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest +import org.springframework.context.annotation.ComponentScan +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +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.web.reactive.function.BodyInserters +import java.io.File +import java.nio.file.Paths +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.assertTrue + +@RunWith(SpringRunner::class) +@WebFluxTest +@ContextConfiguration(classes = [BluePrintCoreConfiguration::class, + BluePrintCatalogService::class, SecurityProperties::class]) +@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"]) +@TestPropertySource(locations = ["classpath:application-test.properties"]) +class TemplateControllerTest { + + private val log = LoggerFactory.getLogger(TemplateControllerTest::class.toString()) + + @Autowired + lateinit var webTestClient: WebTestClient + + var resolutionKey = "7cafa9f3-bbc8-49ec-8f25-fcaa6ac3ff08" + val blueprintName = "baseconfiguration" + val blueprintVersion = "1.0.0" + val templatePrefix = "activate" + val payloadDummyTemplateData = "PAYLOAD DATA" + + var requestArguments = "bpName=$blueprintName&bpVersion=$blueprintVersion" + + "&artifactName=$templatePrefix&resolutionKey=$resolutionKey" + + @AfterTest + fun cleanDir() { + deleteDir("target", "blueprints") + } + + @Test + fun `ping return Success`() { + runBlocking { + webTestClient.get().uri("/api/v1/template/ping") + .exchange() + .expectStatus().isOk + .expectBody() + .equals("Success") + } + } + + @Test + fun `store same value and tries to retrieve - duplicate entry execption`() { + runBlocking { + + resolutionKey = "1" + + post(resolutionKey) + post(resolutionKey) + + webTestClient + .get() + .uri("/api/v1/template?$requestArguments") + .exchange() + .expectStatus().is4xxClientError + .expectBody().equals(payloadDummyTemplateData) + } + } + + @Test + fun `get returns requested JSON content-type`() { + runBlocking { + resolutionKey = "2" + post(resolutionKey) + get("json", resolutionKey) + } + } + + @Test + fun `get returns requested XML content-type`() { + runBlocking { + resolutionKey = "3" + post(resolutionKey) + get("xml", resolutionKey) + } + } + + @Test + fun `get returns 400 error if missing arg`() { + runBlocking { + val arguments = "bpBADName=$blueprintName" + + "&bpBADVersion=$blueprintVersion" + + "&artifactName=$templatePrefix" + + "&resolutionKey=$resolutionKey" + + webTestClient.get().uri("/api/v1/template?$arguments") + .exchange() + .expectStatus().isBadRequest + } + } + + @Test + fun `get returns 404 if entry not found`() { + runBlocking { + + webTestClient + .get() + .uri("/api/v1/template?bpName=$blueprintName&bpVersion=$blueprintVersion" + + "&artifactName=$templatePrefix&resolutionKey=bob") + .exchange() + .expectStatus().isNotFound + } + } + + private fun post(resKey: String) { + webTestClient + .post() + .uri("/api/v1/template/$blueprintName/$blueprintVersion/$templatePrefix/$resKey") + .body(BodyInserters.fromObject(payloadDummyTemplateData)) + .exchange() + .expectStatus().is2xxSuccessful + .expectBody() + .consumeWith { + log.info("Stored result under UUID ${it.responseBody}") + } + } + + private fun get(expectedType: String, resKey: String) { + var requestArguments = "bpName=$blueprintName&bpVersion=$blueprintVersion" + + "&artifactName=$templatePrefix&resolutionKey=$resKey" + + if (expectedType.isNotEmpty()) { + requestArguments = "$requestArguments&format=$expectedType" + webTestClient + .get() + .uri("/api/v1/template?$requestArguments") + .exchange() + .expectStatus().is2xxSuccessful + .expectHeader().contentType(MediaType.valueOf("application/$expectedType")) + .expectBody().equals(payloadDummyTemplateData) + } else { + webTestClient + .get() + .uri("/api/v1/template?$requestArguments") + .exchange() + .expectStatus().is2xxSuccessful + .expectHeader().contentType(MediaType.TEXT_PLAIN) + .expectBody().equals(payloadDummyTemplateData) + } + } +}
\ No newline at end of file diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintErrorCode.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintErrorCode.kt index 79ef395e3..51d088ee1 100644 --- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintErrorCode.kt +++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/data/BlueprintErrorCode.kt @@ -76,6 +76,11 @@ enum class ErrorCode (val value: Int, val httpCode: Int) { override fun message(detailMsg: String): String { return "Duplicated entry while saving Blueprint. Details : {$detailMsg}" } + }, + DUPLICATE_DATA(11, 409) { + override fun message(detailMsg: String): String { + return "Duplicated data - was expecting one result, got more than one. Details : {$detailMsg}" + } }; abstract fun message(detailMsg: String): String |