000c2872dbee37e1a226ab84cd8cf08c2583989c
[ccsdk/sli/core.git] / sli / provider / src / main / java / org / onap / ccsdk / sli / core / sli / provider / SvcLogicServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.core.sli.provider;
23
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Properties;
27 import org.onap.ccsdk.sli.core.dblib.DbLibService;
28 import org.onap.ccsdk.sli.core.sli.ConfigurationException;
29 import org.onap.ccsdk.sli.core.sli.MetricLogger;
30 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
31 import org.onap.ccsdk.sli.core.sli.SvcLogicDblibStore;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
33 import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
34 import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
35 import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
36 import org.onap.ccsdk.sli.core.sli.SvcLogicStoreFactory;
37 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
38 import org.osgi.framework.BundleContext;
39 import org.osgi.framework.FrameworkUtil;
40 import org.osgi.framework.InvalidSyntaxException;
41 import org.osgi.framework.ServiceEvent;
42 import org.osgi.framework.ServiceListener;
43 import org.osgi.framework.ServiceReference;
44 import org.osgi.util.tracker.ServiceTracker;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.slf4j.MDC;
48
49 public class SvcLogicServiceImpl implements SvcLogicService {
50
51     private static final Map<String, SvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, SvcLogicNodeExecutor>() {
52         {
53             put("block", new BlockNodeExecutor());
54             put("call", new CallNodeExecutor());
55             put("configure", new ConfigureNodeExecutor());
56             put("delete", new DeleteNodeExecutor());
57             put("execute", new ExecuteNodeExecutor());
58             put("exists", new ExistsNodeExecutor());
59             put("for", new ForNodeExecutor());
60             put("get-resource", new GetResourceNodeExecutor());
61             put("is-available", new IsAvailableNodeExecutor());
62             put("notify", new NotifyNodeExecutor());
63             put("record", new RecordNodeExecutor());
64             put("release", new ReleaseNodeExecutor());
65             put("reserve", new ReserveNodeExecutor());
66             put("return", new ReturnNodeExecutor());
67             put("save", new SaveNodeExecutor());
68             put("set", new SetNodeExecutor());
69             put("switch", new SwitchNodeExecutor());
70             put("update", new UpdateNodeExecutor());
71             put("break", new BreakNodeExecutor());
72             put("while", new WhileNodeExecutor());
73
74         }
75     };
76
77     private static final Logger LOG = LoggerFactory.getLogger(SvcLogicServiceImpl.class);
78     protected HashMap<String, SvcLogicNodeExecutor> nodeExecutors = null;
79     protected BundleContext bctx = null;
80     protected Properties properties;
81     protected SvcLogicStore store;
82
83     public SvcLogicServiceImpl(SvcLogicPropertiesProvider resourceProvider) throws SvcLogicException {
84         properties = resourceProvider.getProperties();
85         getStore();
86     }
87
88     public SvcLogicServiceImpl(SvcLogicPropertiesProvider resourceProvider, DbLibService dbSvc)
89             throws SvcLogicException {
90         properties = resourceProvider.getProperties();
91         store = new SvcLogicDblibStore(dbSvc);
92     }
93
94
95     protected void registerExecutors() {
96
97         LOG.info("Entered register executors");
98         for (String nodeType : BUILTIN_NODES.keySet()) {
99             LOG.info("SLI - registering node executor for node type " + nodeType);
100             registerExecutor(nodeType, BUILTIN_NODES.get(nodeType));
101         }
102         LOG.info("Done registerExecutors");
103     }
104
105     public void registerExecutor(ServiceReference sr) {
106         String nodeName = (String) sr.getProperty("nodeType");
107         if (nodeName != null) {
108
109             SvcLogicNodeExecutor executor;
110
111             try {
112                 executor = (SvcLogicNodeExecutor) bctx.getService(sr);
113             } catch (Exception e) {
114                 LOG.error("Cannot get service executor for {}", nodeName, e);
115                 return;
116             }
117             registerExecutor(nodeName, executor);
118         }
119     }
120
121     public void registerExecutor(String nodeName, SvcLogicNodeExecutor executor) {
122         if (nodeExecutors == null) {
123             nodeExecutors = new HashMap<>();
124         }
125         LOG.info("SLI - registering executor for node type {}", nodeName);
126         nodeExecutors.put(nodeName, executor);
127     }
128
129     public void unregisterExecutor(ServiceReference sr) {
130         String nodeName = (String) sr.getProperty("nodeType");
131
132         if (nodeName != null) {
133             unregisterExecutor(nodeName);
134         }
135     }
136
137     public void unregisterExecutor(String nodeName) {
138         LOG.info("SLI - unregistering executor for node type {}", nodeName);
139         nodeExecutors.remove(nodeName);
140     }
141
142     public SvcLogicContext execute(SvcLogicGraph graph, SvcLogicContext ctx) throws SvcLogicException {
143         if (nodeExecutors == null) {
144             registerExecutors();
145         }
146
147         // Set service name in MDC to reference current working directed graph
148         MDC.put(MetricLogger.SERVICE_NAME, graph.getModule() + ":" + graph.getRpc() + "/v" + graph.getVersion());
149
150         MDC.put("currentGraph", graph.toString());
151
152         SvcLogicNode curNode = graph.getRootNode();
153         LOG.info("About to execute graph {}", graph.toString());
154
155         while (curNode != null) {
156             MDC.put("nodeId", curNode.getNodeId() + " (" + curNode.getNodeType() + ")");
157             LOG.info("About to execute node # {} ({})", curNode.getNodeId(), curNode.getNodeType());
158
159             SvcLogicNode nextNode = executeNode(curNode, ctx);
160             curNode = nextNode;
161         }
162         MDC.remove("nodeId");
163         MDC.remove("currentGraph");
164
165         return (ctx);
166     }
167
168     public SvcLogicNode executeNode(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
169         if (node == null) {
170             return (null);
171         }
172
173         if (LOG.isDebugEnabled()) {
174             LOG.debug("Executing node {}", node.getNodeId());
175         }
176
177         SvcLogicNodeExecutor executor = nodeExecutors.get(node.getNodeType());
178
179         if (executor != null) {
180             LOG.debug("Executing node executor for node type {} - {}", node.getNodeType(),
181                     executor.getClass().getName());
182             return (executor.execute(this, node, ctx));
183         } else {
184             throw new SvcLogicException("Attempted to execute a node of type " + node.getNodeType() + ", but no executor was registered for this type");
185         }
186     }
187
188     @Override
189     public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException {
190         return (store.hasGraph(module, rpc, version, mode));
191     }
192
193     @Override
194     public Properties execute(String module, String rpc, String version, String mode, Properties props)
195             throws SvcLogicException {
196         return (execute(module, rpc, version, mode, props, null));
197     }
198
199     @Override
200     public Properties execute(String module, String rpc, String version, String mode, Properties props,
201             DOMDataBroker domDataBroker) throws SvcLogicException {
202         LOG.info("Fetching service logic from data store");
203         SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
204
205         if (graph == null) {
206             Properties retProps = new Properties();
207             retProps.setProperty("error-code", "401");
208             retProps.setProperty("error-message",
209                     "No service logic found for [" + module + "," + rpc + "," + version + "," + mode + "]");
210             return (retProps);
211         }
212
213         SvcLogicContext ctx = new SvcLogicContext(props);
214         ctx.setAttribute("currentGraph", graph.toString());
215         ctx.setAttribute("X-ECOMP-RequestID", MDC.get("X-ECOMP-RequestID"));
216         ctx.setDomDataBroker(domDataBroker);
217
218         execute(graph, ctx);
219
220         return (ctx.toProperties());
221     }
222
223     public SvcLogicStore getStore() throws SvcLogicException {
224         // Create and initialize SvcLogicStore object - used to access
225         // saved service logic.
226         if (store != null) {
227             return store;
228         }
229
230         try {
231             store = SvcLogicStoreFactory.getSvcLogicStore(properties);
232         } catch (Exception e) {
233             throw new ConfigurationException("Could not get service logic store", e);
234
235         }
236
237         try {
238             store.init(properties);
239         } catch (SvcLogicException e) {
240             throw new ConfigurationException("Could not get service logic store", e);
241         }
242
243         return store;
244     }
245 }