Prevent a task from starting if an inst with the same name is running.
resolves #81 Using LockRegistryLeaderInitiator to do leadership election. When task is started and singleInstanceEnabled isset to true then we use leader election to determine if a task needs to be started. Error Event Name had to be updated
This commit is contained in:
committed by
Michael Minella
parent
94e074d841
commit
d8a73ba183
@@ -19,9 +19,12 @@ package org.springframework.cloud.task.executionid;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.h2.tools.Server;
|
||||
@@ -51,6 +54,7 @@ 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.core.simple.SimpleJdbcInsert;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
@@ -122,6 +126,7 @@ public class TaskStartTests {
|
||||
template.execute("DROP TABLE IF EXISTS TASK_SEQ");
|
||||
template.execute("DROP TABLE IF EXISTS TASK_EXECUTION_PARAMS");
|
||||
template.execute("DROP TABLE IF EXISTS TASK_EXECUTION");
|
||||
template.execute("DROP TABLE IF EXISTS TASK_LOCK");
|
||||
template.execute("DROP TABLE IF EXISTS BATCH_STEP_EXECUTION_SEQ");
|
||||
template.execute("DROP TABLE IF EXISTS BATCH_STEP_EXECUTION_CONTEXT");
|
||||
template.execute("DROP TABLE IF EXISTS BATCH_STEP_EXECUTION");
|
||||
@@ -184,6 +189,43 @@ public class TaskStartTests {
|
||||
taskRepository.completeTaskExecution(1, 0, new Date(),"");
|
||||
this.applicationContext = getTaskApplication(1).run(new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateTaskExecutionWithSingleInstanceEnabled() throws Exception {
|
||||
String params[] = {"--spring.cloud.task.singleInstanceEnabled=true",
|
||||
"--spring.cloud.task.name=foo"};
|
||||
boolean testFailed = false;
|
||||
try {
|
||||
taskRepository.createTaskExecution();
|
||||
assertEquals("Only one row is expected", 1, taskExplorer.getTaskExecutionCount());
|
||||
enableLock("foo");
|
||||
getTaskApplication(1).run(params);
|
||||
}
|
||||
catch (ApplicationContextException taskException) {
|
||||
assertEquals("Failed to start bean 'taskLifecycleListener'; nested " +
|
||||
"exception is org.springframework.cloud.task." +
|
||||
"listener.TaskExecutionException: Failed to process " +
|
||||
"@BeforeTask or @AfterTask annotation because: Task with name \"foo\" is already running.",
|
||||
taskException.getMessage());
|
||||
testFailed = true;
|
||||
}
|
||||
assertTrue("Expected TaskExecutionException for because of " +
|
||||
"singleInstanceEnabled is enabled", testFailed);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateTaskExecutionWithSingleInstanceDisabled() throws Exception {
|
||||
taskRepository.createTaskExecution();
|
||||
TaskExecution execution = taskRepository.createTaskExecution();
|
||||
taskRepository.startTaskExecution(execution.getExecutionId(), "bar",
|
||||
new Date(), new ArrayList<>(), "");
|
||||
String params[] = {"--spring.cloud.task.name=bar"};
|
||||
enableLock("bar");
|
||||
this.applicationContext = getTaskApplication(1).run(params);
|
||||
assertTrue(waitForDBToBePopulated());
|
||||
}
|
||||
|
||||
private SpringApplication getTaskApplication(Integer executionId) {
|
||||
SpringApplication myapp = new SpringApplication(TaskStartApplication.class);
|
||||
Map<String,Object> myMap = new HashMap<>();
|
||||
@@ -217,6 +259,16 @@ public class TaskStartTests {
|
||||
return isDbPopulated;
|
||||
}
|
||||
|
||||
private void enableLock(String lockKey) {
|
||||
SimpleJdbcInsert taskLockInsert = new SimpleJdbcInsert(this.dataSource).withTableName("TASK_LOCK");
|
||||
Map<String, Object> taskLockParams = new HashMap<>();
|
||||
taskLockParams.put("LOCK_KEY", UUID.nameUUIDFromBytes(lockKey.getBytes()).toString());
|
||||
taskLockParams.put("REGION", "DEFAULT");
|
||||
taskLockParams.put("CLIENT_ID", "aClientID");
|
||||
taskLockParams.put("CREATED_DATE", new Date());
|
||||
taskLockInsert.execute(taskLockParams);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class TaskLauncherConfiguration {
|
||||
private static Server defaultServer;
|
||||
|
||||
Reference in New Issue
Block a user