When a flow is finished, alert the user as is configured in the execution options.

@param flow the execution
@param alerterHolder the alerter holder
@param extraReasons the extra reasons for alerting
765813
public static void alertUserOnFlowFinished(final ExecutableFlow flow, final AlerterHolder
      alerterHolder, final String[] extraReasons) {
    final ExecutionOptions options = flow.getExecutionOptions();
    final Alerter mailAlerter = alerterHolder.get("email");
    if (flow.getStatus() != Status.SUCCEEDED) {
      if (options.getFailureEmails() != null && !options.getFailureEmails().isEmpty()) {
        try {
          mailAlerter.alertOnError(flow, extraReasons);
        } catch (final Exception e) {
          logger.error("Failed to alert on error for execution " + flow.getExecutionId(), e);
        }
      }
      if (options.getFlowParameters().containsKey("alert.type")) {
        final String alertType = options.getFlowParameters().get("alert.type");
        final Alerter alerter = alerterHolder.get(alertType);
        if (alerter != null) {
          try {
            alerter.alertOnError(flow, extraReasons);
          } catch (final Exception e) {
            logger.error("Failed to alert on error by " + alertType + " for execution " + flow
                .getExecutionId(), e);
          }
        } else {
          logger.error("Alerter type " + alertType + " doesn't exist. Failed to alert.");
        }
      }
    } else {
      if (options.getSuccessEmails() != null && !options.getSuccessEmails().isEmpty()) {
        try {
          mailAlerter.alertOnSuccess(flow);
        } catch (final Exception e) {
          logger.error("Failed to alert on success for execution " + flow.getExecutionId(), e);
        }
      }
      if (options.getFlowParameters().containsKey("alert.type")) {
        final String alertType = options.getFlowParameters().get("alert.type");
        final Alerter alerter = alerterHolder.get(alertType);
        if (alerter != null) {
          try {
            alerter.alertOnSuccess(flow);
          } catch (final Exception e) {
            logger.error("Failed to alert on success by " + alertType + " for execution " + flow
                .getExecutionId(), e);
          }
        } else {
          logger.error("Alerter type " + alertType + " doesn't exist. Failed to alert.");
        }
      }
    }
  }
1276909
private void ajaxSetFlowLock(final Project project,
      final HashMap<String, Object> ret, final HttpServletRequest req)
      throws ServletException {
    final String flowName = getParam(req, FLOW_NAME_PARAM);
    final Flow flow = project.getFlow(flowName);
    if (flow == null) {
      ret.put(ERROR_PARAM,
          "Flow " + flowName + " not found in project " + project.getName());
      return;
    }

    boolean isLocked = Boolean.parseBoolean(getParam(req, FLOW_IS_LOCKED_PARAM));

    // if there is a change in the locked value, then check to see if the project has a flow trigger
    // that needs to be paused/resumed.
    if (isLocked != flow.isLocked()) {
      try {
        if (projectManager.hasFlowTrigger(project, flow)) {
          if (isLocked) {
            if (this.scheduler.pauseFlowTriggerIfPresent(project.getId(), flow.getId())) {
              logger.info("Flow trigger for flow " + project.getName() + "." + flow.getId() +
                      " is paused");
            } else {
              logger.warn("Flow trigger for flow " + project.getName() + "." + flow.getId() +
              " doesn't exist");
            }
          } else {
            if (this.scheduler.resumeFlowTriggerIfPresent(project.getId(), flow.getId())) {
              logger.info("Flow trigger for flow " + project.getName() + "." + flow.getId() +
                  " is resumed");
            } else {
              logger.warn("Flow trigger for flow " + project.getName() + "." + flow.getId() +
                  " doesn't exist");
            }
          }
        }
      } catch (Exception e) {
        ret.put(ERROR_PARAM, e);
      }
    }

    flow.setLocked(isLocked);
    ret.put(FLOW_IS_LOCKED_PARAM, flow.isLocked());
    ret.put(FLOW_ID_PARAM, flow.getId());
    this.projectManager.updateFlow(project, flow);
  }
836429
public void alertException() {
        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))  //306998.15
            logger.logp(Level.FINE, CLASS_NAME,"alertException", "entry  _outWriter: --> " + _outWriter);
        writerException = true;
        if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled()&&logger.isLoggable (Level.FINE))  //306998.15
            logger.logp(Level.FINE, CLASS_NAME,"alertException", "exit");
    }
