6de22825b7c2d88fe73d233b0f28181535a72cdb
[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.util.ArrayList;
26 import java.util.List;
27 import org.camunda.bpm.engine.RepositoryService;
28 import org.camunda.bpm.engine.delegate.DelegateExecution;
29 import org.camunda.bpm.engine.delegate.ExecutionListener;
30 import org.camunda.bpm.engine.impl.bpmn.parser.AbstractBpmnParseListener;
31 import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseListener;
32 import org.camunda.bpm.engine.impl.cfg.AbstractProcessEnginePlugin;
33 import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
34 import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity;
35 import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
36 import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
37 import org.camunda.bpm.engine.impl.pvm.process.TransitionImpl;
38 import org.camunda.bpm.engine.impl.util.xml.Element;
39 import org.camunda.bpm.engine.impl.variable.VariableDeclaration;
40 import org.onap.logging.ref.slf4j.ONAPLogConstants;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.slf4j.MDC;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.stereotype.Component;
46
47
48
49 /**
50  * Plugin for MSO logging and URN mapping.
51  */
52 @Component
53 public class LoggingAndURNMappingPlugin extends AbstractProcessEnginePlugin {
54
55     public static final String SERVICE_INSTANCE_ID = "ServiceInstanceId";
56     public static final String SERVICE_NAME = "ServiceName";
57
58     @Autowired
59     private LoggingParseListener loggingParseListener;
60
61     @Override
62     public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
63         List<BpmnParseListener> preParseListeners = processEngineConfiguration.getCustomPreBPMNParseListeners();
64         if (preParseListeners == null) {
65             preParseListeners = new ArrayList<>();
66             processEngineConfiguration.setCustomPreBPMNParseListeners(preParseListeners);
67         }
68         preParseListeners.add(loggingParseListener);
69     }
70
71     /**
72      * Called when a process flow is parsed so we can inject listeners.
73      */
74     @Component
75     public class LoggingParseListener extends AbstractBpmnParseListener {
76
77
78         private void injectLogExecutionListener(ActivityImpl activity) {
79             activity.addListener(ExecutionListener.EVENTNAME_END, new LoggingExecutionListener("END"));
80
81             activity.addListener(ExecutionListener.EVENTNAME_START, new LoggingExecutionListener("START"));
82
83             activity.addListener(ExecutionListener.EVENTNAME_TAKE, new LoggingExecutionListener("TAKE"));
84         }
85
86         @Override
87         public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) {}
88
89         @Override
90         public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {
91             // Inject these listeners only on the main start event for the flow, not on any embedded subflow start
92             // events
93
94             injectLogExecutionListener(startEventActivity);
95         }
96
97         @Override
98         public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
99             injectLogExecutionListener(activity);
100         }
101
102         @Override
103         public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
104             injectLogExecutionListener(activity);
105         }
106
107         @Override
108         public void parseInclusiveGateway(Element inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
109             injectLogExecutionListener(activity);
110         }
111
112         @Override
113         public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
114             injectLogExecutionListener(activity);
115         }
116
117         @Override
118         public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
119             injectLogExecutionListener(activity);
120         }
121
122         @Override
123         public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
124             injectLogExecutionListener(activity);
125         }
126
127         @Override
128         public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity) {
129             injectLogExecutionListener(activity);
130         }
131
132         @Override
133         public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
134             injectLogExecutionListener(activity);
135         }
136
137         @Override
138         public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
139             injectLogExecutionListener(activity);
140         }
141
142         @Override
143         public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity) {
144             injectLogExecutionListener(activity);
145         }
146
147         @Override
148         public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting,
149                 ActivityImpl timerActivity) {
150             injectLogExecutionListener(timerActivity);
151         }
152
153         @Override
154         public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting,
155                 ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
156             injectLogExecutionListener(activity);
157         }
158
159         @Override
160         public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity) {
161             injectLogExecutionListener(activity);
162         }
163
164         @Override
165         public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity) {
166             injectLogExecutionListener(activity);
167         }
168
169         @Override
170         public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration,
171                 ActivityImpl activity) {
172             injectLogExecutionListener(activity);
173         }
174
175         @Override
176         public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
177             // injectLogExecutionListener(activity);
178         }
179
180         @Override
181         public void parseSendTask(Element sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
182             injectLogExecutionListener(activity);
183         }
184
185         @Override
186         public void parseMultiInstanceLoopCharacteristics(Element activityElement,
187                 Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
188             injectLogExecutionListener(activity);
189         }
190
191         @Override
192         public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity) {
193             injectLogExecutionListener(timerActivity);
194         }
195
196         @Override
197         public void parseRootElement(Element rootElement, List<ProcessDefinitionEntity> processDefinitions) {
198
199         }
200
201         @Override
202         public void parseReceiveTask(Element receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
203             injectLogExecutionListener(activity);
204         }
205
206         @Override
207         public void parseIntermediateSignalCatchEventDefinition(Element signalEventDefinition,
208                 ActivityImpl signalActivity) {
209             injectLogExecutionListener(signalActivity);
210         }
211
212         @Override
213         public void parseBoundarySignalEventDefinition(Element signalEventDefinition, boolean interrupting,
214                 ActivityImpl signalActivity) {
215             injectLogExecutionListener(signalActivity);
216         }
217
218         @Override
219         public void parseEventBasedGateway(Element eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
220             injectLogExecutionListener(activity);
221         }
222
223         @Override
224         public void parseTransaction(Element transactionElement, ScopeImpl scope, ActivityImpl activity) {
225             injectLogExecutionListener(activity);
226         }
227
228         @Override
229         public void parseCompensateEventDefinition(Element compensateEventDefinition,
230                 ActivityImpl compensationActivity) {
231             injectLogExecutionListener(compensationActivity);
232         }
233
234         @Override
235         public void parseIntermediateThrowEvent(Element intermediateEventElement, ScopeImpl scope,
236                 ActivityImpl activity) {
237             injectLogExecutionListener(activity);
238         }
239
240         @Override
241         public void parseIntermediateCatchEvent(Element intermediateEventElement, ScopeImpl scope,
242                 ActivityImpl activity) {
243             injectLogExecutionListener(activity);
244         }
245
246         @Override
247         public void parseBoundaryEvent(Element boundaryEventElement, ScopeImpl scopeElement,
248                 ActivityImpl nestedActivity) {
249             injectLogExecutionListener(nestedActivity);
250         }
251
252         @Override
253         public void parseIntermediateMessageCatchEventDefinition(Element messageEventDefinition,
254                 ActivityImpl nestedActivity) {
255             injectLogExecutionListener(nestedActivity);
256         }
257
258         @Override
259         public void parseBoundaryMessageEventDefinition(Element element, boolean interrupting,
260                 ActivityImpl messageActivity) {
261             injectLogExecutionListener(messageActivity);
262         }
263     }
264
265     /**
266      * Logs details about the current activity.
267      */
268     public class LoggingExecutionListener implements ExecutionListener {
269         private final Logger logger = LoggerFactory.getLogger(LoggingExecutionListener.class);
270
271         private String event;
272
273         public LoggingExecutionListener() {
274             this.event = "";
275         }
276
277         public LoggingExecutionListener(String event) {
278             this.event = event;
279         }
280
281         public String getEvent() {
282             return event;
283         }
284
285         @Override
286         public void notify(DelegateExecution execution) throws Exception {
287             // required for legacy groovy processing in camunda
288             execution.setVariable("isDebugLogEnabled", "true");
289             if (!isBlank(execution.getCurrentActivityName())) {
290                 try {
291
292                     String id = execution.getId();
293                     if (id != null) {
294                         RepositoryService repositoryService =
295                                 execution.getProcessEngineServices().getRepositoryService();
296                         String processName = repositoryService.createProcessDefinitionQuery()
297                                 .processDefinitionId(execution.getProcessDefinitionId()).singleResult().getName();
298
299
300                         String requestId = (String) execution.getVariable("mso-request-id");
301                         String svcid = (String) execution.getVariable("mso-service-instance-id");
302                         try {
303                             MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, requestId);
304                             MDC.put(SERVICE_INSTANCE_ID, svcid);
305                             MDC.put(SERVICE_NAME, processName);
306                         } catch (Exception e) {
307                             logger.error("Error trying to add variables to MDC", e);
308                         }
309                     }
310                 } catch (Exception e) {
311                     logger.error("Exception occurred", e);
312                 }
313             }
314         }
315
316         private boolean isBlank(Object object) {
317             return object == null || "".equals(object.toString().trim());
318         }
319     }
320 }