5eb40225e7fa8f1bc58c0d0e10e500ee8095b8b8
[ccsdk/cds.git] / ms / blueprintsprocessor / functions / python-executor / src / main / kotlin / org / onap / ccsdk / apps / blueprintsprocessor / functions / python / executor / ComponentJythonExecutor.kt
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor
18
19 import com.fasterxml.jackson.databind.node.ArrayNode
20 import org.apache.commons.io.FilenameUtils
21 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
22 import org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor.utils.PythonExecutorUtils
23 import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.AbstractComponentFunction
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
25 import org.onap.ccsdk.apps.controllerblueprints.core.checkNotEmptyNThrow
26 import org.onap.ccsdk.apps.controllerblueprints.core.data.OperationAssignment
27 import org.slf4j.LoggerFactory
28 import org.springframework.beans.factory.annotation.Autowired
29 import org.springframework.beans.factory.config.ConfigurableBeanFactory
30 import org.springframework.context.ApplicationContext
31 import org.springframework.context.annotation.Scope
32 import org.springframework.stereotype.Component
33
34 @Component("component-jython-executor")
35 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
36 open class ComponentJythonExecutor(private val pythonExecutorProperty: PythonExecutorProperty) : AbstractComponentFunction() {
37
38     private val log = LoggerFactory.getLogger(ComponentJythonExecutor::class.java)
39
40     private var componentFunction: AbstractComponentFunction? = null
41
42     @Autowired
43     lateinit var applicationContext: ApplicationContext
44
45     fun populateJythonComponentInstance(executionServiceInput: ExecutionServiceInput) {
46         val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
47
48         val operationAssignment: OperationAssignment = bluePrintContext
49                 .nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName)
50
51         val blueprintBasePath: String = bluePrintContext.rootPath
52
53         val artifactName: String = operationAssignment.implementation?.primary
54                 ?: throw BluePrintProcessorException("missing primary field to get artifact name for node template ($nodeTemplateName)")
55
56         val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
57
58         val pythonFileName = artifactDefinition.file
59                 ?: throw BluePrintProcessorException("missing file name for node template ($nodeTemplateName)'s artifactName($artifactName)")
60
61         val pythonClassName = FilenameUtils.getBaseName(pythonFileName)
62
63         val content: String? = bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName)
64
65         checkNotEmptyNThrow(content, "artifact ($artifactName) content is empty")
66
67         val pythonPath: MutableList<String> = operationAssignment.implementation?.dependencies ?: arrayListOf()
68         pythonPath.add(blueprintBasePath)
69         pythonPath.addAll(pythonExecutorProperty.modulePaths)
70
71         val jythonInstances: MutableMap<String, Any> = hashMapOf()
72         jythonInstances["log"] = LoggerFactory.getLogger(nodeTemplateName)
73
74         val instanceDependenciesNode: ArrayNode = operationInputs[PythonExecutorConstants.INPUT_INSTANCE_DEPENDENCIES] as? ArrayNode
75                 ?: throw BluePrintProcessorException("Failed to get property(${PythonExecutorConstants.INPUT_INSTANCE_DEPENDENCIES})")
76
77         instanceDependenciesNode.forEach { instanceName ->
78             jythonInstances[instanceName.textValue()] = applicationContext.getBean(instanceName.textValue())
79         }
80
81         componentFunction = PythonExecutorUtils.getPythonComponent(pythonExecutorProperty.executionPath,
82                 pythonPath, content, pythonClassName, jythonInstances)
83     }
84
85
86     override fun process(executionServiceInput: ExecutionServiceInput) {
87
88         log.info("Processing : $operationInputs")
89         checkNotNull(bluePrintRuntimeService) { "failed to get bluePrintRuntimeService" }
90
91         // Populate Component Instance
92         populateJythonComponentInstance(executionServiceInput)
93
94         // Invoke Jython Component Script
95         componentFunction!!.process(executionServiceInput)
96
97     }
98
99     override fun recover(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
100         componentFunction!!.recover(runtimeException, executionRequest)
101     }
102
103 }