86440e6912cf01e8a19e3f89841bb8d8505ea007
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2019 IBM.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils
19
20 import com.fasterxml.jackson.databind.JsonNode
21 import com.fasterxml.jackson.databind.ObjectMapper
22 import com.fasterxml.jackson.databind.node.NullNode
23 import com.fasterxml.jackson.databind.node.ObjectNode
24 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
25 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
26 import org.onap.ccsdk.cds.controllerblueprints.core.*
27 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
28 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonReactorUtils
29 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
30 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
31 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
32 import org.slf4j.LoggerFactory
33 import java.util.*
34
35 class ResourceAssignmentUtils {
36     companion object {
37
38         private val logger = LoggerFactory.getLogger(ResourceAssignmentUtils::class.toString())
39
40         suspend fun resourceDefinitions(blueprintBasePath: String): MutableMap<String, ResourceDefinition> {
41             val dictionaryFile = normalizedFile(blueprintBasePath, BluePrintConstants.TOSCA_DEFINITIONS_DIR,
42                     ResourceResolutionConstants.FILE_NAME_RESOURCE_DEFINITION_TYPES)
43             checkFileExists(dictionaryFile) { "resource definition file(${dictionaryFile.absolutePath}) is missing" }
44             return JacksonReactorUtils.getMapFromFile(dictionaryFile, ResourceDefinition::class.java)
45         }
46
47         // TODO("Modify Value type from Any to JsonNode")
48         @Throws(BluePrintProcessorException::class)
49         fun setResourceDataValue(resourceAssignment: ResourceAssignment,
50                                  raRuntimeService: ResourceAssignmentRuntimeService, value: Any?) {
51
52             val resourceProp = checkNotNull(resourceAssignment.property) { "Failed in setting resource value for resource mapping $resourceAssignment" }
53             checkNotEmpty(resourceAssignment.name) {
54                 "Failed in setting resource value for resource mapping $resourceAssignment"
55             }
56
57             if (resourceAssignment.dictionaryName.isNullOrEmpty()) {
58                 resourceAssignment.dictionaryName = resourceAssignment.name
59                 logger.warn("Missing dictionary key, setting with template key (${resourceAssignment.name}) as dictionary key (${resourceAssignment.dictionaryName})")
60             }
61
62             try {
63                 if (resourceProp.type.isNotEmpty()) {
64                     val convertedValue = convertResourceValue(resourceProp.type, value)
65                     logger.info("Setting Resource Value ($convertedValue) for Resource Name (${resourceAssignment.dictionaryName}) of type (${resourceProp.type})")
66                     setResourceValue(resourceAssignment, raRuntimeService, convertedValue)
67                     resourceAssignment.updatedDate = Date()
68                     resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
69                     resourceAssignment.status = BluePrintConstants.STATUS_SUCCESS
70                 }
71             } catch (e: Exception) {
72                 throw BluePrintProcessorException("Failed in setting value for template key (${resourceAssignment.name}) and " +
73                         "dictionary key (${resourceAssignment.dictionaryName}) of type (${resourceProp.type}) with error message (${e.message})", e)
74             }
75         }
76
77         private fun setResourceValue(resourceAssignment: ResourceAssignment, raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode) {
78             raRuntimeService.putResolutionStore(resourceAssignment.name, value)
79             raRuntimeService.putDictionaryStore(resourceAssignment.dictionaryName!!, value)
80             resourceAssignment.property!!.value = value
81         }
82
83         private fun convertResourceValue(type: String, value: Any?): JsonNode {
84
85             return if (value == null || value is NullNode) {
86                 logger.info("Returning {} value from convertResourceValue", value)
87                 NullNode.instance
88             } else if (BluePrintTypes.validPrimitiveTypes().contains(type) && value is String) {
89                 JacksonUtils.convertPrimitiveResourceValue(type, value)
90             } else if (value is String) {
91                 JacksonUtils.jsonNode(value)
92             } else {
93                 JacksonUtils.getJsonNode(value)
94             }
95
96         }
97
98         fun setFailedResourceDataValue(resourceAssignment: ResourceAssignment, message: String?) {
99             if (isNotEmpty(resourceAssignment.name)) {
100                 resourceAssignment.updatedDate = Date()
101                 resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
102                 resourceAssignment.status = BluePrintConstants.STATUS_FAILURE
103                 resourceAssignment.message = message
104             }
105         }
106
107         @Throws(BluePrintProcessorException::class)
108         fun assertTemplateKeyValueNotNull(resourceAssignment: ResourceAssignment) {
109             val resourceProp = checkNotNull(resourceAssignment.property) { "Failed to populate mandatory resource resource mapping $resourceAssignment" }
110             if (resourceProp.required != null && resourceProp.required!! && (resourceProp.value == null || resourceProp.value !is NullNode)) {
111                 logger.error("failed to populate mandatory resource mapping ($resourceAssignment)")
112                 throw BluePrintProcessorException("failed to populate mandatory resource mapping ($resourceAssignment)")
113             }
114         }
115
116         @Throws(BluePrintProcessorException::class)
117         fun generateResourceDataForAssignments(assignments: List<ResourceAssignment>): String {
118             val result: String
119             try {
120                 val mapper = ObjectMapper()
121                 val root: ObjectNode = mapper.createObjectNode()
122
123                 assignments.forEach {
124                     if (isNotEmpty(it.name) && it.property != null) {
125                         val rName = it.name
126                         val type = nullToEmpty(it.property?.type).toLowerCase()
127                         val value = it.property?.value
128                         logger.info("Generating Resource name ($rName), type ($type), value ($value)")
129                         root.set(rName, value)
130                     }
131                 }
132                 result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root)
133                 logger.info("Generated Resource Param Data ($result)")
134             } catch (e: Exception) {
135                 throw BluePrintProcessorException("Resource Assignment is failed with $e.message", e)
136             }
137
138             return result
139         }
140
141         fun transformToRARuntimeService(blueprintRuntimeService: BluePrintRuntimeService<*>, templateArtifactName: String): ResourceAssignmentRuntimeService {
142             val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService(blueprintRuntimeService.id(), blueprintRuntimeService.bluePrintContext())
143             resourceAssignmentRuntimeService.createUniqueId(templateArtifactName)
144             resourceAssignmentRuntimeService.setExecutionContext(blueprintRuntimeService.getExecutionContext() as MutableMap<String, JsonNode>)
145
146             return resourceAssignmentRuntimeService
147         }
148
149         @Throws(BluePrintProcessorException::class)
150         fun getPropertyType(raRuntimeService: ResourceAssignmentRuntimeService, dataTypeName: String, propertyName: String): String {
151             lateinit var type: String
152             try {
153                 val dataTypeProps = checkNotNull(raRuntimeService.bluePrintContext().dataTypeByName(dataTypeName)?.properties)
154                 val propertyDefinition = checkNotNull(dataTypeProps[propertyName])
155                 type = checkNotEmpty(propertyDefinition.type) { "Couldn't get data type ($dataTypeName)" }
156                 logger.trace("Data type({})'s property ({}) is ({})", dataTypeName, propertyName, type)
157             } catch (e: Exception) {
158                 logger.error("couldn't get data type($dataTypeName)'s property ($propertyName), error message $e")
159                 throw BluePrintProcessorException("${e.message}", e)
160             }
161             return type
162         }
163     }
164 }