711144
protected void createServiceWarningViewState(final Flow flow) {
        val stateWarning = createViewState(flow, CasWebflowConstants.STATE_ID_SHOW_WARNING_VIEW, CasWebflowConstants.VIEW_ID_CONFIRM);
        createTransitionForState(stateWarning, CasWebflowConstants.TRANSITION_ID_SUCCESS, "finalizeWarning");
        val finalizeWarn = createActionState(flow, "finalizeWarning", createEvaluateAction("serviceWarningAction"));
        createTransitionForState(finalizeWarn, CasWebflowConstants.STATE_ID_REDIRECT, CasWebflowConstants.STATE_ID_REDIRECT);
    }
298473
public String createSlaMessage(final ExecutableFlow flow) {
    final int execId = flow.getExecutionId();
    final String durationStr = durationToString(this.duration);
    switch (this.type.getComponent()) {
      case FLOW:
        final String basicinfo =
            "SLA Alert: Your flow " + this.flowName + " failed to " + this.type.getStatus()
                + " within " + durationStr + "<br/>";
        final String expected =
            "Here are details : <br/>" + "Flow " + this.flowName + " in execution "
                + execId + " is expected to FINISH within " + durationStr + " from "
                + fmt.print(new DateTime(flow.getStartTime())) + "<br/>";
        final String actual = "Actual flow status is " + flow.getStatus();
        return basicinfo + expected + actual;
      case JOB:
        return "SLA Alert: Your job " + this.jobName + " failed to " + this.type.getStatus()
            + " within " + durationStr + " in execution " + execId;
      default:
        return "Unrecognized SLA component type " + this.type.getComponent();
    }
  }
530465
public void setFlows(java.util.Collection<ListedFlow> flows) {
        if (flows == null) {
            this.flows = null;
            return;
        }

        this.flows = new java.util.ArrayList<ListedFlow>(flows);
    }
790493
public static boolean isFinished(final ExecutableFlow flow) {
    switch (flow.getStatus()) {
      case SUCCEEDED:
      case FAILED:
      case KILLED:
        return true;
      default:
        return false;
    }
  }
923071
@Override
    public Flow getFlow()
    {
        return new Flow()
        {
            @Override
            public boolean isHandled()
            {
                return false;
            }

            @Override
            public boolean is(Flow type)
            {
                return false;
            }
        };
    }
735277
public UpdateResponse updateFlowConfig(FlowId flowId, FlowConfig flowConfig, boolean triggerListener) {
    log.info("[GAAS-REST] Update called with flowGroup {} flowName {}", flowId.getFlowGroup(), flowId.getFlowName());

    if (!flowId.getFlowGroup().equals(flowConfig.getId().getFlowGroup()) || !flowId.getFlowName().equals(flowConfig.getId().getFlowName())) {
      throw new FlowConfigLoggedException(HttpStatus.S_400_BAD_REQUEST,
          "flowName and flowGroup cannot be changed in update", null);
    }
    if (isUnscheduleRequest(flowConfig)) {
      // flow config is not changed if it is just a request to un-schedule
      FlowConfig originalFlowConfig = getFlowConfig(flowId);
      originalFlowConfig.setSchedule(NEVER_RUN_CRON_SCHEDULE);
      flowConfig = originalFlowConfig;
    }

    this.flowCatalog.put(createFlowSpecForConfig(flowConfig), triggerListener);
    return new UpdateResponse(HttpStatus.S_200_OK);
  }
441986
public void notifyResetFlowProperties() 
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.entry(tc, "notifyResetFlowProperties");
 
    pendingFlowReset = true;
  
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.exit(tc, "notifyResetFlowProperties"); 
  }
736173
private void propagateStatusAndAlert(final ExecutableFlowBase base, final Status status) {
    if (!Status.isStatusFinished(base.getStatus()) && base.getStatus() != Status.KILLING) {
      this.logger.info("Setting " + base.getNestedId() + " to " + status);
      boolean shouldAlert = false;
      if (base.getStatus() != status) {
        base.setStatus(status);
        shouldAlert = true;
      }
      if (base.getParentFlow() != null) {
        propagateStatusAndAlert(base.getParentFlow(), status);
      } else if (this.azkabanProps.getBoolean(ConfigurationKeys.AZKABAN_POLL_MODEL, false)) {
        // Alert on the root flow if the first error is encountered.
        // Todo jamiesjc: Add a new FLOW_STATUS_CHANGED event type and alert on that event.
        if (shouldAlert && base.getStatus() == Status.FAILED_FINISHING) {
          ExecutionControllerUtils.alertUserOnFirstError((ExecutableFlow) base, this.alerterHolder);
        }
      }
    }
  }
