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

io.camunda.operate.webapp.elasticsearch.reader.IncidentReader Maven / Gradle / Ivy

There is a newer version: 8.7.0-alpha2-rc1
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
package io.camunda.operate.webapp.elasticsearch.reader;

import static io.camunda.operate.webapp.rest.dto.incidents.IncidentDto.FALLBACK_PROCESS_DEFINITION_NAME;

import io.camunda.operate.cache.ProcessCache;
import io.camunda.operate.conditions.ElasticsearchCondition;
import io.camunda.operate.store.FlowNodeStore;
import io.camunda.operate.store.IncidentStore;
import io.camunda.operate.webapp.data.IncidentDataHolder;
import io.camunda.operate.webapp.reader.OperationReader;
import io.camunda.operate.webapp.rest.dto.incidents.IncidentDto;
import io.camunda.operate.webapp.rest.dto.incidents.IncidentErrorTypeDto;
import io.camunda.operate.webapp.rest.dto.incidents.IncidentFlowNodeDto;
import io.camunda.operate.webapp.rest.dto.incidents.IncidentResponseDto;
import io.camunda.webapps.operate.TreePath;
import io.camunda.webapps.schema.entities.operate.ErrorType;
import io.camunda.webapps.schema.entities.operate.IncidentEntity;
import io.camunda.webapps.schema.entities.operation.OperationEntity;
import java.util.*;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;

@Conditional(ElasticsearchCondition.class)
@Component
public class IncidentReader extends AbstractReader
    implements io.camunda.operate.webapp.reader.IncidentReader {

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

  @Autowired private OperationReader operationReader;

  @Autowired private ProcessInstanceReader processInstanceReader;

  @Autowired private ProcessCache processCache;

  @Autowired private IncidentStore incidentStore;

  @Autowired private FlowNodeStore flowNodeStore;

  @Override
  public List getAllIncidentsByProcessInstanceKey(final Long processInstanceKey) {
    return incidentStore.getIncidentsByProcessInstanceKey(processInstanceKey);
  }

  /**
   * Returns map of incident ids per process instance id.
   *
   * @param processInstanceKeys
   * @return
   */
  @Override
  public Map> getIncidentKeysPerProcessInstance(
      final List processInstanceKeys) {
    return incidentStore.getIncidentKeysPerProcessInstance(processInstanceKeys);
  }

  @Override
  public IncidentEntity getIncidentById(final Long incidentKey) {
    return incidentStore.getIncidentById(incidentKey);
  }

  @Override
  public IncidentResponseDto getIncidentsByProcessInstanceId(final String processInstanceId) {
    // get treePath for process instance
    final String treePath = processInstanceReader.getProcessInstanceTreePath(processInstanceId);

    final List> errorTypes = new ArrayList<>();
    final List incidents =
        incidentStore.getIncidentsWithErrorTypesFor(treePath, errorTypes);

    final IncidentResponseDto incidentResponse = new IncidentResponseDto();
    incidentResponse.setErrorTypes(
        errorTypes.stream()
            .map(
                m -> {
                  final var entry = m.entrySet().iterator().next();
                  return IncidentErrorTypeDto.createFrom(entry.getKey())
                      .setCount(entry.getValue().intValue());
                })
            .collect(Collectors.toList()));

    final Map processNames = new HashMap<>();
    incidents.stream()
        .filter(inc -> processNames.get(inc.getProcessDefinitionKey()) == null)
        .forEach(
            inc ->
                processNames.put(
                    inc.getProcessDefinitionKey(),
                    processCache.getProcessNameOrBpmnProcessId(
                        inc.getProcessDefinitionKey(), FALLBACK_PROCESS_DEFINITION_NAME)));

    final Map> operations =
        operationReader.getOperationsPerIncidentKey(processInstanceId);

    final Map incData =
        collectFlowNodeDataForPropagatedIncidents(incidents, processInstanceId, treePath);

    // collect flow node statistics
    incidentResponse.setFlowNodes(
        incData.values().stream()
            .collect(
                Collectors.groupingBy(
                    IncidentDataHolder::getFinalFlowNodeId, Collectors.counting()))
            .entrySet()
            .stream()
            .map(entry -> new IncidentFlowNodeDto(entry.getKey(), entry.getValue().intValue()))
            .collect(Collectors.toList()));

    final List incidentsDtos =
        IncidentDto.sortDefault(
            IncidentDto.createFrom(incidents, operations, processNames, incData));
    incidentResponse.setIncidents(incidentsDtos);
    incidentResponse.setCount(incidents.size());
    return incidentResponse;
  }

  /**
   * Returns map incidentId -> IncidentDataHolder.
   *
   * @param incidents
   * @param processInstanceId
   * @param currentTreePath
   * @return
   */
  @Override
  public Map collectFlowNodeDataForPropagatedIncidents(
      final List incidents,
      final String processInstanceId,
      final String currentTreePath) {

    final Set flowNodeInstanceIdsSet = new HashSet<>();
    final Map incDatas = new HashMap<>();
    for (final IncidentEntity inc : incidents) {
      final IncidentDataHolder incData = new IncidentDataHolder().setIncidentId(inc.getId());
      if (!String.valueOf(inc.getProcessInstanceKey()).equals(processInstanceId)) {
        final String callActivityInstanceId =
            TreePath.extractFlowNodeInstanceId(inc.getTreePath(), currentTreePath);
        incData.setFinalFlowNodeInstanceId(callActivityInstanceId);
        flowNodeInstanceIdsSet.add(callActivityInstanceId);
      } else {
        incData.setFinalFlowNodeInstanceId(String.valueOf(inc.getFlowNodeInstanceKey()));
        incData.setFinalFlowNodeId(inc.getFlowNodeId());
      }
      incDatas.put(inc.getId(), incData);
    }

    if (flowNodeInstanceIdsSet.size() > 0) {
      // select flowNodeIds by flowNodeInstanceIds
      final Map flowNodeIdsMap =
          flowNodeStore.getFlowNodeIdsForFlowNodeInstances(flowNodeInstanceIdsSet);

      // set flow node id, where not yet set
      incDatas.values().stream()
          .filter(iData -> iData.getFinalFlowNodeId() == null)
          .forEach(
              iData ->
                  iData.setFinalFlowNodeId(flowNodeIdsMap.get(iData.getFinalFlowNodeInstanceId())));
    }
    return incDatas;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy