Migrate ccsdk/apps to ccsdk/cds
[ccsdk/cds.git] / ms / blueprintsprocessor / functions / resource-resolution / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / functions / resource / resolution / utils / ResourceAssignmentUtils.kt
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.att.eelf.configuration.EELFLogger
21 import com.att.eelf.configuration.EELFManager
22 import com.fasterxml.jackson.databind.JsonNode
23 import com.fasterxml.jackson.databind.ObjectMapper
24 import com.fasterxml.jackson.databind.node.NullNode
25 import com.fasterxml.jackson.databind.node.ObjectNode
26 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
27 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
28 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
29 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
30 import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty
31 import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmptyOrThrow
32 import org.onap.ccsdk.cds.controllerblueprints.core.nullToEmpty
33 import org.onap.ccsdk.cds.controllerblueprints.core.returnNotEmptyOrThrow
34 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
35 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
36 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
37 import java.util.*
38
39 class ResourceAssignmentUtils {
40     companion object {
41
42         private val logger: EELFLogger = EELFManager.getInstance().getLogger(ResourceAssignmentUtils::class.toString())
43
44         // TODO("Modify Value type from Any to JsonNode")
45         @Throws(BluePrintProcessorException::class)
46         fun setResourceDataValue(resourceAssignment: ResourceAssignment,
47                                  raRuntimeService: ResourceAssignmentRuntimeService, value: Any?) {
48
49             val resourceProp = checkNotNull(resourceAssignment.property) { "Failed in setting resource value for resource mapping $resourceAssignment" }
50             checkNotEmptyOrThrow(resourceAssignment.name, "Failed in setting resource value for resource mapping $resourceAssignment")
51
52             if (resourceAssignment.dictionaryName.isNullOrEmpty()) {
53                 resourceAssignment.dictionaryName = resourceAssignment.name
54                 logger.warn("Missing dictionary key, setting with template key (${resourceAssignment.name}) as dictionary key (${resourceAssignment.dictionaryName})")
55             }
56
57             try {
58                 if (resourceProp.type.isNotEmpty()) {
59                     val convertedValue = convertResourceValue(resourceProp.type, value)
60                     logger.info("Setting Resource Value ($convertedValue) for Resource Name (${resourceAssignment.dictionaryName}) of type (${resourceProp.type})")
61                     setResourceValue(resourceAssignment, raRuntimeService, convertedValue)
62                     resourceAssignment.updatedDate = Date()
63                     resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
64                     resourceAssignment.status = BluePrintConstants.STATUS_SUCCESS
65                 }
66             } catch (e: Exception) {
67                 throw BluePrintProcessorException("Failed in setting value for template key (${resourceAssignment.name}) and " +
68                         "dictionary key (${resourceAssignment.dictionaryName}) of type (${resourceProp.type}) with error message (${e.message})", e)
69             }
70         }
71
72         private fun setResourceValue(resourceAssignment: ResourceAssignment, raRuntimeService: ResourceAssignmentRuntimeService, value: JsonNode) {
73             raRuntimeService.putResolutionStore(resourceAssignment.name, value)
74             raRuntimeService.putDictionaryStore(resourceAssignment.dictionaryName!!, value)
75             resourceAssignment.property!!.value = value
76         }
77
78         private fun convertResourceValue(type: String, value: Any?): JsonNode {
79
80             return if (value == null || value is NullNode) {
81                 logger.info("Returning {} value from convertResourceValue", value)
82                 NullNode.instance
83             } else if (BluePrintTypes.validPrimitiveTypes().contains(type) && value is String) {
84                 JacksonUtils.convertPrimitiveResourceValue(type, value)
85             } else if (value is String) {
86                 JacksonUtils.jsonNode(value)
87             } else {
88                 JacksonUtils.getJsonNode(value)
89             }
90
91         }
92
93         fun setFailedResourceDataValue(resourceAssignment: ResourceAssignment, message: String?) {
94             if (checkNotEmpty(resourceAssignment.name)) {
95                 resourceAssignment.updatedDate = Date()
96                 resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
97                 resourceAssignment.status = BluePrintConstants.STATUS_FAILURE
98                 resourceAssignment.message = message
99             }
100         }
101
102         @Throws(BluePrintProcessorException::class)
103         fun assertTemplateKeyValueNotNull(resourceAssignment: ResourceAssignment) {
104             val resourceProp = checkNotNull(resourceAssignment.property) { "Failed to populate mandatory resource resource mapping $resourceAssignment" }
105             if (resourceProp.required != null && resourceProp.required!! && (resourceProp.value == null || resourceProp.value !is NullNode)) {
106                 logger.error("failed to populate mandatory resource mapping ($resourceAssignment)")
107                 throw BluePrintProcessorException("failed to populate mandatory resource mapping ($resourceAssignment)")
108             }
109         }
110
111         @Throws(BluePrintProcessorException::class)
112         fun generateResourceDataForAssignments(assignments: List<ResourceAssignment>): String {
113             val result: String
114             try {
115                 val mapper = ObjectMapper()
116                 val root: ObjectNode = mapper.createObjectNode()
117
118                 assignments.forEach {
119                     if (checkNotEmpty(it.name) && it.property != null) {
120                         val rName = it.name
121                         val type = nullToEmpty(it.property?.type).toLowerCase()
122                         val value = it.property?.value
123                         logger.info("Generating Resource name ($rName), type ($type), value ($value)")
124                         root.set(rName, value)
125                     }
126                 }
127                 result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root)
128                 logger.info("Generated Resource Param Data ($result)")
129             } catch (e: Exception) {
130                 throw BluePrintProcessorException("Resource Assignment is failed with $e.message", e)
131             }
132
133             return result
134         }
135
136         fun transformToRARuntimeService(blueprintRuntimeService: BluePrintRuntimeService<*>, templateArtifactName: String): ResourceAssignmentRuntimeService {
137             val resourceAssignmentRuntimeService = ResourceAssignmentRuntimeService(blueprintRuntimeService.id(), blueprintRuntimeService.bluePrintContext())
138             resourceAssignmentRuntimeService.createUniqueId(templateArtifactName)
139             resourceAssignmentRuntimeService.setExecutionContext(blueprintRuntimeService.getExecutionContext() as MutableMap<String, JsonNode>)
140
141             return resourceAssignmentRuntimeService
142         }
143
144         @Throws(BluePrintProcessorException::class)
145         fun getPropertyType(raRuntimeService: ResourceAssignmentRuntimeService, dataTypeName: String, propertyName: String): String {
146             lateinit var type: String
147             try {
148                 val dataTypeProps = checkNotNull(raRuntimeService.bluePrintContext().dataTypeByName(dataTypeName)?.properties)
149                 val propertyDefinition = checkNotNull(dataTypeProps[propertyName])
150                 type = returnNotEmptyOrThrow(propertyDefinition.type) { "Couldn't get data type ($dataTypeName)" }
151                 logger.trace("Data type({})'s property ({}) is ({})", dataTypeName, propertyName, type)
152             } catch (e: Exception) {
153                 logger.error("couldn't get data type($dataTypeName)'s property ($propertyName), error message $e")
154                 throw BluePrintProcessorException("${e.message}", e)
155             }
156             return type
157         }
158     }
159 }