Emailer extends AbstractMailer implements Alerter { @Override public void alertOnError(final ExecutableFlow flow, final String... extraReasons) { final EmailMessage message = this.messageCreator.createMessage(); final MailCreator mailCreator = getMailCreator(flow); List<ExecutableFlow> last72hoursExecutions = new ArrayList<>(); if (flow.getStartTime() > 0) { final long startTime = flow.getStartTime() - Duration.ofHours(72).toMillis(); try { last72hoursExecutions = this.executorLoader.fetchFlowHistory(flow.getProjectId(), flow .getFlowId(), startTime); } catch (final ExecutorManagerException e) { logger.error("unable to fetch past executions", e); } } final boolean mailCreated = mailCreator.createErrorEmail(flow, last72hoursExecutions, message, this.azkabanName, this.scheme, this.clientHostname, this.clientPortNumber, extraReasons); sendEmail(message, mailCreated, "error email message for execution " + flow.getExecutionId()); } @Inject  Emailer(final Props props, final CommonMetrics commonMetrics,
      final EmailMessageCreator messageCreator, final ExecutorLoader executorLoader); String getAzkabanURL(); void sendEmail(final List<String> emailList, final String subject, final String body); @Override void alertOnSla(final SlaOption slaOption, final String slaMessage); @Override void alertOnFirstError(final ExecutableFlow flow); @Override void alertOnError(final ExecutableFlow flow, final String... extraReasons); @Override void alertOnSuccess(final ExecutableFlow flow); @Override void alertOnFailedUpdate(final Executor executor, List<ExecutableFlow> flows,
      final ExecutorManagerException updateException); @Override void alertOnFailedExecutorHealthCheck(final Executor executor,
      final List<ExecutableFlow> flows, final ExecutorManagerException failureException,
      final List<String> emailList); void sendEmail(final EmailMessage message, final boolean mailCreated,
      final String operation);  }
@Test public void testSendErrorEmail() throws Exception { final Flow flow = this.project.getFlow("jobe"); flow.addFailureEmails(this.receiveAddrList); Assert.assertNotNull(flow); final ExecutableFlow exFlow = new ExecutableFlow(this.project, flow); final CommonMetrics commonMetrics = new CommonMetrics(new MetricsManager(new MetricRegistry())); final Emailer emailer = new Emailer(this.props, commonMetrics, this.messageCreator, this.executorLoader); emailer.alertOnError(exFlow); verify(this.message).addAllToAddress(this.receiveAddrList); verify(this.message).setSubject("Flow 'jobe' has failed on azkaban"); assertThat(TestUtils.readResource("errorEmail2.html", this)) .isEqualToIgnoringWhitespace(this.message.getBody()); }