Store resolution and expose with REST API 73/90273/11
authorAlexis de Talhouët <adetalhouet89@gmail.com>
Fri, 21 Jun 2019 02:12:08 +0000 (22:12 -0400)
committerAlexis de Talhouët <adetalhouet89@gmail.com>
Tue, 25 Jun 2019 18:33:36 +0000 (18:33 +0000)
Change-Id: Ie1fe9c02542ccd5fbfa18f1e2d6ddb633f55c214
Issue-ID: CCSDK-1423
Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
18 files changed:
ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt
ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionComponent.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionConstants.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionRepository.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultRepository.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionResultService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
ms/blueprintsprocessor/functions/restconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/restconf/executor/RestconfComponentFunction.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionController.java [deleted file]
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResolutionResultsServiceExceptionHandler.kt
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceController.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceException.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/inbounds/resource-api/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/resolutionresults/api/ResourceControllerTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt

index 1b84964..65d1c3e 100644 (file)
@@ -49,11 +49,6 @@ abstract class CliComponentFunction : AbstractScriptComponentFunction() {
         resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey)
     }
 
-    fun resolveAndGenerateMessage(artifactMapping: String, artifactTemplate: String): String = runBlocking {
-        resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName,
-                artifactMapping, artifactTemplate)
-    }
-
     fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking {
         resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName,
                 artifactPrefix, mapOf())
index be7451a..4cec6a2 100644 (file)
@@ -44,11 +44,6 @@ abstract class NetconfComponentFunction : AbstractScriptComponentFunction() {
         resourceResolutionService().resolveFromDatabase(bluePrintRuntimeService, artifactName, resolutionKey)
     }
 
-    fun resolveAndGenerateMessage(artifactMapping: String, artifactTemplate: String): String = runBlocking {
-        resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName,
-                artifactMapping, artifactTemplate)
-    }
-
     fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking {
         resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName,
                 artifactPrefix, mapOf())
index 0bc8376..7c2c11c 100644 (file)
@@ -37,10 +37,15 @@ open class ResourceResolutionComponent(private val resourceResolutionService: Re
         val occurrence = getOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE)
         val key = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY)
         val storeResult = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
+        val resourceId = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID)
+        val resourceType = getOptionalOperationInput(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE)
+
 
         val properties: MutableMap<String, Any> = mutableMapOf()
-        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] =
-            storeResult?.asBoolean() ?: false
+        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] = storeResult?.asBoolean() ?: false
+        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_KEY] = key?.asText() ?: ""
+        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID] = resourceId?.asText() ?: ""
+        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE] = resourceType?.asText() ?: ""
 
         val artifactPrefixNamesNode = getOperationInput(ResourceResolutionConstants.INPUT_ARTIFACT_PREFIX_NAMES)
         val artifactPrefixNames = JacksonUtils.getListFromJsonNode(artifactPrefixNamesNode, String::class.java)
index 9d422f1..929e9e8 100644 (file)
@@ -27,6 +27,8 @@ object ResourceResolutionConstants {
         const val RESOURCE_RESOLUTION_INPUT_KEY = "resolution-key"
         const val RESOURCE_RESOLUTION_INPUT_STORE_RESULT = "store-result"
         const val RESOURCE_RESOLUTION_INPUT_OCCURRENCE = "occurrence"
+        const val RESOURCE_RESOLUTION_INPUT_RESOURCE_ID = "resource-id"
+        const val RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE = "resource-type"
 
 
 }
\ No newline at end of file
index fe59062..b148293 100644 (file)
@@ -20,6 +20,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution
 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.processor.ResourceAssignmentProcessor
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
@@ -48,27 +49,26 @@ interface ResourceResolutionService {
     suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
                                  artifactPrefix: String, properties: Map<String, Any>): String
 
-    suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                 artifactMapping: String, artifactTemplate: String?): String
-
     suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>,
                                            resourceDefinitions: MutableMap<String, ResourceDefinition>,
                                            resourceAssignments: MutableList<ResourceAssignment>,
