summaryrefslogtreecommitdiffstats
path: root/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/plugins/LoggingAndURNMappingPlugin.java
diff options
context:
space:
mode:
Diffstat (limited to 'bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/plugins/LoggingAndURNMappingPlugin.java')
-rw-r--r--bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/plugins/LoggingAndURNMappingPlugin.java424
1 files changed, 424 insertions, 0 deletions
diff --git a/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/plugins/LoggingAndURNMappingPlugin.java b/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/plugins/LoggingAndURNMappingPlugin.java
new file mode 100644
index 0000000000..8e3f254def
--- /dev/null
+++ b/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/plugins/LoggingAndURNMappingPlugin.java
@@ -0,0 +1,424 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.mso.bpmn.core.plugins;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.ExecutionListener;
+import org.camunda.bpm.engine.impl.bpmn.parser.AbstractBpmnParseListener;
+import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseListener;
+import org.camunda.bpm.engine.impl.cfg.AbstractProcessEnginePlugin;
+import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.camunda.bpm.engine.impl.context.Context;
+import org.camunda.bpm.engine.impl.interceptor.Command;
+import org.camunda.bpm.engine.impl.interceptor.CommandContext;
+import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
+import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
+import org.camunda.bpm.engine.impl.pvm.process.TransitionImpl;
+import org.camunda.bpm.engine.impl.util.xml.Element;
+import org.camunda.bpm.engine.impl.variable.VariableDeclaration;
+
+import org.openecomp.mso.bpmn.core.BPMNLogger;
+import org.openecomp.mso.bpmn.core.PropertyConfiguration;
+import org.openecomp.mso.bpmn.core.mybatis.CustomMyBatisSessionFactory;
+import org.openecomp.mso.bpmn.core.mybatis.URNMapping;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+
+/**
+ * Plugin for MSO logging and URN mapping.
+ */
+public class LoggingAndURNMappingPlugin extends AbstractProcessEnginePlugin {
+ private static MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL);
+ private static final String FSPROPKEY = "URNMapping.FileSystemLoading.Enabled";
+
+ @Override
+ public void preInit(
+ ProcessEngineConfigurationImpl processEngineConfiguration) {
+ List<BpmnParseListener> preParseListeners = processEngineConfiguration
+ .getCustomPreBPMNParseListeners();
+ if (preParseListeners == null) {
+ preParseListeners = new ArrayList<BpmnParseListener>();
+ processEngineConfiguration.setCustomPreBPMNParseListeners(preParseListeners);
+ }
+ preParseListeners.add(new LoggingParseListener());
+ }
+
+ /**
+ * Called when a process flow is parsed so we can inject listeners.
+ */
+ public static class LoggingParseListener extends AbstractBpmnParseListener {
+ private void injectLogExecutionListener(ActivityImpl activity) {
+ activity.addListener(
+ ExecutionListener.EVENTNAME_END,
+ new LoggingExecutionListener("END"));
+
+ activity.addListener(
+ ExecutionListener.EVENTNAME_START,
+ new LoggingExecutionListener("START"));
+
+ activity.addListener(
+ ExecutionListener.EVENTNAME_TAKE,
+ new LoggingExecutionListener("TAKE"));
+ }
+
+ public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) {
+ }
+
+ public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {
+ // Inject these listeners only on the main start event for the flow, not on any embedded subflow start events
+ if (scope instanceof ProcessDefinitionEntity) {
+ startEventActivity.addListener(ExecutionListener.EVENTNAME_START, new URNMappingInitializerListener("START"));
+ startEventActivity.addListener(ExecutionListener.EVENTNAME_START, new LoggingInitializerListener("START"));
+ }
+
+ injectLogExecutionListener(startEventActivity);
+ }
+
+ public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseInclusiveGateway(Element inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting, ActivityImpl timerActivity) {
+ injectLogExecutionListener(timerActivity);
+ }
+
+ public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting, ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
+ //injectLogExecutionListener(activity);
+ }
+
+ public void parseSendTask(Element sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseMultiInstanceLoopCharacteristics(Element activityElement, Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity) {
+ injectLogExecutionListener(timerActivity);
+ }
+
+ public void parseRootElement(Element rootElement, List<ProcessDefinitionEntity> processDefinitions) {
+ //injectLogExecutionListener(activity);
+ }
+
+ public void parseReceiveTask(Element receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseIntermediateSignalCatchEventDefinition(Element signalEventDefinition, ActivityImpl signalActivity) {
+ injectLogExecutionListener(signalActivity);
+ }
+
+ public void parseBoundarySignalEventDefinition(Element signalEventDefinition, boolean interrupting, ActivityImpl signalActivity) {
+ injectLogExecutionListener(signalActivity);
+ }
+
+ public void parseEventBasedGateway(Element eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseTransaction(Element transactionElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity) {
+ injectLogExecutionListener(compensationActivity);
+ }
+
+ public void parseIntermediateThrowEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseIntermediateCatchEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
+ injectLogExecutionListener(activity);
+ }
+
+ public void parseBoundaryEvent(Element boundaryEventElement, ScopeImpl scopeElement, ActivityImpl nestedActivity) {
+ injectLogExecutionListener(nestedActivity);
+ }
+
+ public void parseIntermediateMessageCatchEventDefinition(Element messageEventDefinition, ActivityImpl nestedActivity) {
+ injectLogExecutionListener(nestedActivity);
+ }
+
+ public void parseBoundaryMessageEventDefinition(Element element, boolean interrupting, ActivityImpl messageActivity) {
+ injectLogExecutionListener(messageActivity);
+ }
+ }
+
+ /**
+ * Initializes URN mapping variables on process entry.
+ */
+ public static class URNMappingInitializerListener implements ExecutionListener {
+ private String event;
+
+ public URNMappingInitializerListener(String eventData) {
+ this.event = eventData;
+ }
+
+ public String getEvent() {
+ return event;
+ }
+
+ public void notify(DelegateExecution execution) throws Exception {
+ ProcessEngineConfigurationImpl processEngineConfiguration =
+ Context.getProcessEngineConfiguration();
+ loadURNProperties(execution, processEngineConfiguration);
+ }
+
+ private void loadURNProperties(DelegateExecution execution,
+ ProcessEngineConfigurationImpl processEngineConfiguration) {
+ Map<String,String> bpmnProps = PropertyConfiguration.getInstance().getProperties("mso.bpmn.properties");
+ if (bpmnProps == null) {
+ LOGGER.debug("Unable to load mso.bpmn.properties; loading URN Mapping from DB");
+
+ LOGGER.error (MessageEnum.BPMN_GENERAL_EXCEPTION, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError,
+ "Unable to load mso.bpmn.properties; loading URN Mapping from DB");
+
+ loadFromDB(execution, processEngineConfiguration);
+ } else {
+ String fsEnabled = bpmnProps.get(FSPROPKEY);
+ if (fsEnabled != null) {
+ if (Boolean.parseBoolean(fsEnabled)) {
+ LOGGER.debug("File system loading is enabled; loading URN properties from File system");
+ LOGGER.info(MessageEnum.BPMN_GENERAL_INFO, "BPMN", "File system loading is enabled; loading URN properties from File System");
+ loadFromFileSystem(execution);
+ } else {
+ LOGGER.debug("File system loading is disabled; loading URN properties from DB");
+ LOGGER.info (MessageEnum.BPMN_GENERAL_INFO, "BPMN", "File system loading is disabled; loading URN properties from DB");
+
+ loadFromDB(execution, processEngineConfiguration);
+ }
+ } else {
+
+ LOGGER.error (MessageEnum.BPMN_GENERAL_EXCEPTION, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError,
+ "Unable to retrieve URNMapping.FileSystemLoading.Enabled from mso.bpmn.properties; loading URN Mapping from DB");
+
+ loadFromDB(execution, processEngineConfiguration);
+ }
+ }
+ }
+
+ private void loadFromFileSystem(DelegateExecution execution) {
+ PropertyConfiguration propertyConfiguration = PropertyConfiguration.getInstance();
+ Map<String,String> props = propertyConfiguration.getProperties("mso.bpmn.urn.properties");
+ for (String key : props.keySet()) {
+ String varName = URNMapping.createIdentifierFromURN(key);
+ String varValue = props.get(key);
+ execution.setVariable(varName, varValue);
+ }
+ }
+
+ private void loadFromDB(DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
+ Command<List<URNMapping>> command = new Command<List<URNMapping>>() {
+ @SuppressWarnings("unchecked")
+ public List<URNMapping> execute(CommandContext commandContext) {
+ return (List<URNMapping>) commandContext.getDbSqlSession().selectList(
+ "mso.urnMapping.selectAll", null);
+ }
+ };
+
+ CustomMyBatisSessionFactory sessionFactory = new CustomMyBatisSessionFactory();
+ sessionFactory.initFromProcessEngineConfiguration(processEngineConfiguration,
+ "customMyBatisConfiguration.xml");
+
+ List<URNMapping> mappings = sessionFactory.getCommandExecutorTxRequired().execute(command);
+
+ if (mappings != null && mappings.size() > 0) {
+ for (URNMapping mapping : mappings) {
+ String varName = URNMapping.createIdentifierFromURN(mapping.getName());
+ String varValue = mapping.getValue();
+
+ LOGGER.debug("URN Mapping = '" + mapping.getName()
+ + "', setting variable '" + varName + "' to '" + varValue + "'");
+
+ execution.setVariable(varName, varValue);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the isDebugLogEnabled variable on process entry.
+ */
+ public static class LoggingInitializerListener implements ExecutionListener {
+ private String event;
+
+ public LoggingInitializerListener(String eventData) {
+ this.event = eventData;
+ }
+
+ public String getEvent() {
+ return event;
+ }
+
+ public void notify(DelegateExecution execution) throws Exception {
+ String processKey = execution.getProcessEngineServices().getRepositoryService()
+ .getProcessDefinition(execution.getProcessDefinitionId()).getKey();
+
+ // If a "true" value is already injected, e.g. from a top-level flow, it SHOULD NOT be
+ // overridden by the value in the URN mapping. This allows a top-level flow and all
+ // invoked subflows to be debugged by turning on the debug flag for just the top-level
+ // flow, assuming the isDebugEnabled flag variable is passed from the top-level flow to
+ // its subflows.
+
+ // If a "false" value is already injected, e.g. from a top-level flow, it SHOULD be
+ // overridden by the value in the URN mapping. This allows a subflow to be debugged
+ // without turning on the the debug flag for the top-level flow.
+
+ String injectedValue = (String) execution.getVariable("isDebugLogEnabled");
+ String urnValue = "true".equals(execution.getVariable("URN_log_debug_" + processKey)) ? "true" : "false";
+
+ if ("true".equals(injectedValue)) {
+ LOGGER.debug("Setting isDebugLogEnabled to \"" + injectedValue + "\" for process: " + processKey + " (injected value)");
+ execution.setVariable("isDebugLogEnabled", injectedValue);
+ } else {
+ LOGGER.debug("Setting isDebugLogEnabled to \"" + urnValue + "\" for process: " + processKey + " (from URN mapping)");
+ execution.setVariable("isDebugLogEnabled", urnValue);
+ }
+ }
+ }
+
+ /**
+ * Logs details about the current activity.
+ */
+ public static class LoggingExecutionListener implements ExecutionListener {
+ private static MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL);
+ private static ConcurrentHashMap<String, Long> startTimes = new ConcurrentHashMap<String, Long>();
+
+ private String event;
+
+ public LoggingExecutionListener(String event) {
+ this.event = event;
+ }
+
+ public String getEvent() {
+ return event;
+ }
+
+ public void notify(DelegateExecution execution) throws Exception {
+ BPMNLogger.debug(
+ (String) execution.getVariable("isDebugLogEnabled"),
+ "Logging for activity---------------:" + event + ":"
+ + execution.getCurrentActivityName()
+ + ", processDefinitionId="
+ + execution.getProcessDefinitionId() + ", activtyId="
+ + execution.getCurrentActivityId() + ", activtyName='"
+ + execution.getCurrentActivityName() + "'"
+ + ", processInstanceId="
+ + execution.getProcessInstanceId() + ", businessKey="
+ + execution.getProcessBusinessKey() + ", executionId="
+ + execution.getId());
+
+ if (!isBlank(execution.getCurrentActivityName())) {
+ try {
+ String id = execution.getId();
+ if ("START".equals(event) && id != null ) {
+ startTimes.put(id, (Long)System.currentTimeMillis());
+ } else if ("END".equals(event) && id != null) {
+ String prefix = (String) execution.getVariable("prefix");
+
+ if (prefix != null ) {
+ MsoLogger.setServiceName("MSO." + prefix.substring(0,prefix.length()-1));
+ }
+
+ String requestId = (String) execution.getVariable("att-mso-request-id");
+ String svcid = (String) execution.getVariable("att-mso-service-instance-id");
+ MsoLogger.setLogContext(requestId, svcid);
+ long startTime = startTimes.remove(id);
+
+ if (startTime != 0) {
+
+ LOGGER.recordMetricEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ event + ": " + execution.getCurrentActivityName(), "BPMN", execution.getCurrentActivityName(), null);
+
+ }
+ }
+ } catch(Exception e) {
+ // Do nothing
+ }
+ }
+ }
+
+ private boolean isBlank(Object object) {
+ return object == null || object.toString().trim().equals("");
+ }
+ }
+}