Add Naming Service & IP Assign custom resource resolution capability 20/107320/4
authorPaira, Saurav(sp694w) <sp694w@att.com>
Thu, 7 May 2020 12:54:40 +0000 (12:54 +0000)
committerSaurav Paira <sp694w@att.com>
Mon, 18 May 2020 17:13:58 +0000 (17:13 +0000)
Issue-ID: CCSDK-2185
Signed-off-by: Paira, Saurav(sp694w) <sp694w@att.com>
Change-Id: I70550fe9582b2db0a70c7b66591438b674173411

ms/blueprintsprocessor/application/src/main/resources/application.properties
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/capabilities/IpAssignResolutionCapability.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapability.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapabilityTest.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapabilityTest.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt
ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestClientServiceTest.kt

index 6fb737e..429011a 100755 (executable)
@@ -94,6 +94,18 @@ blueprintsprocessor.restclient.sdnc.url=http://sdnc:8282
 blueprintsprocessor.restclient.sdnc.username=admin
 blueprintsprocessor.restclient.sdnc.password=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
 
+# Naming MS REST client settings
+blueprintsprocessor.restclient.naming-ms.type=basic-auth
+blueprintsprocessor.restclient.naming-ms.url=http://naming-ms:8282
+blueprintsprocessor.restclient.naming-ms.username=admin
+blueprintsprocessor.restclient.naming-ms.password=demo123456!
+
+# IPAssign MS REST client settings
+blueprintsprocessor.restclient.ipassign-ms.type=basic-auth
+blueprintsprocessor.restclient.ipassign-ms.url=http://naming-ms:8282
+blueprintsprocessor.restclient.ipassign-ms.username=admin
+blueprintsprocessor.restclient.ipassign-ms.password=demo123456!
+
 # Primary AAI Data REST Client settings
 blueprintsprocessor.restclient.aai-data.type=basic-auth
 blueprintsprocessor.restclient.aai-data.url=https://aai:8443
index dff00c7..15fd1d6 100644 (file)
@@ -78,7 +78,7 @@ interface ResourceResolutionService {
         resolveDefinition: String,
         sources: List<String>
     ):