-                                           identifierName: String)
+                                           artifactPrefix: String,
+                                           properties: Map<String, Any>)
 }
 
 @Service(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION)
 open class ResourceResolutionServiceImpl(private var applicationContext: ApplicationContext,
                                          private var resolutionResultService: ResourceResolutionResultService,
-                                         private var blueprintTemplateService: BluePrintTemplateService) :
-        ResourceResolutionService {
+                                         private var blueprintTemplateService: BluePrintTemplateService,
+                                         private var resourceResolutionDBService: ResourceResolutionDBService) :
+    ResourceResolutionService {
 
     private val log = LoggerFactory.getLogger(ResourceResolutionService::class.java)
 
     override fun registeredResourceSources(): List<String> {
         return applicationContext.getBeanNamesForType(ResourceAssignmentProcessor::class.java)
-                .filter { it.startsWith(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) }
-                .map { it.substringAfter(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) }
+            .filter { it.startsWith(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) }
+            .map { it.substringAfter(ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR) }
     }
 
     override suspend fun resolveFromDatabase(bluePrintRuntimeService: BluePrintRuntimeService<*>,
@@ -78,12 +78,13 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
     }
 
     override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                          artifactNames: List<String>, properties: Map<String, Any>): MutableMap<String, String> {
+                                          artifactNames: List<String>,
+                                          properties: Map<String, Any>): MutableMap<String, String> {
 
         val resolvedParams: MutableMap<String, String> = hashMapOf()
         artifactNames.forEach { artifactName ->
             val resolvedContent = resolveResources(bluePrintRuntimeService, nodeTemplateName,
-                    artifactName, properties)
+                artifactName, properties)
             resolvedParams[artifactName] = resolvedContent
         }
         return resolvedParams
@@ -97,52 +98,38 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
         // Resource Assignment Artifact Definition Name
         val artifactMapping = "$artifactPrefix-mapping"
 
-        val result = resolveResources(bluePrintRuntimeService, nodeTemplateName,
-                artifactMapping, artifactTemplate)
-
-        if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
-                && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) {
-            resolutionResultService.write(properties, result, bluePrintRuntimeService, artifactPrefix)
-            log.info("resolution saved into database successfully : ($properties)")
-        }
-
-        return result
-    }
-
-
-    override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                          artifactMapping: String, artifactTemplate: String?): String {
-
         val resolvedContent: String
         log.info("Resolving resource for template artifact($artifactTemplate) with resource assignment artifact($artifactMapping)")
 
-        val identifierName = artifactTemplate ?: "no-template"
-
         val resourceAssignmentContent =
-                bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactMapping)
+            bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactMapping)
 
         val resourceAssignments: MutableList<ResourceAssignment> =
-                JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment::class.java)
-                        as? MutableList<ResourceAssignment>
-                        ?: throw BluePrintProcessorException("couldn't get Dictionary Definitions")
+            JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment::class.java)
+                    as? MutableList<ResourceAssignment>
+                ?: throw BluePrintProcessorException("couldn't get Dictionary Definitions")
 
         // Get the Resource Dictionary Name
         val resourceDefinitions: MutableMap<String, ResourceDefinition> = ResourceAssignmentUtils
-                .resourceDefinitions(bluePrintRuntimeService.bluePrintContext().rootPath)
+            .resourceDefinitions(bluePrintRuntimeService.bluePrintContext().rootPath)
 
         // Resolve resources
-        resolveResourceAssignments(bluePrintRuntimeService, resourceDefinitions, resourceAssignments, identifierName)
+        resolveResourceAssignments(bluePrintRuntimeService,
+            resourceDefinitions,
+            resourceAssignments,
+            artifactPrefix,
+            properties)
 
         val resolvedParamJsonContent =
-                ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignments.toList())
+            ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignments.toList())
 
-        // Check Template is there
-        if (artifactTemplate != null) {
-            resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName,
-                    artifactTemplate, resolvedParamJsonContent)
+        resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName,
+            artifactTemplate, resolvedParamJsonContent)
 
-        } else {
-            resolvedContent = resolvedParamJsonContent
+        if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
+            && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) {
+            resolutionResultService.write(properties, resolvedContent, bluePrintRuntimeService, artifactPrefix)
+            log.info("template resolution saved into database successfully : ($properties)")
         }
 
         return resolvedContent
