public static WorkflowRuntimeOverview computeOverview(
      ObjectMapper objectMapper,
      WorkflowSummary summary,
      WorkflowRollupOverview rollupBase,
      Map<String, Task> realTaskMap) {

    Map<String, StepRuntimeState> states =
        realTaskMap.entrySet().stream()
            .collect(
                Collectors.toMap(
                    Map.Entry::getKey,
                    e ->
                        StepHelper.retrieveStepRuntimeState(
                            e.getValue().getOutputData(), objectMapper)));

    EnumMap<StepInstance.Status, WorkflowStepStatusSummary> stepStatusMap =
        toStepStatusMap(summary, states);

    WorkflowRollupOverview rollupOverview =
        realTaskMap.values().stream()
            .filter(t -> t.getOutputData().containsKey(Constants.STEP_RUNTIME_SUMMARY_FIELD))
            .map(
                t -> {
                  StepRuntimeSummary stepSummary =
                      StepHelper.retrieveRuntimeSummary(objectMapper, t.getOutputData());
                  switch (stepSummary.getType()) {
                    case FOREACH:
                      if (stepSummary.getArtifacts().containsKey(Artifact.Type.FOREACH.key())) {
                        ForeachArtifact artifact =
                            stepSummary.getArtifacts().get(Artifact.Type.FOREACH.key()).asForeach();
                        if (artifact.getForeachOverview() != null
                            && artifact.getForeachOverview().getCheckpoint() > 0) {
                          return artifact.getForeachOverview().getOverallRollup();
                        }
                      }
                      break;
                    case SUBWORKFLOW:
                      if (stepSummary.getArtifacts().containsKey(Artifact.Type.SUBWORKFLOW.key())) {
                        SubworkflowArtifact artifact =
                            stepSummary
                                .getArtifacts()
                                .get(Artifact.Type.SUBWORKFLOW.key())
                                .asSubworkflow();
                        if (artifact.getSubworkflowOverview() != null) {
                          return artifact.getSubworkflowOverview().getRollupOverview();
                        }
                      }
                      break;
                    case TEMPLATE:
                    default:
                      break;
                  }

                  StepInstance.Status status = StepHelper.retrieveStepStatus(t.getOutputData());
                  WorkflowRollupOverview.CountReference ref =
                      new WorkflowRollupOverview.CountReference();
                  ref.setCnt(1);
                  if (status.isOverview()) {
                    ref.setRef(
                        Collections.singletonMap(
                            RollupAggregationHelper.getReference(
                                summary.getWorkflowId(), summary.getWorkflowRunId()),
                            Collections.singletonList(
                                RollupAggregationHelper.getReference(
                                    summary.getWorkflowInstanceId(),
                                    stepSummary.getStepId(),
                                    stepSummary.getStepAttemptId()))));
                  }
                  return WorkflowRollupOverview.of(1L, Collections.singletonMap(status, ref));
                })
            .reduce(new WorkflowRollupOverview(), WorkflowRollupOverview::aggregate);

    rollupOverview.aggregate(rollupBase);

    return WorkflowRuntimeOverview.of(summary.getTotalStepCount(), stepStatusMap, rollupOverview);
  }
@Test
  public void testComputeOverview() throws Exception {
    WorkflowSummary workflowSummary =
        loadObject("fixtures/parameters/sample-wf-summary-params.json", WorkflowSummary.class);
    Task t = new Task();
    t.setTaskType(Constants.MAESTRO_TASK_NAME);
    t.setSeq(1);
    Map<String, Object> summary = new HashMap<>();
    summary.put("runtime_state", Collections.singletonMap("status", "SUCCEEDED"));
    summary.put("type", "NOOP");
    t.setOutputData(Collections.singletonMap(Constants.STEP_RUNTIME_SUMMARY_FIELD, summary));
    WorkflowRuntimeOverview overview =
        TaskHelper.computeOverview(
            MAPPER,
            workflowSummary,
            new WorkflowRollupOverview(),
            Collections.singletonMap("job1", t));
    Assert.assertEquals(4, overview.getTotalStepCount());
    Assert.assertEquals(
        singletonEnumMap(
            StepInstance.Status.SUCCEEDED,
            WorkflowStepStatusSummary.of(0L).addStep(Arrays.asList(2L, null, null))),
        overview.getStepOverview());
    WorkflowRollupOverview expected = new WorkflowRollupOverview();
    expected.setTotalLeafCount(1L);
    WorkflowRollupOverview.CountReference ref = new WorkflowRollupOverview.CountReference();
    ref.setCnt(1);
    expected.setOverview(singletonEnumMap(StepInstance.Status.SUCCEEDED, ref));
    Assert.assertEquals(expected, overview.getRollupOverview());
  }