diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java index 9ac094dc4..c2339b95d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ import org.springframework.util.ClassUtils; * @author Michael Minella * @author Chris Schaefer * @author Mahmoud Ben Hassine + * @author Jinwoo Bae */ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAware { @@ -261,7 +262,13 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw } } finally { - + stepExecution.setEndTime(LocalDateTime.now()); + Duration stepExecutionDuration = BatchMetrics.calculateDuration(stepExecution.getStartTime(), + stepExecution.getEndTime()); + if (logger.isInfoEnabled()) { + logger.info("Step: [" + stepExecution.getStepName() + "] executed in " + + BatchMetrics.formatDuration(stepExecutionDuration)); + } try { // Update the step execution to the latest known value so the // listeners can act on it @@ -287,14 +294,8 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw name, stepExecution.getJobExecution().getJobInstance().getJobName()), e); } stopObservation(stepExecution, observation); - stepExecution.setEndTime(LocalDateTime.now()); stepExecution.setExitStatus(exitStatus); - Duration stepExecutionDuration = BatchMetrics.calculateDuration(stepExecution.getStartTime(), - stepExecution.getEndTime()); - if (logger.isInfoEnabled()) { - logger.info("Step: [" + stepExecution.getStepName() + "] executed in " - + BatchMetrics.formatDuration(stepExecutionDuration)); - } + try { getJobRepository().update(stepExecution); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/AbstractStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/AbstractStepTests.java new file mode 100644 index 000000000..56e11f5b7 --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/AbstractStepTests.java @@ -0,0 +1,57 @@ +package org.springframework.batch.core.step; + +import org.junit.jupiter.api.Test; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobInstance; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.core.repository.JobRepository; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link AbstractStep}. + */ +class AbstractStepTests { + + private AbstractStep tested; + + + StepExecution execution = new StepExecution("foo", + new JobExecution(new JobInstance(1L, "bar"), new JobParameters())); + + @Test + void testSetEndTime() throws Exception { + tested = new AbstractStep() { + @Override + protected void doExecute(StepExecution stepExecution) { + } + }; + + JobRepository jobRepository = mock(); + + final List stepEndTime = new ArrayList<>(); + + tested.setStepExecutionListeners(new StepExecutionListener[] { new StepExecutionListener() { + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + stepEndTime.add(stepExecution.getEndTime()); + return ExitStatus.COMPLETED; + } + } }); + + tested.setJobRepository(jobRepository); + tested.execute(execution); + + assertEquals(1, stepEndTime.size()); + assertNotNull(stepEndTime.get(0)); + } +}