00ee6eb235aec8b5553867b8a6d94226b0c6d62f
[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         private static MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, LoggingAndURNMappingPlugin.class);
75         private static final String FSPROPKEY = "URNMapping.FileSystemLoading.Enabled";
76         
77         @Autowired
78         private LoggingParseListener loggingParseListener;
79         
80         @Override
81         public void preInit(
82                         ProcessEngineConfigurationImpl processEngineConfiguration) {
83                 List<BpmnParseListener> preParseListeners = processEngineConfiguration
84                                 .getCustomPreBPMNParseListeners();
85                 if (preParseListeners == null) {
86                         preParseListeners = new ArrayList<>();
87                         processEngineConfiguration.setCustomPreBPMNParseListeners(preParseListeners);
88                 }
89                 preParseListeners.add(loggingParseListener);
90         }
91         
92         /**
93          * Called when a process flow is parsed so we can inject listeners.
94          */
95         @Component
96         public class LoggingParseListener extends AbstractBpmnParseListener {           
97                 
98                 
99                 private void injectLogExecutionListener(ActivityImpl activity) {
100                         activity.addListener(
101                                         ExecutionListener.EVENTNAME_END,
102                                         new LoggingExecutionListener("END"));
103
104                         activity.addListener(
105                                         ExecutionListener.EVENTNAME_START,
106                                         new LoggingExecutionListener("START"));
107
108                         activity.addListener(
109                                         ExecutionListener.EVENTNAME_TAKE,
110                                         new LoggingExecutionListener("TAKE"));
111                 }
112
113                 @Override
114                 public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) {
115                 }
116
117                 @Override
118                 public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {
119                         // Inject these listeners only on the main start event for the flow, not on any embedded subflow start events                   
120
121                         injectLogExecutionListener(startEventActivity);
122                 }
123
124                 @Override
125                 public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
126                         injectLogExecutionListener(activity);
127                 }
128
129                 @Override
130                 public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
131                         injectLogExecutionListener(activity);
132                 }
133
134                 @Override
135                 public void parseInclusiveGateway(Element inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
136                         injectLogExecutionListener(activity);
137                 }
138
139                 @Override
140                 public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
141                         injectLogExecutionListener(activity);
142                 }
143
144                 @Override
145                 public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
146                         injectLogExecutionListener(activity);
147                 }
148
149                 @Override
150                 public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
151                         injectLogExecutionListener(activity);
152                 }
153
154                 @Override
155                 public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity) {
156                         injectLogExecutionListener(activity);
157                 }
158
159                 @Override
160                 public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
161                         injectLogExecutionListener(activity);
162                 }
163
164                 @Override
165                 public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
166                         injectLogExecutionListener(activity);
167                 }
168
169                 @Override
170                 public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity) {
171                         injectLogExecutionListener(activity);
172                 }
173
174                 @Override
175                 public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting, ActivityImpl timerActivity) {
176                         injectLogExecutionListener(timerActivity);
177                 }
178
179                 @Override
180                 public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting, ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
181                         injectLogExecutionListener(activity);
182                 }
183
184                 @Override
185                 public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity) {
186                         injectLogExecutionListener(activity);
187                 }
188
189                 @Override
190                 public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity) {
191                         injectLogExecutionListener(activity);
192                 }
193
194                 @Override
195                 public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) {
196                         injectLogExecutionListener(activity);
197                 }
198
199                 @Override
200                 public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
201                         //injectLogExecutionListener(activity);
202                 }
203
204                 @Override
205                 public void parseSendTask(Element sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
206                         injectLogExecutionListener(activity);
207                 }
208
209                 @Override
210                 public void parseMultiInstanceLoopCharacteristics(Element activityElement, Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
211                         injectLogExecutionListener(activity);
212                 }
213
214                 @Override
215                 public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity) {
216                         injectLogExecutionListener(timerActivity);
217                 }
218
219                 @Override
220                 public void parseRootElement(Element rootElement, List<ProcessDefinitionEntity> processDefinitions) {
221                         //injectLogExecutionListener(activity);
222                 }
223
224                 @Override
225                 public void parseReceiveTask(Element receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
226                         injectLogExecutionListener(activity);
227                 }
228
229                 @Override
230                 public void parseIntermediateSignalCatchEventDefinition(Element signalEventDefinition, ActivityImpl signalActivity) {
231                         injectLogExecutionListener(signalActivity);
232                 }
233
234                 @Override
235                 public void parseBoundarySignalEventDefinition(Element signalEventDefinition, boolean interrupting, ActivityImpl signalActivity) {
236                         injectLogExecutionListener(signalActivity);
237                 }
238
239                 @Override
240                 public void parseEventBasedGateway(Element eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
241                         injectLogExecutionListener(activity);
242                 }
243
244                 @Override
245                 public void parseTransaction(Element transactionElement, ScopeImpl scope, ActivityImpl activity) {
246                         injectLogExecutionListener(activity);
247                 }
248
249                 @Override
250                 public void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity) {
251                         injectLogExecutionListener(compensationActivity);
252                 }
253
254                 @Override
255                 public void parseIntermediateThrowEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
256                         injectLogExecutionListener(activity);
257                 }
258
259                 @Override
260                 public void parseIntermediateCatchEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
261                         injectLogExecutionListener(activity);
262                 }
263
264                 @Override
265                 public void parseBoundaryEvent(Element boundaryEventElement, ScopeImpl scopeElement, ActivityImpl nestedActivity) {
266                         injectLogExecutionListener(nestedActivity);
267                 }
268
269                 @Override
270                 public void parseIntermediateMessageCatchEventDefinition(Element messageEventDefinition, ActivityImpl nestedActivity) {
271                         injectLogExecutionListener(nestedActivity);
272                 }
273
274                 @Override
275                 public void parseBoundaryMessageEventDefinition(Element element, boolean interrupting, ActivityImpl messageActivity) {
276                         injectLogExecutionListener(messageActivity);
277                 }
278         }
279         
280         /**
281          * Logs details about the current activity.
282          */     
283         public class LoggingExecutionListener implements ExecutionListener {
284                 private final MsoLogger logger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL,LoggingExecutionListener.class); 
285
286                 private String event;
287                 
288                 public LoggingExecutionListener() {
289                         this.event = "";
290                 }
291
292                 public LoggingExecutionListener(String event) {
293                         this.event = event;
294                 }
295                 
296                 public String getEvent() {
297                         return event;
298                 }
299
300                 @Override
301                 public void notify(DelegateExecution execution) throws Exception {
302                         logger.trace("Logging for activity---------------:" + event + ":"
303                                                 + execution.getCurrentActivityName()
304                                                 + ", processDefinitionId="
305                                                 + execution.getProcessDefinitionId() + ", activtyId="
306                                                 + execution.getCurrentActivityId() + ", activtyName='"
307                                                 + execution.getCurrentActivityName() + "'"
308                                                 + ", processInstanceId="
309                                                 + execution.getProcessInstanceId() + ", businessKey="
310                                                 + execution.getProcessBusinessKey() + ", executionId="
311                                                 + execution.getId());
312                         //required for legacy groovy processing in camunda
313                         execution.setVariable("isDebugLogEnabled", "true");
314                         if (!isBlank(execution.getCurrentActivityName())) {
315                                 try {
316                                 
317                                         String id = execution.getId();
318                                         if (id != null ) {                              
319                                                 RepositoryService repositoryService = execution.getProcessEngineServices().getRepositoryService();
320                                                 String processName = repositoryService.createProcessDefinitionQuery()
321                                                   .processDefinitionId(execution.getProcessDefinitionId())
322                                                   .singleResult()
323                                                   .getName();
324                                                 
325                                                 if (execution.getBpmnModelElementInstance() instanceof StartEvent) {
326                                                         logger.debug("Starting process: " + processName);
327                                                 }
328                                                 if (execution.getBpmnModelElementInstance() instanceof EndEvent) {
329                                                         logger.debug("Ending process: " + processName);
330                                                 }
331                                                 
332                                                 String serviceName = MDC.get(MsoLogger.SERVICE_NAME);
333                                                 
334                                                 if(serviceName != null && !serviceName.contains(processName))
335                                                         MsoLogger.setServiceName( serviceName + "." + processName);
336                                                 else if(serviceName == null)
337                                                         MsoLogger.setServiceName(processName);
338                                                 
339                                                 String requestId = (String) execution.getVariable("mso-request-id");
340                                                 String svcid = (String) execution.getVariable("mso-service-instance-id");
341                                                 MsoLogger.setLogContext(requestId, svcid);                                                      
342                                         }
343                                 } catch(Exception e) {                                  
344                                         logger.error(e);
345                                 }
346                         }
347                 }
348
349                 private boolean isBlank(Object object) {
350                         return object == null || "".equals(object.toString().trim());
351                 }
352         }
353 }