c2dbd73126a1ff1c0c51275d3578e4b661b7f066
[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.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR
23 import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.scripts.BlueprintJythonService
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
25 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
26 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintScriptsService
27 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
28 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
29 import org.slf4j.LoggerFactory
30 import org.springframework.beans.factory.config.ConfigurableBeanFactory
31 import org.springframework.context.ApplicationContext
32 import org.springframework.context.annotation.Scope
33 import org.springframework.stereotype.Service
34 import java.io.File
35
36 @Service("${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-capability")
37 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
38 open class CapabilityResourceResolutionProcessor(private var applicationContext: ApplicationContext,
39                                                  private val bluePrintScriptsService: BluePrintScriptsService,
40                                                  private val bluePrintJythonService: BlueprintJythonService) :
41         ResourceAssignmentProcessor() {
42
43     override fun getName(): String {
44         return "${PREFIX_RESOURCE_RESOLUTION_PROCESSOR}source-capability"
45     }
46
47     override fun process(resourceAssignment: ResourceAssignment) {
48
49         val resourceDefinition = resourceDictionaries[resourceAssignment.dictionaryName]
50                 ?: throw BluePrintProcessorException("couldn't get resource definition for ${resourceAssignment.dictionaryName}")
51
52         val resourceSource = resourceDefinition.sources[resourceAssignment.dictionarySource]
53                 ?: throw BluePrintProcessorException("couldn't get resource definition " +
54                         "${resourceAssignment.dictionaryName} source(${resourceAssignment.dictionarySource})")
55
56         val resourceSourceProps = checkNotNull(resourceSource.properties) { "failed to get $resourceSource properties" }
57         /**
58          * Get the Capability Resource Source Info from Property Definitions.
59          */
60         val capabilityResourceSourceProperty = JacksonUtils
61                 .getInstanceFromMap(resourceSourceProps, CapabilityResourceSource::class.java)
62
63         val scriptType = capabilityResourceSourceProperty.scriptType
64         val scriptClassReference = capabilityResourceSourceProperty.scriptClassReference
65
66         var componentResourceAssignmentProcessor: ResourceAssignmentProcessor? = null
67
68         when (scriptType) {
69             BluePrintConstants.SCRIPT_KOTLIN -> {
70                 componentResourceAssignmentProcessor = getKotlinResourceAssignmentProcessorInstance(scriptClassReference,
71                         capabilityResourceSourceProperty.instanceDependencies)
72             }
73             BluePrintConstants.SCRIPT_INTERNAL -> {
74                 // Initialize Capability Resource Assignment Processor
75                 componentResourceAssignmentProcessor = applicationContext.getBean(scriptClassReference, ResourceAssignmentProcessor::class.java)
76             }
77             BluePrintConstants.SCRIPT_JYTHON -> {
78                 val content = getJythonContent(scriptClassReference)
79                 componentResourceAssignmentProcessor = getJythonResourceAssignmentProcessorInstance(scriptClassReference,
80                         content, capabilityResourceSourceProperty.instanceDependencies)
81             }
82         }
83
84         checkNotNull(componentResourceAssignmentProcessor) { "failed to get capability resource assignment processor($scriptClassReference)" }
85
86         // Assign Current Blueprint runtime and ResourceDictionaries
87         componentResourceAssignmentProcessor.raRuntimeService = raRuntimeService
88         componentResourceAssignmentProcessor.resourceDictionaries = resourceDictionaries
89
90         // Invoke componentResourceAssignmentProcessor
91         componentResourceAssignmentProcessor.apply(resourceAssignment)
92     }
93
94     override fun recover(runtimeException: RuntimeException, resourceAssignment: ResourceAssignment) {
95
96         TODO("To Implement")
97     }
98
99     private fun getKotlinResourceAssignmentProcessorInstance(scriptClassName: String,
100                                                              instanceNames: List<String>? = null): ResourceAssignmentProcessor {
101         var scriptPropertyInstances: MutableMap<String, Any>? = null
102
103         if (instanceNames != null && instanceNames.isNotEmpty()) {
104             scriptPropertyInstances = hashMapOf()
105             instanceNames.forEach {
106                 scriptPropertyInstances[it] = applicationContext.getBean(it)
107                         ?: throw BluePrintProcessorException("couldn't get the dependency instance($it)")
108             }
109         }
110
111         return getKotlinResourceAssignmentProcessorInstance(scriptClassName, scriptPropertyInstances)
112
113     }
114
115     fun getKotlinResourceAssignmentProcessorInstance(scriptClassName: String,
116                                                      scriptPropertyInstances: MutableMap<String, Any>? = null):
117             ResourceAssignmentProcessor {
118
119         val resourceAssignmentProcessor = bluePrintScriptsService
120                 .scriptInstance<ResourceAssignmentProcessor>(raRuntimeService.bluePrintContext(),
121                         scriptClassName, false)
122
123         // Add additional Instance
124         if (scriptPropertyInstances != null) {
125             resourceAssignmentProcessor.scriptPropertyInstances = scriptPropertyInstances
126         }
127
128         return resourceAssignmentProcessor
129     }
130
131     private fun getJythonContent(instanceName: String): String {
132         val absolutePath = raRuntimeService.bluePrintContext().rootPath
133                 .plus(File.separator)
134                 .plus(BluePrintConstants.TOSCA_SCRIPTS_JYTHON_DIR)
135                 .plus(File.separator)
136                 .plus("$instanceName.py")
137
138         return JacksonUtils.getContent(absolutePath)
139
140     }
141
142     /**
143      * getJythonResourceAssignmentProcessorInstance Purpose: prepare the jython
144      * executor component as a resource assignment processor
145      *
146      * @param pythonClassName String
147      * @param content String
148      * @param dependencyInstances List<String>
149      * @return resourceAssignmentProcessor ResourceAssignmentProcessor
150      */
151     private fun getJythonResourceAssignmentProcessorInstance(pythonClassName: String, content: String,
152                                                              dependencyInstances: List<String>?):
153             ResourceAssignmentProcessor {
154         val jythonContextInstance: MutableMap<String, Any> = hashMapOf()
155         jythonContextInstance["log"] = LoggerFactory.getLogger(pythonClassName)
156         jythonContextInstance["raRuntimeService"] = raRuntimeService
157         dependencyInstances?.forEach { instanceName ->
158             jythonContextInstance[instanceName] = applicationContext.getBean(instanceName)
159         }
160
161         return getJythonResourceAssignmentProcessorInstance(pythonClassName, content, jythonContextInstance)
162     }
163
164     fun getJythonResourceAssignmentProcessorInstance(pythonClassName: String, content: String,
165                                                      dependencyInstances: MutableMap<String, Any>):
166             ResourceAssignmentProcessor {
167
168         val resourceAssignmentProcessor = bluePrintJythonService
169                 .jythonInstance<ResourceAssignmentProcessor>(raRuntimeService.bluePrintContext(), pythonClassName,
170                         content, dependencyInstances)
171
172         // Add additional Instance
173         if (dependencyInstances != null) {
174             resourceAssignmentProcessor.scriptPropertyInstances = dependencyInstances
175         }
176
177         return resourceAssignmentProcessor
178     }
179 }