@@ -156,44 +143,55 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
     override suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>,
                                                     resourceDefinitions: MutableMap<String, ResourceDefinition>,
                                                     resourceAssignments: MutableList<ResourceAssignment>,
-                                                    identifierName: String) {
+                                                    artifactPrefix: String,
+                                                    properties: Map<String, Any>) {
 
         val bulkSequenced = BulkResourceSequencingUtils.process(resourceAssignments)
         val resourceAssignmentRuntimeService =
-                ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, identifierName)
+            ResourceAssignmentUtils.transformToRARuntimeService(blueprintRuntimeService, artifactPrefix)
 
         coroutineScope {
             bulkSequenced.forEach { batchResourceAssignments ->
                 // Execute Non Dependent Assignments in parallel ( ie asynchronously )
                 val deferred = batchResourceAssignments.filter { it.name != "*" && it.name != "start" }
-                        .map { resourceAssignment ->
-                            async {
-                                val dictionaryName = resourceAssignment.dictionaryName
-                                val dictionarySource = resourceAssignment.dictionarySource
-                                /**
-                                 * Get the Processor name
-                                 */
-                                val processorName = processorName(dictionaryName!!, dictionarySource!!, resourceDefinitions)
-
-                                val resourceAssignmentProcessor =
-                                        applicationContext.getBean(processorName) as? ResourceAssignmentProcessor
-                                                ?: throw BluePrintProcessorException("failed to get resource processor ($processorName) " +
-                                                        "for resource assignment(${resourceAssignment.name})")
-                                try {
-                                    // Set BluePrint Runtime Service
-                                    resourceAssignmentProcessor.raRuntimeService = resourceAssignmentRuntimeService
-                                    // Set Resource Dictionaries
-                                    resourceAssignmentProcessor.resourceDictionaries = resourceDefinitions
-                                    // Invoke Apply Method
-                                    resourceAssignmentProcessor.applyNB(resourceAssignment)
-                                    // Set errors from RA
-                                    blueprintRuntimeService.setBluePrintError(resourceAssignmentRuntimeService.getBluePrintError())
-                                } catch (e: RuntimeException) {
-                                    log.error("Fail in processing ${resourceAssignment.name}", e)
-                                    throw BluePrintProcessorException(e)
+                    .map { resourceAssignment ->
+                        async {
+                            val dictionaryName = resourceAssignment.dictionaryName
+                            val dictionarySource = resourceAssignment.dictionarySource
+                            /**
+                             * Get the Processor name
+                             */
+                            val processorName = processorName(dictionaryName!!, dictionarySource!!, resourceDefinitions)
+
+                            val resourceAssignmentProcessor =
+                                applicationContext.getBean(processorName) as? ResourceAssignmentProcessor
+                                    ?: throw BluePrintProcessorException("failed to get resource processor ($processorName) " +
+                                            "for resource assignment(${resourceAssignment.name})")
+                            try {
+                                // Set BluePrint Runtime Service
+                                resourceAssignmentProcessor.raRuntimeService = resourceAssignmentRuntimeService
+                                // Set Resource Dictionaries
+                                resourceAssignmentProcessor.resourceDictionaries = resourceDefinitions
+                                // Invoke Apply Method
+                                resourceAssignmentProcessor.applyNB(resourceAssignment)
+
+                                if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
+                                    && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) {
+                                    resourceResolutionDBService.write(properties,
+                                        blueprintRuntimeService,
+                                        artifactPrefix,
+                                        resourceAssignment)
+                                    log.info("resolution saved into database successfully : ($resourceAssignment)")
                                 }
+
+                                // Set errors from RA
+                                blueprintRuntimeService.setBluePrintError(resourceAssignmentRuntimeService.getBluePrintError())
+                            } catch (e: RuntimeException) {
+                                log.error("Fail in processing ${resourceAssignment.name}", e)
+                                throw BluePrintProcessorException(e)
                             }
                         }
+                    }
                 log.debug("Resolving (${deferred.size})resources parallel.")
                 deferred.awaitAll()
             }
@@ -217,10 +215,10 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
             }
             else -> {
                 val resourceDefinition = resourceDefinitions[dictionaryName]
-                        ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dictionaryName")
+                    ?: throw BluePrintProcessorException("couldn't get resource dictionary definition for $dictionaryName")
 
                 val resourceSource = resourceDefinition.sources[dictionarySource]
-                        ?: throw BluePrintProcessorException("couldn't get resource definition $dictionaryName source($dictionarySource)")
+                    ?: throw BluePrintProcessorException("couldn't get resource definition $dictionaryName source($dictionarySource)")
 
                 ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR.plus(resourceSource.type)
             }
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolution.kt
new file mode 100644 (file)
index 0000000..767a1fe
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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 com.fasterxml.jackson.annotation.JsonProperty
+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")
+@Proxy(lazy = false)
+class ResourceResolution : Serializable {
+
+    @Id
+    @Column(name = "resource_resolution_id")
+    var id: String? = null
+
+    @Column(name = "resolution_key", nullable = false)
+    var resolutionKey: String? = null
+
+    @Column(name = "resource_type", nullable = false)
+    var resourceType: String? = null
+
+    @Column(name = "resource_id", nullable = false)
+    var resourceId: 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
+
+    @Column(name = "status", nullable = false)
+    var status: String? = null
+
+    @Column(name = "name", nullable = false)
+    var name: String? = null
+
+    @Column(name = "dictionary_vname", nullable = false)
+    var dictionaryName: String? = null
+
+    @Column(name = "dictionary_status", nullable = false)
+    var dictionarySource: String? = null
+
+    @Column(name = "dictionary_version", nullable = false)
+    var dictionaryVersion: Int = 0
+
+    @Lob
+    @Column(name = "value", nullable = false)
+    var value: 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/ResourceResolutionDBService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/db/ResourceResolutionDBService.kt
new file mode 100644 (file)
index 0000000..81239be
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * 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.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.slf4j.LoggerFactory
+import org.springframework.dao.DataIntegrityViolationException
+import org.springframework.stereotype.Service
+import java.util.*
+
+@Service
+class ResourceResolutionDBService(private val resourceResolutionRepository: ResourceResolutionRepository) {
+
+    private val log = LoggerFactory.getLogger(ResourceResolutionDBService::class.toString())
+
+    suspend fun readValue(blueprintName: String,
+                          blueprintVersion: String,
+                          artifactPrefix: String,
+                          resolutionKey: String,
+                          name: String): ResourceResolution = withContext(Dispatchers.IO) {
+
+        resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName(
+            resolutionKey,
+            blueprintName,
+            blueprintVersion,
+            artifactPrefix,
+            name)
+    }
+
+    suspend fun readWithResolutionKey(blueprintName: String,
+                                      blueprintVersion: String,
+                                      artifactPrefix: String,
+                                      resolutionKey: String): List<ResourceResolution> = withContext(Dispatchers.IO) {
+
+        resourceResolutionRepository.findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(
+            resolutionKey,
+            blueprintName,
+            blueprintVersion,
+            artifactPrefix)
+    }
+
+    suspend fun readWithResourceIdAndResourceType(blueprintName: String,
+                                                  blueprintVersion: String,
+                                                  resourceId: String,
+                                                  resourceType: String): List<ResourceResolution> = withContext(Dispatchers.IO) {
+
+        resourceResolutionRepository.findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(
+            blueprintName,
+            blueprintVersion,
+            resourceId,
+            resourceType)
+    }
+
+    suspend fun write(properties: Map<String, Any>,
+                      bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                      artifactPrefix: String,
+                      resourceAssignment: ResourceAssignment): ResourceResolution = 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()
+        val resourceType =
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_TYPE].toString()
+        val resourceId =
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOURCE_ID].toString()
+
+        write(blueprintName,
+            blueprintVersion,
+            resolutionKey,
+            resourceId,
+            resourceType,
+            artifactPrefix,
+            resourceAssignment)
+    }
+
+    suspend fun write(blueprintName: String,
+                      blueprintVersion: String,
+                      resolutionKey: String,
+                      resourceId: String,
+                      resourceType: String,
+                      artifactPrefix: String,
+                      resourceAssignment: ResourceAssignment): ResourceResolution = withContext(Dispatchers.IO) {
+
+        val resourceResolution = ResourceResolution()
+        resourceResolution.id = UUID.randomUUID().toString()
+        resourceResolution.artifactName = artifactPrefix
+        resourceResolution.blueprintVersion = blueprintVersion
+        resourceResolution.blueprintName = blueprintName
+        resourceResolution.resolutionKey = resolutionKey
+        resourceResolution.resourceType = resourceType
+        resourceResolution.resourceId = resourceId
+        resourceResolution.value = JacksonUtils.getValue(resourceAssignment.property?.value!!).toString()
+        resourceResolution.name = resourceAssignment.name
+        resourceResolution.dictionaryName = resourceAssignment.dictionaryName
+        resourceResolution.dictionaryVersion = resourceAssignment.version
+        resourceResolution.dictionarySource = resourceAssignment.dictionarySource
+        resourceResolution.status = resourceAssignment.status
+
+        try {
+            resourceResolutionRepository.saveAndFlush(resourceResolution)
+        } catch (ex: Exception) {
+            throw BluePrintException("Failed to store resource resolution result.", ex)
+        }
+    }
+}
\ No newline at end of file
index 72bb4a3..d2cbf84 100644 (file)
@@ -17,9 +17,21 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db
 
 import org.springframework.data.jpa.repository.JpaRepository
 
