All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.flowable.engine.test.impl.logger.ProcessExecutionLogger Maven / Gradle / Ivy

There is a newer version: 7.0.1
Show newest version
/* 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.
 */
package org.flowable.engine.test.impl.logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.test.impl.logger.DebugInfoExecutionTree.DebugInfoExecutionTreeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author jbarrez
 */
public class ProcessExecutionLogger {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProcessExecutionLogger.class);

    protected Map> debugInfoMap = new HashMap<>();

    // To avoid going to the db (and thus influencing process execution/tests), we store all encountered executions here,
    // to build up a tree representation with that information afterwards.
    protected Map createdExecutions = new HashMap<>();
    protected Map deletedExecutions = new HashMap<>();

    public ProcessExecutionLogger() {

    }

    public void addDebugInfo(AbstractDebugInfo debugInfo) {
        addDebugInfo(debugInfo, false);
    }

    public synchronized void addDebugInfo(AbstractDebugInfo debugInfo, boolean generateExecutionTreeRepresentation) {

        // Store debug info
        String threadName = Thread.currentThread().getName();
        if (!debugInfoMap.containsKey(threadName)) {
            debugInfoMap.put(threadName, new ArrayList<>());
        }
        debugInfoMap.get(threadName).add(debugInfo);

        // Generate execution tree
        if (generateExecutionTreeRepresentation) {
            debugInfo.setExecutionTrees(generateExecutionTrees());
        }
    }

    protected List generateExecutionTrees() {

        // Gather information
        List processInstances = new ArrayList<>();
        Map> parentMapping = new HashMap<>();

        for (ExecutionEntity executionEntity : createdExecutions.values()) {
            if (!deletedExecutions.containsKey(executionEntity.getId())) {
                if (executionEntity.getParentId() == null) {
                    processInstances.add(executionEntity);
                } else {
                    if (!parentMapping.containsKey(executionEntity.getParentId())) {
                        parentMapping.put(executionEntity.getParentId(), new ArrayList<>());
                    }
                    parentMapping.get(executionEntity.getParentId()).add(executionEntity);
                }
            }
        }

        // Build tree representation
        List executionTrees = new ArrayList<>();
        for (ExecutionEntity processInstance : processInstances) {

            DebugInfoExecutionTree executionTree = new DebugInfoExecutionTree();
            executionTrees.add(executionTree);

            DebugInfoExecutionTreeNode rootNode = new DebugInfoExecutionTreeNode();
            executionTree.setProcessInstance(rootNode);
            rootNode.setId(processInstance.getId());

            internalPopulateExecutionTree(rootNode, parentMapping);
        }

        return executionTrees;
    }

    protected void internalPopulateExecutionTree(DebugInfoExecutionTreeNode parentNode, Map> parentMapping) {
        if (parentMapping.containsKey(parentNode.getId())) {
            for (ExecutionEntity childExecutionEntity : parentMapping.get(parentNode.getId())) {
                DebugInfoExecutionTreeNode childNode = new DebugInfoExecutionTreeNode();
                childNode.setId(childExecutionEntity.getId());
                childNode.setActivityId(childExecutionEntity.getCurrentFlowElement() != null ? childExecutionEntity.getCurrentFlowElement().getId() : null);
                childNode.setActivityName(childExecutionEntity.getCurrentFlowElement() != null ? childExecutionEntity.getCurrentFlowElement().getName() : null);
                childNode.setProcessDefinitionId(childExecutionEntity.getProcessDefinitionId());

                childNode.setParentNode(childNode);
                parentNode.getChildNodes().add(childNode);

                internalPopulateExecutionTree(childNode, parentMapping);
            }
        }
    }

    public void logDebugInfo() {
        logDebugInfo(false);
    }

    public void logDebugInfo(boolean clearAfterLogging) {

        LOGGER.info("--------------------------------");
        LOGGER.info("CommandInvoker debug information");
        LOGGER.info("--------------------------------");
        for (String threadName : debugInfoMap.keySet()) {

            LOGGER.info("");
            LOGGER.info("Thread '{}':", threadName);
            LOGGER.info("");

            for (DebugInfo debugInfo : debugInfoMap.get(threadName)) {
                debugInfo.printOut(LOGGER);
            }

        }

        LOGGER.info("");

        if (clearAfterLogging) {
            clear();
        }
    }

    public void clear() {
        debugInfoMap.clear();
        createdExecutions.clear();
    }

    public void executionCreated(ExecutionEntity executionEntity) {
        createdExecutions.put(executionEntity.getId(), executionEntity);
    }

    public void executionDeleted(ExecutionEntity executionEntity) {
        deletedExecutions.put(executionEntity.getId(), executionEntity);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy