Reputation: 371
I was wondering if there is a way to use a the afterStep and make a step exceution listener to check for any failed steps in a job, and add that step name and exit status to the execution context.
Although a step in my job has failed, we return RepeatStatus.FINISHED
. I create an email report and I want to include the failed step name and status. Here's my email tasklet
public class SendEmailTasklet implements Tasklet {
final static Logger LOGGER = LoggerFactory.getLogger(SendEmailTasklet.class);
@Autowired
public JavaMailSender emailSender;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
JobParameters jobParameters = chunkContext.getStepContext().getStepExecution().getJobParameters();
ExecutionContext ec = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
//obtain email address and program name from the execution context
String programName = ec.getString(AbstractSetupTasklet.BATCH_PROGRAM_NAME);
String toEmail = jobParameters.getString("TOEMAIL");
if(StringUtils.isEmpty(toEmail)) {
LOGGER.info("No email address associated with the user. Job status is " + programStatus);
return RepeatStatus.FINISHED;
}
else {
//construct the message
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(toEmail);
message.setSubject("Batch Reporting");
message.setText("The batch program " + programName + " has exited with a status of " + programStatus);
emailSender.send(message);
LOGGER.info("Email succesfully sent to user at " + toEmail);
return RepeatStatus.FINISHED;
}
}
}
As seen in the code above, I want to return the programStatus
or something that says 'the job failed on X step with a status of X'
EDIT:
For anyone wondering, I'll post my completed code below. I made a new method to construct an email message to cut down on repeat code as well
public class SendEmailTasklet implements Tasklet {
final static Logger LOGGER = LoggerFactory.getLogger(SendEmailTasklet.class);
@Autowired
public JavaMailSender emailSender;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
//Get the job info
JobParameters jobParameters = chunkContext.getStepContext().getStepExecution().getJobParameters();
ExecutionContext ec = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
//Get the step info
JobExecution jobExecutions = chunkContext.getStepContext().getStepExecution().getJobExecution();
Collection<StepExecution> stepExecution = jobExecutions.getStepExecutions();
//Get the email address and program name
String programName = ec.getString(AbstractSetupTasklet.BATCH_PROGRAM_NAME);
String toEmail = jobParameters.getString("TOEMAIL");
//If no email address exists, do not send the email.
if(StringUtils.isEmpty(toEmail)) {
LOGGER.info("No email address associated with the user.");
return RepeatStatus.FINISHED;
}
else {
//Check for the first failed step
for (StepExecution step : stepExecution) {
if(step.getExitStatus().equals(ExitStatus.FAILED)) {
String failedStep = step.getStepName();
sendBatchReportEmail(toEmail, programName, failedStep);
LOGGER.info(programName + " has failed on the step " + failedStep);
break;
}
}
sendBatchReportEmail(toEmail, programName, null);
LOGGER.info("No email address associated with the user.");
return RepeatStatus.FINISHED;
}
}
public void sendBatchReportEmail(String toEmail, String programName, String stepName) {
if(Utils.isEmpty(stepName)) {
//construct the message
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(toEmail);
message.setSubject("Batch Reporting");
message.setText("The batch program " + programName + " has completed.");
emailSender.send(message);
LOGGER.info("Email succesfully sent to user at " + toEmail);
}
else {
//construct the message
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(toEmail);
message.setSubject("Batch Reporting");
message.setText("The batch program " + programName + " has failed on step: " + stepName);
emailSender.send(message);
LOGGER.info("Email succesfully sent to user at " + toEmail + "and has failed on the step: " + stepName);
}
}
}
Upvotes: 0
Views: 702
Reputation: 31590
You can get access to the job execution from the chunk context with chunkContext.getStepContext().getStepExecution().getJobExecution()
.
Once you have the job execution, you can get all step executions with jobExecution.getStepExecutions()
and iterate through them to check the last failed step.
The last failed StepExecution gives you the step name, exit code and description which you need to create your message then add it to the job execution context.
Hope this helps.
Upvotes: 1