-interface ResourceResolutionRepository : JpaRepository<ResourceResolutionResult, String> {
+interface ResourceResolutionRepository : JpaRepository<ResourceResolution, String> {
 
-    fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?,
-                                                                              blueprintVersion: String?,
-                                                                              artifactName: String): ResourceResolutionResult
-}
+    fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactNameAndName(key: String,
+                                                                                     blueprintName: String?,
+                                                                                     blueprintVersion: String?,
+                                                                                     artifactName: String,
+                                                                                     name: String): ResourceResolution
+
+    fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(resolutionKey: String,
+                                                                              blueprintName: String,
+                                                                              blueprintVersion: String,
+                                                                              artifactPrefix: String): List<ResourceResolution>
+
+    fun findByBlueprintNameAndBlueprintVersionAndResourceIdAndResourceType(blueprintName: String,
+                                                                           blueprintVersion: String,
+                                                                           resourceId: String,
+                                                                           resourceType: String): List<ResourceResolution>
+}
\ 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
new file mode 100644 (file)
index 0000000..efc130a
--- /dev/null
@@ -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 ResourceResolutionResultRepository : JpaRepository<ResourceResolutionResult, String> {
+
+    fun findByResolutionKeyAndBlueprintNameAndBlueprintVersionAndArtifactName(key: String, blueprintName: String?,
+                                                                              blueprintVersion: String?,
+                                                                              artifactName: String): ResourceResolutionResult
+}
index 3cb9dec..ebb34ba 100644 (file)
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Service
 import java.util.*
 
 @Service
