Add node template workflow service. 41/82141/3
authorMuthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
Wed, 13 Mar 2019 14:56:28 +0000 (10:56 -0400)
committerBrinda Santh Muthuramalingam <brindasanth@in.ibm.com>
Wed, 13 Mar 2019 21:16:15 +0000 (21:16 +0000)
Change-Id: I3a9167fe58b697f8fb9c7f5fd09768950afe1ff4
Issue-ID: CCSDK-1154
Signed-off-by: Muthuramalingam, Brinda Santh <brindasanth@in.ibm.com>
15 files changed:
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt
ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceHandler.kt
ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/execution/AbstractComponentFunction.kt
ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BluePrintWorkflowExecutionServiceImpl.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintSvcLogicService.kt
ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/ComponentWorkflowExecutionService.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/DGWorkflowExecutionService.kt [moved from ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintDGExecutionService.kt with 75% similarity]
ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/executor/ComponentExecuteNodeExecutor.kt
ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BluePrintWorkflowExecutionServiceImplTest.kt [new file with mode: 0644]
ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintServiceLogicTest.kt
ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/DGWorkflowExecutionServiceTest.kt [moved from ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BlueprintDGExecutionServiceTest.kt with 84% similarity]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctions.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/interfaces/BluePrintWorkflowExecutionService.kt [new file with mode: 0644]

index aadbec8..ebeda69 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +18,7 @@
 package org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api
 
 import io.grpc.stub.StreamObserver
+import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.apps.blueprintsprocessor.core.BluePrintCoreConfiguration
 import org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api.utils.toJava
 import org.onap.ccsdk.apps.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc
@@ -28,18 +30,20 @@ import org.springframework.stereotype.Service
 
 @Service
 open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration,
