Introduced Error Message to Task Execution
To provide the ability to control task orchestration via the exit message, we moved the stack trace storage to a new field. This means that exit message is now a field we can use similar to how exit code is in batch, and still have the stack trace of an unsuccessful task execution stored. Resolves spring-cloud/spring-cloud-task#186 Disabled integration tests by default Just some cleanup on merge
This commit is contained in:
committed by
Glenn Renfro
parent
551a4bc53a
commit
db0565b7cf
2
pom.xml
2
pom.xml
@@ -71,8 +71,8 @@
|
||||
<module>spring-cloud-task-batch</module>
|
||||
<module>spring-cloud-task-stream</module>
|
||||
<module>spring-cloud-task-starter</module>
|
||||
<module>spring-cloud-task-integration-tests</module>
|
||||
<module>spring-cloud-task-samples</module>
|
||||
<module>spring-cloud-task-integration-tests</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -156,7 +156,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
}
|
||||
|
||||
if(this.applicationFailedEvent != null) {
|
||||
this.taskExecution.setExitMessage(stackTraceToString(this.applicationFailedEvent.getException()));
|
||||
this.taskExecution.setErrorMessage(stackTraceToString(this.applicationFailedEvent.getException()));
|
||||
}
|
||||
|
||||
if(this.taskExecution.getExitCode() != 0){
|
||||
@@ -165,7 +165,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
}
|
||||
taskExecution.setExitMessage(invokeOnTaskEnd(taskExecution).getExitMessage());
|
||||
taskRepository.completeTaskExecution(taskExecution.getExecutionId(), taskExecution.getExitCode(),
|
||||
taskExecution.getEndTime(), taskExecution.getExitMessage());
|
||||
taskExecution.getEndTime(), taskExecution.getExitMessage(), taskExecution.getErrorMessage());
|
||||
|
||||
this.finished = true;
|
||||
|
||||
@@ -237,7 +237,8 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
return new TaskExecution(taskExecution.getExecutionId(),
|
||||
taskExecution.getExitCode(), taskExecution.getTaskName(), startTime,
|
||||
endTime,taskExecution.getExitMessage(),
|
||||
Collections.unmodifiableList(taskExecution.getArguments()));
|
||||
Collections.unmodifiableList(taskExecution.getArguments()),
|
||||
taskExecution.getErrorMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.util.Assert;
|
||||
* Represents the state of the Task for each execution.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
* @author Michael Minella
|
||||
*/
|
||||
|
||||
public class TaskExecution {
|
||||
@@ -59,6 +60,13 @@ public class TaskExecution {
|
||||
*/
|
||||
private String exitMessage;
|
||||
|
||||
/**
|
||||
* Error information available upon the failure of a task
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* The arguments that were used for this task execution.
|
||||
*/
|
||||
@@ -70,7 +78,8 @@ public class TaskExecution {
|
||||
|
||||
public TaskExecution(long executionId, Integer exitCode, String taskName,
|
||||
Date startTime, Date endTime,
|
||||
String exitMessage, List<String> arguments) {
|
||||
String exitMessage, List<String> arguments,
|
||||
String errorMessage) {
|
||||
|
||||
Assert.notNull(arguments, "arguments must not be null");
|
||||
Assert.notNull(startTime, "startTime must not be null");
|
||||
@@ -81,6 +90,7 @@ public class TaskExecution {
|
||||
this.arguments = new ArrayList<>(arguments);
|
||||
this.startTime = (Date)startTime.clone();
|
||||
this.endTime = (endTime != null) ? (Date)endTime.clone() : null;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public long getExecutionId() {
|
||||
@@ -135,6 +145,14 @@ public class TaskExecution {
|
||||
this.arguments = new ArrayList<> (arguments);
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TaskExecution{" +
|
||||
@@ -144,6 +162,7 @@ public class TaskExecution {
|
||||
", startTime=" + startTime +
|
||||
", endTime=" + endTime +
|
||||
", exitMessage='" + exitMessage + '\'' +
|
||||
", errorMessage='" + errorMessage + "\'" +
|
||||
", arguments=" + arguments +
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -42,6 +42,20 @@ public interface TaskRepository {
|
||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||
String exitMessage);
|
||||
|
||||
/**
|
||||
* Notifies the repository that a taskExecution has completed.
|
||||
*
|
||||
* @param executionId to the task execution to be updated.
|
||||
* @param exitCode to be stored for this task.
|
||||
* @param endTime designated when the task completed.
|
||||
* @param exitMessage to be stored for the task.
|
||||
* @return the updated {@link TaskExecution}
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Transactional
|
||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||
String exitMessage, String errorMessage);
|
||||
|
||||
/**
|
||||
* Notifies the repository that a taskExecution needs to be created.
|
||||
*
|
||||
|
||||
@@ -58,7 +58,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
public static final String SELECT_CLAUSE = "TASK_EXECUTION_ID, "
|
||||
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
||||
+ "EXIT_MESSAGE, LAST_UPDATED ";
|
||||
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED ";
|
||||
|
||||
public static final String FROM_CLAUSE = "%PREFIX%EXECUTION";
|
||||
|
||||
@@ -78,12 +78,12 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
+ "%PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = ?";
|
||||
|
||||
private static final String UPDATE_TASK_EXECUTION = "UPDATE %PREFIX%EXECUTION set "
|
||||
+ "END_TIME = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, LAST_UPDATED = ? "
|
||||
+ "where TASK_EXECUTION_ID = ?";
|
||||
+ "END_TIME = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, ERROR_MESSAGE = ?, "
|
||||
+ "LAST_UPDATED = ? where TASK_EXECUTION_ID = ?";
|
||||
|
||||
private static final String GET_EXECUTION_BY_ID = "SELECT TASK_EXECUTION_ID, " +
|
||||
"START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
||||
+ "EXIT_MESSAGE, LAST_UPDATED "
|
||||
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED "
|
||||
+ "from %PREFIX%EXECUTION where TASK_EXECUTION_ID = ?";
|
||||
|
||||
private static final String FIND_ARGUMENT_FROM_ID = "SELECT TASK_EXECUTION_ID, "
|
||||
@@ -129,7 +129,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
Date startTime, List<String> arguments) {
|
||||
long taskExecutionId = getNextExecutionId();
|
||||
TaskExecution taskExecution = new TaskExecution(taskExecutionId, null, taskName,
|
||||
startTime, null, null, arguments);
|
||||
startTime, null, null, arguments, null);
|
||||
|
||||
Object[] queryParameters = new Object[]{ taskExecutionId, startTime, taskName, new Date()};
|
||||
jdbcTemplate.update(
|
||||
@@ -142,7 +142,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
@Override
|
||||
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime,
|
||||
String exitMessage) {
|
||||
String exitMessage, String errorMessage) {
|
||||
// Check if given TaskExecution's Id already exists, if none is found
|
||||
// it is invalid and an exception should be thrown.
|
||||
if (jdbcTemplate.queryForObject(getQuery(CHECK_TASK_EXECUTION_EXISTS), Integer.class,
|
||||
@@ -150,15 +150,21 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
throw new IllegalStateException("Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||
}
|
||||
|
||||
Object[] parameters = new Object[]{ endTime, exitCode, exitMessage, new Date(),
|
||||
Object[] parameters = new Object[]{ endTime, exitCode, exitMessage, errorMessage, new Date(),
|
||||
taskExecutionId};
|
||||
jdbcTemplate.update(
|
||||
getQuery(UPDATE_TASK_EXECUTION),
|
||||
parameters,
|
||||
new int[]{ Types.TIMESTAMP, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP,
|
||||
new int[]{ Types.TIMESTAMP, Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP,
|
||||
Types.BIGINT});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime,
|
||||
String exitMessage) {
|
||||
completeTaskExecution(taskExecutionId, exitCode, endTime, exitMessage, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the table prefix property. This will be prefixed to all
|
||||
* the table names before queries are executed. Defaults to
|
||||
@@ -374,7 +380,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
rs.getTimestamp("START_TIME"),
|
||||
rs.getTimestamp("END_TIME"),
|
||||
rs.getString("EXIT_MESSAGE"),
|
||||
getTaskArguments(id));
|
||||
getTaskArguments(id),
|
||||
rs.getString("ERROR_MESSAGE"));
|
||||
}
|
||||
|
||||
private Integer getNullableExitCode(ResultSet rs) throws SQLException {
|
||||
|
||||
@@ -56,17 +56,23 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
Date startTime, List<String> arguments) {
|
||||
long taskExecutionId = getNextExecutionId();
|
||||
TaskExecution taskExecution = new TaskExecution(taskExecutionId, null, taskName,
|
||||
startTime, null, null, arguments);
|
||||
startTime, null, null, arguments, null);
|
||||
taskExecutions.put(taskExecutionId, taskExecution);
|
||||
return taskExecution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage) {
|
||||
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage, String errorMessage) {
|
||||
TaskExecution taskExecution= taskExecutions.get(executionId);
|
||||
taskExecution.setEndTime(endTime);
|
||||
taskExecution.setExitCode(exitCode);
|
||||
taskExecution.setExitMessage(exitMessage);
|
||||
taskExecution.setErrorMessage(errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage) {
|
||||
completeTaskExecution(executionId, exitCode, endTime, exitMessage, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,6 +42,18 @@ public interface TaskExecutionDao {
|
||||
TaskExecution createTaskExecution( String taskName,
|
||||
Date startTime, List<String> arguments);
|
||||
|
||||
/**
|
||||
* Update and existing {@link TaskExecution}.
|
||||
*
|
||||
* @param executionId the id of the taskExecution to be updated.
|
||||
* @param exitCode the status of the task upon completion.
|
||||
* @param endTime the time the task completed.
|
||||
* @param exitMessage the message assigned to the task upon completion.
|
||||
* @param errorMessage error information available upon failure of a task.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage, String errorMessage);
|
||||
|
||||
/**
|
||||
* Update and existing {@link TaskExecution}.
|
||||
*
|
||||
|
||||
@@ -51,19 +51,25 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage) {
|
||||
return completeTaskExecution(executionId, exitCode, endTime, exitMessage, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||
String exitMessage) {
|
||||
String exitMessage, String errorMessage) {
|
||||
initialize();
|
||||
|
||||
validateExitInformation(executionId, exitCode, endTime);
|
||||
exitMessage = trimExitMessage(exitMessage);
|
||||
taskExecutionDao.completeTaskExecution(executionId, exitCode, endTime, exitMessage);
|
||||
taskExecutionDao.completeTaskExecution(executionId, exitCode, endTime, exitMessage, errorMessage);
|
||||
logger.debug("Updating: TaskExecution with executionId="+executionId
|
||||
+ " with the following {"
|
||||
+ "exitCode=" + exitCode
|
||||
+ ", endTime=" + endTime
|
||||
+ ", exitMessage='" + exitMessage + '\''
|
||||
+ ", errorMessage='" + errorMessage + '\''
|
||||
+ '}');
|
||||
|
||||
return taskExecutionDao.getTaskExecution(executionId);
|
||||
|
||||
@@ -6,6 +6,7 @@ CREATE TABLE TASK_EXECUTION (
|
||||
TASK_NAME VARCHAR(100) ,
|
||||
EXIT_CODE INTEGER ,
|
||||
EXIT_MESSAGE VARCHAR(2500) ,
|
||||
ERROR_MESSAGE VARCHAR(2500) ,
|
||||
LAST_UPDATED TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ CREATE TABLE TASK_EXECUTION (
|
||||
TASK_NAME VARCHAR(100) ,
|
||||
EXIT_CODE INTEGER ,
|
||||
EXIT_MESSAGE VARCHAR(2500) ,
|
||||
ERROR_MESSAGE VARCHAR(2500) ,
|
||||
LAST_UPDATED TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ CREATE TABLE TASK_EXECUTION (
|
||||
TASK_NAME VARCHAR(100) ,
|
||||
EXIT_CODE INTEGER ,
|
||||
EXIT_MESSAGE VARCHAR(2500) ,
|
||||
ERROR_MESSAGE VARCHAR(2500) ,
|
||||
LAST_UPDATED TIMESTAMP
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ CREATE TABLE TASK_EXECUTION (
|
||||
TASK_NAME VARCHAR2(100) ,
|
||||
EXIT_CODE INTEGER ,
|
||||
EXIT_MESSAGE VARCHAR2(2500) ,
|
||||
ERROR_MESSAGE VARCHAR2(2500) ,
|
||||
LAST_UPDATED TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ CREATE TABLE TASK_EXECUTION (
|
||||
TASK_NAME VARCHAR(100) ,
|
||||
EXIT_CODE INTEGER ,
|
||||
EXIT_MESSAGE VARCHAR(2500) ,
|
||||
ERROR_MESSAGE VARCHAR(2500) ,
|
||||
LAST_UPDATED TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ CREATE TABLE TASK_EXECUTION (
|
||||
TASK_NAME VARCHAR(100) ,
|
||||
EXIT_CODE INTEGER ,
|
||||
EXIT_MESSAGE VARCHAR(2500) ,
|
||||
ERROR_MESSAGE VARCHAR(2500) ,
|
||||
LAST_UPDATED DATETIME
|
||||
);
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ public class TaskCoreTests {
|
||||
private static final String UPDATE_TASK_MESSAGE = "Updating: TaskExecution with executionId=";
|
||||
private static final String SUCCESS_EXIT_CODE_MESSAGE = "with the following {exitCode=0";
|
||||
private static final String EXCEPTION_EXIT_CODE_MESSAGE = "with the following {exitCode=1";
|
||||
private static final String EXIT_MESSAGE =
|
||||
"exitMessage='java.lang.IllegalStateException: Failed to execute CommandLineRunner";
|
||||
private static final String ERROR_MESSAGE =
|
||||
"errorMessage='java.lang.IllegalStateException: Failed to execute CommandLineRunner";
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class TaskCoreTests {
|
||||
assertTrue("Test results have incorrect exit code: " + output,
|
||||
output.contains(EXCEPTION_EXIT_CODE_MESSAGE));
|
||||
assertTrue("Test results have incorrect exit message: " + output,
|
||||
output.contains(EXIT_MESSAGE));
|
||||
output.contains(ERROR_MESSAGE));
|
||||
assertTrue("Test results have exception message: " + output,
|
||||
output.contains(EXCEPTION_MESSAGE));
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class TaskExecutionListenerTests {
|
||||
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
|
||||
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
||||
TaskExecution taskExecution = new TaskExecution(0, null, "wombat",
|
||||
new Date(), new Date(), null, new ArrayList<String>());
|
||||
new Date(), new Date(), null, new ArrayList<String>(), null);
|
||||
verifyListenerResults(true, false, false, taskExecution,taskExecutionListener);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class TaskExecutionListenerTests {
|
||||
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
|
||||
|
||||
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat",
|
||||
new Date(), new Date(), null, new ArrayList<String>());
|
||||
new Date(), new Date(), null, new ArrayList<String>(), null);
|
||||
verifyListenerResults(true, true, false, taskExecution,taskExecutionListener);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public class TaskExecutionListenerTests {
|
||||
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
|
||||
|
||||
TaskExecution taskExecution = new TaskExecution(0, 1, "wombat", new Date(),
|
||||
new Date(), null, new ArrayList<String>());
|
||||
new Date(), null, new ArrayList<String>(), null);
|
||||
verifyListenerResults(true, true, true, taskExecution,taskExecutionListener);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public class TaskExecutionListenerTests {
|
||||
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
|
||||
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
||||
TaskExecution taskExecution = new TaskExecution(0, null, "wombat",
|
||||
new Date(), new Date(), null, new ArrayList<String>());
|
||||
new Date(), new Date(), null, new ArrayList<String>(), null);
|
||||
verifyListenerResults(true, false, false, taskExecution,annotatedListener);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public class TaskExecutionListenerTests {
|
||||
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
|
||||
|
||||
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat",
|
||||
new Date(), new Date(), null, new ArrayList<String>());
|
||||
new Date(), new Date(), null, new ArrayList<String>(), null);
|
||||
verifyListenerResults(true, true, false, taskExecution,annotatedListener);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public class TaskExecutionListenerTests {
|
||||
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
|
||||
|
||||
TaskExecution taskExecution = new TaskExecution(0, 1, "wombat", new Date(),
|
||||
new Date(), null, new ArrayList<String>());
|
||||
new Date(), null, new ArrayList<String>(), null);
|
||||
verifyListenerResults(true, true, true, taskExecution,annotatedListener);
|
||||
}
|
||||
|
||||
@@ -169,13 +169,16 @@ public class TaskExecutionListenerTests {
|
||||
assertEquals(TestListener.END_MESSAGE, actualListener.getTaskExecution().getExitMessage());
|
||||
assertNotNull(actualListener.getThrowable());
|
||||
assertTrue(actualListener.getThrowable() instanceof RuntimeException);
|
||||
assertTrue(actualListener.getTaskExecution().getErrorMessage().startsWith("java.lang.RuntimeException: This was expected"));
|
||||
}
|
||||
else if(isTaskEnd){
|
||||
assertEquals(TestListener.END_MESSAGE, actualListener.getTaskExecution().getExitMessage());
|
||||
assertNull(actualListener.getTaskExecution().getErrorMessage());
|
||||
assertNull(actualListener.getThrowable());
|
||||
}
|
||||
else {
|
||||
assertEquals(TestListener.START_MESSAGE, actualListener.getTaskExecution().getExitMessage());
|
||||
assertNull(actualListener.getTaskExecution().getErrorMessage());
|
||||
assertNull(actualListener.getThrowable());
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public class TaskLifecycleListenerTests {
|
||||
assertEquals(exitCode, taskExecution.getExitCode());
|
||||
|
||||
if(exception != null) {
|
||||
assertTrue(taskExecution.getExitMessage().length() > exception.getStackTrace().length);
|
||||
assertTrue(taskExecution.getErrorMessage().length() > exception.getStackTrace().length);
|
||||
}
|
||||
else {
|
||||
assertNull(taskExecution.getExitMessage());
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.task.repository.database.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import org.springframework.cloud.task.util.TestDBUtils;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@@ -42,30 +43,30 @@ public class FindAllPagingQueryProviderTests {
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{"Oracle", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED, ROWNUM as "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, ROWNUM as "
|
||||
+ "TMP_ROW_NUM FROM (SELECT TASK_EXECUTION_ID, START_TIME, "
|
||||
+ "END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED "
|
||||
+ "END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED "
|
||||
+ "FROM %PREFIX%EXECUTION ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC)) WHERE TMP_ROW_NUM >= 1 AND "
|
||||
+ "TMP_ROW_NUM < 11"},
|
||||
{"HSQL Database Engine","SELECT LIMIT 0 10 TASK_EXECUTION_ID, "
|
||||
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, "
|
||||
+ "LAST_UPDATED FROM %PREFIX%EXECUTION ORDER BY "
|
||||
+ "ERROR_MESSAGE, LAST_UPDATED FROM %PREFIX%EXECUTION ORDER BY "
|
||||
+ "START_TIME DESC, TASK_EXECUTION_ID DESC"},
|
||||
{"PostgreSQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED "
|
||||
+ "FROM %PREFIX%EXECUTION ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC LIMIT 10 OFFSET 0"},
|
||||
{"MySQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "%PREFIX%EXECUTION ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"},
|
||||
{"Microsoft SQL Server","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED, ROW_NUMBER() "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, ROW_NUMBER() "
|
||||
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
|
||||
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION) TASK_EXECUTION_PAGE "
|
||||
+ "WHERE TMP_ROW_NUM >= 1 AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, "
|
||||
|
||||
@@ -16,19 +16,20 @@
|
||||
|
||||
package org.springframework.cloud.task.repository.database.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import org.springframework.cloud.task.repository.database.PagingQueryProvider;
|
||||
import org.springframework.cloud.task.util.TestDBUtils;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@@ -43,34 +44,34 @@ public class WhereClausePagingQueryProviderTests {
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
{"Oracle", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED, ROWNUM as "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, ROWNUM as "
|
||||
+ "TMP_ROW_NUM FROM (SELECT TASK_EXECUTION_ID, START_TIME, "
|
||||
+ "END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED "
|
||||
+ "FROM %PREFIX%EXECUTION "
|
||||
+ "END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, "
|
||||
+ "LAST_UPDATED FROM %PREFIX%EXECUTION "
|
||||
+ "WHERE TASK_EXECUTION_ID = '0000' ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC)) WHERE TMP_ROW_NUM >= 1 AND "
|
||||
+ "TMP_ROW_NUM < 11"},
|
||||
{"HSQL Database Engine","SELECT LIMIT 0 10 TASK_EXECUTION_ID, "
|
||||
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, "
|
||||
+ "LAST_UPDATED FROM %PREFIX%EXECUTION "
|
||||
+ "ERROR_MESSAGE, LAST_UPDATED FROM %PREFIX%EXECUTION "
|
||||
+ "WHERE TASK_EXECUTION_ID = '0000' ORDER BY "
|
||||
+ "START_TIME DESC, TASK_EXECUTION_ID DESC"},
|
||||
{"PostgreSQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED "
|
||||
+ "FROM %PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = '0000' "
|
||||
+ "ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC LIMIT 10 OFFSET 0"},
|
||||
{"MySQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "%PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = '0000' "
|
||||
+ "ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"},
|
||||
{"Microsoft SQL Server","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED FROM "
|
||||
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED, ROW_NUMBER() "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, ROW_NUMBER() "
|
||||
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
|
||||
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = "
|
||||
+ "'0000') TASK_EXECUTION_PAGE WHERE TMP_ROW_NUM >= 1 "
|
||||
|
||||
@@ -70,6 +70,6 @@ public class TaskExecutionCreator {
|
||||
TaskExecution expectedTaskExecution) {
|
||||
return taskRepository.completeTaskExecution(expectedTaskExecution.getExecutionId(),
|
||||
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
|
||||
expectedTaskExecution.getExitMessage());
|
||||
expectedTaskExecution.getExitMessage(), expectedTaskExecution.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,8 @@ public class TestDBUtils {
|
||||
rs.getTimestamp("START_TIME"),
|
||||
rs.getTimestamp("END_TIME"),
|
||||
rs.getString("EXIT_MESSAGE"),
|
||||
new ArrayList<String>(0));
|
||||
new ArrayList<String>(0),
|
||||
rs.getString("ERROR_MESSAGE"));
|
||||
return taskExecution;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ public class TestVerifierUtils {
|
||||
String taskName = UUID.randomUUID().toString();
|
||||
|
||||
return new TaskExecution(executionId, 0, taskName,
|
||||
startTime, null, null, new ArrayList<String>());
|
||||
startTime, null, null, new ArrayList<String>(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +108,7 @@ public class TestVerifierUtils {
|
||||
String exitMessage = UUID.randomUUID().toString();
|
||||
|
||||
return new TaskExecution(executionId, exitCode, taskName,
|
||||
startTime, endTime, exitMessage, new ArrayList<String>());
|
||||
startTime, endTime, exitMessage, new ArrayList<String>(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,7 +117,6 @@ public class TestVerifierUtils {
|
||||
* @return
|
||||
*/
|
||||
public static TaskExecution createSampleTaskExecution(long executionId) {
|
||||
Random randomGenerator = new Random();
|
||||
Date startTime = new Date();
|
||||
String taskName = UUID.randomUUID().toString();
|
||||
List<String> args = new ArrayList<>(ARG_SIZE);
|
||||
@@ -125,7 +124,7 @@ public class TestVerifierUtils {
|
||||
args.add(UUID.randomUUID().toString());
|
||||
}
|
||||
return new TaskExecution(executionId, null, taskName,
|
||||
startTime, null, null, args);
|
||||
startTime, null, null, args, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,6 +152,9 @@ public class TestVerifierUtils {
|
||||
assertEquals("exitMessage must be equal",
|
||||
expectedTaskExecution.getExitMessage(),
|
||||
actualTaskExecution.getExitMessage());
|
||||
assertEquals("errorMessage must be equal",
|
||||
expectedTaskExecution.getErrorMessage(),
|
||||
actualTaskExecution.getErrorMessage());
|
||||
if (expectedTaskExecution.getArguments() != null) {
|
||||
assertNotNull("arguments should not be null",
|
||||
actualTaskExecution.getArguments());
|
||||
|
||||
@@ -79,9 +79,12 @@ assumed to be 0.
|
||||
|The time the task was completed as indicated by the `ApplicationReadyEvent`.
|
||||
|
||||
|`exitMessage`
|
||||
|Any information available at the time of exit. If an exception is the cause of the end
|
||||
of the task (as indicated via an `ApplicationFailedEvent`), the stack trace for that
|
||||
exception will be stored here.
|
||||
|Any information available at the time of exit. This can programatically be set via a
|
||||
`TaskExecutionListener`.
|
||||
|
||||
|`errorMessage`
|
||||
|If an exception is the cause of the end of the task (as indicated via an
|
||||
`ApplicationFailedEvent`), the stack trace for that exception will be stored here.
|
||||
|
||||
|`arguments`
|
||||
|A `List` of the string command line arguments as they were passed into the executable boot
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>skipIntegrationTests</id>
|
||||
<id>integrationTests</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -115,7 +115,25 @@
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
<skipTests>false</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>skipIntegrationTests</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<skipTests>false</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -44,10 +44,13 @@ import org.springframework.cloud.task.repository.support.SimpleTaskExplorer;
|
||||
import org.springframework.cloud.task.repository.support.TaskExecutionDaoFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.SocketUtils;
|
||||
@@ -61,8 +64,8 @@ public class TaskLauncherSinkTests {
|
||||
|
||||
private final static int WAIT_INTERVAL = 500;
|
||||
private final static int MAX_WAIT_TIME = 5000;
|
||||
private final static String URL = "maven://org.springframework.cloud.task.app:"
|
||||
+ "timestamp-task:jar:1.0.0.BUILD-SNAPSHOT";
|
||||
private final static String URL = "maven://io.spring.cloud:"
|
||||
+ "timestamp-task:jar:1.1.0.BUILD-SNAPSHOT";
|
||||
private final static String DATASOURCE_URL;
|
||||
private final static String DATASOURCE_USER_NAME = "SA";
|
||||
private final static String DATASOURCE_USER_PASSWORD = "";
|
||||
@@ -104,6 +107,7 @@ public class TaskLauncherSinkTests {
|
||||
properties.put("spring.datasource.password", DATASOURCE_USER_PASSWORD);
|
||||
properties.put("spring.datasource.driverClassName", DATASOURCE_DRIVER_CLASS_NAME);
|
||||
properties.put("spring.application.name",TASK_NAME);
|
||||
properties.put("spring.cloud.task.initialize.enable", "false");
|
||||
|
||||
JdbcTemplate template = new JdbcTemplate(this.dataSource);
|
||||
template.execute("DROP TABLE IF EXISTS TASK_TASK_BATCH");
|
||||
@@ -119,6 +123,16 @@ public class TaskLauncherSinkTests {
|
||||
template.execute("DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_CONTEXT");
|
||||
template.execute("DROP TABLE IF EXISTS BATCH_JOB_EXECUTION");
|
||||
template.execute("DROP TABLE IF EXISTS BATCH_JOB_INSTANCE");
|
||||
|
||||
|
||||
DataSourceInitializer initializer = new DataSourceInitializer();
|
||||
|
||||
initializer.setDataSource(dataSource);
|
||||
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
|
||||
databasePopulator.addScript(new ClassPathResource("/org/springframework/cloud/task/schema-h2.sql"));
|
||||
initializer.setDatabasePopulator(databasePopulator);
|
||||
|
||||
initializer.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -115,6 +115,45 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integrationTests</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/TaskPartitionerTests.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>skipIntegrationTests</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/TaskPartitionerTests.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -99,7 +99,7 @@ public class JobConfiguration {
|
||||
|
||||
@Bean
|
||||
public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer) throws Exception {
|
||||
Resource resource = resourceLoader.getResource("maven://io.spring.cloud:partitioned-batch-job:1.0.3.BUILD-SNAPSHOT");
|
||||
Resource resource = resourceLoader.getResource("maven://io.spring.cloud:partitioned-batch-job:1.1.0.BUILD-SNAPSHOT");
|
||||
|
||||
DeployerPartitionHandler partitionHandler = new DeployerPartitionHandler(taskLauncher, jobExplorer, resource, "workerStep");
|
||||
|
||||
|
||||
@@ -52,6 +52,14 @@
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
Reference in New Issue
Block a user