Implement Base Jython Executor function.

Change-Id: I3fb066a021de4a7b3aa1fce7f6c191bc3944fb51
Issue-ID: CCSDK-696
Signed-off-by: Muthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt
index f84b2c5..9da5b0e 100644
--- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt
+++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt
@@ -59,6 +59,8 @@
 

     fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String

 

+    fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition

+

     fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)

 

     fun setWorkflowInputValue(workflowName: String, propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)

@@ -269,17 +271,21 @@
         return propertyAssignmentValue

     }

 

-    override fun resolveNodeTemplateArtifact(nodeTemplateName: String,

-                                             artifactName: String): String {

-        val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)

-

-        val artifactDefinition: ArtifactDefinition = nodeTemplate.artifacts?.get(artifactName)

-                ?: throw BluePrintProcessorException(String.format("failed to get artifat definition {} from the node template"

-                        , artifactName))

+    override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String {

+        val artifactDefinition: ArtifactDefinition = resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)

         val propertyAssignmentExpression = PropertyAssignmentService(this)

         return propertyAssignmentExpression.artifactContent(artifactDefinition)

     }

 

+    override fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition {

+        val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)

+

+        return nodeTemplate.artifacts?.get(artifactName)

+                ?: throw BluePrintProcessorException(String.format("failed to get artifat definition {} from the node template"

+                        , artifactName))

+

+    }

+

 

     override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {

         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)

diff --git a/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Definitions/activation-blueprint.json b/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Definitions/activation-blueprint.json
index ee02b3a..e067a7d 100644
--- a/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Definitions/activation-blueprint.json
+++ b/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Definitions/activation-blueprint.json
@@ -143,7 +143,7 @@
         "artifacts": {
           "component-script": {
             "type": "artifact-script-python",
-            "file": "Scripts/baseconfig-template.vtl"
+            "file": "Scripts/SamplePythonComponentNode.py"
           }
         }
       }