-            MutableMap<String, JsonNode>
+        MutableMap<String, JsonNode>
 
     suspend fun resolveResourceAssignments(
         blueprintRuntimeService: BluePrintRuntimeService<*>,
@@ -159,7 +159,7 @@ open class ResourceResolutionServiceImpl(
 
         val resourceAssignments: MutableList<ResourceAssignment> =
             JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment::class.java)
-                    as? MutableList<ResourceAssignment>
+                as? MutableList<ResourceAssignment>
                 ?: throw BluePrintProcessorException("couldn't get Dictionary Definitions")
 
         if (isToStore(properties)) {
@@ -185,19 +185,24 @@ open class ResourceResolutionServiceImpl(
             properties
         )
 
-        val resolutionSummary = properties.getOrDefault(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_SUMMARY, false) as Boolean
+        val resolutionSummary = properties.getOrDefault(
+            ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_RESOLUTION_SUMMARY,
+            false
+        ) as Boolean
         val resolvedParamJsonContent =
             ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignments.toList())
-        val artifactTemplateDefinition = bluePrintRuntimeService.bluePrintContext().checkNodeTemplateArtifact(nodeTemplateName, artifactTemplate)
+        val artifactTemplateDefinition =
+            bluePrintRuntimeService.bluePrintContext().checkNodeTemplateArtifact(nodeTemplateName, artifactTemplate)
 
         val resolvedContent = when {
             artifactTemplateDefinition != null -> {
                 blueprintTemplateService.generateContent(
-                        bluePrintRuntimeService, nodeTemplateName,
-                        artifactTemplate, resolvedParamJsonContent, false,
-                        mutableMapOf(
-                                ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE to
-                                        properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE].asJsonPrimitive()
+                    bluePrintRuntimeService, nodeTemplateName,
+                    artifactTemplate, resolvedParamJsonContent, false,
+                    mutableMapOf(
+                        ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE to
+                            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_OCCURRENCE]
+                                .asJsonPrimitive()
                         )
                 )
             }
@@ -277,13 +282,16 @@ open class ResourceResolutionServiceImpl(
                                 applicationContext.getBean(processorName) as? ResourceAssignmentProcessor
                                     ?: throw BluePrintProcessorException(
                                         "failed to get resource processor ($processorName) " +
-                                                "for resource assignment(${resourceAssignment.name})"
+                                            "for resource assignment(${resourceAssignment.name})"
                                     )
                             try {
                                 // Set BluePrint Runtime Service
                                 resourceAssignmentProcessor.raRuntimeService = resourceAssignmentRuntimeService
                                 // Set Resource Dictionaries
                                 resourceAssignmentProcessor.resourceDictionaries = resourceDefinitions
+
+                                resourceAssignmentProcessor.resourceAssignments = resourceAssignments
+
                                 // Invoke Apply Method
                                 resourceAssignmentProcessor.applyNB(resourceAssignment)
 
@@ -347,7 +355,7 @@ open class ResourceResolutionServiceImpl(
     // Check whether to store or not the resolution of resource and template
     private fun isToStore(properties: Map<String, Any>): Boolean {
         return properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT) &&
-                properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean
+            properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean
     }
 
     // Check whether resolution already exist in the database for the specified resolution-key or resourceId/resourceType
@@ -388,8 +396,8 @@ open class ResourceResolutionServiceImpl(
                 )
             if (existingResourceAssignments.isNotEmpty()) {
                 log.info(
-                    "Resolution with resourceId=($resourceId) and resourceType=($resourceType) already exist - will resolve " +
-                            "all resources not already resolved."
+                    "Resolution with resourceId=($resourceId) and resourceType=($resourceType) already " +
+                        "exist - will resolve all resources not already resolved."
                 )
             }
             return existingResourceAssignments
@@ -426,9 +434,9 @@ open class ResourceResolutionServiceImpl(
     // Comparision between what we have in the database vs what we have to assign.
     private fun compareOne(resourceResolution: ResourceResolution, resourceAssignment: ResourceAssignment): Boolean {
         return (resourceResolution.name == resourceAssignment.name &&
-                resourceResolution.dictionaryName == resourceAssignment.dictionaryName &&
-                resourceResolution.dictionarySource == resourceAssignment.dictionarySource &&
-                resourceResolution.dictionaryVersion == resourceAssignment.version)
+            resourceResolution.dictionaryName == resourceAssignment.dictionaryName &&
+            resourceResolution.dictionarySource == resourceAssignment.dictionarySource &&
+            resourceResolution.dictionaryVersion == resourceAssignment.version)
     }
 
     private fun exposeOccurrencePropertyInResourceAssignments(
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapability.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapability.kt
new file mode 100644 (file)
index 0000000..b38c320
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 2019 AT&T.
+ *
+ *  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.capabilities
+
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
+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.blueprintsprocessor.rest.restClientService
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.KeyIdentifier
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.springframework.http.HttpMethod
+
+/**
+ * @author saurav.paira
+ */
+
+open class IpAssignResolutionCapability : ResourceAssignmentProcessor() {
+
+    val log = logger(IpAssignResolutionCapability::class)
+
+    override fun getName(): String {
+        return "${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}ipassignment-capability"
+    }
+
+    override suspend fun processNB(resourceAssignment: ResourceAssignment) {
+        try {
+            if (!setFromInput(resourceAssignment) && isTemplateKeyValueNull(resourceAssignment)) {
+                val dName = resourceAssignment.dictionaryName!!
+                val dSource = resourceAssignment.dictionarySource!!
+                val resourceDefinition = resourceDefinition(dName)
+
+                /** Check Resource Assignment has the source definitions, If not get from Resource Definitions **/
+                val resourceSource = resourceAssignment.dictionarySourceDefinition
+                    ?: resourceDefinition?.sources?.get(dSource)
+                    ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
+
+                val resourceSourceProperties =
+                    checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
+
+                // Get all matching resources assignments to process
+                val groupResourceAssignments =
+                    resourceAssignments.filter {
+                        it.dictionarySource == dSource
+                    }.toMutableList()
+
+                // inputKeyMapping is dynamic based on dependencies
+                val inputKeyMapping: MutableMap<String, String> =
+                    resourceAssignment.dependencies?.map { it to it }?.toMap()
+                        as MutableMap<String, String>
+
+                // Get the values from runtime store
+                val resolvedKeyValues = resolveInputKeyMappingVariables(inputKeyMapping)
+                log.info("\nResolved Input Key mappings: \n{}", resolvedKeyValues)
+
+                resolvedKeyValues?.map { KeyIdentifier(it.key, it.value) }
+                    ?.let { resourceAssignment.keyIdentifiers.addAll(it) }
+
+                // Generate the payload using already resolved value
+                val generatedPayload = generatePayload(resolvedKeyValues, groupResourceAssignments)
+                log.info("\nIP Assign mS Request Payload: \n{}", generatedPayload.asJsonType().toPrettyString())
+
+                resourceSourceProperties["resolved-payload"] = JacksonUtils.jsonNode(generatedPayload)
+
+                // Get the Rest Client service, selector will be included in application.properties
+                val restClientService = BluePrintDependencyService.restClientService(
+                    "ipassign-ms"
+                )
+
+                // Get the Rest Response
+                val response = restClientService.exchangeResource(
+                    HttpMethod.POST.name,
+                    "/web/service/v1/assign", generatedPayload
+                )
+                val responseStatusCode = response.status
+                val responseBody = response.body
+                log.info("\nIP Assign mS Response : \n{}", responseBody.asJsonType().toPrettyString())
+                if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
+                    populateResource(groupResourceAssignments, responseBody)
+                } else {
+                    val errMsg =
+                        "Failed to dictionary name ($dName), dictionary source($($dName) " +
+                            "response_code: ($responseStatusCode)"
+                    log.warn(errMsg)
+                    throw BluePrintProcessorException(errMsg)
+                }
+                // Parse the error Body and assign the property value
+            }
+            // Check the value has populated for mandatory case
+            ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment)
+        } catch (e: Exception) {
+            ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message)
+            throw BluePrintProcessorException(
+                "Failed in template key ($resourceAssignment) assignments with: ${e.message}",
+                e
+            )
+        }
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
+        raRuntimeService.getBluePrintError().addError(runtimeException.message!!)
+    }
+
+    /** Generates aggregated request payload for Ip Assign mS. Parses the resourceassignments of
+     * sourceCapability "ipassign-ms". It generates below sample payload
+     * {
+    "requests": [{
+    "name": "fixed_ipv4_Address_01",
+    "property": {
+    "CloudRegionId": "abcd123",
+    "IpServiceName": "MobilityPlan",
+    }
+    }, {
+    "name": "fixed_ipv4_Address_02",
+    "property": {
+    "CloudRegionId": "abcd123",
+    "IpServiceName": "MobilityPlan",
+    }
+    }
+    ]
+    } */
+    private fun generatePayload(
+        input: Map<String, Any>,
+        groupResourceAssignments: MutableList<ResourceAssignment>
+    ): String {
+        data class IpRequest(val name: String = "", val property: Map<String, String> = mutableMapOf<String, String>())
+        data class IpAssignRequest(val requests: MutableList<IpRequest> = mutableListOf())
+
+        val ipAssignRequests = IpAssignRequest()
+        groupResourceAssignments.forEach {
+            val ipRequest = IpRequest(it.name, input.mapValues { it.value.toString().removeSurrounding("\"") })
+            ipAssignRequests.requests.add(ipRequest)
+        }
+        return ipAssignRequests.asJsonType().toString()
+    }
+
+    private fun populateResource(
+        resourceAssignments: MutableList<ResourceAssignment>,
+        restResponse: String
+    ) {
+        /** Parse all the resource assignment fields and set the corresponding value */
+        resourceAssignments.forEach { resourceAssignment ->
+            // Set the List of Complex Values
+            val parsedResourceAssignmentValue = checkNotNull(
+                JacksonUtils.jsonNode(restResponse).path(resourceAssignment.name).textValue()
+            ) {
+                "Failed to find path ($resourceAssignment.name) in response ($restResponse)"
+            }
+
+            ResourceAssignmentUtils.setResourceDataValue(
+                resourceAssignment,
+                raRuntimeService,
+                parsedResourceAssignmentValue
+            )
+        }
+    }
+}
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapability.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapability.kt
new file mode 100644 (file)
index 0000000..dbac70a
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * 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.capabilities
+
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
+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.blueprintsprocessor.rest.restClientService
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.KeyIdentifier
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.springframework.http.HttpMethod
+
+/**
+ * @author brindasanth
+ */
+
+open class NamingResolutionCapability : ResourceAssignmentProcessor() {
+
+    val log = logger(NamingResolutionCapability::class)
+
+    override fun getName(): String {
+        return "${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}naming-capability"
+    }
+
+    override suspend fun processNB(resourceAssignment: ResourceAssignment) {
+        try {
+            if (!setFromInput(resourceAssignment) && isTemplateKeyValueNull(resourceAssignment)) {
+                val dName = resourceAssignment.dictionaryName!!
+                val dSource = resourceAssignment.dictionarySource!!
+                val resourceDefinition = resourceDefinition(dName)
+
+                /** Check Resource Assignment has the source definitions, If not get from Resource Definitions **/
+                val resourceSource = resourceAssignment.dictionarySourceDefinition
+                    ?: resourceDefinition?.sources?.get(dSource)
+                    ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
+
+                val resourceSourceProperties =
+                    checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
+
+                // Get all matching resources assignments to process
+                val groupResourceAssignments =
+                    resourceAssignments.filter {
+                        it.dictionarySource == dSource
+                    }.toMutableList()
+
+                // inputKeyMapping is dynamic based on dependencies
+                val inputKeyMapping: MutableMap<String, String> =
+                    resourceAssignment.dependencies?.map { it to it }?.toMap()
+                        as MutableMap<String, String>
+                log.info("\nResolving Input Key mappings: \n{}", inputKeyMapping)
+
+                // Get the values from runtime store
+                val resolvedKeyValues = resolveInputKeyMappingVariables(inputKeyMapping)
+                log.info("\nResolved Input Key mappings: \n{}", resolvedKeyValues)
+
+                resolvedKeyValues?.map { KeyIdentifier(it.key, it.value) }
+                    ?.let { resourceAssignment.keyIdentifiers.addAll(it) }
+
+                // Generate the payload using already resolved value
+                val generatedPayload = generatePayload(resolvedKeyValues, groupResourceAssignments)
+                log.info("\nNaming mS Request Payload: \n{}", generatedPayload.asJsonType().toPrettyString())
+
+                resourceSourceProperties["resolved-payload"] = JacksonUtils.jsonNode(generatedPayload)
+
+                // Get the Rest Client service, selector will be included in application.properties
+                val restClientService = BluePrintDependencyService.restClientService(
+                    "naming-ms"
+                )
+
+                // Get the Rest Response
+                val response = restClientService.exchangeResource(
+                    HttpMethod.POST.name,
+                    "/web/service/v1/genNetworkElementName/cds", generatedPayload
+                )
+
+                val responseStatusCode = response.status
+                val responseBody = response.body
+                log.info("\nNaming mS Response : \n{}", responseBody.asJsonType().toPrettyString())
+                if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
+                    populateResource(groupResourceAssignments, responseBody)
+                } else {
+                    val errMsg =
+                        "Failed to dictionary name ($dName), dictionary source($($dName) " +
+                            "response_code: ($responseStatusCode)"
+                    log.warn(errMsg)
+                    throw BluePrintProcessorException(errMsg)
+                }
+                // Parse the error Body and assign the property value
+            }
+            // Check the value has populated for mandatory case
+            ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment)
+        } catch (e: Exception) {
+            ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message)
+            throw BluePrintProcessorException(
+                "Failed in template key ($resourceAssignment) assignments with: ${e.message}",
+                e
+            )
+        }
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
+        raRuntimeService.getBluePrintError().addError(runtimeException.message!!)
+    }
+
+    /** Generates aggregated request payload for Naming mS. Parses the resourceassignments of
+     * sourceCapability "naming-ms". "naming-type" should be provides as property metadata for
+     * each resourceassigment of sourceCapability "naming-ms". It generates below sample payload
+     * {
+    "elements": [{
+    "vf-module-name": "${vf-module-name}",
+    "naming-type": "VF-MODULE",
+    "naming-code": "dbc",
+    "vf-module-label": "adsf",
+    "policy-instance-name": "SDNC_Policy.Config_Json.xml",
+    "vnf-name": "vnf-123",
+    "vf-module-type": "base"
+    }, {
+    "vnfc-name": "${vnfc-name}",
+    "naming-type": "VNFC",
+    "naming-code": "dbc",
+    "vf-module-label": "adsf",
+    "policy-instance-name": "SDNC_Policy.Config_Json.xml",
+    "vnf-name": "vnf-123",
+    "vf-module-type": "base"
+    }
+    ]
+    } */
+    private fun generatePayload(
+        input: Map<String, Any>,
+        groupResourceAssignments: MutableList<ResourceAssignment>
+    ): String {
+        data class NameAssignRequest(val elements: MutableList<Map<String, String>> = mutableListOf())
+
+        val nameAssignRequests = NameAssignRequest()
+        groupResourceAssignments.forEach {
+            val metadata = resourceDictionaries[it.dictionaryName]?.property?.metadata
+            val namingType = metadata?.get("naming-type")
+            val moduleName = namingType.plus("-name").toLowerCase()
+            val moduleValue = "\${".plus(moduleName.plus("}"))
+
+            val request: MutableMap<String, String> = input.mapValues {
+                    it.value.toString().removeSurrounding("\"") } as MutableMap<String, String>
+            if (namingType != null) {
+                request["naming-type"] = namingType
+            }
+            request[moduleName] = moduleValue
+            nameAssignRequests.elements.add(request)
+        }
+        return nameAssignRequests.asJsonType().toString()
+    }
+
+    private fun populateResource(
+        resourceAssignments: MutableList<ResourceAssignment>,
+        restResponse: String
+    ) {
+        /** Parse all the resource assignment fields and set the corresponding value */
+        resourceAssignments.forEach { resourceAssignment ->
+            // Set the List of Complex Values
+            val metadata =
+                resourceDictionaries[resourceAssignment.dictionaryName]?.property?.metadata
+
+            /** Naming ms returns the keys with "${naming-type}-name" */
+            val responseKey = metadata?.get("naming-type")?.toLowerCase().plus("-name")
+
+            val parsedResourceAssignmentValue = checkNotNull(
+                JacksonUtils.jsonNode(restResponse).path(responseKey).textValue()
+            ) {
+                "Failed to find path ($responseKey) in response ($restResponse)"
+            }
+
+            ResourceAssignmentUtils.setResourceDataValue(
+                resourceAssignment,
+                raRuntimeService,
+                parsedResourceAssignmentValue
+            )
+        }
+    }
+}
index 868f919..42e0861 100644 (file)
@@ -57,6 +57,7 @@ open class CapabilityResourceResolutionProcessor(private var componentFunctionSc
 
             val resourceSourceProps =
                 checkNotNull(resourceSource.properties) { "failed to get $resourceSource properties" }
+
             /**
              * Get the Capability Resource Source Info from Property Definitions.
              */
@@ -77,6 +78,7 @@ open class CapabilityResourceResolutionProcessor(private var componentFunctionSc
             // Assign Current Blueprint runtime and ResourceDictionaries
             componentResourceAssignmentProcessor!!.scriptType = scriptType
             componentResourceAssignmentProcessor!!.raRuntimeService = raRuntimeService
+            componentResourceAssignmentProcessor!!.resourceAssignments = resourceAssignments
             componentResourceAssignmentProcessor!!.resourceDictionaries = resourceDictionaries
 
             // Invoke componentResourceAssignmentProcessor
@@ -93,12 +95,9 @@ open class CapabilityResourceResolutionProcessor(private var componentFunctionSc
     }
 
     suspend fun scriptInstance(scriptType: String, scriptClassReference: String, instanceDependencies: List<String>):
-            ResourceAssignmentProcessor {
+        ResourceAssignmentProcessor {
 
-        log.info(
-            "creating resource resolution of script type($scriptType), reference name($scriptClassReference) and" +
-                    "instanceDependencies($instanceDependencies)"
-        )
+        log.info("creating resource resolution of script type($scriptType), reference name($scriptClassReference)")
 
         val scriptComponent = componentFunctionScriptingService
             .scriptInstance<ResourceAssignmentProcessor>(
index 454a899..0c0735f 100644 (file)
@@ -40,6 +40,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
 
     lateinit var raRuntimeService: ResourceAssignmentRuntimeService
     var resourceDictionaries: MutableMap<String, ResourceDefinition> = hashMapOf()
+    var resourceAssignments: MutableList<ResourceAssignment> = arrayListOf()
 
     var scriptPropertyInstances: MutableMap<String, Any> = hashMapOf()
     lateinit var scriptType: String
@@ -104,7 +105,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
     }
 
     open suspend fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: MutableMap<String, JsonNode>):
-            String {
+        String {
         if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) {
             return valueToResolve
         }
@@ -196,4 +197,16 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
     fun addError(error: String) {
         raRuntimeService.getBluePrintError().addError(error)
     }
+
+    fun isTemplateKeyValueNull(resourceAssignment: ResourceAssignment): Boolean {
+        val resourceProp = checkNotNull(resourceAssignment.property) {
+            "Failed to populate mandatory resource resource mapping $resourceAssignment"
+        }
+        if (resourceProp.required != null && resourceProp.required!! &&
+            resourceProp.value.isNullOrMissing()
+        ) {
+            return true
+        }
+        return false
+    }
 }
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapabilityTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapabilityTest.kt
new file mode 100644 (file)
index 0000000..e252b41
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Copyright © 2019 AT&T.
+ *
+ *  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.capabilities
+
+import com.fasterxml.jackson.databind.node.NullNode
+import io.mockk.coEvery
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.mockkObject
+import kotlinx.coroutines.runBlocking
+import org.junit.Before
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.CapabilityResourceResolutionProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceAssignments
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceDefinitions
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResolutionSummary
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
+
+/**
+ * @author saurav.paira
+ */
+
+class IpAssignResolutionCapabilityTest {
+    val log = logger(IpAssignResolutionCapabilityTest::class)
+
+    @Before
+    fun setup() {
+
+        mockkObject(BluePrintDependencyService)
+
+        val blueprintWebClientService = mockk<BlueprintWebClientService>()
+        // Create mock Response
+        val mockResponse = BlueprintWebClientService.WebClientResponse(
+            200, """{
+            "fixed_ipv4_Address_01" : "10.10.10.11",
+            "fixed_ipv4_Address_02" : "10.10.10.12",
+            "fixed_ipv4_Address_03" : "10.10.10.13"
+            }
+        """.trimMargin()
+        )
+        every { blueprintWebClientService.exchangeResource(any(), any(), any()) } returns mockResponse
+
+        val restLibPropertyService = mockk<BluePrintRestLibPropertyService>()
+        every { restLibPropertyService.blueprintWebClientService("ipassign-ms") } returns blueprintWebClientService
+        every { BluePrintDependencyService.applicationContext.getBean(any()) } returns restLibPropertyService
+    }
+
+    @Test
+    fun testIpAssignResolutionCapability() {
+        runBlocking {
+            val componentFunctionScriptingService = mockk<ComponentFunctionScriptingService>()
+            coEvery {
+                componentFunctionScriptingService
+                    .scriptInstance<ResourceAssignmentProcessor>(any(), any(), any())
+            } returns IpAssignResolutionCapability()
+
+            coEvery {
+                componentFunctionScriptingService.cleanupInstance(any(), any())
+            } returns mockk()
+
+            val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
+            every { raRuntimeService.bluePrintContext() } returns mockk()
+            every { raRuntimeService.getInputValue("fixed_ipv4_Address_01") } returns NullNode.getInstance()
+            every { raRuntimeService.getInputValue("fixed_ipv4_Address_02") } returns NullNode.getInstance()
+            every { raRuntimeService.getInputValue("fixed_ipv4_Address_03") } returns NullNode.getInstance()
+
+            every { raRuntimeService.getResolutionStore("CloudRegionId") } returns "cloud-123".asJsonPrimitive()
+            every { raRuntimeService.getResolutionStore("IpServiceName") } returns "MobilityPlan".asJsonPrimitive()
+
+            every { raRuntimeService.putResolutionStore(any(), any()) } returns Unit
+            every { raRuntimeService.putDictionaryStore(any(), any()) } returns Unit
+
+            val capabilityResourceResolutionProcessor =
+                CapabilityResourceResolutionProcessor(componentFunctionScriptingService)
+            capabilityResourceResolutionProcessor.raRuntimeService = raRuntimeService
+
+            capabilityResourceResolutionProcessor.resourceDictionaries = resourceDefinitions()
+            // log.info("ResourceAssignments Definitions : ${ capabilityResourceResolutionProcessor.resourceDictionaries.asJsonString(true)} ")
+            val resourceAssignments = resourceAssignments()
+            val resourceAssignmentList = resourceAssignments.values.toMutableList()
+            // log.info("ResourceAssignments Assignments : ${resourceAssignmentList.asJsonString(true)} ")
+            capabilityResourceResolutionProcessor.resourceAssignments = resourceAssignmentList
+
+            var status = capabilityResourceResolutionProcessor.applyNB(resourceAssignments["fixed_ipv4_Address_01"]!!)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals(
+                "10.10.10.11".asJsonPrimitive(), resourceAssignments["fixed_ipv4_Address_01"]!!.property!!.value,
+                "assigned value miss match"
+            )
+
+            status = capabilityResourceResolutionProcessor.applyNB(resourceAssignments["fixed_ipv4_Address_02"]!!)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals(
+                "10.10.10.12".asJsonPrimitive(), resourceAssignments["fixed_ipv4_Address_02"]!!.property!!.value,
+                "assigned value miss match"
+            )
+
+            status = capabilityResourceResolutionProcessor.applyNB(resourceAssignments["fixed_ipv4_Address_03"]!!)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals(
+                "10.10.10.13".asJsonPrimitive(), resourceAssignments["fixed_ipv4_Address_03"]!!.property!!.value,
+                "assigned value miss match"
+            )
+
+            val resoulutionSummary =
+                    ResourceAssignmentUtils.generateResolutionSummaryData(resourceAssignments.values.toList(),
+                        capabilityResourceResolutionProcessor.resourceDictionaries)
+            log.info(resoulutionSummary.asJsonType().toPrettyString())
+            assertNotNull(resoulutionSummary.asJsonType().get("resolution-summary"))
+
+            val summaries = JacksonUtils.jsonNode(resoulutionSummary)["resolution-summary"]
+            val list = JacksonUtils.getListFromJsonNode(summaries, ResolutionSummary::class.java)
+            val ipAddress = list.filter { it.name == "fixed_ipv4_Address_01" }
+
+            assertEquals(list.size, 5)
+            assertNotNull(ipAddress[0].keyIdentifiers)
+            assertNotNull(ipAddress[0].requestPayload)
+        }
+    }
+
+        /** Test dictionaries */
+
+    /** Test dictionaries */
+    private fun resourceDefinitions(): MutableMap<String, ResourceDefinition> {
+        return BluePrintTypes.resourceDefinitions {
+            resourceDefinition("CloudRegionId", "Cloud Region Id Resource Definition") {
+                tags("CloudRegionId")
+                updatedBy("saurav.paira@att.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("IpServiceName", "Ip Service Name Resource Definition") {
+                tags("IpServiceName")
+                updatedBy("saurav.paira@att.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("fixed_ipv4_Address_01", "fixed_ipv4_Address_01 Resource Definition") {
+                tags("fixed_ipv4_Address_01")
+                updatedBy("saurav.paira@att.com")
+                property("string", true)
+                sources {
+                    sourceCapability("ipassign-ms", "") {
+                        definedProperties {
+                            type("internal")
+                            scriptClassReference(IpAssignResolutionCapability::class)
+                            keyDependencies(
+                                arrayListOf(
+                                    "CloudRegionId",
+                                    "IpServiceName"
+                                )
+                            )
+                        }
+                    }
+                }
+            }
+            resourceDefinition("fixed_ipv4_Address_02", "fixed_ipv4_Address_02 Resource Definition") {
+                tags("fixed_ipv4_Address_01")
+                updatedBy("saurav.paira@att.com")
+                property("string", true)
+                sources {
+                    sourceCapability("ipassign-ms", "") {
+                        definedProperties {
+                            type("internal")
+                            scriptClassReference(IpAssignResolutionCapability::class)
+                            keyDependencies(
+                                arrayListOf(
+                                    "CloudRegionId",
+                                    "IpServiceName"
+                                )
+                            )
+                        }
+                    }
+                }
+            }
+            resourceDefinition("fixed_ipv4_Address_03", "fixed_ipv4_Address_03 Resource Definition") {
+                tags("fixed_ipv4_Address_03")
+                updatedBy("saurav.paira@att.com")
+                property("string", true)
+                sources {
+                    sourceCapability("ipassign-ms", "") {
+                        definedProperties {
+                            type("internal")
+                            scriptClassReference(IpAssignResolutionCapability::class)
+                            keyDependencies(
+                                arrayListOf(
+                                    "CloudRegionId",
+                                    "IpServiceName"
+                                )
+                            )
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private fun resourceAssignments(): MutableMap<String, ResourceAssignment> {
+        return BluePrintTypes.resourceAssignments {
+            resourceAssignment(
+                name = "CloudRegionId", dictionaryName = "CloudRegionId",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "IpServiceName", dictionaryName = "IpServiceName",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "fixed_ipv4_Address_01", dictionaryName = "fixed_ipv4_Address_01",
+                dictionarySource = "ipassign-ms"
+            ) {
+                property("string", true, "")
+                dependencies(
+                    arrayListOf(
+                        "CloudRegionId",
+                        "IpServiceName"
+                    )
+                )
+            }
+            resourceAssignment(
+                name = "fixed_ipv4_Address_02", dictionaryName = "fixed_ipv4_Address_02",
+                dictionarySource = "ipassign-ms"
+            ) {
+                property("string", true, "")
+                dependencies(
+                    arrayListOf(
+                        "fixed_ipv4_Address_01"
+                    )
+                )
+            }
+            resourceAssignment(
+                name = "fixed_ipv4_Address_03", dictionaryName = "fixed_ipv4_Address_03",
+                dictionarySource = "ipassign-ms"
+            ) {
+                property("string", true, "")
+                dependencies(
+                    arrayListOf(
+                        "fixed_ipv4_Address_02"
+                    )
+                )
+            }
+        }
+    }
+}
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapabilityTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapabilityTest.kt
new file mode 100644 (file)
index 0000000..ee53f8a
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * 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.capabilities
+
+import com.fasterxml.jackson.databind.node.NullNode
+import io.mockk.coEvery
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.mockkObject
+import kotlinx.coroutines.runBlocking
+import org.junit.Before
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.CapabilityResourceResolutionProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceAssignments
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.resourceDefinitions
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
+import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
+import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
+import org.onap.ccsdk.cds.controllerblueprints.core.logger
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResolutionSummary
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils.BulkResourceSequencingUtils
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
+
+/**
+ * @author brindasanth
+ */
+
+class NamingResolutionCapabilityTest {
+
+    private val log = logger(NamingResolutionCapabilityTest::class)
+
+    @Before
+    fun setup() {
+
+        mockkObject(BluePrintDependencyService)
+
+        val blueprintWebClientService = mockk<BlueprintWebClientService>()
+        // Create mock Response
+        val mockResponse = BlueprintWebClientService.WebClientResponse<String>(
+            200, """{
+            "vf-module-name" : "dlsst001dbcx-adsf-Base-01",
+            "vnfc-name" : "dlsst001dbcx"
+            }
+        """.trimMargin()
+        )
+        every { blueprintWebClientService.exchangeResource(any(), any(), any()) } returns mockResponse
+
+        val restLibPropertyService = mockk<BluePrintRestLibPropertyService>()
+        every { restLibPropertyService.blueprintWebClientService("naming-ms") } returns blueprintWebClientService
+        every { BluePrintDependencyService.applicationContext.getBean(any()) } returns restLibPropertyService
+    }
+
+    @Test
+    fun testNamingResolutionCapability() {
+        runBlocking {
+            val componentFunctionScriptingService = mockk<ComponentFunctionScriptingService>()
+            coEvery {
+                componentFunctionScriptingService
+                    .scriptInstance<ResourceAssignmentProcessor>(any(), any(), any())
+            } returns NamingResolutionCapability()
+
+            coEvery {
+                componentFunctionScriptingService.cleanupInstance(any(), any())
+            } returns mockk()
+
+            val raRuntimeService = mockk<ResourceAssignmentRuntimeService>()
+            every { raRuntimeService.bluePrintContext() } returns mockk<BluePrintContext>()
+            every { raRuntimeService.getInputValue("vf-module-name") } returns NullNode.getInstance()
+            every { raRuntimeService.getInputValue("vnfc-name") } returns NullNode.getInstance()
+
+            every { raRuntimeService.getResolutionStore("policy-instance-name") } returns "SDNC_Policy.Config_MS_1806SRIOV_VNATJson.4.xml".asJsonPrimitive()
+            every { raRuntimeService.getResolutionStore("naming-code") } returns "dbc".asJsonPrimitive()
+            every { raRuntimeService.getResolutionStore("vnf-name") } returns "vnf-123".asJsonPrimitive()
+            every { raRuntimeService.getResolutionStore("vf-module-label") } returns "adsf".asJsonPrimitive()
+            every { raRuntimeService.getResolutionStore("vf-module-type") } returns "base".asJsonPrimitive()
+            every { raRuntimeService.getResolutionStore("cloud-region-id") } returns "region-123".asJsonPrimitive()
+
+            every { raRuntimeService.putResolutionStore(any(), any()) } returns Unit
+            every { raRuntimeService.putDictionaryStore(any(), any()) } returns Unit
+
+            val capabilityResourceResolutionProcessor =
+                CapabilityResourceResolutionProcessor(componentFunctionScriptingService)
+            capabilityResourceResolutionProcessor.raRuntimeService = raRuntimeService
+
+            capabilityResourceResolutionProcessor.resourceDictionaries = resourceDefinitions()
+            // log.info("ResourceAssignments Definitions : ${ capabilityResourceResolutionProcessor.resourceDictionaries.asJsonString(true)} ")
+            val resourceAssignments = resourceAssignments()
+            val resourceAssignmentList = resourceAssignments.values.toMutableList()
+            // log.info("ResourceAssignments Assignments : ${resourceAssignmentList.asJsonString(true)} ")
+            capabilityResourceResolutionProcessor.resourceAssignments = resourceAssignmentList
+
+            val bulkSequenced =
+                BulkResourceSequencingUtils.process(capabilityResourceResolutionProcessor.resourceAssignments)
+            // log.info("Bulk Sequenced : ${bulkSequenced} ")
+            val resourceAssignment1 = resourceAssignments["vf-module-name"]
+            var status = capabilityResourceResolutionProcessor.applyNB(resourceAssignment1!!)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals(
+                "dlsst001dbcx-adsf-Base-01".asJsonPrimitive(), resourceAssignment1.property!!.value,
+                "assigned value miss match"
+            )
+
+            val resourceAssignment2 = resourceAssignments["vnfc-name"]
+            status = capabilityResourceResolutionProcessor.applyNB(resourceAssignment2!!)
+            assertTrue(status, "failed to execute capability source")
+            assertEquals(
+                "dlsst001dbcx".asJsonPrimitive(), resourceAssignment2.property!!.value,
+                "assigned value miss match"
+            )
+
+            val resoulutionSummary =
+                ResourceAssignmentUtils.generateResolutionSummaryData(resourceAssignments.values.toList(),
+                    capabilityResourceResolutionProcessor.resourceDictionaries)
+            log.info(resoulutionSummary.asJsonType().toPrettyString())
+            assertNotNull(resoulutionSummary.asJsonType().get("resolution-summary"))
+
+            val summaries = JacksonUtils.jsonNode(resoulutionSummary)["resolution-summary"]
+            val list = JacksonUtils.getListFromJsonNode(summaries, ResolutionSummary::class.java)
+            val vnfModuleName = list.filter { it.name == "vf-module-name" }
+
+            assertEquals(list.size, 9)
+            assertNotNull(vnfModuleName[0].keyIdentifiers)
+            assertNotNull(vnfModuleName[0].requestPayload)
+        }
+    }
+
+    /** Test dictionaries */
+    private fun resourceDefinitions(): MutableMap<String, ResourceDefinition> {
+        return BluePrintTypes.resourceDefinitions {
+            resourceDefinition("naming-code", "naming-code Resource Definition") {
+                tags("naming-code")
+                updatedBy("brindasanth@onap.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("naming-type", "naming-type Resource Definition") {
+                tags("naming-type")
+                updatedBy("brindasanth@onap.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("cloud-region-id", "cloud-region-id Resource Definition") {
+                tags("cloud-region-id")
+                updatedBy("brindasanth@onap.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("policy-instance-name", "policy-instance-name Resource Definition") {
+                tags("policy-instance-name")
+                updatedBy("sp694w@att.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("vnf-name", "vnf-name Resource Definition") {
+                tags("vnf-name")
+                updatedBy("sp694w@att.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("vf-module-label", "vf-module-label Resource Definition") {
+                tags("vf-module-label")
+                updatedBy("sp694w@att.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("vf-module-type", "vf-module-type Resource Definition") {
+                tags("vf-module-type")
+                updatedBy("sp694w@att.com")
+                property("string", true)
+                sources {
+                    sourceInput("input", "") {}
+                }
+            }
+            resourceDefinition("vf-module-name", "vf-module-name Resource Definition") {
+                tags("vf-module-name")
+                updatedBy("brindasanth@onap.com")
+                property("string", true) {
+                    metadata("naming-type", "VF-MODULE")
+                }
+                sources {
+                    sourceCapability("naming-ms", "") {
+                        definedProperties {
+                            type("internal")
+                            scriptClassReference(NamingResolutionCapability::class)
+                            keyDependencies(
+                                arrayListOf(
+                                    "policy-instance-name",
+                                    "naming-code",
+                                    "vnf-name",
+                                    "vf-module-label",
+                                    "vf-module-type"
+                                )
+                            )
+                        }
+                    }
+                }
+            }
+            resourceDefinition("vnfc-name", "vnfc-name Resource Definition") {
+                tags("vnfc-name")
+                updatedBy("brindasanth@onap.com")
+                property("string", true) {
+                    metadata("naming-type", "VNFC")
+                }
+
+                sources {
+                    sourceCapability("naming-ms", "") {
+                        definedProperties {
+                            type("internal")
+                            scriptClassReference(NamingResolutionCapability::class)
+                            keyDependencies(
+                                arrayListOf("vf-module-name")
+                            )
+                        }
+                    }
+                }
+            }
+            resourceDefinition("ra-dict-name-3", "ra-dict-name-3 Resource Definition") {
+                tags("ra-dict-name-3")
+                updatedBy("brindasanth@onap.com")
+                property("string", true)
+                sources {
+                    sourceCapability("naming-ms", "") {
+                        definedProperties {
+                            type("internal")
+                            scriptClassReference(NamingResolutionCapability::class)
+                            keyDependencies(
+                                arrayListOf("vf-module-name")
+                            )
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private fun resourceAssignments(): MutableMap<String, ResourceAssignment> {
+        return BluePrintTypes.resourceAssignments {
+            resourceAssignment(
+                name = "naming-code", dictionaryName = "naming-code",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "naming-type", dictionaryName = "naming-type",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "cloud-region-id", dictionaryName = " cloud-region-id",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "policy-instance-name", dictionaryName = " policy-instance-name",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "vnf-name", dictionaryName = " vnf-name",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "vf-module-label", dictionaryName = " vf-module-label",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "vf-module-type", dictionaryName = " vf-module-type",
+                dictionarySource = "input"
+            ) {
+                property("string", true, "")
+                dependencies(arrayListOf())
+            }
+            resourceAssignment(
+                name = "vf-module-name", dictionaryName = "vf-module-name",
+                dictionarySource = "naming-ms"
+            ) {
+                property("string", true, "")
+                dependencies(
+                    arrayListOf(
+                        "policy-instance-name",
+                        "naming-code",
+                        "vnf-name",
+                        "vf-module-label",
+                        "vf-module-type"
+                    )
+                )
+            }
+            resourceAssignment(
+                name = "vnfc-name", dictionaryName = "vnfc-name",
+                dictionarySource = "naming-ms"
+            ) {
+                property("string", true, "")
+                dependencies(
+                    arrayListOf(
+                        "vf-module-name"
+                    )
+                )
+            }
+        }
+    }
+}
index 9a55231..422f651 100644 (file)
@@ -17,6 +17,7 @@
 package org.onap.ccsdk.cds.controllerblueprints.resource.dict.utils
 
 import org.apache.commons.collections.CollectionUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.asListOfString
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.TopologicalSortingUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
@@ -51,20 +52,25 @@ object BulkResourceSequencingUtils {
         resourceAssignmentMap.forEach { _, resourceAssignment ->
             // Get the dependencies from the assignment sources, if not get from the Resource Assignment dependencies
             if (resourceAssignment.dictionarySourceDefinition != null) {
-                val dependencies = resourceAssignment.dictionarySourceDefinition?.properties?.get("key-dependencies")?.asListOfString()
+                val dependencies =
+                    resourceAssignment.dictionarySourceDefinition?.properties?.get("key-dependencies")?.asListOfString()
                 dependencies?.forEach { dependency ->
                     topologySorting.add(resourceAssignmentMap[dependency]!!, resourceAssignment)
                 }
             } else if (CollectionUtils.isNotEmpty(resourceAssignment.dependencies)) {
                 for (dependency in resourceAssignment.dependencies!!) {
-                    topologySorting.add(resourceAssignmentMap[dependency]!!, resourceAssignment)
+                    val ra = resourceAssignmentMap[dependency]
+                        ?: throw BluePrintProcessorException("Couldn't get Resource Assignment dependency " +
+                            "Key($dependency)")
+                    topologySorting.add(ra, resourceAssignment)
                 }
             } else {
                 topologySorting.add(startResourceAssignment, resourceAssignment)
             }
         }
 
-        val sequencedResourceAssignments: MutableList<ResourceAssignment> = topologySorting.topSort()!! as MutableList<ResourceAssignment>
+        val sequencedResourceAssignments: MutableList<ResourceAssignment> =
+            topologySorting.topSort()!! as MutableList<ResourceAssignment>
         log.trace("Sorted Sequenced Assignments ({})", sequencedResourceAssignments)
 
         var batchResourceAssignment: MutableList<ResourceAssignment>? = null
index fa357e1..3260314 100644 (file)
@@ -77,7 +77,7 @@ import kotlin.test.assertNotNull
         "server.ssl.keyStoreType=PKCS12",
         "server.ssl.keyAlias=tomcat",
         "blueprintsprocessor.restclient.sample.type=basic-auth",
-        "blueprintsprocessor.restclient.sample.url=http://127.0.0.1:8081",
+        "blueprintsprocessor.restclient.sample.url=http://127.0.0.1:9081",
         "blueprintsprocessor.restclient.sample.username=admin",
         "blueprintsprocessor.restclient.sample.password=jans",
         "blueprintsprocessor.restclient.test.type=ssl-basic-auth",
@@ -104,7 +104,7 @@ class RestClientServiceTest {
     @Before
     fun start() {
         // Second Http server required for non-SSL requests to be processed along with the https server.
-        val factory: ReactiveWebServerFactory = NettyReactiveWebServerFactory(8081)
+        val factory: ReactiveWebServerFactory = NettyReactiveWebServerFactory(9081)
         this.http = factory.getWebServer(this.httpHandler)
         this.http.start()
     }
@@ -144,7 +144,7 @@ class RestClientServiceTest {
     fun testSimpleBasicAuth() {
         val json: String = "{\n" +
                 "  \"type\" : \"basic-auth\",\n" +
-                "  \"url\" : \"http://localhost:8081\",\n" +
+                "  \"url\" : \"http://localhost:9081\",\n" +
                 "  \"username\" : \"admin\",\n" +
                 "  \"password\" : \"jans\"\n" +
                 "}"