2 * Copyright © 2019 IBM.
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.services.execution
19 import com.fasterxml.jackson.databind.JsonNode
20 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
21 import org.onap.ccsdk.cds.controllerblueprints.core.*
22 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
23 import org.onap.ccsdk.cds.controllerblueprints.core.data.Implementation
24 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
25 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
26 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.ArtifactDefinitionBuilder
27 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeTemplate
28 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.nodeType
29 import org.springframework.beans.factory.config.ConfigurableBeanFactory
30 import org.springframework.context.annotation.Scope
31 import org.springframework.stereotype.Component
34 * This is generic Script Component Executor function
35 * @author Brinda Santh
37 @Component("component-script-executor")
38 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
39 open class ComponentScriptExecutor(private var componentFunctionScriptingService: ComponentFunctionScriptingService)
40 : AbstractComponentFunction() {
43 const val SCRIPT_TYPE = "script-type"
44 const val SCRIPT_CLASS_REFERENCE = "script-class-reference"
45 const val DYNAMIC_PROPERTIES = "dynamic-properties"
46 const val RESPONSE_DATA = "response-data"
47 const val STATUS = "status"
50 lateinit var scriptComponentFunction: AbstractScriptComponentFunction
52 override suspend fun processNB(executionRequest: ExecutionServiceInput) {
54 val scriptType = operationInputs.getAsString(SCRIPT_TYPE)
55 val scriptClassReference = operationInputs.getAsString(SCRIPT_CLASS_REFERENCE)
57 val scriptDependencies: MutableList<String> = arrayListOf()
58 populateScriptDependencies(scriptDependencies)
60 scriptComponentFunction = componentFunctionScriptingService.scriptInstance(this, scriptType,
61 scriptClassReference, scriptDependencies)
63 // Handles both script processing and error handling
64 scriptComponentFunction.executeScript(executionServiceInput)
67 override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
68 bluePrintRuntimeService.getBluePrintError()
69 .addError("Failed in ComponentCliExecutor : ${runtimeException.message}")
73 open fun populateScriptDependencies(scriptDependencies: MutableList<String>) {
74 /** Place holder for Child to add extra dependencies */
78 /** Component Extensions **/
80 fun BluePrintTypes.componentScriptExecutor(): NodeType {
81 return nodeType(id = "component-script-executor", version = BluePrintConstants.DEFAULT_VERSION_NUMBER,
82 derivedFrom = BluePrintConstants.MODEL_TYPE_NODE_COMPONENT,
83 description = "Generic Script Component Executor") {
84 attribute(ComponentScriptExecutor.RESPONSE_DATA, BluePrintConstants.DATA_TYPE_JSON, false)
85 attribute(ComponentScriptExecutor.STATUS, BluePrintConstants.DATA_TYPE_STRING, true)
87 operation("ComponentScriptExecutor", "ComponentScriptExecutor Operation") {
89 property(ComponentScriptExecutor.SCRIPT_TYPE, BluePrintConstants.DATA_TYPE_STRING, true,
91 defaultValue(BluePrintConstants.SCRIPT_INTERNAL)
93 validValues(listOf(BluePrintConstants.SCRIPT_INTERNAL.asJsonPrimitive(),
94 BluePrintConstants.SCRIPT_JYTHON.asJsonPrimitive(),
95 BluePrintConstants.SCRIPT_KOTLIN.asJsonPrimitive()))
98 property(ComponentScriptExecutor.SCRIPT_CLASS_REFERENCE, BluePrintConstants.DATA_TYPE_STRING,
99 true, "Kotlin Script class name or jython script name.")
100 property(ComponentScriptExecutor.DYNAMIC_PROPERTIES, BluePrintConstants.DATA_TYPE_JSON, false,
101 "Dynamic Json Content or DSL Json reference.")
104 property(ComponentScriptExecutor.RESPONSE_DATA, BluePrintConstants.DATA_TYPE_JSON, false,
106 property(ComponentScriptExecutor.STATUS, BluePrintConstants.DATA_TYPE_STRING, true,
107 "Status of the Component Execution ( success or failure )")
113 /** Component Builder */
115 fun componentScriptExecutor(id: String, description: String,
116 block: ComponentScriptExecutorBuilder.() -> Unit): NodeTemplate {
117 return ComponentScriptExecutorBuilder(id, description).apply(block).build()
120 class ComponentScriptExecutorBuilder(private val id: String, private val description: String) {
121 private var implementation: Implementation? = null
122 private var inputs: MutableMap<String, JsonNode>? = null
123 private var outputs: MutableMap<String, JsonNode>? = null
124 private var artifacts: MutableMap<String, ArtifactDefinition>? = null
126 fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF) {
127 val implementation = Implementation().apply {
128 this.operationHost = operationHost!!
129 this.timeout = timeout
131 this.implementation = implementation
134 fun inputs(block: InputAssignmentBuilder.() -> Unit) {
135 this.inputs = InputAssignmentBuilder().apply(block).build()
138 fun outputs(block: OutputAssignmentBuilder.() -> Unit) {
139 this.outputs = OutputAssignmentBuilder().apply(block).build()
142 fun artifact(id: String, type: String, file: String) {
143 if (artifacts == null)
144 artifacts = hashMapOf()
145 artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).build()
148 fun artifact(id: String, type: String, file: String, block: ArtifactDefinitionBuilder.() -> Unit) {
149 if (artifacts == null)
150 artifacts = hashMapOf()
151 artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).apply(block).build()
154 fun build(): NodeTemplate {
155 return nodeTemplate(id, "component-script-executor", description) {
156 operation("ComponentScriptExecutor") {
157 implementation(implementation)
165 class InputAssignmentBuilder {
166 val properties: MutableMap<String, JsonNode> = hashMapOf()
168 fun type(type: String) {
169 properties[ComponentScriptExecutor.SCRIPT_TYPE] = type.asJsonPrimitive()
172 fun scriptClassReference(scriptClassReference: String) {
173 properties[ComponentScriptExecutor.SCRIPT_CLASS_REFERENCE] = scriptClassReference.asJsonPrimitive()
176 fun dynamicProperty(dynamicProperty: Any) {
177 dynamicProperty(dynamicProperty.asJsonType())
180 fun dynamicProperty(dynamicProperty: JsonNode) {
181 properties[ComponentScriptExecutor.DYNAMIC_PROPERTIES] = dynamicProperty
184 fun build(): MutableMap<String, JsonNode> {
189 class OutputAssignmentBuilder {
190 val properties: MutableMap<String, JsonNode> = hashMapOf()
192 fun status(status: String) {
193 properties[ComponentScriptExecutor.STATUS] = status.asJsonPrimitive()
196 fun responseData(responseData: Any) {
197 responseData(responseData.asJsonType())
200 fun responseData(responseData: JsonNode) {
201 properties[ComponentScriptExecutor.RESPONSE_DATA] = responseData
204 fun build(): MutableMap<String, JsonNode> {