Support merge JSON to SvcLogicContext
[ccsdk/sli/core.git] / sli / provider-base / src / main / java / org / onap / ccsdk / sli / core / sli / provider / base / SvcLogicServiceImplBase.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  *  Modifications Copyright (C) 2018 IBM.
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.ccsdk.sli.core.sli.provider.base;
25
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Properties;
29 import org.onap.ccsdk.sli.core.sli.ExitNodeException;
30 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
31 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
33 import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
34 import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
35 import org.onap.logging.ref.slf4j.ONAPLogConstants;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.slf4j.MDC;
39
40 public class SvcLogicServiceImplBase implements SvcLogicServiceBase {
41         protected SvcLogicResolver resolver;
42     protected static final Map<String, AbstractSvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, AbstractSvcLogicNodeExecutor>() {
43         {
44             put("block", new BlockNodeExecutor());
45             put("call", new CallNodeExecutor());
46             put("configure", new ConfigureNodeExecutor());
47             put("delete", new DeleteNodeExecutor());
48             put("execute", new ExecuteNodeExecutor());
49             put("exists", new ExistsNodeExecutor());
50             put("for", new ForNodeExecutor());
51             put("get-resource", new GetResourceNodeExecutor());
52             put("is-available", new IsAvailableNodeExecutor());
53             put("notify", new NotifyNodeExecutor());
54             put("record", new RecordNodeExecutor());
55             put("release", new ReleaseNodeExecutor());
56             put("reserve", new ReserveNodeExecutor());
57             put("return", new ReturnNodeExecutor());
58             put("save", new SaveNodeExecutor());
59             put("set", new SetNodeExecutor());
60             put("switch", new SwitchNodeExecutor());
61             put("update", new UpdateNodeExecutor());
62             put("break", new BreakNodeExecutor());
63             put("while", new WhileNodeExecutor());
64             put("exit", new ExitNodeExecutor());
65         }
66     };
67
68     private static final Logger LOG = LoggerFactory.getLogger(SvcLogicServiceImplBase.class);
69     protected HashMap<String, AbstractSvcLogicNodeExecutor> nodeExecutors = null;
70     protected Properties properties;
71     protected SvcLogicStore store;
72     protected static final String CURRENT_GRAPH="currentGraph";
73
74     public SvcLogicServiceImplBase(SvcLogicStore store, SvcLogicResolver resolver) {
75         this.store = store;
76         this.resolver = resolver;
77     }
78
79     protected void registerExecutors() {
80         for (String nodeType : BUILTIN_NODES.keySet()) {
81             registerExecutor(nodeType, BUILTIN_NODES.get(nodeType));
82         }
83     }
84
85     public void registerExecutor(String nodeName, AbstractSvcLogicNodeExecutor executor) {
86         if (nodeExecutors == null) {
87             nodeExecutors = new HashMap<>();
88         }
89         executor.setResolver(resolver);
90         nodeExecutors.put(nodeName, executor);
91     }
92
93     public void unregisterExecutor(String nodeName) {
94         nodeExecutors.remove(nodeName);
95     }
96
97     public SvcLogicContext execute(SvcLogicGraph graph, SvcLogicContext ctx) throws SvcLogicException {
98         if (nodeExecutors == null) {
99             registerExecutors();
100         }
101
102         MDC.put(CURRENT_GRAPH, graph.toString());
103
104         SvcLogicNode curNode = graph.getRootNode();
105         LOG.info("About to execute graph {}", graph.toString());
106                 try {
107                         while (curNode != null) {
108                                 SvcLogicNode nextNode = executeNode(curNode, ctx);
109                                 curNode = nextNode;
110                         }
111                 } catch (ExitNodeException e) {
112             LOG.debug("SvcLogicServiceImpl caught ExitNodeException");
113                 }
114         MDC.remove("nodeId");
115         MDC.remove(CURRENT_GRAPH);
116
117         return (ctx);
118     }
119     
120         public SvcLogicNode executeNode(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
121         if (node == null) {
122             return (null);
123         }
124
125                 LOG.info("About to execute node #{} {} node in graph {}", node.getNodeId(), node.getNodeType(), node.getGraph().toString());
126
127         AbstractSvcLogicNodeExecutor executor = nodeExecutors.get(node.getNodeType());
128
129         if (executor != null) {
130                 MDC.put("nodeId", node.getNodeId() + " (" + node.getNodeType() + ")");
131             return (executor.execute(this, node, ctx));
132         } else {
133             throw new SvcLogicException("Attempted to execute a node of type " + node.getNodeType() + ", but no executor was registered for this type");
134         }
135     }
136
137     @Override
138     public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException {
139         return (store.hasGraph(module, rpc, version, mode));
140     }
141
142     @Override
143     public Properties execute(String module, String rpc, String version, String mode, Properties props)
144             throws SvcLogicException {
145
146         SvcLogicContext ctx = new SvcLogicContext(props);
147
148         return(execute(module, rpc, version, mode, ctx).toProperties());
149     }
150
151     @Override
152     public SvcLogicContext execute(String module, String rpc, String version, String mode, SvcLogicContext ctx) throws SvcLogicException {
153         SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
154
155                 if (ctx == null) {
156                         ctx = new SvcLogicContext();
157                 }
158
159         if (graph == null) {
160             ctx.setAttribute("error-code", "401");
161             ctx.setAttribute("error-message",
162                     "No service logic found for [" + module + "," + rpc + "," + version + "," + mode + "]");
163             return (ctx);
164         }
165
166
167
168         ctx.setAttribute(CURRENT_GRAPH, graph.toString());
169         // To support legacy code we should not stop populating X-ECOMP-RequestID
170         ctx.setAttribute("X-ECOMP-RequestID", MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
171         execute(graph, ctx);
172         return (ctx);
173     }
174
175     @Override
176         public SvcLogicStore getStore() throws SvcLogicException {
177                 return this.store;
178         }
179
180 }