From c5276ff19122435871c3deedbf0d983962ac2537 Mon Sep 17 00:00:00 2001 From: Alexis de Talhouët Date: Thu, 20 Jun 2019 22:48:12 -0400 Subject: Refactor resolution controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tempalte and resources for get/put API Change-Id: Ia00bdb08f5f52231481edc6de232f850c66874e9 Issue-ID: CCSDK-1423 Signed-off-by: Alexis de Talhouët --- .../BlueprintProcessorApplication.java | 2 +- .../resolution/ResourceResolutionService.kt | 6 +- .../resolution/db/ResourceResolutionResult.kt | 69 ------- .../db/ResourceResolutionResultRepository.kt | 25 --- .../db/ResourceResolutionResultService.kt | 79 -------- .../resource/resolution/db/TemplateResolution.kt | 69 +++++++ .../resolution/db/TemplateResolutionRepository.kt | 25 +++ .../resolution/db/TemplateResolutionService.kt | 89 +++++++++ .../api/ResolutionResultsServiceController.kt | 104 ---------- .../ResolutionResultsServiceExceptionHandler.kt | 103 ---------- .../api/ResolutionResultsServiceHandler.kt | 71 ------- .../resolutionresults/api/ResourceController.kt | 84 -------- .../resolutionresults/api/ResourceException.kt | 21 -- .../resource/api/ResourceController.kt | 84 ++++++++ .../resource/api/ResourceException.kt | 20 ++ .../resource/api/ResourceExceptionHandler.kt | 108 +++++++++++ .../resource/api/TemplateController.kt | 87 +++++++++ .../api/ResourceResolutionControllerTest.java | 22 --- .../api/ResolutionResultsServiceHandlerTest.kt | 215 --------------------- .../api/ResourceControllerTest.kt | 2 + .../resource/api/TemplateControllerTest.kt | 182 +++++++++++++++++ .../core/data/BlueprintErrorCode.kt | 5 + 22 files changed, 675 insertions(+), 797 deletions(-) delete mode 100755 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResult.kt delete mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt delete mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt create mode 100755 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt create mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt create mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionService.kt delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceController.kt delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.kt delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandler.kt delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceController.kt delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceException.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceException.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateController.kt delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionControllerTest.java delete mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceHandlerTest.kt create mode 100644 ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/TemplateControllerTest.kt (limited to 'ms') 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/ResourceResolutionResult.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResult.kt deleted file mode 100755 index c9b747e59..000000000 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResult.kt +++ /dev/null @@ -1,69 +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.functions.resource.resolution.db - -import com.fasterxml.jackson.annotation.JsonFormat -import org.hibernate.annotations.Proxy -import org.springframework.data.annotation.LastModifiedDate -import org.springframework.data.jpa.domain.support.AuditingEntityListener -import java.io.Serializable -import java.util.* -import javax.persistence.Column -import javax.persistence.Entity -import javax.persistence.EntityListeners -import javax.persistence.Id -import javax.persistence.Lob -import javax.persistence.Table -import javax.persistence.Temporal -import javax.persistence.TemporalType - -@EntityListeners(AuditingEntityListener::class) -@Entity -@Table(name = "RESOURCE_RESOLUTION_RESULT") -@Proxy(lazy = false) -class ResourceResolutionResult : Serializable { - - @Id - @Column(name = "resource_resolution_result_id") - var id: String? = null - - @Column(name = "resolution_key", nullable = false) - var resolutionKey: String? = null - - @Column(name = "blueprint_name", nullable = false) - var blueprintName: String? = null - - @Column(name = "blueprint_version", nullable = false) - var blueprintVersion: String? = null - - @Column(name = "artifact_name", nullable = false) - var artifactName: String? = null - - @Lob - @Column(name = "result", nullable = false) - var result: String? = null - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - @LastModifiedDate - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "creation_date") - var createdDate = Date() - - companion object { - private const val serialVersionUID = 1L - } -} \ 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/ResourceResolutionResultRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt deleted file mode 100644 index efc130a84..000000000 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 org.springframework.data.jpa.repository.JpaRepository - -interface ResourceResolutionResultRepository : JpaRepository { - - fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?, - blueprintVersion: String?, - artifactName: String): ResourceResolutionResult -} 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, 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/TemplateResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt new file mode 100755 index 000000000..ea5626a80 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolution.kt @@ -0,0 +1,69 @@ +/* + * 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.functions.resource.resolution.db + +import com.fasterxml.jackson.annotation.JsonFormat +import org.hibernate.annotations.Proxy +import org.springframework.data.annotation.LastModifiedDate +import org.springframework.data.jpa.domain.support.AuditingEntityListener +import java.io.Serializable +import java.util.* +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.EntityListeners +import javax.persistence.Id +import javax.persistence.Lob +import javax.persistence.Table +import javax.persistence.Temporal +import javax.persistence.TemporalType + +@EntityListeners(AuditingEntityListener::class) +@Entity +@Table(name = "TEMPLATE_RESOLUTION") +@Proxy(lazy = false) +class TemplateResolution : Serializable { + + @Id + @Column(name = "template_resolution_id") + var id: String? = null + + @Column(name = "resolution_key", nullable = false) + var resolutionKey: String? = null + + @Column(name = "blueprint_name", nullable = false) + var blueprintName: String? = null + + @Column(name = "blueprint_version", nullable = false) + var blueprintVersion: String? = null + + @Column(name = "artifact_name", nullable = false) + var artifactName: String? = null + + @Lob + @Column(name = "result", nullable = false) + var result: String? = null + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @LastModifiedDate + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "creation_date") + var createdDate = Date() + + companion object { + private const val serialVersionUID = 1L + } +} \ 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/TemplateResolutionRepository.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt new file mode 100644 index 000000000..136b5e952 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/TemplateResolutionRepository.kt @@ -0,0 +1,25 @@ +/* + * 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 org.springframework.data.jpa.repository.JpaRepository + +interface TemplateResolutionRepository : JpaRepository { + + fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?, + blueprintVersion: String?, + 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, + 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 = 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 deleted file mode 100644 index 7f8f7da79..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.kt +++ /dev/null @@ -1,103 +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 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 { - log.error(e.message, e) - 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 { - log.error(e.message, e) - 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 { - 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)) - } - - @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity { - 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)) - } - - @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: Exception): ResponseEntity { - 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)) - } - - @ExceptionHandler - fun ResolutionResultsServiceExceptionHandler(e: ResourceException): ResponseEntity { - log.error(e.message, e) - return ResponseEntity(ErrorMessage(e.message, e.code, debugMsg), HttpStatus.resolve(e.code)) - } -} - -@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 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/resolutionresults/api/ResourceController.kt deleted file mode 100644 index 40aa1a3e6..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceController.kt +++ /dev/null @@ -1,84 +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 io.swagger.annotations.ApiOperation -import kotlinx.coroutines.runBlocking -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolution -import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService -import org.springframework.http.MediaType -import org.springframework.http.ResponseEntity -import org.springframework.security.access.prepost.PreAuthorize -import org.springframework.web.bind.annotation.* - -@RestController -@RequestMapping("/api/v1/resources") -open class ResourceController(private var resourceResolutionDBService: ResourceResolutionDBService) { - - @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE]) - @ResponseBody - fun ping(): String = runBlocking { - "Success" - } - - @RequestMapping(path = [""], - method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE]) - @ApiOperation(value = "Fetch all resource values associated to a resolution key. ", - notes = "Retrieve a stored resource value using the blueprint metadata, artifact name and the resolution-key.", - produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody - @PreAuthorize("hasRole('USER')") - fun getAllFromResolutionKeyOrFromResourceTypeAndId(@RequestParam(value = "bpName", required = true) bpName: String, - @RequestParam(value = "bpVersion", required = true) bpVersion: String, - @RequestParam(value = "artifactName", required = false, defaultValue = "") artifactName: String, - @RequestParam(value = "resolutionKey", required = false, defaultValue = "") resolutionKey: String, - @RequestParam(value = "resourceType", required = false, defaultValue = "") resourceType: String, - @RequestParam(value = "resourceId", required = false, defaultValue = "") resourceId: String) - : ResponseEntity> = runBlocking { - - if ((resolutionKey.isNotEmpty() || artifactName.isNotEmpty()) && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) { - throw ResourceException("Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") - } else if (resolutionKey.isNotEmpty() && artifactName.isNotEmpty()) { - ResponseEntity.ok() - .body(resourceResolutionDBService.readWithResolutionKey(bpName, bpVersion, artifactName, resolutionKey)) - } else if (resourceType.isNotEmpty() && resourceId.isNotEmpty()){ - ResponseEntity.ok() - .body(resourceResolutionDBService.readWithResourceIdAndResourceType(bpName, bpVersion, resourceId, resourceType)) - } else { - throw ResourceException("Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") - } - } - - @RequestMapping(path = ["/resource"], - method = [RequestMethod.GET], - produces = [MediaType.APPLICATION_JSON_VALUE]) - @ApiOperation(value = "Fetch a resource value using resolution key.", - notes = "Retrieve a stored resource value using the blueprint metadata, artifact name, resolution-key along with the name of the resource value to retrieve.", - produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody - @PreAuthorize("hasRole('USER')") - fun getOneFromResolutionKey(@RequestParam(value = "bpName", required = true) bpName: String, - @RequestParam(value = "bpVersion", required = true) bpVersion: String, - @RequestParam(value = "artifactName", required = true) artifactName: String, - @RequestParam(value = "resolutionKey", required = true) resolutionKey: String, - @RequestParam(value = "name", required = true) name: String) - : ResponseEntity = runBlocking { - - ResponseEntity.ok() - .body(resourceResolutionDBService.readValue(bpName, bpVersion, artifactName, resolutionKey, name)) - } -} \ 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/ResourceException.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceException.kt deleted file mode 100644 index 6815c05ef..000000000 --- a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceException.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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.resolutionresults.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/resource/api/ResourceController.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt new file mode 100644 index 000000000..c50853ff2 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceController.kt @@ -0,0 +1,84 @@ +/* + * 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.ResourceResolution +import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/api/v1/resources") +open class ResourceController(private var resourceResolutionDBService: ResourceResolutionDBService) { + + @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE]) + @ResponseBody + fun ping(): String = runBlocking { + "Success" + } + + @RequestMapping(path = [""], + method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE]) + @ApiOperation(value = "Fetch all resource values associated to a resolution key. ", + notes = "Retrieve a stored resource value using the blueprint metadata, artifact name and the resolution-key.", + produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun getAllFromResolutionKeyOrFromResourceTypeAndId(@RequestParam(value = "bpName", required = true) bpName: String, + @RequestParam(value = "bpVersion", required = true) bpVersion: String, + @RequestParam(value = "artifactName", required = false, defaultValue = "") artifactName: String, + @RequestParam(value = "resolutionKey", required = false, defaultValue = "") resolutionKey: String, + @RequestParam(value = "resourceType", required = false, defaultValue = "") resourceType: String, + @RequestParam(value = "resourceId", required = false, defaultValue = "") resourceId: String) + : ResponseEntity> = runBlocking { + + if ((resolutionKey.isNotEmpty() || artifactName.isNotEmpty()) && (resourceId.isNotEmpty() || resourceType.isNotEmpty())) { + throw ResourceException("Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") + } else if (resolutionKey.isNotEmpty() && artifactName.isNotEmpty()) { + ResponseEntity.ok() + .body(resourceResolutionDBService.readWithResolutionKey(bpName, bpVersion, artifactName, resolutionKey)) + } else if (resourceType.isNotEmpty() && resourceId.isNotEmpty()){ + ResponseEntity.ok() + .body(resourceResolutionDBService.readWithResourceIdAndResourceType(bpName, bpVersion, resourceId, resourceType)) + } else { + throw ResourceException("Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.") + } + } + + @RequestMapping(path = ["/resource"], + method = [RequestMethod.GET], + produces = [MediaType.APPLICATION_JSON_VALUE]) + @ApiOperation(value = "Fetch a resource value using resolution key.", + notes = "Retrieve a stored resource value using the blueprint metadata, artifact name, resolution-key along with the name of the resource value to retrieve.", + produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + @PreAuthorize("hasRole('USER')") + fun getOneFromResolutionKey(@RequestParam(value = "bpName", required = true) bpName: String, + @RequestParam(value = "bpVersion", required = true) bpVersion: String, + @RequestParam(value = "artifactName", required = true) artifactName: String, + @RequestParam(value = "resolutionKey", required = true) resolutionKey: String, + @RequestParam(value = "name", required = true) name: String) + : ResponseEntity = runBlocking { + + ResponseEntity.ok() + .body(resourceResolutionDBService.readValue(bpName, bpVersion, artifactName, resolutionKey, name)) + } +} \ No newline at end of file diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceException.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceException.kt new file mode 100644 index 000000000..19c42f2ea --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceException.kt @@ -0,0 +1,20 @@ +/* + * 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.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/resource/api/ResourceExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt new file mode 100644 index 000000000..f01dccff7 --- /dev/null +++ b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceExceptionHandler.kt @@ -0,0 +1,108 @@ +/* + * 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 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.dao.IncorrectResultSizeDataAccessException +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 API and provide relevant HTTP status codes and messages + * + * @author Serge Simard + * @version 1.0 + */ +@RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.resource.api") +open class ResourceExceptionHandler { + + private val log = LoggerFactory.getLogger(ExceptionHandler::class.toString()) + + private val debugMsg = "Resolution_Service_Error_Message" + + @ExceptionHandler + fun resolutionResultsServiceExceptionHandler(e: BluePrintProcessorException): ResponseEntity { + val errorCode = ErrorCode.BLUEPRINT_PATH_MISSING + return returnError(e, errorCode) + } + + @ExceptionHandler + fun resolutionResultsServiceExceptionHandler(e: ServerWebInputException): ResponseEntity { + val errorCode = ErrorCode.INVALID_REQUEST_FORMAT + return returnError(e, errorCode) + } + + @ExceptionHandler + fun resolutionResultsServiceExceptionHandler(e: IncorrectResultSizeDataAccessException): ResponseEntity { + val errorCode = ErrorCode.DUPLICATE_DATA + return returnError(e, errorCode) + } + + @ExceptionHandler + fun resolutionResultsServiceExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity { + val errorCode = ErrorCode.RESOURCE_NOT_FOUND + return returnError(e, errorCode) + } + + @ExceptionHandler + fun resolutionResultsServiceExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity { + val errorCode = ErrorCode.RESOURCE_NOT_FOUND + return returnError(e, errorCode) + } + + @ExceptionHandler + fun resolutionResultsServiceExceptionHandler(e: Exception): ResponseEntity { + val errorCode = ErrorCode.GENERIC_FAILURE + return returnError(e, errorCode) + } + + fun returnError(e: Exception, errorCode: ErrorCode): ResponseEntity { + log.error(e.message, e) + val errorMessage = + ErrorMessage(errorCode.message(e.message!!), + errorCode.value, + debugMsg) + return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)!!) + } + + @ExceptionHandler + fun ResolutionResultsServiceExceptionHandler(e: ResourceException): ResponseEntity { + log.error(e.message, e) + return ResponseEntity(ErrorMessage(e.message, e.code, debugMsg), HttpStatus.resolve(e.code)) + } +} + +@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/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 = 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 = 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 -- cgit 1.2.3-korg