@@ -181,6 +181,24 @@
         }
       },
       "activate": {
+        "inputs": {
+          "request-id": {
+            "required": true,
+            "type": "string"
+          },
+          "action-name": {
+            "required": true,
+            "type": "string"
+          },
+          "scope-type": {
+            "required": true,
+            "type": "string"
+          },
+          "hostname": {
+            "required": true,
+            "type": "string"
+          }
+        },
         "steps": {
           "call-resource-assignment": {
             "description": "Netconf Activation Workflow",
diff --git a/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Scripts/SamplePythonComponentNode.py b/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Scripts/SamplePythonComponentNode.py
index fc51513..0a583dc 100644
--- a/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Scripts/SamplePythonComponentNode.py
+++ b/components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration/Scripts/SamplePythonComponentNode.py
@@ -1,8 +1,12 @@
-from com.brvith.orchestrator.core.interfaces import ComponentNode
+from abstract_blueprint_function import AbstractPythonComponentFunction
+from blueprint_constants import *
 
-class SamplePythonComponentNode(ComponentNode):
-    def prepare(self, context, componentContext):
+class SamplePythonComponentNode(AbstractPythonComponentFunction):
+
+    def process(self, execution_request):
+        print "Processing calling.." + PROPERTY_BLUEPRINT_BASE_PATH
         return None
 
-    def prepare(self, context, componentContext):
-        return None
\ No newline at end of file
+    def recover(self, runtime_exception, execution_request):
+        print "Recovering calling.." + PROPERTY_BLUEPRINT_BASE_PATH
+        return None
diff --git a/components/scripts/python/ccsdk_blueprints/__init__.py b/components/scripts/python/ccsdk_blueprints/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/components/scripts/python/ccsdk_blueprints/__init__.py
diff --git a/components/scripts/python/ccsdk_blueprints/abstract_blueprint_function.py b/components/scripts/python/ccsdk_blueprints/abstract_blueprint_function.py
new file mode 100644
index 0000000..0ddab16
--- /dev/null
+++ b/components/scripts/python/ccsdk_blueprints/abstract_blueprint_function.py
@@ -0,0 +1,11 @@
+from org.onap.ccsdk.apps.blueprintsprocessor.services.execution import AbstractComponentFunction
+
+class AbstractPythonComponentFunction(AbstractComponentFunction):
+
+    def process(self, execution_request):
+        print "Processing calling.."
+        return None
+
+    def recover(self, runtime_exception, execution_request):
+        print "Recovering calling.."
+        return None
diff --git a/components/scripts/python/ccsdk_blueprints/blueprint_constants.py b/components/scripts/python/ccsdk_blueprints/blueprint_constants.py
new file mode 100644
index 0000000..2ec95f3
--- /dev/null
+++ b/components/scripts/python/ccsdk_blueprints/blueprint_constants.py
@@ -0,0 +1,23 @@
+
+PROPERTY_BLUEPRINT_PROCESS_ID= "blueprint-process-id"
+PROPERTY_BLUEPRINT_BASE_PATH= "blueprint-basePath"
+PROPERTY_BLUEPRINT_RUNTIME= "blueprint-runtime"
+PROPERTY_BLUEPRINT_INPUTS_DATA= "blueprint-inputs-data"
+PROPERTY_BLUEPRINT_CONTEXT= "blueprint-context"
+PROPERTY_BLUEPRINT_NAME= "template_name"
+PROPERTY_BLUEPRINT_VERSION= "template_version"
+
+METADATA_USER_GROUPS = "user-groups"
+METADATA_TEMPLATE_NAME = "template_name"
+METADATA_TEMPLATE_VERSION = "template_version"
+METADATA_TEMPLATE_AUTHOR = "template_author"
+METADATA_TEMPLATE_TAGS = "template_tags"
+METADATA_WORKFLOW_NAME = "workflow_name"
+
+PAYLOAD_DATA = "payload-data"
+PROPERTY_CURRENT_STEP = "current-step"
+PROPERTY_CURRENT_NODE_TEMPLATE = "current-node-template"
+PROPERTY_CURRENT_INTERFACE = "current-interface"
+PROPERTY_CURRENT_OPERATION = "current-operation"
+PROPERTY_CURRENT_IMPLEMENTATION = "current-implementation"
+PROPERTY_EXECUTION_REQUEST = "execution-request"
diff --git a/components/scripts/python/ccsdk_blueprints/blueprint_runtime_service.py b/components/scripts/python/ccsdk_blueprints/blueprint_runtime_service.py
new file mode 100644
index 0000000..022b472
--- /dev/null
+++ b/components/scripts/python/ccsdk_blueprints/blueprint_runtime_service.py
@@ -0,0 +1,13 @@
+class BluePrintRuntimeService:
+
+    def __init__(self, bps):
+        self.bps = bps
+
+    def resolveNodeTemplateArtifact(self, node_template_name, artifact_name):
+        return self.bps.resolveNodeTemplateArtifact(node_template_name, artifact_name)
+
+    def setNodeTemplateAttributeValue(self, nodeTemplateName, attributeName, value):
+        return self.bps.setNodeTemplateAttributeValue(nodeTemplateName, attributeName, value)
+
+    def setNodeTemplatePropertyValue(self, nodeTemplateName, propertyName, value):
+        return self.bps.setNodeTemplatePropertyValue(nodeTemplateName, propertyName, value)
diff --git a/components/scripts/python/ccsdk_blueprints/sample_blueprint_component.py b/components/scripts/python/ccsdk_blueprints/sample_blueprint_component.py
new file mode 100644
index 0000000..62665dc
--- /dev/null
+++ b/components/scripts/python/ccsdk_blueprints/sample_blueprint_component.py
@@ -0,0 +1,12 @@
+from abstract_blueprint_function import AbstractPythonComponentFunction
+from blueprint_constants import *
+
+class SampleBlueprintComponent(AbstractPythonComponentFunction):
+
+    def process(self, execution_request):
+        print "Processing calling.." + PROPERTY_BLUEPRINT_BASE_PATH
+        return None
+
+    def recover(self, runtime_exception, execution_request):
+        print "Recovering calling.." + PROPERTY_BLUEPRINT_BASE_PATH
+        return None
diff --git a/ms/blueprintsprocessor/.gitignore b/ms/blueprintsprocessor/.gitignore
index b25ff7b..983e231 100644
--- a/ms/blueprintsprocessor/.gitignore
+++ b/ms/blueprintsprocessor/.gitignore
@@ -15,6 +15,7 @@
 **/target/*
 **/logs/*
 **/tokens/*
+**/lib/cachedir/**
 
 # Added for Intellij IDEA IDE
 **/debug-logs/*
diff --git a/ms/blueprintsprocessor/functions/pom.xml b/ms/blueprintsprocessor/functions/pom.xml
index 50ea7b0..efd550d 100644
--- a/ms/blueprintsprocessor/functions/pom.xml
+++ b/ms/blueprintsprocessor/functions/pom.xml
@@ -31,6 +31,7 @@
     <description>Blueprints Processor Functions POM</description>
     <modules>
         <module>resource-resolution</module>
+        <module>python-executor</module>
     </modules>
 
     <dependencies>
diff --git a/ms/blueprintsprocessor/functions/python-executor/pom.xml b/ms/blueprintsprocessor/functions/python-executor/pom.xml
new file mode 100644
index 0000000..4f9cc74
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>functions</artifactId>
+        <groupId>org.onap.ccsdk.apps.blueprintsprocessor</groupId>
+        <version>0.4.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.onap.ccsdk.apps.blueprintsprocessor.functions</groupId>
+    <artifactId>python-executor</artifactId>
+    <name>Blueprints Processor Function - Python Executor</name>
+    <description>Blueprints Processor Function - Python Executor</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.python</groupId>
+            <artifactId>jython-standalone</artifactId>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/ComponentPythonExecutor.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/ComponentPythonExecutor.kt
new file mode 100644
index 0000000..823b13f
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/ComponentPythonExecutor.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor
+
+import org.apache.commons.io.FilenameUtils
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor.utils.PythonExecutorUtils
+import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.AbstractComponentFunction
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.apps.controllerblueprints.core.checkNotEmptyNThrow
+import org.onap.ccsdk.apps.controllerblueprints.core.data.OperationAssignment
+import org.slf4j.LoggerFactory
+import org.springframework.stereotype.Component
+
+@Component("component-python-executor")
+class ComponentPythonExecutor(private val pythonExecutorProperty: PythonExecutorProperty) : AbstractComponentFunction() {
+
+    private val log = LoggerFactory.getLogger(ComponentPythonExecutor::class.java)
+
+    private var componentFunction: AbstractComponentFunction? = null
+
+
+    override fun process(executionServiceInput: ExecutionServiceInput) {
+
+        log.info("Processing : ${executionServiceInput.metadata}")
+        checkNotNull(bluePrintRuntimeService) { "failed to get bluePrintRuntimeService" }
+
+        val bluePrintContext = bluePrintRuntimeService!!.bluePrintContext()
+
+        val operationAssignment: OperationAssignment = bluePrintContext
+                .nodeTemplateInterfaceOperation(nodeTemplateName, interfaceName, operationName)
+
+        val blueprintBasePath: String = bluePrintRuntimeService!!.get(BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH)?.asText()
+                ?: throw BluePrintProcessorException("python execute path is missing for node template ($nodeTemplateName)")
+
+        val artifactName: String = operationAssignment.implementation?.primary
+                ?: throw BluePrintProcessorException("missing primary field to get artifact name for node template ($nodeTemplateName)")
+
+        val artifactDefinition = bluePrintRuntimeService!!.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
+
+        val pythonFileName = artifactDefinition.file
+                ?: throw BluePrintProcessorException("missing file name for node template ($nodeTemplateName)'s artifactName($artifactName)")
+
+        val pythonClassName = FilenameUtils.getBaseName(pythonFileName)
+
+        val content: String? = bluePrintRuntimeService!!.resolveNodeTemplateArtifact(nodeTemplateName, artifactName)
+
+        checkNotEmptyNThrow(content, "artifact ($artifactName) content is empty")
+
+        val pythonPath: MutableList<String> = operationAssignment.implementation?.dependencies ?: arrayListOf()
+        pythonPath.add(blueprintBasePath)
+        pythonPath.addAll(pythonExecutorProperty.modulePaths)
+
+        val properties: MutableMap<String, Any> = hashMapOf()
+        properties["log"] = log
+
+        componentFunction = PythonExecutorUtils.getPythonComponent(pythonExecutorProperty.executionPath, pythonPath, content, pythonClassName, properties)
+
+        componentFunction!!.process(executionServiceInput)
+
+    }
+
+    override fun recover(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
+        componentFunction!!.recover(runtimeException, executionRequest)
+    }
+
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/PythonExecutorConfiguration.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/PythonExecutorConfiguration.kt
new file mode 100644
index 0000000..dd80fb0
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/PythonExecutorConfiguration.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor
+
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.boot.context.properties.EnableConfigurationProperties
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Configuration
+
+@Configuration
+@ComponentScan
+@EnableConfigurationProperties
+open class PythonExecutorConfiguration
+
+@Configuration
+open class PythonExecutorProperty {
+    @Value("\${blueprints.processor.functions.python.executor.executionPath}")
+    lateinit var executionPath: String
+    @Value("#{'\${blueprints.processor.functions.python.executor.modulePaths}'.split(',')}")
+    lateinit var modulePaths: List<String>
+
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtils.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtils.kt
new file mode 100644
index 0000000..66c919d
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtils.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor.utils
+
+import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.AbstractComponentFunction
+import org.python.core.PyObject
+import org.python.util.PythonInterpreter
+import org.slf4j.LoggerFactory
+import java.util.*
+
+class PythonExecutorUtils {
+    companion object {
+
+        private val log = LoggerFactory.getLogger(PythonExecutorUtils::class.java)
+
+        fun getPythonComponent(executePath: String, pythonPath: MutableList<String>, content: String?, interfaceName: String,
+                               properties: MutableMap<String, Any>): AbstractComponentFunction {
+
+            initPython(executePath, pythonPath, arrayListOf())
+            val pythonInterpreter = PythonInterpreter()
+
+            properties.forEach { (name, value) ->
+                pythonInterpreter.set(name, value)
+            }
+
+            pythonInterpreter.exec("import sys")
+
+            content?.let {
+                pythonInterpreter.exec(content)
+            }
+
+            val initCommand = interfaceName.plus(" = ").plus(interfaceName).plus("()")
+            pythonInterpreter.exec(initCommand)
+            val pyObject: PyObject = pythonInterpreter.get(interfaceName)
+
+            log.info("Component Object {}", pyObject)
+
+            return pyObject.__tojava__(AbstractComponentFunction::class.java) as AbstractComponentFunction
+        }
+
+        private fun initPython(executablePath: String,
+                       pythonPath: MutableList<String>, argv: MutableList<String>) {
+
+            val props = Properties()
+            // Build up the python.path
+            val sb = StringBuilder()
+            sb.append(System.getProperty("java.class.path"))
+
+            for (p in pythonPath) {
+                sb.append(":").append(p)
+            }
+            log.debug("Paths : $sb")
+
+            props["python.import.site"] = "true"
+            props.setProperty("python.path", sb.toString())
+            props.setProperty("python.verbose", "error")
+            props.setProperty("python.executable", executablePath)
+
+            PythonInterpreter.initialize(System.getProperties(), props, argv.toTypedArray())
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/ComponentPythonExecutorTest.kt b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/ComponentPythonExecutorTest.kt
new file mode 100644
index 0000000..e16f2f0
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/ComponentPythonExecutorTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor
+
+import com.fasterxml.jackson.databind.JsonNode
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ActionIdentifiers
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.CommonHeader
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.apps.controllerblueprints.core.putJsonElement
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.TestPropertySource
+import org.springframework.test.context.junit4.SpringRunner
+
+@RunWith(SpringRunner::class)
+@ContextConfiguration(classes = [PythonExecutorConfiguration::class, PythonExecutorProperty::class])
+@TestPropertySource(properties =
+["blueprints.processor.functions.python.executor.modulePaths=./../../../../components/scripts/python/ccsdk_blueprints",
+    "blueprints.processor.functions.python.executor.executionPath=./../../../../components/scripts/python/ccsdk_blueprints"])
+
+class ComponentPythonExecutorTest {
+
+    @Autowired
+    lateinit var componentPythonExecutor: ComponentPythonExecutor
+
+
+    @Test
+    fun testPythonComponentInjection() {
+
+        val executionServiceInput = ExecutionServiceInput()
+        val commonHeader = CommonHeader()
+        commonHeader.requestId = "1234"
+        executionServiceInput.commonHeader = commonHeader
+
+        val actionIdentifiers = ActionIdentifiers()
+        actionIdentifiers.blueprintName = "baseconfiguration"
+        actionIdentifiers.blueprintVersion = "1.0.0"
+        actionIdentifiers.actionName = "activate"
+        executionServiceInput.actionIdentifiers = actionIdentifiers
+
+
+        val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(commonHeader.requestId,
+                "./../../../../components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration")
+
+        componentPythonExecutor.bluePrintRuntimeService = bluePrintRuntimeService
+
+
+        val metaData: MutableMap<String, JsonNode> = hashMapOf()
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_STEP, "resource-assignment-py")
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "resource-assignment-py")
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "DefaultComponentNode")
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process")
+        executionServiceInput.metadata = metaData
+
+        componentPythonExecutor.apply(executionServiceInput)
+
+    }
+}
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtilsTest.kt b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtilsTest.kt
new file mode 100644
index 0000000..6197c4b
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtilsTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.python.executor.utils
+
+import org.junit.Test
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
+import org.slf4j.LoggerFactory
+import kotlin.test.assertNotNull
+
+
+class PythonExecutorUtilsTest {
+
+    private val log = LoggerFactory.getLogger(PythonExecutorUtils::class.java)
+
+    @Test
+    fun testGetPythonComponent() {
+
+        val pythonPath: MutableList<String> = arrayListOf()
+        pythonPath.add("./../../../../components/scripts/python/ccsdk_blueprints")
+
+        val properties: MutableMap<String, Any> = hashMapOf()
+        properties["logger"] = log
+
+        val content = JacksonUtils.getContent("./../../../../components/scripts/python/ccsdk_blueprints/sample_blueprint_component.py")
+
+        val abstractComponentFunction = PythonExecutorUtils.getPythonComponent("/home/brindasanth/onap/apps/components/scripts/python/ccsdk_blueprints", pythonPath, content,
+                "SampleBlueprintComponent", properties)
+
+        assertNotNull(abstractComponentFunction, "failed to get python component")
+
+        abstractComponentFunction.process(ExecutionServiceInput())
+
+    }
+
+
+}
+
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/resources/logback-test.xml b/ms/blueprintsprocessor/functions/python-executor/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..a816a06
--- /dev/null
+++ b/ms/blueprintsprocessor/functions/python-executor/src/test/resources/logback-test.xml
@@ -0,0 +1,35 @@
+<!--

+  ~ Copyright © 2017-2018 AT&T Intellectual Property.

+  ~

+  ~ Licensed under the Apache License, Version 2.0 (the "License");

+  ~ you may not use this file except in compliance with the License.

+  ~ You may obtain a copy of the License at

+  ~

+  ~     http://www.apache.org/licenses/LICENSE-2.0

+  ~

+  ~ Unless required by applicable law or agreed to in writing, software

+  ~ distributed under the License is distributed on an "AS IS" BASIS,

+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  ~ See the License for the specific language governing permissions and

+  ~ limitations under the License.

+  -->

+

+<configuration>

+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

+        <!-- encoders are assigned the type

+             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->

+        <encoder>

+            <pattern>%d{HH:mm:ss.SSS} %-5level %logger{100} - %msg%n</pattern>

+        </encoder>

+    </appender>

+

+

+    <logger name="org.springframework" level="warn"/>

+    <logger name="org.hibernate" level="info"/>

+    <logger name="org.onap.ccsdk.apps.blueprintsprocessor" level="info"/>

+

+    <root level="warn">

+        <appender-ref ref="STDOUT"/>

+    </root>

+

+</configuration>

diff --git a/ms/blueprintsprocessor/functions/resource-resolution/pom.xml b/ms/blueprintsprocessor/functions/resource-resolution/pom.xml
index a2d3bb8..858be70 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/pom.xml
+++ b/ms/blueprintsprocessor/functions/resource-resolution/pom.xml
@@ -25,7 +25,7 @@
     <groupId>org.onap.ccsdk.apps.blueprintsprocessor.functions</groupId>
     <artifactId>resource-resolution</artifactId>
     <packaging>jar</packaging>
-    <name>Blueprints Processor Resolution Service</name>
-    <description>Blueprints Processor Resolution Service</description>
+    <name>Blueprints Processor Function - Resource Resolution</name>
+    <description>Blueprints Processor Function - Resource Resolution</description>
 
 </project>
diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/execution/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
index 9a0d1f9..801b660 100644
--- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
+++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
@@ -19,7 +19,10 @@
 

 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput

 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceOutput

+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants

+import org.onap.ccsdk.apps.controllerblueprints.core.getAsString

 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode

+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService

 import org.slf4j.LoggerFactory

 

 /**

@@ -29,14 +32,39 @@
 abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServiceInput, ExecutionServiceOutput> {

     private val log = LoggerFactory.getLogger(AbstractComponentFunction::class.java)

 

-    override fun prepareRequest(executionRequest: ExecutionServiceInput): ExecutionServiceInput {

+    var executionServiceInput: ExecutionServiceInput? = null

+    val executionServiceOutput = ExecutionServiceOutput()

+    var bluePrintRuntimeService: BluePrintRuntimeService<*>? = null

+    var processId: String = ""

+    var workflowName: String = ""

+    var stepName: String = ""

+    var interfaceName: String = ""

+    var operationName: String = ""

+    var nodeTemplateName: String = ""

+

+

+    override fun prepareRequest(executionServiceInput: ExecutionServiceInput): ExecutionServiceInput {

+

+        this.executionServiceInput = this.executionServiceInput

+

+        processId = executionServiceInput.commonHeader.requestId

+        workflowName = executionServiceInput.actionIdentifiers.actionName

+

+        val metadata = executionServiceInput.metadata

+        stepName = metadata.getAsString(BluePrintConstants.PROPERTY_CURRENT_STEP)

+        nodeTemplateName = metadata.getAsString(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE)

+        interfaceName = metadata.getAsString(BluePrintConstants.PROPERTY_CURRENT_INTERFACE)

+        operationName = metadata.getAsString(BluePrintConstants.PROPERTY_CURRENT_OPERATION)

+

+        checkNotNull(bluePrintRuntimeService) { "failed to prepare blueprint runtime" }

+

         log.info("prepareRequest...")

-        return executionRequest

+        return executionServiceInput

     }

 

     override fun prepareResponse(): ExecutionServiceOutput {

         log.info("Preparing Response...")

-        return ExecutionServiceOutput()

+        return this.executionServiceOutput

     }

 

     override fun apply(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {

diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintSvcLogicService.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintSvcLogicService.kt
index 8750d98..0600f62 100644
--- a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintSvcLogicService.kt
+++ b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintSvcLogicService.kt
@@ -125,12 +125,6 @@
     override fun execute(graph: SvcLogicGraph, svcLogicContext: SvcLogicContext): SvcLogicContext {
         MDC.put("currentGraph", graph.toString())
 
-        val ctx = svcLogicContext as BlueprintSvcLogicContext
-
-        val blueprintRuntimeService = ctx.getBluePrintService()
-
-        log.info("Blueprint Runtime Service : ${blueprintRuntimeService}")
-
         var curNode: SvcLogicNode? = graph.getRootNode()
         log.info("About to execute graph {}", graph.toString())
 
@@ -138,7 +132,7 @@
             while (curNode != null) {
                 MDC.put("nodeId", curNode.nodeId.toString() + " (" + curNode.nodeType + ")")
                 log.info("About to execute node # {} ({})", curNode.nodeId, curNode.nodeType)
-                val nextNode = this.executeNode(curNode, ctx)
+                val nextNode = this.executeNode(curNode, svcLogicContext)
                 curNode = nextNode
             }
         } catch (var5: ExitNodeException) {
@@ -147,6 +141,6 @@
 
         MDC.remove("nodeId")
         MDC.remove("currentGraph")
-        return ctx
+        return svcLogicContext
     }
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/executor/ComponentExecuteNodeExecutor.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/executor/ComponentExecuteNodeExecutor.kt
index 125a1ff..ace9f27 100644
--- a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/executor/ComponentExecuteNodeExecutor.kt
+++ b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/executor/ComponentExecuteNodeExecutor.kt
@@ -60,6 +60,8 @@
             log.info("executing node template($nodeTemplateName) component($componentName)")
             // Get the Component Instance
             val plugin = this.getComponentFunction(componentName)
+            // Set the Blueprint Service
+            plugin.bluePrintRuntimeService = ctx.getBluePrintService()
 
             val executionInput = ctx.getRequest() as ExecutionServiceInput
             // Get the Request from the Context and Set to the Function Input and Invoke the function
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintServiceLogicTest.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintServiceLogicTest.kt
index 5c90852..6fe767c 100644
--- a/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintServiceLogicTest.kt
+++ b/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintServiceLogicTest.kt
@@ -16,11 +16,16 @@
 
 package org.onap.ccsdk.apps.blueprintsprocessor.services.workflow
 
+import com.fasterxml.jackson.databind.JsonNode
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ActionIdentifiers
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.CommonHeader
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.apps.blueprintsprocessor.services.workflow.executor.ComponentExecuteNodeExecutor
 import org.onap.ccsdk.apps.blueprintsprocessor.services.workflow.utils.SvcGraphUtils
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.apps.controllerblueprints.core.putJsonElement
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
@@ -45,7 +50,7 @@
         val graph = SvcGraphUtils.getSvcGraphFromClassPathFile("service-logic/one-component.xml")
         val svcLogicContext = BlueprintSvcLogicContext()
         svcLogicContext.setBluePrintRuntimeService(bluePrintRuntimeService)
-        svcLogicContext.setRequest(ExecutionServiceInput())
+        svcLogicContext.setRequest(getDefaultExecutionServiceInput())
         blueprintSvcLogicService.execute(graph, svcLogicContext)
 
     }
@@ -55,8 +60,30 @@
         val graph = SvcGraphUtils.getSvcGraphFromClassPathFile("service-logic/two-component.xml")
         val svcLogicContext = BlueprintSvcLogicContext()
         svcLogicContext.setBluePrintRuntimeService(bluePrintRuntimeService)
-        svcLogicContext.setRequest(ExecutionServiceInput())
+        svcLogicContext.setRequest(getDefaultExecutionServiceInput())
         blueprintSvcLogicService.execute(graph, svcLogicContext)
 
     }
+
+    private fun getDefaultExecutionServiceInput(): ExecutionServiceInput {
+        val executionServiceInput = ExecutionServiceInput()
+        val commonHeader = CommonHeader()
+        commonHeader.requestId = "1234"
+        executionServiceInput.commonHeader = commonHeader
+
+        val actionIdentifiers = ActionIdentifiers()
+        actionIdentifiers.blueprintName = "baseconfiguration"
+        actionIdentifiers.blueprintVersion = "1.0.0"
+        actionIdentifiers.actionName = "activate"
+        executionServiceInput.actionIdentifiers = actionIdentifiers
+
+        val metaData: MutableMap<String, JsonNode> = hashMapOf()
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_STEP,"resource-assignment-py")
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "resource-assignment-py")
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "DefaultComponentNode")
+        metaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process")
+        executionServiceInput.metadata = metaData
+
+        return executionServiceInput
+    }
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml
index 761fdc7..637a07a 100644
--- a/ms/blueprintsprocessor/parent/pom.xml
+++ b/ms/blueprintsprocessor/parent/pom.xml
@@ -38,6 +38,7 @@
         <eelf.version>1.0.0</eelf.version>
         <sli.version>0.3.1</sli.version>
         <guava.version>26.0-jre</guava.version>
+        <jython.version>2.7.1</jython.version>
         <springfox.swagger2.version>2.9.2</springfox.swagger2.version>
         <h2database.version>1.4.197</h2database.version>
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
@@ -228,6 +229,11 @@
                 <artifactId>guava</artifactId>
                 <version>${guava.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.python</groupId>
+                <artifactId>jython-standalone</artifactId>
+                <version>${jython.version}</version>
+            </dependency>
 
             <!-- Database -->
             <dependency>