c6b7d77e514576a90526cd89ae0ef213229ceccf
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  *
4  * Modifications Copyright © 2019 IBM, Bell Canada.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.processor
20
21 import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.CapabilityResourceSource
22 import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.scripts.BlueprintJythonService
23 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
25 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintScriptsService
26 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
27 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
28 import org.slf4j.LoggerFactory
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.Service
33 import java.io.File
34
35 @Service("rr-processor-source-capability")
36 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
37 open class CapabilityResourceResolutionProcessor(private var applicationContext: ApplicationContext,
38                                                  private val bluePrintScriptsService: BluePrintScriptsService,
39                                                  private val bluePrintJythonService: BlueprintJythonService) :
40         ResourceAssignmentProcessor() {
41
42     override fun getName(): String {
43         return "resource-assignment-processor-capability"
44     }
45
46     override fun process(resourceAssignment: ResourceAssignment) {
47
48         val resourceDefinition = resourceDictionaries[resourceAssignment.dictionaryName]
49                 ?: throw BluePrintProcessorException("couldn't get resource definition for ${resourceAssignment.dictionaryName}")
50
51         val resourceSource = resourceDefinition.sources[resourceAssignment.dictionarySource]
52                 ?: throw BluePrintProcessorException("couldn't get resource definition " +
53                         "${resourceAssignment.dictionaryName} source(${resourceAssignment.dictionarySource})")
54
55         val resourceSourceProps = checkNotNull(resourceSource.properties) { "failed to get $resourceSource properties" }
56         /**
57          * Get the Capability Resource Source Info from Property Definitions.
58          */
59         val capabilityResourceSourceProperty = JacksonUtils
60                 .getInstanceFromMap(resourceSourceProps, CapabilityResourceSource::class.java)
61
62         val scriptType = capabilityResourceSourceProperty.scriptType
63         val scriptClassReference = capabilityResourceSourceProperty.scriptClassReference
64
65         var componentResourceAssignmentProcessor: ResourceAssignmentProcessor? = null
66
67         when (scriptType) {
68             BluePrintConstants.SCRIPT_KOTLIN -> {
69                 componentResourceAssignmentProcessor = getKotlinResourceAssignmentProcessorInstance(scriptClassReference,
70                         capabilityResourceSourceProperty.instanceDependencies)
71             }
72             BluePrintConstants.SCRIPT_INTERNAL -> {
73                 // Initialize Capability Resource Assignment Processor
74                 componentResourceAssignmentProcessor = applicationContext.getBean(scriptClassReference, ResourceAssignmentProcessor::class.java)
75             }
76             BluePrintConstants.SCRIPT_JYTHON -> {
77                 val content = getJythonContent(scriptClassReference)
78                 componentResourceAssignmentProcessor = getJythonResourceAssignmentProcessorInstance(scriptClassReference,
79                         content, capabilityResourceSourceProperty.instanceDependencies)
80             }
81         }
82
83         checkNotNull(componentResourceAssignmentProcessor) { "failed to get capability resource assignment processor($scriptClassReference)" }
84
85         // Assign Current Blueprint runtime and ResourceDictionaries
86         componentResourceAssignmentProcessor.raRuntimeService = raRuntimeService
87         componentResourceAssignmentProcessor.resourceDictionaries = resourceDictionaries
88
89         // Invoke componentResourceAssignmentProcessor
90         componentResourceAssignmentProcessor.apply(resourceAssignment)
91     }
92
93     override fun recover(runtimeException: RuntimeException, resourceAssignment: ResourceAssignment) {
94
95         TODO("To Implement")
96     }
97
98     private fun getKotlinResourceAssignmentProcessorInstance(scriptClassName: String,
99                                                              instanceNames: List<String>? = null): ResourceAssignmentProcessor {
100         var scriptPropertyInstances: MutableMap<String, Any>? = null
101
102         if (instanceNames != null && instanceNames.isNotEmpty()) {
103             scriptPropertyInstances = hashMapOf()
104             instanceNames.forEach {
105                 scriptPropertyInstances[it] = applicationContext.getBean(it)
106                         ?: throw BluePrintProcessorException("couldn't get the dependency instance($it)")
107             }
108         }
109
110         return getKotlinResourceAssignmentProcessorInstance(scriptClassName, scriptPropertyInstances)
111
112     }
113
114     fun getKotlinResourceAssignmentProcessorInstance(scriptClassName: String,
115                                                      scriptPropertyInstances: MutableMap<String, Any>? = null):
116             ResourceAssignmentProcessor {
117
118         val resourceAssignmentProcessor = bluePrintScriptsService
119                 .scriptInstance<ResourceAssignmentProcessor>(raRuntimeService.bluePrintContext(),
120                         scriptClassName, false)
121
122         // Add additional Instance
123         if (scriptPropertyInstances != null) {
124             resourceAssignmentProcessor.scriptPropertyInstances = scriptPropertyInstances
125         }
126
127         return resourceAssignmentProcessor
128     }
129
130     private fun getJythonContent(instanceName: String): String {
131         val absolutePath = raRuntimeService.bluePrintContext().rootPath
132                 .plus(File.separator)
133                 .plus(BluePrintConstants.TOSCA_SCRIPTS_JYTHON_DIR)
134                 .plus(File.separator)
135                 .plus("$instanceName.py")
136
137         return JacksonUtils.getContent(absolutePath)
138
139     }
140
141     /**
142      * getJythonResourceAssignmentProcessorInstance Purpose: prepare the jython
143      * executor component as a resource assignment processor
144      *
145      * @param pythonClassName String
146      * @param content String
147      * @param dependencyInstances List<String>
148      * @return resourceAssignmentProcessor ResourceAssignmentProcessor
149      */
150     private fun getJythonResourceAssignmentProcessorInstance(pythonClassName: String, content: String,
151                                                              dependencyInstances: List<String>?):
152             ResourceAssignmentProcessor {
153         val jythonContextInstance: MutableMap<String, Any> = hashMapOf()
154         jythonContextInstance["log"] = LoggerFactory.getLogger(pythonClassName)
155         jythonContextInstance["raRuntimeService"] = raRuntimeService
156         dependencyInstances?.forEach { instanceName ->
157             jythonContextInstance[instanceName] = applicationContext.getBean(instanceName)
158         }
159
160         return getJythonResourceAssignmentProcessorInstance(pythonClassName, content, jythonContextInstance)
161     }
162
163     fun getJythonResourceAssignmentProcessorInstance(pythonClassName: String, content: String,
164                                                      dependencyInstances: MutableMap<String, Any>):
165             ResourceAssignmentProcessor {
166
167         val resourceAssignmentProcessor = bluePrintJythonService
168                 .jythonInstance<ResourceAssignmentProcessor>(raRuntimeService.bluePrintContext(), pythonClassName,
169                         content, dependencyInstances)
170
171         // Add additional Instance
172         if (dependencyInstances != null) {
173             resourceAssignmentProcessor.scriptPropertyInstances = dependencyInstances
174         }
175
176         return resourceAssignmentProcessor
177     }
178 }