e9bb2ffe42e40ee5bb85114ba731cc04f9eda539
[ccsdk/cds.git] /
1 /*
2  *  Copyright © 2018 IBM.
3  *  Modifications Copyright © 2017-2018 AT&T Intellectual Property.
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.processor
19
20 import com.fasterxml.jackson.databind.JsonNode
21 import org.apache.commons.collections.MapUtils
22 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
23 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
24 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
25 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
26 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
27 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode
28 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
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 abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssignment, Boolean> {
36
37     private val log = LoggerFactory.getLogger(ResourceAssignmentProcessor::class.java)
38
39     lateinit var raRuntimeService: ResourceAssignmentRuntimeService
40     lateinit var resourceDictionaries: MutableMap<String, ResourceDefinition>
41
42     var scriptPropertyInstances: MutableMap<String, Any> = hashMapOf()
43     lateinit var scriptType: String
44
45     /**
46      * This will be called from the scripts to serve instance from runtime to scripts.
47      */
48     open fun <T> scriptPropertyInstanceType(name: String): T {
49         return scriptPropertyInstances as? T
50                 ?: throw BluePrintProcessorException("couldn't get script property instance ($name)")
51     }
52
53     open fun getFromInput(resourceAssignment: ResourceAssignment): JsonNode? {
54         var value: JsonNode? = null
55         try {
56             value = raRuntimeService.getInputValue(resourceAssignment.name)
57             ResourceAssignmentUtils.setResourceDataValue(resourceAssignment, raRuntimeService, value)
58         } catch (e: BluePrintProcessorException) {
59             // NoOp - couldn't find value from input
60         }
61         return value
62     }
63
64     open fun resourceDefinition(name: String): ResourceDefinition {
65         return resourceDictionaries[name]
66                 ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)")
67     }
68
69     open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> {
70         val resolvedInputKeyMapping = HashMap<String, Any>()
71         if (MapUtils.isNotEmpty(inputKeyMapping)) {
72             for ((key, value) in inputKeyMapping) {
73                 val resultValue = raRuntimeService.getResolutionStore(value)
74                 val expressionValue = JacksonUtils.getValue(resultValue)
75                 log.trace("Reference dictionary key ({}), value ({})", key, expressionValue)
76                 resolvedInputKeyMapping[key] = expressionValue
77             }
78         }
79         return resolvedInputKeyMapping
80     }
81
82     open fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: Map<String, Any>): String {
83         if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) {
84             return valueToResolve
85         }
86         return BluePrintTemplateService.generateContent(valueToResolve, additionalContext = keyMapping)
87     }
88
89     final override suspend fun applyNB(resourceAssignment: ResourceAssignment): Boolean {
90         try {
91             processNB(resourceAssignment)
92         } catch (runtimeException: RuntimeException) {
93             log.error("failed in ${getName()} : ${runtimeException.message}", runtimeException)
94             recoverNB(runtimeException, resourceAssignment)
95         }
96         return true
97     }
98
99     suspend fun executeScript(resourceAssignment: ResourceAssignment) {
100         return when (scriptType) {
101             BluePrintConstants.SCRIPT_JYTHON -> {
102                 executeScriptBlocking(resourceAssignment)
103             }
104             else -> {
105                 executeScriptNB(resourceAssignment)
106             }
107         }
108     }
109
110     private suspend fun executeScriptNB(resourceAssignment: ResourceAssignment) {
111         try {
112             processNB(resourceAssignment)
113         } catch (runtimeException: RuntimeException) {
114             log.error("failed in ${getName()} : ${runtimeException.message}", runtimeException)
115             recoverNB(runtimeException, resourceAssignment)
116         }
117     }
118
119     private fun executeScriptBlocking(resourceAssignment: ResourceAssignment) {
120         try {
121             process(resourceAssignment)
122         } catch (runtimeException: RuntimeException) {
123             log.error("failed in ${getName()} : ${runtimeException.message}", runtimeException)
124             recover(runtimeException, resourceAssignment)
125         }
126     }
127
128     /**
129      * If Jython Script, Override Blocking methods(process() and recover())
130      * If Kotlin or Internal Scripts, Override non blocking methods ( processNB() and recoverNB()), so default
131      * blocking
132      * methods will have default implementation,
133      *
134      * Always applyNB() method will be invoked, apply() won't be called from parent
135      */
136
137     final override fun apply(resourceAssignment: ResourceAssignment): Boolean {
138         throw BluePrintException("Not Implemented, use applyNB method")
139     }
140
141     final override fun prepareRequest(resourceAssignment: ResourceAssignment): ResourceAssignment {
142         throw BluePrintException("Not Implemented required")
143     }
144
145     final override fun prepareResponse(): Boolean {
146         throw BluePrintException("Not Implemented required")
147     }
148
149     final override suspend fun prepareRequestNB(resourceAssignment: ResourceAssignment): ResourceAssignment {
150         throw BluePrintException("Not Implemented required")
151     }
152
153     final override suspend fun prepareResponseNB(): Boolean {
154         throw BluePrintException("Not Implemented required")
155     }
156
157     override fun process(resourceAssignment: ResourceAssignment) {
158         throw BluePrintException("Not Implemented, child class will implement this")
159     }
160
161     override fun recover(runtimeException: RuntimeException, resourceAssignment: ResourceAssignment) {
162         throw BluePrintException("Not Implemented, child class will implement this")
163     }
164
165     fun addError(type: String, name: String, error: String) {
166         raRuntimeService.getBluePrintError().addError(type, name, error)
167     }
168
169     fun addError(error: String) {
170         raRuntimeService.getBluePrintError().addError(error)
171     }
172 }