summaryrefslogtreecommitdiffstats
path: root/ms/blueprintsprocessor/modules/inbounds/configs-api
diff options
context:
space:
mode:
authorSerge Simard <serge@agilitae.com>2019-08-08 10:55:57 -0400
committerSerge Simard <serge@agilitae.com>2019-08-13 14:57:10 +0000
commit34c424689a52614fb414d65899282497fe25b164 (patch)
tree91fdafc99a280064f0ef19c1576fdcbbae303cfc /ms/blueprintsprocessor/modules/inbounds/configs-api
parent571c49342a905616298d923a9d29a201ae4ecd11 (diff)
Resource Configuration Snapshots Executor and API
Issue-ID: CCSDK-1604 Signed-off-by: Serge Simard <serge@agilitae.com> Change-Id: I349c649e941431b48a309123489d26fb22e0e50a Signed-off-by: Serge Simard <serge@agilitae.com>
Diffstat (limited to 'ms/blueprintsprocessor/modules/inbounds/configs-api')
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml50
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt124
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotException.kt20
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt118
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt175
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties30
-rw-r--r--ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/logback.xml35
7 files changed, 552 insertions, 0 deletions
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml
new file mode 100644
index 000000000..d6dacb595
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.ccsdk.cds.blueprintsprocessor</groupId>
+ <artifactId>inbounds</artifactId>
+ <version>0.5.2-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>configs-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Blueprints Processor Resource Configurations API</name>
+ <description>Blueprints Processor Resource Configurations API</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.cds.blueprintsprocessor.functions</groupId>
+ <artifactId>config-snapshots</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.cds.controllerblueprints</groupId>
+ <artifactId>blueprint-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt
new file mode 100644
index 000000000..eb7929509
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotController.kt
@@ -0,0 +1,124 @@
+/*
+ * 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.configs.api
+
+import com.fasterxml.jackson.databind.JsonNode
+import io.swagger.annotations.Api
+import io.swagger.annotations.ApiOperation
+import io.swagger.annotations.ApiParam
+import kotlinx.coroutines.runBlocking
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshotService
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.security.access.prepost.PreAuthorize
+import org.springframework.web.bind.annotation.*
+
+/**
+ * Exposes Resource Configuration Snapshot API to store and retrieve stored resource configurations.
+ *
+ * @author Serge Simard
+ * @version 1.0
+ */
+@RestController
+@RequestMapping("/api/v1/configs")
+@Api(value = "/api/v1/configs",
+ description = "Interaction with stored configurations.")
+open class ResourceConfigSnapshotController(private val resourceConfigSnapshotService: ResourceConfigSnapshotService) {
+
+ @RequestMapping(path = ["/health-check"],
+ method = [RequestMethod.GET],
+ produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ResponseBody
+ @ApiOperation(value = "Health Check", hidden = true)
+ fun ressCfgSnapshotControllerHealthCheck(): JsonNode = runBlocking {
+ "Success".asJsonPrimitive()
+ }
+
+ @RequestMapping(path = [""],
+ method = [RequestMethod.GET],
+ produces = [MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE])
+ @ApiOperation(value = "Retrieve a resource configuration snapshot.",
+ notes = "Retrieve a config snapshot, identified by its Resource Id and Type. " +
+ "An extra 'format' parameter can be passed to tell what content-type is expected.")
+ @ResponseBody
+ @PreAuthorize("hasRole('USER')")
+ fun get(
+ @ApiParam(value = "Resource Type associated of the resource configuration snapshot.", required = false)
+ @RequestParam(value = "resourceType", required = true) resourceType: String,
+
+ @ApiParam(value = "Resource Id associated of the resource configuration snapshot.", required = false)
+ @RequestParam(value = "resourceId", required = true) resourceId: String,
+
+ @ApiParam(value = "Status of the snapshot being retrieved.", defaultValue = "RUNNING", required = false)
+ @RequestParam(value = "status", required = false, defaultValue = "RUNNING") status: String,
+
+ @ApiParam(value = "Expected format of the snapshot being retrieved.", defaultValue = MediaType.TEXT_PLAIN_VALUE,
+ required = false)
+ @RequestParam(value = "format", required = false, defaultValue = MediaType.TEXT_PLAIN_VALUE) format: String)
+
+ : ResponseEntity<String> = runBlocking {
+
+ var configSnapshot = ""
+
+ if (resourceType.isNotEmpty() && resourceId.isNotEmpty()) {
+ try {
+ configSnapshot = resourceConfigSnapshotService.findByResourceIdAndResourceTypeAndStatus(resourceId,
+ resourceType, ResourceConfigSnapshot.Status.valueOf(status.toUpperCase()))
+ } catch (ex : NoSuchElementException) {
+ throw ResourceConfigSnapshotException(
+ "Could not find configuration snapshot entry for type $resourceType and Id $resourceId")
+ }
+ } else {
+ throw IllegalArgumentException("Missing param. You must specify resource-id and resource-type.")
+ }
+
+ var expectedContentType = format
+ if (expectedContentType.indexOf('/') < 0) {
+ expectedContentType = "application/$expectedContentType"
+ }
+ val expectedMediaType: MediaType = MediaType.valueOf(expectedContentType)
+
+ ResponseEntity.ok().contentType(expectedMediaType).body(configSnapshot)
+ }
+
+ @PostMapping("/{resourceType}/{resourceId}/{status}",
+ produces = [MediaType.APPLICATION_JSON_VALUE])
+ @ApiOperation(value = "Store a resource configuration snapshot identified by resourceId, resourceType, status.",
+ notes = "Store a resource configuration snapshot, identified by its resourceId and resourceType, " +
+ "and optionally its status, either RUNNING or CANDIDATE.",
+ response = ResourceConfigSnapshot::class, produces = MediaType.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ @PreAuthorize("hasRole('USER')")
+ fun postWithResourceIdAndResourceType(
+ @ApiParam(value = "Resource Type associated with the resolution.", required = false)
+ @PathVariable(value = "resourceType", required = true) resourceType: String,
+ @ApiParam(value = "Resource Id associated with the resolution.", required = false)
+ @PathVariable(value = "resourceId", required = true) resourceId: String,
+ @ApiParam(value = "Status of the snapshot being retrieved.", defaultValue = "RUNNING", required = true)
+ @PathVariable(value = "status", required = true) status: String,
+ @ApiParam(value = "Config snapshot to store.", required = true)
+ @RequestBody snapshot: String): ResponseEntity<ResourceConfigSnapshot> = runBlocking {
+
+ val resultStored =
+ resourceConfigSnapshotService.write(snapshot, resourceId, resourceType,
+ ResourceConfigSnapshot.Status.valueOf(status.toUpperCase()))
+
+ ResponseEntity.ok().body(resultStored)
+ }
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotException.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotException.kt
new file mode 100644
index 000000000..1eeea9893
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotException.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.configs.api
+
+class ResourceConfigSnapshotException(message: String) : RuntimeException(message) {
+ var code: Int = 404
+}
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt
new file mode 100644
index 000000000..d21464ef5
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotExceptionHandler.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.configs.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 ResourceConfigSnapshot API and provide relevant HTTP status codes and messages
+ *
+ * @author Serge Simard
+ * @version 1.0
+ */
+@RestControllerAdvice("org.onap.ccsdk.cds.blueprintsprocessor.configs.api")
+open class ResourceConfigSnapshotExceptionHandler {
+
+ private val log = LoggerFactory.getLogger(ResourceConfigSnapshotExceptionHandler::class.toString())
+
+ private val debugMsg = "Resource_Config_Snapshot_ExceptionHandler_Error_Message"
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.BLUEPRINT_PATH_MISSING
+ return returnError(e, errorCode)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.INVALID_REQUEST_FORMAT
+ return returnError(e, errorCode, false)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: IllegalArgumentException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.INVALID_REQUEST_FORMAT
+ return returnError(e, errorCode, false)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: IncorrectResultSizeDataAccessException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.DUPLICATE_DATA
+ return returnError(e, errorCode)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.RESOURCE_NOT_FOUND
+ return returnError(e, errorCode, false)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.RESOURCE_NOT_FOUND
+ return returnError(e, errorCode, false)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: Exception): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.GENERIC_FAILURE
+ return returnError(e, errorCode)
+ }
+
+ @ExceptionHandler
+ fun resourceConfigSnapshotExceptionHandler(e: ResourceConfigSnapshotException): ResponseEntity<ErrorMessage> {
+ val errorCode = ErrorCode.RESOURCE_NOT_FOUND
+ return returnError(e, errorCode, false)
+ }
+
+ fun returnError(e: Exception, errorCode: ErrorCode, toBeLogged: Boolean = true): ResponseEntity<ErrorMessage> {
+ if (toBeLogged) {
+ log.error(e.message, e)
+ } else {
+ log.error(e.message)
+ }
+ val errorMessage =
+ ErrorMessage(errorCode.message(e.message!!),
+ errorCode.value,
+ debugMsg)
+ return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode)!!)
+ }
+}
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonTypeName("errorMessage")
+@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
+class ErrorMessage(var message: String?, var code: Int?, var debugMessage: String?) : Serializable {
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+ var timestamp = Date()
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt
new file mode 100644
index 000000000..c3f18fcba
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/configs/api/ResourceConfigSnapshotControllerTest.kt
@@ -0,0 +1,175 @@
+/*
+ * 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.configs.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.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.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.util.*
+
+@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 ResourceConfigSnapshotControllerTest {
+
+ private val log = LoggerFactory.getLogger(ResourceConfigSnapshotControllerTest::class.toString())
+
+ @Autowired
+ lateinit var webTestClient: WebTestClient
+
+ val resourceId = "fcaa6ac3ff08"
+ val resourceType = "PNF"
+ val snapshotData = "PAYLOAD DATA"
+
+ var requestArguments = "resourceId=$resourceId&resourceType=$resourceType"
+
+ @Test
+ fun `ping return Success`() {
+ runBlocking {
+ webTestClient.get().uri("/api/v1/configs/health-check")
+ .exchange()
+ .expectStatus().isOk
+ .expectBody()
+ .equals("Success")
+ }
+ }
+
+ @Test
+ fun `update configuration is allowed and updates timestamp`() {
+ runBlocking {
+
+ webTestClient
+ .post()
+ .uri("/api/v1/configs/$resourceType/$resourceId/running")
+ .body(BodyInserters.fromObject(snapshotData))
+ .exchange()
+ .expectStatus().is2xxSuccessful
+ .expectBody()
+ .jsonPath("$.createdDate")
+ .value<String> { println(it) }
+
+ webTestClient
+ .post()
+ .uri("/api/v1/configs/$resourceType/$resourceId/running")
+ .body(BodyInserters.fromObject(snapshotData))
+ .exchange()
+ .expectStatus().is2xxSuccessful
+ .expectBody()
+ .jsonPath("$.createdDate")
+ .value<String> { println(it)}
+ }
+ }
+
+ @Test
+ fun `get returns requested JSON content-type`() {
+ runBlocking {
+ post(resourceType, "22", "RUNNING")
+ get("json", resourceType,"22", "RUNNING")
+ }
+ }
+
+ @Test
+ fun `get returns requested XML content-type`() {
+ runBlocking {
+ post(resourceType, "3", "CANDIDATE")
+ get("xml", resourceType, "3", "CANDIDATE")
+ }
+ }
+
+ @Test
+ fun `get returns 400 error if missing arg`() {
+ runBlocking {
+ val arguments = "artifactName=WRONGARG1&resolutionKey=WRONGARG1"
+
+ webTestClient.get().uri("/api/v1/configs?$arguments")
+ .exchange()
+ .expectStatus().isBadRequest
+ }
+ }
+
+ @Test
+ fun `get returns 400 error if wrong Status arg`() {
+ runBlocking {
+ val arguments = "resourceId=MISSING&resourceType=PNF&status=TOTALLY_WRONG"
+
+ webTestClient.get().uri("/api/v1/configs?$arguments")
+ .exchange()
+ .expectStatus().isBadRequest
+ }
+ }
+
+ @Test
+ fun `get returns 404 if entry not found`() {
+ runBlocking {
+
+ webTestClient
+ .get()
+ .uri("/api/v1/configs?resourceId=MISSING&resourceType=PNF")
+ .exchange()
+ .expectStatus().isNotFound
+ }
+ }
+
+ private fun post( resourceType: String, resourceId: String, status: String) {
+ webTestClient
+ .post()
+ .uri("/api/v1/configs/$resourceType/$resourceId/$status")
+ .body(BodyInserters.fromObject(snapshotData))
+ .exchange()
+ .expectStatus().is2xxSuccessful
+ .expectBody()
+ }
+
+ private fun get(expectedType : String, resourceType: String, resourceId: String, status: String) {
+ var requestArguments = "resourceId=$resourceId&resourceType=$resourceType&status=$status"
+
+ if (expectedType.isNotEmpty()) {
+ requestArguments = "$requestArguments&format=$expectedType"
+ webTestClient
+ .get()
+ .uri("/api/v1/configs?$requestArguments")
+ .exchange()
+ .expectStatus().is2xxSuccessful
+ .expectHeader().contentType(MediaType.valueOf("application/$expectedType"))
+ .expectBody().equals(snapshotData)
+ } else {
+ webTestClient
+ .get()
+ .uri("/api/v1/configs?$requestArguments")
+ .exchange()
+ .expectStatus().is2xxSuccessful
+ .expectHeader().contentType(MediaType.TEXT_PLAIN)
+ .expectBody().equals(snapshotData)
+ }
+ }
+} \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties
new file mode 100644
index 000000000..e02ed89f9
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/application-test.properties
@@ -0,0 +1,30 @@
+# 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.
+
+blueprintsprocessor.db.primary.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
+blueprintsprocessor.db.primary.username=sa
+blueprintsprocessor.db.primary.password=
+blueprintsprocessor.db.primary.driverClassName=org.h2.Driver
+blueprintsprocessor.db.primary.hibernateHbm2ddlAuto=create-drop
+blueprintsprocessor.db.primary.hibernateDDLAuto=update
+blueprintsprocessor.db.primary.hibernateNamingStrategy=org.hibernate.cfg.ImprovedNamingStrategy
+blueprintsprocessor.db.primary.hibernateDialect=org.hibernate.dialect.H2Dialect
+# Controller Blueprints Core Configuration
+blueprintsprocessor.blueprintDeployPath=./target/blueprints/deploy
+blueprintsprocessor.blueprintWorkingPath=./target/blueprints/work
+blueprintsprocessor.blueprintArchivePath=./target/blueprints/archive
+
+# Python executor
+blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints
+blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints
diff --git a/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/logback.xml b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/logback.xml
new file mode 100644
index 000000000..ed92b8963
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/inbounds/configs-api/src/test/resources/logback.xml
@@ -0,0 +1,35 @@
+<!--
+ ~ 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.
+ -->
+
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} %-5level %logger{100} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+
+ <logger name="org.springframework" level="warn"/>
+ <logger name="org.hibernate" level="info"/>
+ <logger name="org.onap.ccsdk.cds.blueprintsprocessor" level="info"/>
+
+ <root level="info">
+ <appender-ref ref="STDOUT"/>
+ </root>
+
+</configuration>