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