296ab64df365b48ae96657bd16e091c844cb0001
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.core.plugins;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.Properties;
34 import java.util.concurrent.ConcurrentHashMap;
35 import org.camunda.bpm.engine.RepositoryService;
36 import org.camunda.bpm.engine.delegate.DelegateExecution;
37 import org.camunda.bpm.engine.delegate.ExecutionListener;
38 import org.camunda.bpm.engine.impl.bpmn.parser.AbstractBpmnParseListener;
39 import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseListener;
40 import org.camunda.bpm.engine.impl.cfg.AbstractProcessEnginePlugin;
41 import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
42 import org.camunda.bpm.engine.impl.context.Context;
43 import org.camunda.bpm.engine.impl.interceptor.Command;
44 import org.camunda.bpm.engine.impl.interceptor.CommandContext;
45 import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity;
46 import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
47 import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
48 import org.camunda.bpm.engine.impl.pvm.process.TransitionImpl;
49 import org.camunda.bpm.engine.impl.util.xml.Element;
50 import org.camunda.bpm.engine.impl.variable.VariableDeclaration;
51 import org.camunda.bpm.model.bpmn.impl.instance.FlowNodeImpl;
52 import org.camunda.bpm.model.bpmn.instance.EndEvent;
53 import org.camunda.bpm.model.bpmn.instance.FlowNode;
54 import org.camunda.bpm.model.bpmn.instance.StartEvent;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.core.env.AbstractEnvironment;
59 import org.springframework.core.env.Environment;
60 import org.springframework.core.env.MapPropertySource;
61 import org.springframework.core.env.PropertySource;
62 import org.springframework.stereotype.Component;
63
64
65
66 /**
67  * Plugin for MSO logging and URN mapping.
68  */
69 @Component
70 public class LoggingAndURNMappingPlugin extends AbstractProcessEnginePlugin {
71
72     @Autowired
73     private LoggingParseListener loggingParseListener;
74
75     @Override
76     public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
77         List<BpmnParseListener> preParseListeners = processEngineConfiguration.getCustomPreBPMNParseListeners();
78         if (preParseListeners == null) {
79             preParseListeners = new ArrayList<>();
80             processEngineConfiguration.setCustomPreBPMNParseListeners(preParseListeners);
81         }
82         preParseListeners.add(loggingParseListener);
83     }
84
85     /**
86      * Called when a process flow is parsed so we can inject listeners.
87      */
88     @Component
89     public class LoggingParseListener extends AbstractBpmnParseListener {
90
91
92         private void injectLogExecutionListener(ActivityImpl activity) {
93             activity.addListener(ExecutionListener.EVENTNAME_END, new LoggingExecutionListener("END"));
94
95             activity.addListener(ExecutionListener.EVENTNAME_START, new LoggingExecutionListener("START"));
96
97             activity.addListener(ExecutionListener.EVENTNAME_TAKE, new LoggingExecutionListener("TAKE"));
98         }
99
100         @Override
101         public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) {}
102
103         @Override
104         public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {
105             // Inject these listeners only on the main start event for the flow, not on any embedded subflow start
106             // events
107
108             injectLogExecutionListener(startEventActivity);
109         }
110
111         @Override
112         public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
113             injectLogExecutionListener(activity);
114         }
115
116         @Override
117         public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
118             injectLogExecutionListener(activity);
119         }
120
121         @Override
122         public void parseInclusiveGateway(Element inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
123             injectLogExecutionListener(activity);
124         }
125
126         @Override
127         public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
128             injectLogExecutionListener(activity);
129         }
130
131         @Override
132         public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
133             injectLogExecutionListener(activity);
134         }
135
136         @Override
137         public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
138             injectLogExecutionListener(activity);
139         }
140
141         @Override
142         public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity) {
143             injectLogExecutionListener(activity);
144         }
145
146         @Override
147         public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
148             injectLogExecutionListener(activity);
149         }
150
151         @Override
152         public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
153             injectLogExecutionListener(activity);
154         }
155
156         @Override
157         public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity) {
158             injectLogExecutionListener(activity);
159         }
160
161         @Override
162         public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting,
163                 ActivityImpl timerActivity) {
164             injectLogExecutionListener(timerActivity);
165         }
166
167         @Override
168         public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting,
169                 ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
170             injectLogExecutionListener(activity);
171         }
172
173         @Override
174         public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity) {
175             injectLogExecutionListener(activity);
176         }
177
178         @Override
179         public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity) {
180             injectLogExecutionListener(activity);
181         }
182
183         @Override
184         public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration,
185                 ActivityImpl activity) {
186             injectLogExecutionListener(activity);
187         }
188
189         @Override
190         public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
191             // injectLogExecutionListener(activity);
192         }
193
194         @Override
195         public void parseSendTask(Element sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
196             injectLogExecutionListener(activity);
197         }
198
199         @Override
200         public void parseMultiInstanceLoopCharacteristics(Element activityElement,
201                 Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
202             injectLogExecutionListener(activity);
203         }
204
205         @Override
206         public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity) {
207             injectLogExecutionListener(timerActivity);
208         }
209
210         @Override
211         public void parseRootElement(Element rootElement, List<ProcessDefinitionEntity> processDefinitions) {
212
213         }
214
215         @Override
216         public void parseReceiveTask(Element receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
217             injectLogExecutionListener(activity);
218         }
219
220         @Override
221         public void parseIntermediateSignalCatchEventDefinition(Element signalEventDefinition,
222                 ActivityImpl signalActivity) {
223             injectLogExecutionListener(signalActivity);
224         }
225
226         @Override
227         public void parseBoundarySignalEventDefinition(Element signalEventDefinition, boolean interrupting,
228                 ActivityImpl signalActivity) {
229             injectLogExecutionListener(signalActivity);
230         }
231
232         @Override
233         public void parseEventBasedGateway(Element eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
234             injectLogExecutionListener(activity);
235         }
236
237         @Override
238         public void parseTransaction(Element transactionElement, ScopeImpl scope, ActivityImpl activity) {
239             injectLogExecutionListener(activity);
240         }
241
242         @Override
243         public void parseCompensateEventDefinition(Element compensateEventDefinition,
244                 ActivityImpl compensationActivity) {
245             injectLogExecutionListener(compensationActivity);
246         }
247
248         @Override
249         public void parseIntermediateThrowEvent(Element intermediateEventElement, ScopeImpl scope,
250                 ActivityImpl activity) {
251             injectLogExecutionListener(activity);
252         }
253
254         @Override
255         public void parseIntermediateCatchEvent(Element intermediateEventElement, ScopeImpl scope,
256                 ActivityImpl activity) {
257             injectLogExecutionListener(activity);
258         }
259
260         @Override
261         public void parseBoundaryEvent(Element boundaryEventElement, ScopeImpl scopeElement,
262                 ActivityImpl nestedActivity) {
263             injectLogExecutionListener(nestedActivity);
264         }
265
266         @Override
267         public void parseIntermediateMessageCatchEventDefinition(Element messageEventDefinition,
268                 ActivityImpl nestedActivity) {
269             injectLogExecutionListener(nestedActivity);
270         }
271
272         @Override
273         public void parseBoundaryMessageEventDefinition(Element element, boolean interrupting,
274                 ActivityImpl messageActivity) {
275             injectLogExecutionListener(messageActivity);
276         }
277     }
278
279     /**
280      * Logs details about the current activity.
281      */
282     public class LoggingExecutionListener implements ExecutionListener {
283         private final Logger logger = LoggerFactory.getLogger(LoggingExecutionListener.class);
284
285         private String event;
286
287         public LoggingExecutionListener() {
288             this.event = "";
289         }
290
291         public LoggingExecutionListener(String event) {
292             this.event = event;
293         }
294
295         public String getEvent() {
296             return event;
297         }
298
299         @Override
300         public void notify(DelegateExecution execution) throws Exception {
301             // required for legacy groovy processing in camunda
302             execution.setVariable("isDebugLogEnabled", "true");
303             if (!isBlank(execution.getCurrentActivityName())) {
304                 try {
305
306                     String id = execution.getId();
307                     if (id != null) {
308                         RepositoryService repositoryService =
309                                 execution.getProcessEngineServices().getRepositoryService();
310                         String processName = repositoryService.createProcessDefinitionQuery()
311                                 .processDefinitionId(execution.getProcessDefinitionId()).singleResult().getName();
312
313
314                         String requestId = (String) execution.getVariable("mso-request-id");
315                         String svcid = (String) execution.getVariable("mso-service-instance-id");
316                     }
317                 } catch (Exception e) {
318                     logger.error("Exception occurred", e);
319                 }
320             }
321         }
322
323         private boolean isBlank(Object object) {
324             return object == null || "".equals(object.toString().trim());
325         }
326     }
327 }