From a726d7aa14e0ae841ede2dbdbc1a825290bf1452 Mon Sep 17 00:00:00 2001 From: "Paira, Saurav(sp694w)" Date: Thu, 7 May 2020 12:54:40 +0000 Subject: Add Naming Service & IP Assign custom resource resolution capability Issue-ID: CCSDK-2185 Signed-off-by: Paira, Saurav(sp694w) Change-Id: I70550fe9582b2db0a70c7b66591438b674173411 --- .../src/main/resources/application.properties | 12 + .../resolution/ResourceResolutionService.kt | 40 ++- .../capabilities/IpAssignResolutionCapability.kt | 175 ++++++++++ .../capabilities/NamingResolutionCapability.kt | 197 ++++++++++++ .../CapabilityResourceResolutionProcessor.kt | 9 +- .../processor/ResourceAssignmentProcessor.kt | 15 +- .../IpAssignResolutionCapabilityTest.kt | 284 +++++++++++++++++ .../capabilities/NamingResolutionCapabilityTest.kt | 354 +++++++++++++++++++++ .../dict/utils/BulkResourceSequencingUtils.kt | 12 +- .../rest/service/RestClientServiceTest.kt | 6 +- 10 files changed, 1076 insertions(+), 28 deletions(-) create mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapability.kt create mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapability.kt create mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapabilityTest.kt create mode 100644 ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapabilityTest.kt diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties index 6fb737edc..429011aff 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties @@ -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 diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt index dff00c7eb..15fd1d673 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt @@ -78,7 +78,7 @@ interface ResourceResolutionService { resolveDefinition: String, sources: List ): - MutableMap + MutableMap suspend fun resolveResourceAssignments( blueprintRuntimeService: BluePrintRuntimeService<*>, @@ -159,7 +159,7 @@ open class ResourceResolutionServiceImpl( val resourceAssignments: MutableList = JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment::class.java) - as? MutableList + as? MutableList ?: 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): 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 index 000000000..b38c32056 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/IpAssignResolutionCapability.kt @@ -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 = + resourceAssignment.dependencies?.map { it to it }?.toMap() + as MutableMap + + // 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, + groupResourceAssignments: MutableList + ): String { + data class IpRequest(val name: String = "", val property: Map = mutableMapOf()) + data class IpAssignRequest(val requests: MutableList = 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, + 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 index 000000000..dbac70a39 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapability.kt @@ -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 = + resourceAssignment.dependencies?.map { it to it }?.toMap() + as MutableMap + 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, + groupResourceAssignments: MutableList + ): String { + data class NameAssignRequest(val elements: MutableList> = 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 = input.mapValues { + it.value.toString().removeSurrounding("\"") } as MutableMap + if (namingType != null) { + request["naming-type"] = namingType + } + request[moduleName] = moduleValue + nameAssignRequests.elements.add(request) + } + return nameAssignRequests.asJsonType().toString() + } + + private fun populateResource( + resourceAssignments: MutableList, + 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 + ) + } + } +} diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt index 868f919c1..42e086137 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/CapabilityResourceResolutionProcessor.kt @@ -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): - 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( diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt index 454a899aa..0c0735ff0 100644 --- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt @@ -40,6 +40,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode = hashMapOf() + var resourceAssignments: MutableList = arrayListOf() var scriptPropertyInstances: MutableMap = hashMapOf() lateinit var scriptType: String @@ -104,7 +105,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode): - String { + String { if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) { return valueToResolve } @@ -196,4 +197,16 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode() + // 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() + every { restLibPropertyService.blueprintWebClientService("ipassign-ms") } returns blueprintWebClientService + every { BluePrintDependencyService.applicationContext.getBean(any()) } returns restLibPropertyService + } + + @Test + fun testIpAssignResolutionCapability() { + runBlocking { + val componentFunctionScriptingService = mockk() + coEvery { + componentFunctionScriptingService + .scriptInstance(any(), any(), any()) + } returns IpAssignResolutionCapability() + + coEvery { + componentFunctionScriptingService.cleanupInstance(any(), any()) + } returns mockk() + + val raRuntimeService = mockk() + 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 { + 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 { + 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 index 000000000..ee53f8a04 --- /dev/null +++ b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/capabilities/NamingResolutionCapabilityTest.kt @@ -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() + // Create mock Response + val mockResponse = BlueprintWebClientService.WebClientResponse( + 200, """{ + "vf-module-name" : "dlsst001dbcx-adsf-Base-01", + "vnfc-name" : "dlsst001dbcx" + } + """.trimMargin() + ) + every { blueprintWebClientService.exchangeResource(any(), any(), any()) } returns mockResponse + + val restLibPropertyService = mockk() + every { restLibPropertyService.blueprintWebClientService("naming-ms") } returns blueprintWebClientService + every { BluePrintDependencyService.applicationContext.getBean(any()) } returns restLibPropertyService + } + + @Test + fun testNamingResolutionCapability() { + runBlocking { + val componentFunctionScriptingService = mockk() + coEvery { + componentFunctionScriptingService + .scriptInstance(any(), any(), any()) + } returns NamingResolutionCapability() + + coEvery { + componentFunctionScriptingService.cleanupInstance(any(), any()) + } returns mockk() + + val raRuntimeService = mockk() + every { raRuntimeService.bluePrintContext() } returns mockk() + 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 { + 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 { + 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" + ) + ) + } + } + } +} diff --git a/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt b/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt index 9a5523113..422f65157 100644 --- a/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt +++ b/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/utils/BulkResourceSequencingUtils.kt @@ -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 = topologySorting.topSort()!! as MutableList + val sequencedResourceAssignments: MutableList = + topologySorting.topSort()!! as MutableList log.trace("Sorted Sequenced Assignments ({})", sequencedResourceAssignments) var batchResourceAssignment: MutableList? = null diff --git a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestClientServiceTest.kt b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestClientServiceTest.kt index fa357e1fe..326031487 100644 --- a/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestClientServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/rest-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/rest/service/RestClientServiceTest.kt @@ -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" + "}" -- cgit 1.2.3-korg