1307946
@Override
  public boolean isFlowRunning(final int projectId, final String flowId) {
    boolean isRunning = false;
    try {
      isRunning = isFlowRunningHelper(projectId, flowId,
          this.executorLoader.fetchUnfinishedFlows().values());

    } catch (final ExecutorManagerException e) {
      logger.error(
          "Failed to check if the flow is running for project " + projectId + ", flow " + flowId,
          e);
    }
    return isRunning;
  }
289864
@PostConstruct
    public void init() {
        Objects.requireNonNull(context, "context");
        FlowHandler contentFlowHandler = (FlowHandler) context.getRegisteredObject("ContentFlowHandler");
        sideList.propagateMouseEventsToParent();
        sideList.getSelectionModel().selectedItemProperty().addListener((o, oldVal, newVal) -> {
            new Thread(()->{
                Platform.runLater(()->{
                    if (newVal != null) {
                        try {
                            contentFlowHandler.handle(newVal.getId());
                        } catch (VetoException exc) {
                            exc.printStackTrace();
                        } catch (FlowException exc) {
                            exc.printStackTrace();
                        }
                    }
                });
            }).start();
        });
        Flow contentFlow = (Flow) context.getRegisteredObject("ContentFlow");
        bindNodeToController(button, ButtonController.class, contentFlow, contentFlowHandler);
        bindNodeToController(checkbox, CheckboxController.class, contentFlow, contentFlowHandler);
        bindNodeToController(combobox, ComboBoxController.class, contentFlow, contentFlowHandler);
        bindNodeToController(dialogs, DialogController.class, contentFlow, contentFlowHandler);
        bindNodeToController(icons, IconsController.class, contentFlow, contentFlowHandler);
        bindNodeToController(listview, ListViewController.class, contentFlow, contentFlowHandler);
        bindNodeToController(treetableview, TreeTableViewController.class, contentFlow, contentFlowHandler);
        bindNodeToController(progressbar, ProgressBarController.class, contentFlow, contentFlowHandler);
        bindNodeToController(radiobutton, RadioButtonController.class, contentFlow, contentFlowHandler);
        bindNodeToController(slider, SliderController.class, contentFlow, contentFlowHandler);
        bindNodeToController(spinner, SpinnerController.class, contentFlow, contentFlowHandler);
        bindNodeToController(textfield, TextFieldController.class, contentFlow, contentFlowHandler);
        bindNodeToController(highlighter, HighlighterController.class, contentFlow, contentFlowHandler);
        bindNodeToController(chipview, ChipViewController.class, contentFlow, contentFlowHandler);
        bindNodeToController(togglebutton, ToggleButtonController.class, contentFlow, contentFlowHandler);
        bindNodeToController(popup, PopupController.class, contentFlow, contentFlowHandler);
        bindNodeToController(svgLoader, SVGLoaderController.class, contentFlow, contentFlowHandler);
        bindNodeToController(pickers, PickersController.class, contentFlow, contentFlowHandler);
        bindNodeToController(masonry, MasonryPaneController.class, contentFlow, contentFlowHandler);
        bindNodeToController(scrollpane, ScrollPaneController.class, contentFlow, contentFlowHandler);
        bindNodeToController(nodesList, NodesListController.class, contentFlow, contentFlowHandler);
    }
788087
protected boolean handlePausedFlow(Execution execution) throws InterruptedException {
        String branchId = execution.getSystemContext().getBranchId();
        PauseReason reason = findPauseReason(execution.getExecutionId(), branchId);
        if (reason != null) { // need to pause the execution
            pauseFlow(reason, execution);
            return true;
        }
        return false;
    }
745393
def do_stop_alerts(self, _):
        
        self._stop_thread = True
        if self._alerter_thread.is_alive():
            self._alerter_thread.join()
        else:
            print("The alert thread is already stopped")
867482
public void afterCompletion(int status) {
        for (DeferredEventNotification<?> notification : notifications) {
            if (!notification.isBefore() && notification.getStatus().matches(status)) {
                notification.run();
            }
        }
    }
1272716
public void notifyBeforeEvaluation(String expr) {
        if (getEvaluationListeners() == null)
            return;
        for (EvaluationListener listener: getEvaluationListeners()) {
            listener.beforeEvaluation(this, expr);
        }
    }