Formatting Code base with ktlint
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / services / workflow-service / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / services / workflow / BlueprintSvcLogicService.kt
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2019 IBM.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.onap.ccsdk.cds.blueprintsprocessor.services.workflow
19
20 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
21 import org.onap.ccsdk.sli.core.sli.ExitNodeException
22 import org.onap.ccsdk.sli.core.sli.SvcLogicContext
23 import org.onap.ccsdk.sli.core.sli.SvcLogicException
24 import org.onap.ccsdk.sli.core.sli.SvcLogicGraph
25 import org.onap.ccsdk.sli.core.sli.SvcLogicNode
26 import org.onap.ccsdk.sli.core.sli.SvcLogicStore
27 import org.onap.ccsdk.sli.core.sli.provider.base.AbstractSvcLogicNodeExecutor
28 import org.onap.ccsdk.sli.core.sli.provider.base.BlockNodeExecutor
29 import org.onap.ccsdk.sli.core.sli.provider.base.BreakNodeExecutor
30 import org.onap.ccsdk.sli.core.sli.provider.base.ExecuteNodeExecutor
31 import org.onap.ccsdk.sli.core.sli.provider.base.ExitNodeExecutor
32 import org.onap.ccsdk.sli.core.sli.provider.base.ReturnNodeExecutor
33 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase
34 import org.slf4j.LoggerFactory
35 import org.slf4j.MDC
36 import org.springframework.beans.factory.annotation.Autowired
37 import org.springframework.context.ApplicationContext
38 import org.springframework.stereotype.Service
39 import java.util.Properties
40 import javax.annotation.PostConstruct
41
42 interface BlueprintSvcLogicService : SvcLogicServiceBase {
43
44     fun registerDefaultExecutors()
45
46     fun registerExecutors(name: String, svcLogicNodeExecutor: AbstractSvcLogicNodeExecutor)
47
48     fun unRegisterExecutors(name: String)
49
50     suspend fun execute(graph: SvcLogicGraph, bluePrintRuntimeService: BluePrintRuntimeService<*>, input: Any): Any
51
52     @Deprecated("Populate Graph Dynamically from Blueprints, No need to get from Database Store ")
53     override fun getStore(): SvcLogicStore {
54         TODO("not implemented")
55     }
56
57     @Deprecated("Not used in Micro service Implementation")
58     override fun hasGraph(module: String, rpc: String, version: String?, mode: String): Boolean {
59         TODO("not implemented")
60     }
61
62     @Deprecated("Not used in Micro service Implementation")
63     override fun execute(p0: String?, p1: String?, p2: String?, p3: String?, p4: Properties?): Properties {
64         TODO("not implemented")
65     }
66 }
67
68 @Service
69 class DefaultBlueprintSvcLogicService : BlueprintSvcLogicService {
70
71     private val log = LoggerFactory.getLogger(DefaultBlueprintSvcLogicService::class.java)
72
73     private val nodeExecutors: MutableMap<String, AbstractSvcLogicNodeExecutor> = hashMapOf()
74
75     @Autowired
76     private lateinit var context: ApplicationContext
77
78     @PostConstruct
79     override fun registerDefaultExecutors() {
80
81         val executeNodeExecutor = context.getBean(ExecuteNodeExecutor::class.java)
82         registerExecutors("execute", executeNodeExecutor)
83         registerExecutors("block", BlockNodeExecutor())
84         registerExecutors("return", ReturnNodeExecutor())
85         registerExecutors("break", BreakNodeExecutor())
86         registerExecutors("exit", ExitNodeExecutor())
87     }
88
89     override fun registerExecutors(name: String, svcLogicNodeExecutor: AbstractSvcLogicNodeExecutor) {
90         log.debug("Registering executors($name) with type(${svcLogicNodeExecutor.javaClass}")
91         nodeExecutors[name] = svcLogicNodeExecutor
92     }
93
94     override fun unRegisterExecutors(name: String) {
95         if (nodeExecutors.containsKey(name)) {
96             log.info("UnRegistering executors($name)")
97             nodeExecutors.remove(name)
98         }
99     }
100
101     override suspend fun execute(
102         graph: SvcLogicGraph,
103         bluePrintRuntimeService: BluePrintRuntimeService<*>,
104         input: Any
105     ): Any {
106         // Initialise BlueprintSvcLogic Context with Blueprint Runtime Service and Input Request
107         val blueprintSvcLogicContext = BlueprintSvcLogicContext()
108         blueprintSvcLogicContext.setBluePrintRuntimeService(bluePrintRuntimeService)
109         blueprintSvcLogicContext.setRequest(input)
110         // Execute the Graph
111         execute(graph, blueprintSvcLogicContext)
112         // Get the Response
113         return blueprintSvcLogicContext.getResponse()
114     }
115
116     override fun executeNode(node: SvcLogicNode?, ctx: SvcLogicContext): SvcLogicNode? {
117         if (node == null) {
118             return null
119         } else {
120             if (log.isDebugEnabled) {
121                 log.debug("Executing node {}", node.nodeId)
122             }
123
124             val executor = this.nodeExecutors[node.nodeType]
125
126             if (executor != null) {
127                 log.debug("Executing node executor for node type {} - {}", node.nodeType, executor.javaClass.name)
128                 return executor.execute(this, node, ctx)
129             } else {
130                 throw SvcLogicException("Attempted to execute a node of type " + node.nodeType + ", but no executor was registered for this type")
131             }
132         }
133     }
134
135     override fun execute(graph: SvcLogicGraph, svcLogicContext: SvcLogicContext): SvcLogicContext {
136         MDC.put("currentGraph", graph.toString())
137
138         var curNode: SvcLogicNode? = graph.rootNode
139         log.info("About to execute graph {}", graph.toString())
140
141         try {
142             while (curNode != null) {
143                 MDC.put("nodeId", curNode.nodeId.toString() + " (" + curNode.nodeType + ")")
144                 log.info("About to execute node # {} ({})", curNode.nodeId, curNode.nodeType)
145                 val nextNode = this.executeNode(curNode, svcLogicContext)
146                 curNode = nextNode
147             }
148         } catch (var5: ExitNodeException) {
149             log.debug("SvcLogicServiceImpl caught ExitNodeException")
150         }
151
152         MDC.remove("nodeId")
153         MDC.remove("currentGraph")
154         return svcLogicContext
155     }
156 }