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