2 * Copyright © 2019 AT&T.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.capabilities
19 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
20 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.processor.ResourceAssignmentProcessor
21 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
22 import org.onap.ccsdk.cds.blueprintsprocessor.rest.restClientService
23 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
24 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
25 import org.onap.ccsdk.cds.controllerblueprints.core.logger
26 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
27 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
28 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.KeyIdentifier
29 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
30 import org.springframework.http.HttpMethod
33 * @author saurav.paira
36 open class IpAssignResolutionCapability : ResourceAssignmentProcessor() {
38 val log = logger(IpAssignResolutionCapability::class)
40 override fun getName(): String {
41 return "${ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR}ipassignment-capability"
44 override suspend fun processNB(resourceAssignment: ResourceAssignment) {
46 if (!setFromInput(resourceAssignment) && isTemplateKeyValueNull(resourceAssignment)) {
47 val dName = resourceAssignment.dictionaryName!!
48 val dSource = resourceAssignment.dictionarySource!!
49 val resourceDefinition = resourceDefinition(dName)
51 /** Check Resource Assignment has the source definitions, If not get from Resource Definitions **/
52 val resourceSource = resourceAssignment.dictionarySourceDefinition
53 ?: resourceDefinition?.sources?.get(dSource)
54 ?: throw BluePrintProcessorException("couldn't get resource definition $dName source($dSource)")
56 val resourceSourceProperties =
57 checkNotNull(resourceSource.properties) { "failed to get source properties for $dName " }
59 // Get all matching resources assignments to process
60 val groupResourceAssignments =
61 resourceAssignments.filter {
62 it.dictionarySource == dSource
65 // inputKeyMapping is dynamic based on dependencies
66 val inputKeyMapping: MutableMap<String, String> =
67 resourceAssignment.dependencies?.map { it to it }?.toMap()
68 as MutableMap<String, String>
70 // Get the values from runtime store
71 val resolvedInputKeyMapping = resolveInputKeyMappingVariables(
73 resourceAssignment.templatingConstants
75 log.info("\nResolved Input Key mappings: \n$resolvedInputKeyMapping")
77 resolvedInputKeyMapping.map { KeyIdentifier(it.key, it.value) }.let {
78 resourceAssignment.keyIdentifiers.addAll(it)
81 // Generate the payload using already resolved value
82 val generatedPayload = generatePayload(resolvedInputKeyMapping, groupResourceAssignments)
83 log.info("\nIP Assign mS Request Payload: \n{}", generatedPayload.asJsonType().toPrettyString())
85 resourceSourceProperties["resolved-payload"] = JacksonUtils.jsonNode(generatedPayload)
87 // Get the Rest Client service, selector will be included in application.properties
88 val restClientService = BluePrintDependencyService.restClientService(
92 // Get the Rest Response
93 val response = restClientService.exchangeResource(
95 "/web/service/v1/assign", generatedPayload
97 val responseStatusCode = response.status
98 val responseBody = response.body
99 log.info("\nIP Assign mS Response : \n{}", responseBody.asJsonType().toPrettyString())
100 if (responseStatusCode in 200..299 && !responseBody.isBlank()) {
101 populateResource(groupResourceAssignments, responseBody)
104 "Failed to dictionary name ($dName), dictionary source($($dName) " +
105 "response_code: ($responseStatusCode)"
107 throw BluePrintProcessorException(errMsg)
109 // Parse the error Body and assign the property value
111 // Check the value has populated for mandatory case
112 ResourceAssignmentUtils.assertTemplateKeyValueNotNull(resourceAssignment)
113 } catch (e: Exception) {
114 ResourceAssignmentUtils.setFailedResourceDataValue(resourceAssignment, e.message)
115 throw BluePrintProcessorException(
116 "Failed in template key ($resourceAssignment) assignments with: ${e.message}",
122 override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
123 addError(runtimeException.message!!)
126 /** Generates aggregated request payload for Ip Assign mS. Parses the resourceassignments of
127 * sourceCapability "ipassign-ms". It generates below sample payload
130 "name": "fixed_ipv4_Address_01",
132 "CloudRegionId": "abcd123",
133 "IpServiceName": "MobilityPlan",
136 "name": "fixed_ipv4_Address_02",
138 "CloudRegionId": "abcd123",
139 "IpServiceName": "MobilityPlan",
144 private fun generatePayload(
145 input: Map<String, Any>,
146 groupResourceAssignments: MutableList<ResourceAssignment>
148 data class IpRequest(val name: String = "", val property: Map<String, String> = mutableMapOf<String, String>())
149 data class IpAssignRequest(val requests: MutableList<IpRequest> = mutableListOf())
151 val ipAssignRequests = IpAssignRequest()
152 groupResourceAssignments.forEach {
153 val ipRequest = IpRequest(it.name, input.mapValues { it.value.toString().removeSurrounding("\"") })
154 ipAssignRequests.requests.add(ipRequest)
156 return ipAssignRequests.asJsonType().toString()
159 private fun populateResource(
160 resourceAssignments: MutableList<ResourceAssignment>,
163 /** Parse all the resource assignment fields and set the corresponding value */
164 resourceAssignments.forEach { resourceAssignment ->
165 // Set the List of Complex Values
166 val parsedResourceAssignmentValue = checkNotNull(
167 JacksonUtils.jsonNode(restResponse).path(resourceAssignment.name).textValue()
169 "Failed to find path ($resourceAssignment.name) in response ($restResponse)"
172 ResourceAssignmentUtils.setResourceDataValue(
175 parsedResourceAssignmentValue