-class ResourceResolutionResultService(private val resourceResolutionRepository: ResourceResolutionRepository) {
+class ResourceResolutionResultService(private val resourceResolutionRepository: ResourceResolutionResultRepository) {
 
     suspend fun read(bluePrintRuntimeService: BluePrintRuntimeService<*>, artifactPrefix: String,
                      resolutionKey: String): String = withContext(Dispatchers.IO) {
index 9c2a100..4a3e75c 100644 (file)
@@ -128,15 +128,10 @@ class ResourceResolutionServiceTest {
 
             val artifactPrefix = "another"
 
-            // Templating Artifact Definition Name
-            val artifactTemplate = "$artifactPrefix-template"
-            // Resource Assignment Artifact Definition Name
-            val artifactMapping = "$artifactPrefix-mapping"
-
             // Prepare Inputs
             PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment")
 
-            resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", artifactMapping, artifactTemplate)
+            resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", artifactPrefix, mapOf<String, String>())
         }
     }
 }
index 3895c39..b2064cb 100644 (file)
@@ -47,11 +47,6 @@ abstract class RestconfComponentFunction : AbstractScriptComponentFunction() {
         return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName)
     }
 
-    fun resolveAndGenerateMessage(artifactMapping: String, artifactTemplate: String): String = runBlocking {
-        resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName,
-                artifactMapping, artifactTemplate)
-    }
-
     fun resolveAndGenerateMessage(artifactPrefix: String): String = runBlocking {
         resourceResolutionService().resolveResources(bluePrintRuntimeService, nodeTemplateName,
                 artifactPrefix, mapOf())
diff --git a/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionController.java b/ms/blueprintsprocessor/modules/inbounds/resource-api/src/main/java/org/onap/ccsdk/cds/blueprintsprocessor/resource/api/ResourceResolutionController.java
deleted file mode 100644 (file)
index 3e94d79..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Copyright © 2017-2018 AT&T 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.resource.api;
-
-import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionService;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
-import reactor.core.publisher.Mono;
-
-/**
- * ResourceResolutionController
- *
- * @author Brinda Santh Date : 8/13/2018
- */
-
-@RestController
-@RequestMapping("/api/v1/resource")
-public class ResourceResolutionController {
-
-    private ResourceResolutionService resourceResolutionService;
-
-    public ResourceResolutionController(ResourceResolutionService resourceResolutionService) {
-        this.resourceResolutionService = resourceResolutionService;
-    }
-
-    @RequestMapping(path = "/ping", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
-    public @ResponseBody
-    Mono<String> ping() {
-        return Mono.just("Success");
-    }
-}
index 69641c6..7f8f7da 100644 (file)
@@ -48,7 +48,7 @@ open class ResolutionResultsServiceExceptionHandler {
 
     @ExceptionHandler
     fun ResolutionResultsServiceExceptionHandler(e: BluePrintProcessorException): ResponseEntity<ErrorMessage> {
-        log.error(e.message)
+        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))
@@ -56,7 +56,7 @@ open class ResolutionResultsServiceExceptionHandler {
 
     @ExceptionHandler
     fun ResolutionResultsServiceExceptionHandler(e: ServerWebInputException): ResponseEntity<ErrorMessage> {
-        log.error(e.message)
+        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))
@@ -64,7 +64,7 @@ open class ResolutionResultsServiceExceptionHandler {
 
     @ExceptionHandler
     fun ResolutionResultsServiceExceptionHandler(e: EmptyResultDataAccessException): ResponseEntity<ErrorMessage> {
-        log.error(e.message)
+        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))
@@ -72,7 +72,7 @@ open class ResolutionResultsServiceExceptionHandler {
 
     @ExceptionHandler
     fun ResolutionResultsServiceExceptionHandler(e: JpaObjectRetrievalFailureException): ResponseEntity<ErrorMessage> {
-        log.error(e.message)
+        log.error(e.message, e)
 
         var errorCode = ErrorCode.RESOURCE_NOT_FOUND
         val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
@@ -86,6 +86,12 @@ open class ResolutionResultsServiceExceptionHandler {
         val errorMessage = ErrorMessage(errorCode.message(e.message!!), errorCode.value, debugMsg)
         return ResponseEntity(errorMessage, HttpStatus.resolve(errorCode.httpCode))
     }
+
+    @ExceptionHandler
+    fun ResolutionResultsServiceExceptionHandler(e: ResourceException): ResponseEntity<ErrorMessage> {
+        log.error(e.message, e)
+        return ResponseEntity(ErrorMessage(e.message, e.code, debugMsg), HttpStatus.resolve(e.code))
+    }
 }
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
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
new file mode 100644 (file)
index 0000000..40aa1a3
--- /dev/null
@@ -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.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<List<ResourceResolution>> = 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<ResourceResolution> = 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
new file mode 100644 (file)
index 0000000..6815c05
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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/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
new file mode 100644 (file)
index 0000000..fa8bf44
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * 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 com.fasterxml.jackson.core.type.TypeReference
+import com.fasterxml.jackson.module.kotlin.readValue
+import kotlinx.coroutines.runBlocking
+import org.junit.Assert
+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.ResourceResolution
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.db.ResourceResolutionDBService
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintCatalogService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.python.jline.console.internal.ConsoleRunner.property
+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.HttpHeaders
+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.util.function.Consumer
+import kotlin.test.BeforeTest
+import org.h2.value.DataType.readValue
+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 java.lang.reflect.Array
+
+
+@RunWith(SpringRunner::class)
+@WebFluxTest
+@ContextConfiguration(classes = [ResourceController::class, ResourceResolutionDBService::class, SecurityProperties::class])
+@ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"])
+@TestPropertySource(locations = ["classpath:application-test.properties"])
+class ResourceControllerTest {
+
+    private val log = LoggerFactory.getLogger(ResourceControllerTest::class.toString())
+
+    @Autowired
+    lateinit var resourceResolutionDBService: ResourceResolutionDBService
+    @Autowired
+    lateinit var webTestClient: WebTestClient
+
+    val blueprintName = "baseconfiguration"
+    val blueprintVersion = "1.0.0"
+    val templatePrefix = "activate"
+
+    @Test
+    fun `ping return Success`() {
+        runBlocking {
+            webTestClient.get().uri("/api/v1/resources/ping")
+                .exchange()
+                .expectStatus().isOk
+                .expectBody()
+                .equals("Success")
+        }
+    }
+
+    @Test
+    fun getAllFromResolutionKeyTest() {
+
+        val resolutionKey = "1"
+        val ra1 = createRA("bob")
+        val ra2 = createRA("dylan")
+
+        runBlocking {
+
+            store(ra1, resKey = resolutionKey)
+            store(ra2, resKey = resolutionKey)
+
+            webTestClient
+                .get()
+                .uri("/api/v1/resources?bpName=$blueprintName&bpVersion=$blueprintVersion&artifactName=$templatePrefix&resolutionKey=$resolutionKey")
+                .exchange()
+                .expectStatus().isOk
+                .expectBody()
+                .consumeWith {
+                    val json = String(it.responseBody!!)
+                    val typeFactory = JacksonUtils.objectMapper.typeFactory
+                    val list: List<ResourceResolution> = JacksonUtils.objectMapper.readValue(json,
+                        typeFactory.constructCollectionType(List::class.java, ResourceResolution::class.java))
+                    Assert.assertEquals(2, list.size)
+                    assertEqual(ra1, list[0])
+                    assertEqual(ra1, list[0])
+                }
+        }
+    }
+
+    @Test
+    fun getAllFromFromResourceTypeAndIdTest() {
+
+        val resourceId = "1"
+        val resourceType = "ServiceInstance"
+        val ra1 = createRA("bob")
+        val ra2 = createRA("dylan")
+
+        runBlocking {
+
+            store(ra1, resId = resourceId, resType = resourceType)
+            store(ra2, resId = resourceId, resType = resourceType)
+
+            webTestClient
+                .get()
+                .uri("/api/v1/resources?bpName=$blueprintName&bpVersion=$blueprintVersion&resourceType=$resourceType&resourceId=$resourceId")
+                .exchange()
+                .expectStatus().isOk
+                .expectBody()
+                .consumeWith {
+                    val json = String(it.responseBody!!)
+                    val typeFactory = JacksonUtils.objectMapper.typeFactory
+                    val list: List<ResourceResolution> = JacksonUtils.objectMapper.readValue(json,
+                        typeFactory.constructCollectionType(List::class.java, ResourceResolution::class.java))
+                    Assert.assertEquals(2, list.size)
+                    assertEqual(ra1, list[0])
+                    assertEqual(ra1, list[0])
+                }
+        }
+    }
+
+
+    @Test
+    fun getAllFromMissingParamTest() {
+        runBlocking {
+            webTestClient
+                .get()
+                .uri("/api/v1/resources?bpName=$blueprintName&bpVersion=$blueprintVersion")
+                .exchange()
+                .expectStatus().is4xxClientError
+                .expectBody()
+                .consumeWith {
+                    val r = JacksonUtils.objectMapper.readValue(it.responseBody, ErrorMessage::class.java)
+                    Assert.assertEquals("Missing param. Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.",
+                        r.message)
+                }
+        }
+    }
+
+    @Test
+    fun getAllFromWrongInputTest() {
+        runBlocking {
+            webTestClient
+                .get()
+                .uri("/api/v1/resources?bpName=$blueprintName&bpVersion=$blueprintVersion&artifactName=$templatePrefix&resolutionKey=test&resourceId=1")
+                .exchange()
+                .expectStatus().is4xxClientError
+                .expectBody()
+                .consumeWith {
+                    val r = JacksonUtils.objectMapper.readValue(it.responseBody, ErrorMessage::class.java)
+                    Assert.assertEquals("Either retrieve resolved value using artifact name and resolution-key OR using resource-id and resource-type.",
+                        r.message)
+                }
+        }
+    }
+
+    @Test
+    fun getOneFromResolutionKeyTest() {
+        val resolutionKey = "3"
+        val ra = createRA("joe")
+        runBlocking {
+            store(ra, resKey = resolutionKey)
+        }
+        runBlocking {
+            webTestClient.get()
+                .uri("/api/v1/resources/resource?bpName=$blueprintName&bpVersion=$blueprintVersion&artifactName=$templatePrefix&resolutionKey=$resolutionKey&name=joe")
+                .exchange()
+                .expectStatus().isOk
+                .expectBody()
+                .consumeWith {
+                    val r = JacksonUtils.objectMapper.readValue(it.responseBody, ResourceResolution::class.java)
+                    assertEqual(ra, r)
+                }
+        }
+    }
+
+    @Test
+    fun getOneFromResolutionKey404Test() {
+        val resolutionKey = "3"
+        runBlocking {
+            webTestClient.get()
+                .uri("/api/v1/resources/resource?bpName=$blueprintName&bpVersion=$blueprintVersion&artifactName=$templatePrefix&resolutionKey=$resolutionKey&name=doesntexist")
+                .exchange()
+                .expectStatus().is4xxClientError
+                .expectBody()
+        }
+    }
+
+    private suspend fun store(resourceAssignment: ResourceAssignment, resKey: String = "", resId: String = "",
+                              resType: String = "") {
+        resourceResolutionDBService.write(blueprintName,
+            blueprintVersion,
+            resKey,
+            resId,
+            resType,
+            templatePrefix,
+            resourceAssignment)
+    }
+
+    private fun createRA(prefix: String): ResourceAssignment {
+        val property = PropertyDefinition()
+        property.value = "value$prefix".asJsonPrimitive()
+
+        val resourceAssignment = ResourceAssignment()
+        resourceAssignment.name = prefix
+        resourceAssignment.dictionaryName = "dd$prefix"
+        resourceAssignment.dictionarySource = "source$prefix"
+        resourceAssignment.version = 2
+        resourceAssignment.status = "SUCCESS"
+        resourceAssignment.property = property
+        return resourceAssignment
+    }
+
+    private fun assertEqual(resourceAssignment: ResourceAssignment, resourceResolution: ResourceResolution) {
+        Assert.assertEquals(JacksonUtils.getValue(resourceAssignment.property?.value!!).toString(),
+            resourceResolution.value)
+        Assert.assertEquals(resourceAssignment.status, resourceResolution.status)
+        Assert.assertEquals(resourceAssignment.dictionarySource, resourceResolution.dictionarySource)
+        Assert.assertEquals(resourceAssignment.dictionaryName, resourceResolution.dictionaryName)
+        Assert.assertEquals(resourceAssignment.version, resourceResolution.dictionaryVersion)
+        Assert.assertEquals(resourceAssignment.name, resourceResolution.name)
+        Assert.assertEquals(blueprintVersion, resourceResolution.blueprintVersion)
+        Assert.assertEquals(blueprintName, resourceResolution.blueprintName)
+
+    }
+}
\ No newline at end of file
index 80ce72e..a2f1e23 100644 (file)
@@ -79,12 +79,14 @@ open class ResourceAssignment {
 
     override fun toString(): String {
         return StringBuilder()
-                .append("[")
-                .append("name=", name)
-                .append(", dictionaryName=", dictionaryName)
-                .append(", dictionarySource=", dictionarySource)
-                .append("]")
-                .toString()
+            .append("[")
+            .append("name=", name)
+            .append(", status=", status)
+            .append(", property=", property?.value ?: "")
+            .append(", dictionaryName=", dictionaryName)
+            .append(", dictionarySource=", dictionarySource)
+            .append("]")
+            .toString()
     }
 }