-                                     private val executionServiceHandler: ExecutionServiceHandler)
+                                          private val executionServiceHandler: ExecutionServiceHandler)
     : BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase() {
     private val log = LoggerFactory.getLogger(BluePrintProcessingGRPCHandler::class.java)
 
     @PreAuthorize("hasRole('USER')")
     override fun process(
-        responseObserver: StreamObserver<ExecutionServiceOutput>): StreamObserver<ExecutionServiceInput> {
+            responseObserver: StreamObserver<ExecutionServiceOutput>): StreamObserver<ExecutionServiceInput> {
 
         return object : StreamObserver<ExecutionServiceInput> {
             override fun onNext(executionServiceInput: ExecutionServiceInput) {
                 try {
-                    executionServiceHandler.process(executionServiceInput.toJava(), responseObserver)
+                    runBlocking {
+                        executionServiceHandler.process(executionServiceInput.toJava(), responseObserver)
+                    }
                 } catch (e: Exception) {
                     onError(e)
                 }
@@ -48,8 +52,8 @@ open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration
             override fun onError(error: Throwable) {
                 log.debug("Fail to process message", error)
                 responseObserver.onError(io.grpc.Status.INTERNAL
-                    .withDescription(error.message)
-                    .asException())
+                        .withDescription(error.message)
+                        .asException())
             }
 
             override fun onCompleted() {
index 16f0fa8..6e72947 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +18,7 @@
 package org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api
 
 import io.swagger.annotations.ApiOperation
+import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ACTION_MODE_ASYNC
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceOutput
@@ -24,13 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.http.codec.multipart.FilePart
 import org.springframework.security.access.prepost.PreAuthorize
-import org.springframework.web.bind.annotation.PostMapping
-import org.springframework.web.bind.annotation.RequestBody
-import org.springframework.web.bind.annotation.RequestMapping
-import org.springframework.web.bind.annotation.RequestMethod
-import org.springframework.web.bind.annotation.RequestPart
-import org.springframework.web.bind.annotation.ResponseBody
-import org.springframework.web.bind.annotation.RestController
+import org.springframework.web.bind.annotation.*
 import reactor.core.publisher.Mono
 
 @RestController
@@ -42,8 +38,8 @@ open class ExecutionServiceController {
 
     @RequestMapping(path = ["/ping"], method = [RequestMethod.GET], produces = [MediaType.APPLICATION_JSON_VALUE])
     @ResponseBody
-    fun ping(): Mono<String> {
-        return Mono.just("Success")
+    fun ping(): String = runBlocking {
+        "Success"
     }
 
     @PostMapping(path = ["/upload"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@@ -52,20 +48,20 @@ open class ExecutionServiceController {
     @PreAuthorize("hasRole('USER')")
     fun upload(@RequestPart("file") parts: Mono<FilePart>): Mono<String> {
         return parts
-            .filter { it is FilePart }
-            .ofType(FilePart::class.java)
-            .flatMap(executionServiceHandler::upload)
+                .filter { it is FilePart }
+                .ofType(FilePart::class.java)
+                .flatMap(executionServiceHandler::upload)
     }
 
     @RequestMapping(path = ["/process"], method = [RequestMethod.POST], produces = [MediaType.APPLICATION_JSON_VALUE])
     @ApiOperation(value = "Resolve Resource Mappings",
-        notes = "Takes the blueprint information and process as per the payload")
+            notes = "Takes the blueprint information and process as per the payload")
     @ResponseBody
     @PreAuthorize("hasRole('USER')")
-    fun process(@RequestBody executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
+    fun process(@RequestBody executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput = runBlocking {
         if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) {
             throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.")
         }
-        return executionServiceHandler.processSync(executionServiceInput)
+        executionServiceHandler.doProcess(executionServiceInput)
     }
 }
index 5278c17..d8afe16 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,18 +23,14 @@ import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import org.onap.ccsdk.apps.blueprintsprocessor.core.BluePrintCoreConfiguration
-import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ACTION_MODE_ASYNC
-import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ACTION_MODE_SYNC
-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.blueprintsprocessor.core.api.data.Status
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.*
 import org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api.utils.saveCBAFile
 import org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api.utils.toProto
-import org.onap.ccsdk.apps.blueprintsprocessor.services.workflow.BlueprintDGExecutionService
 import org.onap.ccsdk.apps.controllerblueprints.common.api.EventType
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintCatalogService
+import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintWorkflowExecutionService
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintFileUtils
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
 import org.slf4j.LoggerFactory
@@ -44,7 +41,8 @@ import reactor.core.publisher.Mono
 @Service
 class ExecutionServiceHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration,
                               private val bluePrintCatalogService: BluePrintCatalogService,
-                              private val blueprintDGExecutionService: BlueprintDGExecutionService) {
+                              private val bluePrintWorkflowExecutionService
+                              : BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput>) {
 
     private val log = LoggerFactory.getLogger(ExecutionServiceHandler::class.toString())
 
@@ -60,8 +58,8 @@ class ExecutionServiceHandler(private val bluePrintCoreConfiguration: BluePrintC
         }
     }
 
-    fun process(executionServiceInput: ExecutionServiceInput,
-                responseObserver: StreamObserver<org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceOutput>) {
+    suspend fun process(executionServiceInput: ExecutionServiceInput,
+                        responseObserver: StreamObserver<org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceOutput>) {
         when {
             executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC -> {
                 GlobalScope.launch(Dispatchers.Default) {
@@ -77,16 +75,12 @@ class ExecutionServiceHandler(private val bluePrintCoreConfiguration: BluePrintC
                 responseObserver.onCompleted()
             }
             else -> responseObserver.onNext(response(executionServiceInput,
-                "Failed to process request, 'actionIdentifiers.mode' not specified. Valid value are: 'sync' or 'async'.",
-                true).toProto());
+                    "Failed to process request, 'actionIdentifiers.mode' not specified. Valid value are: 'sync' or 'async'.",
+                    true).toProto());
         }
     }
 
-    fun processSync(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
-        return doProcess(executionServiceInput)
-    }
-
-    private fun doProcess(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
+    suspend fun doProcess(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
         val requestId = executionServiceInput.commonHeader.requestId
         log.info("processing request id $requestId")
 
@@ -100,7 +94,8 @@ class ExecutionServiceHandler(private val bluePrintCoreConfiguration: BluePrintC
 
         val blueprintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(requestId, basePath.toString())
 
-        return blueprintDGExecutionService.executeDirectedGraph(blueprintRuntimeService, executionServiceInput)
+        return bluePrintWorkflowExecutionService.executeBluePrintWorkflow(blueprintRuntimeService,
+                executionServiceInput, hashMapOf())
     }
 
     private fun response(executionServiceInput: ExecutionServiceInput, errorMessage: String = "",
index a67e006..f2b6e3f 100644 (file)
@@ -26,11 +26,10 @@ import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.Status
 import org.onap.ccsdk.apps.controllerblueprints.common.api.EventType\r
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException\r
-import org.onap.ccsdk.apps.controllerblueprints.core.asJsonNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.asObjectNode\r
 import org.onap.ccsdk.apps.controllerblueprints.core.getAsString\r
 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode\r
 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService\r
-import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
 import org.slf4j.LoggerFactory\r
 \r
 /**\r
@@ -51,8 +50,11 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
     lateinit var operationName: String\r
     lateinit var nodeTemplateName: String\r
     var operationInputs: MutableMap<String, JsonNode> = hashMapOf()\r
+\r
+    //FIXME("Move to Script abstract class")\r
     /**\r
-     * Store Dynamic Dependency Instances\r
+     * Store Dynamic Script Dependency Instances, Objects present inside won't be persisted or state maintained.\r
+     * Later it will be moved to ScriptComponentFunction class, sub class for abstract class\r
      */\r
     var functionDependencyInstances: MutableMap<String, Any> = hashMapOf()\r
 \r
@@ -91,7 +93,8 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
         operationName = this.operationInputs.getAsString(BluePrintConstants.PROPERTY_CURRENT_OPERATION)\r
         check(operationName.isNotEmpty()) { "couldn't get Operation name for step($stepName)" }\r
 \r
-        val operationResolvedProperties = bluePrintRuntimeService.resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)\r
+        val operationResolvedProperties = bluePrintRuntimeService\r
+                .resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)\r
 \r
         this.operationInputs.putAll(operationResolvedProperties)\r
 \r
@@ -103,15 +106,16 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
         executionServiceOutput.commonHeader = executionServiceInput.commonHeader\r
         executionServiceOutput.actionIdentifiers = executionServiceInput.actionIdentifiers\r
 \r
-\r
         // Resolve the Output Expression\r
         val stepOutputs = bluePrintRuntimeService\r
                 .resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)\r
 \r
-        bluePrintRuntimeService.put("$stepName-step-outputs", stepOutputs.asJsonNode())\r
+        // FIXME("Not the right place to populate the response payload")\r
+        executionServiceOutput.payload = stepOutputs.asObjectNode()\r
 \r
-        executionServiceOutput.payload = JacksonUtils.objectNodeFromObject(stepOutputs)\r
+        bluePrintRuntimeService.put("$stepName-step-outputs", executionServiceOutput.payload)\r
 \r
+        // FIXME("Not the right place to populate the status")\r
         // Populate Status\r
         val status = Status()\r
         status.eventType = EventType.EVENT_COMPONENT_EXECUTED.name\r
@@ -122,8 +126,12 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
     }\r
 \r
     override fun apply(executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {\r
-        prepareRequest(executionServiceInput)\r
-        process(executionServiceInput)\r
+        try {\r
+            prepareRequest(executionServiceInput)\r
+            process(executionServiceInput)\r
+        } catch (runtimeException: RuntimeException) {\r
+            recover(runtimeException, executionServiceInput)\r
+        }\r
         return prepareResponse()\r
     }\r
 \r
@@ -136,6 +144,7 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic
         bluePrintRuntimeService.setNodeTemplateAttributeValue(nodeTemplateName, key, value)\r
     }\r
 \r
+    //FIXME("Move to Script abstract class")\r
     /**\r
      * This will be called from the scripts to serve instance from runtime to scripts.\r
      */\r
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BluePrintWorkflowExecutionServiceImpl.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BluePrintWorkflowExecutionServiceImpl.kt
new file mode 100644 (file)
index 0000000..73f6f49
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.services.workflow
+
+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.BluePrintProcessorException
+import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintWorkflowExecutionService
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
+import org.slf4j.LoggerFactory
+import org.springframework.stereotype.Service
+
+@Service("bluePrintWorkflowExecutionService")
+open class BluePrintWorkflowExecutionServiceImpl(
+        private val componentWorkflowExecutionService: ComponentWorkflowExecutionService,
+        private val dgWorkflowExecutionService: DGWorkflowExecutionService
+) : BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput> {
+
+    private val log = LoggerFactory.getLogger(BluePrintWorkflowExecutionServiceImpl::class.java)!!
+
+    override suspend fun executeBluePrintWorkflow(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                                  executionServiceInput: ExecutionServiceInput,
+                                                  properties: MutableMap<String, Any>): ExecutionServiceOutput {
+
+        val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
+
+        val workflowName = executionServiceInput.actionIdentifiers.actionName
+
+        // Get the DG Node Template
+        val nodeTemplateName = bluePrintContext.workflowFirstStepNodeTemplate(workflowName)
+
+        val derivedFrom = bluePrintContext.nodeTemplateNodeType(nodeTemplateName).derivedFrom
+
+        log.info("Executing workflow($workflowName) NodeTemplate($nodeTemplateName), derived from($derivedFrom)")
+
+        val executionServiceOutput: ExecutionServiceOutput = when {
+            derivedFrom.startsWith(BluePrintConstants.MODEL_TYPE_NODE_COMPONENT, true) -> {
+                componentWorkflowExecutionService
+                        .executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, properties)
+            }
+            derivedFrom.startsWith(BluePrintConstants.MODEL_TYPE_NODE_DG, true) -> {
+                dgWorkflowExecutionService
+                        .executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, properties)
+            }
+            else -> {
+                throw BluePrintProcessorException("couldn't execute workflow($workflowName) step mapped " +
+                        "to node template($nodeTemplateName) derived from($derivedFrom)")
+            }
+        }
+
+        executionServiceOutput.commonHeader = executionServiceInput.commonHeader
+        executionServiceOutput.actionIdentifiers = executionServiceInput.actionIdentifiers
+        // TODO("Populate Response Payload and status")
+        return executionServiceOutput
+    }
+
+}
\ No newline at end of file
index dfa22f6..fd7ec45 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,7 +36,7 @@ interface BlueprintSvcLogicService : SvcLogicServiceBase {
 
     fun unRegisterExecutors(name: String)
 
-    fun execute(graph: SvcLogicGraph, bluePrintRuntimeService: BluePrintRuntimeService<*>, input: Any): Any
+    suspend fun execute(graph: SvcLogicGraph, bluePrintRuntimeService: BluePrintRuntimeService<*>, input: Any): Any
 
     @Deprecated("Populate Graph Dynamically from Blueprints, No need to get from Database Store ")
     override fun getStore(): SvcLogicStore {
@@ -87,7 +88,8 @@ class DefaultBlueprintSvcLogicService : BlueprintSvcLogicService {
         }
     }
 
-    override fun execute(graph: SvcLogicGraph, bluePrintRuntimeService: BluePrintRuntimeService<*>, input: Any): Any {
+    override suspend fun execute(graph: SvcLogicGraph, bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                 input: Any): Any {
         //Initialise BlueprintSvcLogic Context with Blueprint Runtime Service and Input Request
         val blueprintSvcLogicContext = BlueprintSvcLogicContext()
         blueprintSvcLogicContext.setBluePrintRuntimeService(bluePrintRuntimeService)
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/ComponentWorkflowExecutionService.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/ComponentWorkflowExecutionService.kt
new file mode 100644 (file)
index 0000000..76d0c46
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.services.workflow
+
+
+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.interfaces.BluePrintWorkflowExecutionService
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
+import org.springframework.stereotype.Service
+
+@Service("componentWorkflowExecutionService")
+open class ComponentWorkflowExecutionService(private val nodeTemplateExecutionService: NodeTemplateExecutionService)
+    : BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput> {
+
+    override suspend fun executeBluePrintWorkflow(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                                  executionServiceInput: ExecutionServiceInput,
+                                                  properties: MutableMap<String, Any>): ExecutionServiceOutput {
+
+        val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
+
+        val workflowName = executionServiceInput.actionIdentifiers.actionName
+
+        // Get the DG Node Template
+        val nodeTemplateName = bluePrintContext.workflowFirstStepNodeTemplate(workflowName)
+
+        // Assign Workflow inputs
+        val input = executionServiceInput.payload.get("$workflowName-request")
+        bluePrintRuntimeService.assignWorkflowInputs(workflowName, input)
+
+        return nodeTemplateExecutionService.executeNodeTemplate(bluePrintRuntimeService,
+                nodeTemplateName, executionServiceInput)
+    }
+
+}
\ No newline at end of file
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,26 +20,22 @@ package org.onap.ccsdk.apps.blueprintsprocessor.services.workflow
 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.blueprintsprocessor.services.workflow.utils.SvcGraphUtils
+import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintWorkflowExecutionService
 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
 import org.slf4j.LoggerFactory
 import org.springframework.stereotype.Service
 import java.io.File
 
 
-interface BlueprintDGExecutionService {
+@Service("dgWorkflowExecutionService")
+open class DGWorkflowExecutionService(private val blueprintSvcLogicService: BlueprintSvcLogicService)
+    : BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput> {
 
-    fun executeDirectedGraph(bluePrintRuntimeService: BluePrintRuntimeService<*>,
-                             executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput
+    private val log = LoggerFactory.getLogger(DGWorkflowExecutionService::class.java)
 
-}
-
-@Service
-class DefaultBlueprintDGExecutionService(private val blueprintSvcLogicService: BlueprintSvcLogicService) : BlueprintDGExecutionService {
-
-    private val log = LoggerFactory.getLogger(DefaultBlueprintDGExecutionService::class.java)
-
-    override fun executeDirectedGraph(bluePrintRuntimeService: BluePrintRuntimeService<*>,
-                                      executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
+    override suspend fun executeBluePrintWorkflow(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                                  executionServiceInput: ExecutionServiceInput,
+                                                  properties: MutableMap<String, Any>): ExecutionServiceOutput {
 
         val bluePrintContext = bluePrintRuntimeService.bluePrintContext()
 
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/NodeTemplateExecutionService.kt
new file mode 100644 (file)
index 0000000..6ce4753
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.services.workflow
+
+import com.fasterxml.jackson.databind.JsonNode
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+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.blueprintsprocessor.services.execution.AbstractComponentFunction
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.apps.controllerblueprints.core.asJsonNode
+import org.onap.ccsdk.apps.controllerblueprints.core.putJsonElement
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
+import org.slf4j.LoggerFactory
+import org.springframework.context.ApplicationContext
+import org.springframework.stereotype.Service
+
+@Service
+open class NodeTemplateExecutionService(private val applicationContext: ApplicationContext) {
+
+    private val log = LoggerFactory.getLogger(NodeTemplateExecutionService::class.java)!!
+
+    suspend fun executeNodeTemplate(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
+                                    executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput {
+        // Get the Blueprint Context
+        val blueprintContext = bluePrintRuntimeService.bluePrintContext()
+        // Get the Component Name, NodeTemplate type is mapped to Component Name
+        val componentName = blueprintContext.nodeTemplateByName(nodeTemplateName).type
+
+        val interfaceName = blueprintContext.nodeTemplateFirstInterfaceName(nodeTemplateName)
+
+        val operationName = blueprintContext.nodeTemplateFirstInterfaceFirstOperationName(nodeTemplateName)
+
+        log.info("executing node template($nodeTemplateName) component($componentName) " +
+                "interface($interfaceName) operation($operationName)")
+
+        // Get the Component Instance
+        val plugin = applicationContext.getBean(componentName, AbstractComponentFunction::class.java)
+        // Set the Blueprint Service
+        plugin.bluePrintRuntimeService = bluePrintRuntimeService
+        plugin.stepName = nodeTemplateName
+
+        // Populate Step Meta Data
+        val stepInputs: MutableMap<String, JsonNode> = hashMapOf()
+        stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, nodeTemplateName)
+        stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, interfaceName)
+        stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, operationName)
+
+        plugin.bluePrintRuntimeService.put("$nodeTemplateName-step-inputs", stepInputs.asJsonNode())
+
+        // Get the Request from the Context and Set to the Function Input and Invoke the function
+        return withContext(Dispatchers.Default) {
+            plugin.apply(executionServiceInput)
+        }
+    }
+
+}
\ No newline at end of file
index 7a59a0a..1e856b6 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.ccsdk.apps.blueprintsprocessor.services.workflow.executor
 
-import com.fasterxml.jackson.databind.JsonNode
-import kotlinx.coroutines.async
-import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.runBlocking
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
-import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.AbstractComponentFunction
 import org.onap.ccsdk.apps.blueprintsprocessor.services.workflow.BlueprintSvcLogicContext
-import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
-import org.onap.ccsdk.apps.controllerblueprints.core.asJsonNode
-import org.onap.ccsdk.apps.controllerblueprints.core.putJsonElement
+import org.onap.ccsdk.apps.blueprintsprocessor.services.workflow.NodeTemplateExecutionService
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext
 import org.onap.ccsdk.sli.core.sli.SvcLogicException
 import org.onap.ccsdk.sli.core.sli.SvcLogicNode
@@ -33,33 +28,17 @@ import org.onap.ccsdk.sli.core.sli.provider.base.ExecuteNodeExecutor
 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicExpressionResolver
 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase
 import org.slf4j.LoggerFactory
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.context.ApplicationContext
 import org.springframework.stereotype.Service
 
 @Service
-open class ComponentExecuteNodeExecutor : ExecuteNodeExecutor() {
+open class ComponentExecuteNodeExecutor(private val nodeTemplateExecutionService: NodeTemplateExecutionService)
+    : ExecuteNodeExecutor() {
 
     private val log = LoggerFactory.getLogger(ComponentExecuteNodeExecutor::class.java)
 
-    @Autowired
-    private lateinit var context: ApplicationContext
-
-    fun getComponentFunction(pluginName: String): AbstractComponentFunction {
-        return context.getBean(pluginName, AbstractComponentFunction::class.java)
-    }
-
     @Throws(SvcLogicException::class)
     override fun execute(svc: SvcLogicServiceBase, node: SvcLogicNode, svcLogicContext: SvcLogicContext)
             : SvcLogicNode = runBlocking {
-        coroutineScope {
-            val job = async { executeAsy(svc, node, svcLogicContext) }
-            job.await()
-        }
-    }
-
-
-    private fun executeAsy(svc: SvcLogicServiceBase, node: SvcLogicNode, svcLogicContext: SvcLogicContext): SvcLogicNode {
 
         var outValue: String
 
@@ -67,35 +46,11 @@ open class ComponentExecuteNodeExecutor : ExecuteNodeExecutor() {
 
         val nodeTemplateName = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx)
 
-        try {
-            // Get the Blueprint Context
-            val blueprintContext = ctx.getBluePrintService().bluePrintContext()
-            // Get the Component Name, NodeTemplate type is mapped to Component Name
-            val componentName = blueprintContext.nodeTemplateByName(nodeTemplateName).type
+        val executionInput = ctx.getRequest() as ExecutionServiceInput
 
-            val interfaceName = blueprintContext.nodeTemplateFirstInterfaceName(nodeTemplateName)
-
-            val operationName = blueprintContext.nodeTemplateFirstInterfaceFirstOperationName(nodeTemplateName)
-
-            log.info("executing node template($nodeTemplateName) component($componentName) interface($interfaceName) operation($operationName)")
-            // Get the Component Instance
-            val plugin = this.getComponentFunction(componentName)
-            // Set the Blueprint Service
-            plugin.bluePrintRuntimeService = ctx.getBluePrintService()
-            plugin.stepName = nodeTemplateName
-
-            val executionInput = ctx.getRequest() as ExecutionServiceInput
-
-            // Populate Step Meta Data
-            val stepInputs: MutableMap<String, JsonNode> = hashMapOf()
-            stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, nodeTemplateName)
-            stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, interfaceName)
-            stepInputs.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, operationName)
-
-            plugin.bluePrintRuntimeService.put("$nodeTemplateName-step-inputs", stepInputs.asJsonNode())
-
-            // Get the Request from the Context and Set to the Function Input and Invoke the function
-            val executionOutput = plugin.apply(executionInput)
+        try {            // Get the Request from the Context and Set to the Function Input and Invoke the function
+            val executionOutput = nodeTemplateExecutionService.executeNodeTemplate(ctx.getBluePrintService(),
+                    nodeTemplateName, executionInput)
 
             ctx.setResponse(executionOutput)
 
@@ -103,11 +58,12 @@ open class ComponentExecuteNodeExecutor : ExecuteNodeExecutor() {
             ctx.status = executionOutput.status.message
 
         } catch (e: Exception) {
-            this.log.error("Could not execute plugin($nodeTemplateName) : ", e)
+            log.error("Could not execute plugin($nodeTemplateName) : ", e)
             outValue = "failure"
             ctx.status = "failure"
         }
 
-        return this.getNextNode(node, outValue)
+        getNextNode(node, outValue)
     }
+
 }
\ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BluePrintWorkflowExecutionServiceImplTest.kt b/ms/blueprintsprocessor/modules/services/workflow-service/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/services/workflow/BluePrintWorkflowExecutionServiceImplTest.kt
new file mode 100644 (file)
index 0000000..7ac9bc3
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.services.workflow
+
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+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.interfaces.BluePrintWorkflowExecutionService
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit4.SpringRunner
+
+
+@RunWith(SpringRunner::class)
+@ContextConfiguration(classes = [WorkflowServiceConfiguration::class])
+class BluePrintWorkflowExecutionServiceImplTest {
+
+    @Autowired
+    lateinit var bluePrintWorkflowExecutionService: BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput>
+
+    @Test
+    fun testBluePrintWorkflowExecutionService() {
+
+        val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
+                "./../../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+
+        val executionServiceInput = JacksonUtils.readValueFromClassPathFile("execution-input/resource-assignment-input.json",
+                ExecutionServiceInput::class.java)!!
+
+        runBlocking {
+            bluePrintWorkflowExecutionService.executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput,
+                    hashMapOf())
+        }
+    }
+
+}
index 6184162..b374e7d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +17,7 @@
 
 package org.onap.ccsdk.apps.blueprintsprocessor.services.workflow
 
+import kotlinx.coroutines.runBlocking
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
@@ -41,7 +43,7 @@ class BlueprintServiceLogicTest {
     lateinit var applicationContext: ApplicationContext
 
     @Autowired
-    lateinit var blueprintDGExecutionService: BlueprintDGExecutionService
+    lateinit var dgWorkflowExecutionService: DGWorkflowExecutionService
 
     @Test
     fun testExecuteGraphWithSingleComponent() {
@@ -51,8 +53,10 @@ class BlueprintServiceLogicTest {
 
         val executionServiceInput = JacksonUtils.readValueFromClassPathFile("execution-input/resource-assignment-input.json", ExecutionServiceInput::class.java)!!
 
+        runBlocking {
+            dgWorkflowExecutionService.executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, mutableMapOf())
+        }
 
-        blueprintDGExecutionService.executeDirectedGraph(bluePrintRuntimeService, executionServiceInput)
 
     }
 
@@ -64,7 +68,9 @@ class BlueprintServiceLogicTest {
 
         val executionServiceInput = JacksonUtils.readValueFromClassPathFile("execution-input/assign-activate-input.json", ExecutionServiceInput::class.java)!!
 
-        blueprintDGExecutionService.executeDirectedGraph(bluePrintRuntimeService, executionServiceInput)
+        runBlocking {
+            dgWorkflowExecutionService.executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, mutableMapOf())
+        }
 
     }
 
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2019 IBM.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +17,7 @@
 
 package org.onap.ccsdk.apps.blueprintsprocessor.services.workflow
 
+import kotlinx.coroutines.runBlocking
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
@@ -29,12 +31,12 @@ import org.springframework.test.context.junit4.SpringRunner
 
 @RunWith(SpringRunner::class)
 @ContextConfiguration(classes = [WorkflowServiceConfiguration::class, ComponentExecuteNodeExecutor::class])
-class BlueprintDGExecutionServiceTest {
+class DGWorkflowExecutionServiceTest {
 
     private val log = LoggerFactory.getLogger(BlueprintServiceLogicTest::class.java)
 
     @Autowired
-    lateinit var blueprintDGExecutionService: BlueprintDGExecutionService
+    lateinit var dgWorkflowExecutionService: DGWorkflowExecutionService
 
 
     @Test
@@ -45,7 +47,9 @@ class BlueprintDGExecutionServiceTest {
 
         val executionServiceInput = JacksonUtils.readValueFromClassPathFile("execution-input/resource-assignment-input.json", ExecutionServiceInput::class.java)!!
 
-        blueprintDGExecutionService.executeDirectedGraph(bluePrintRuntimeService, executionServiceInput)
+        runBlocking {
+            dgWorkflowExecutionService.executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, mutableMapOf())
+        }
 
     }
 
index 7d98c42..462935d 100644 (file)
@@ -50,6 +50,10 @@ fun MutableMap<String, *>.asJsonNode(): JsonNode {
     return JacksonUtils.jsonNodeFromObject(this)
 }
 
+fun MutableMap<String, *>.asObjectNode(): ObjectNode {
+    return JacksonUtils.objectNodeFromObject(this)
+}
+
 fun format(message: String, vararg args: Any?): String {
     if (args != null && args.isNotEmpty()) {
         return MessageFormatter.arrayFormat(message, args).message
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/interfaces/BluePrintWorkflowExecutionService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/interfaces/BluePrintWorkflowExecutionService.kt
new file mode 100644 (file)
index 0000000..c536aef
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.controllerblueprints.core.interfaces
+
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
+
+interface BluePrintWorkflowExecutionService<Input, Output> {
+
+    suspend fun executeBluePrintWorkflow(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                         executionServiceInput: Input,
+                                         properties: MutableMap<String, Any> = hashMapOf()): Output
+}
\ No newline at end of file