TSK-967: Refactor the DBCleaner

This commit is contained in:
Benjamin Eckstein 2019-12-09 15:19:08 +01:00 committed by Mustapha Zorgati
parent e8c0d473db
commit bf152674d3
21 changed files with 205 additions and 231 deletions

View File

@ -1198,6 +1198,8 @@ public class TaskServiceImpl implements TaskService {
PrioDurationHolder prioDurationFromAttachments) PrioDurationHolder prioDurationFromAttachments)
throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException { throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException {
validateObjectReference(newTaskImpl.getPrimaryObjRef(), "primary ObjectReference", "Task"); validateObjectReference(newTaskImpl.getPrimaryObjRef(), "primary ObjectReference", "Task");
//TODO: not safe to rely only on different timestamps.
// With fast execution below 1ms there will be no concurrencyException
if (oldTaskImpl.getModified() != null && !oldTaskImpl.getModified().equals(newTaskImpl.getModified()) if (oldTaskImpl.getModified() != null && !oldTaskImpl.getModified().equals(newTaskImpl.getModified())
|| oldTaskImpl.getClaimed() != null && !oldTaskImpl.getClaimed().equals(newTaskImpl.getClaimed()) || oldTaskImpl.getClaimed() != null && !oldTaskImpl.getClaimed().equals(newTaskImpl.getClaimed())
|| oldTaskImpl.getState() != null && !oldTaskImpl.getState().equals(newTaskImpl.getState())) { || oldTaskImpl.getState() != null && !oldTaskImpl.getState().equals(newTaskImpl.getState())) {

View File

@ -24,7 +24,6 @@ import pro.taskana.TimeInterval;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.sampledata.DBCleaner;
import pro.taskana.sampledata.SampleDataGenerator; import pro.taskana.sampledata.SampleDataGenerator;
/** /**
@ -44,17 +43,17 @@ public abstract class AbstractAccTest {
public static void resetDb(boolean dropTables) throws SQLException, IOException { public static void resetDb(boolean dropTables) throws SQLException, IOException {
DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource();
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
DBCleaner dbCleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
if (dropTables) { if (dropTables) {
dbCleaner.dropDb(dataSource, schemaName); sampleDataGenerator.dropDb();
} }
dataSource = TaskanaEngineConfigurationTest.getDataSource(); dataSource = TaskanaEngineConfigurationTest.getDataSource();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false,
schemaName); schemaName);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
dbCleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
new SampleDataGenerator(dataSource, schemaName).generateTestData(); sampleDataGenerator.generateTestData();
} }
protected ObjectReference createObjectReference(String company, String system, String systemInstance, String type, protected ObjectReference createObjectReference(String company, String system, String systemInstance, String type,

View File

@ -81,6 +81,13 @@ public class GetClassificationAccTest extends AbstractAccTest {
assertEquals("custom8", classification.getCustom8()); assertEquals("custom8", classification.getCustom8());
} }
@Test
void testGetClassificationWithSpecialCharacter() throws ClassificationNotFoundException {
Classification classification = classificationService.getClassification(
"CLI:100000000000000000000000000000000009");
assertEquals("Zustimmungserklärung", classification.getName());
}
@Test @Test
public void testGetClassificationAsSummary() throws ClassificationNotFoundException { public void testGetClassificationAsSummary() throws ClassificationNotFoundException {
ClassificationSummary classification = classificationService ClassificationSummary classification = classificationService

View File

@ -11,7 +11,6 @@ import org.junit.jupiter.api.BeforeAll;
import pro.taskana.TaskanaEngine; import pro.taskana.TaskanaEngine;
import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.sampledata.DBCleaner;
import pro.taskana.sampledata.SampleDataGenerator; import pro.taskana.sampledata.SampleDataGenerator;
/** /**
@ -35,13 +34,13 @@ public class AbstractReportAccTest {
private static void resetDb() throws SQLException, IOException { private static void resetDb() throws SQLException, IOException {
DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource();
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
DBCleaner cleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false,
schemaName); schemaName);
taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT); taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
new SampleDataGenerator(dataSource, schemaName).generateMonitorData(); sampleDataGenerator.generateMonitorData();
} }
} }

View File

@ -120,11 +120,11 @@ public class UpdateTaskAccTest extends AbstractAccTest {
Task task2 = taskService.getTask("TKI:000000000000000000000000000000000000"); Task task2 = taskService.getTask("TKI:000000000000000000000000000000000000");
task.setCustomAttribute("1", "willi"); task.setCustomAttribute("1", "willi");
Task updatedTask = null; Task updatedTask = taskService.updateTask(task);
updatedTask = taskService.updateTask(task); taskService.getTask(updatedTask.getId());
updatedTask = taskService.getTask(updatedTask.getId());
task2.setCustomAttribute("2", "Walter"); task2.setCustomAttribute("2", "Walter");
//TODO flaky test ... if speed is too high,
Assertions.assertThrows(ConcurrencyException.class, () -> taskService.updateTask(task2), Assertions.assertThrows(ConcurrencyException.class, () -> taskService.updateTask(task2),
"The task has already been updated by another user"); "The task has already been updated by another user");

View File

@ -32,7 +32,7 @@ import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator;
/** /**
* Integration Test for ClassificationServiceImpl with connection management mode AUTOCOMMIT. * Integration Test for ClassificationServiceImpl with connection management mode AUTOCOMMIT.
@ -49,11 +49,10 @@ public class ClassificationServiceImplIntAutoCommitTest {
private TaskanaEngineImpl taskanaEngineImpl; private TaskanaEngineImpl taskanaEngineImpl;
@BeforeClass @BeforeClass
public static void resetDb() throws SQLException { public static void resetDb() {
DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); DataSource ds = TaskanaEngineConfigurationTest.getDataSource();
DBCleaner cleaner = new DBCleaner();
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
cleaner.dropDb(ds, schemaName); new SampleDataGenerator(ds, schemaName).dropDb();
} }
@Before @Before
@ -66,8 +65,8 @@ public class ClassificationServiceImplIntAutoCommitTest {
classificationService = taskanaEngine.getClassificationService(); classificationService = taskanaEngine.getClassificationService();
taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
DBCleaner cleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
cleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
} }
@Test @Test

View File

@ -39,7 +39,7 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.ClassificationImpl; import pro.taskana.impl.ClassificationImpl;
import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator;
/** /**
* Integration Test for ClassificationServiceImpl with connection management mode EXPLICIT. * Integration Test for ClassificationServiceImpl with connection management mode EXPLICIT.
@ -60,9 +60,8 @@ public class ClassificationServiceImplIntExplicitTest {
@BeforeClass @BeforeClass
public static void resetDb() throws SQLException { public static void resetDb() throws SQLException {
DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); DataSource ds = TaskanaEngineConfigurationTest.getDataSource();
DBCleaner cleaner = new DBCleaner();
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
cleaner.dropDb(ds, schemaName); new SampleDataGenerator(ds, schemaName).dropDb();
} }
@Before @Before
@ -75,8 +74,8 @@ public class ClassificationServiceImplIntExplicitTest {
classificationService = taskanaEngine.getClassificationService(); classificationService = taskanaEngine.getClassificationService();
taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT);
DBCleaner cleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
cleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
} }
@Test @Test

View File

@ -50,7 +50,7 @@ import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.WorkbasketImpl;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.util.IdGenerator; import pro.taskana.impl.util.IdGenerator;
import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.security.CurrentUserContext; import pro.taskana.security.CurrentUserContext;
import pro.taskana.security.JAASExtension; import pro.taskana.security.JAASExtension;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -90,8 +90,8 @@ class TaskServiceImplIntAutocommitTest {
taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService(); taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService();
classificationService = taskanaEngine.getClassificationService(); classificationService = taskanaEngine.getClassificationService();
workbasketService = taskanaEngine.getWorkbasketService(); workbasketService = taskanaEngine.getWorkbasketService();
DBCleaner cleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
cleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
} }
@Test @Test

View File

@ -56,7 +56,7 @@ import pro.taskana.impl.WorkbasketImpl;
import pro.taskana.impl.WorkbasketSummaryImpl; import pro.taskana.impl.WorkbasketSummaryImpl;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.util.IdGenerator; import pro.taskana.impl.util.IdGenerator;
import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.security.CurrentUserContext; import pro.taskana.security.CurrentUserContext;
import pro.taskana.security.JAASExtension; import pro.taskana.security.JAASExtension;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -71,8 +71,6 @@ class TaskServiceImplIntExplicitTest {
private static DataSource dataSource; private static DataSource dataSource;
private static DBCleaner cleaner;
private static TaskServiceImpl taskServiceImpl; private static TaskServiceImpl taskServiceImpl;
private static TaskanaEngineConfiguration taskanaEngineConfiguration; private static TaskanaEngineConfiguration taskanaEngineConfiguration;
@ -101,15 +99,15 @@ class TaskServiceImplIntExplicitTest {
classificationService = taskanaEngine.getClassificationService(); classificationService = taskanaEngine.getClassificationService();
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT);
workbasketService = taskanaEngine.getWorkbasketService(); workbasketService = taskanaEngine.getWorkbasketService();
cleaner = new DBCleaner();
DbSchemaCreator creator = new DbSchemaCreator(dataSource, dataSource.getConnection().getSchema()); DbSchemaCreator creator = new DbSchemaCreator(dataSource, dataSource.getConnection().getSchema());
creator.run(); creator.run();
} }
@BeforeEach @BeforeEach
void resetDb() throws SQLException { void resetDb() {
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
cleaner.clearDb(dataSource, schemaName); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
sampleDataGenerator.clearDb();
} }
@WithAccessId(userName = "Elena", groupNames = {"businessadmin"}) @WithAccessId(userName = "Elena", groupNames = {"businessadmin"})
@ -195,7 +193,7 @@ class TaskServiceImplIntExplicitTest {
((WorkbasketSummaryImpl) (test.getWorkbasketSummary())).setId("2"); ((WorkbasketSummaryImpl) (test.getWorkbasketSummary())).setId("2");
Assertions.assertThrows(WorkbasketNotFoundException.class, () -> Assertions.assertThrows(WorkbasketNotFoundException.class, () ->
taskServiceImpl.createTask(test)); taskServiceImpl.createTask(test));
} }
@WithAccessId(userName = "Elena", groupNames = {"businessadmin"}) @WithAccessId(userName = "Elena", groupNames = {"businessadmin"})
@ -223,7 +221,7 @@ class TaskServiceImplIntExplicitTest {
task.setClassificationKey(classification.getKey()); task.setClassificationKey(classification.getKey());
Assertions.assertThrows(ClassificationNotFoundException.class, () -> Assertions.assertThrows(ClassificationNotFoundException.class, () ->
taskServiceImpl.createTask(task)); taskServiceImpl.createTask(task));
} }
@WithAccessId(userName = "Elena", groupNames = {"DummyGroup", "businessadmin"}) @WithAccessId(userName = "Elena", groupNames = {"DummyGroup", "businessadmin"})
@ -351,7 +349,7 @@ class TaskServiceImplIntExplicitTest {
taskanaEngineImpl.setConnection(connection); taskanaEngineImpl.setConnection(connection);
Assertions.assertThrows(TaskNotFoundException.class, () -> Assertions.assertThrows(TaskNotFoundException.class, () ->
taskServiceImpl.transfer(UUID.randomUUID() + "_X", "1")); taskServiceImpl.transfer(UUID.randomUUID() + "_X", "1"));
} }
@WithAccessId(userName = "User", groupNames = {"businessadmin"}) @WithAccessId(userName = "User", groupNames = {"businessadmin"})

View File

@ -40,7 +40,7 @@ import pro.taskana.impl.WorkbasketImpl;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.util.IdGenerator; import pro.taskana.impl.util.IdGenerator;
import pro.taskana.mappings.WorkbasketMapper; import pro.taskana.mappings.WorkbasketMapper;
import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -62,9 +62,8 @@ public class WorkbasketServiceImplIntAutocommitTest {
@BeforeClass @BeforeClass
public static void resetDb() throws SQLException { public static void resetDb() throws SQLException {
DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); DataSource ds = TaskanaEngineConfigurationTest.getDataSource();
DBCleaner cleaner = new DBCleaner();
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
cleaner.dropDb(ds, schemaName); new SampleDataGenerator(ds, schemaName).dropDb();
} }
@Before @Before
@ -76,8 +75,8 @@ public class WorkbasketServiceImplIntAutocommitTest {
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
workBasketService = taskanaEngine.getWorkbasketService(); workBasketService = taskanaEngine.getWorkbasketService();
DBCleaner cleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
cleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
now = Instant.now(); now = Instant.now();
} }

View File

@ -33,7 +33,7 @@ import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.WorkbasketImpl;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.util.IdGenerator; import pro.taskana.impl.util.IdGenerator;
import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.security.JAASRunner; import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId; import pro.taskana.security.WithAccessId;
@ -54,11 +54,10 @@ public class WorkbasketServiceImplIntExplicitTest {
private WorkbasketService workBasketService; private WorkbasketService workBasketService;
@BeforeClass @BeforeClass
public static void resetDb() throws SQLException { public static void resetDb() {
DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); DataSource ds = TaskanaEngineConfigurationTest.getDataSource();
DBCleaner cleaner = new DBCleaner();
String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName();
cleaner.dropDb(ds, schemaName); new SampleDataGenerator(ds, schemaName).dropDb();
} }
@Before @Before
@ -70,8 +69,8 @@ public class WorkbasketServiceImplIntExplicitTest {
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT);
DBCleaner cleaner = new DBCleaner(); SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
cleaner.clearDb(dataSource, schemaName); sampleDataGenerator.clearDb();
} }
@WithAccessId(userName = "Elena", groupNames = {"businessadmin"}) @WithAccessId(userName = "Elena", groupNames = {"businessadmin"})

View File

@ -11,13 +11,27 @@ import pro.taskana.configuration.DbSchemaCreator;
*/ */
class SampleDataGeneratorTest { class SampleDataGeneratorTest {
private static final String JDBC_URL = "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS TASKANA";
@Test @Test
void getScriptsValidSql() { void getScriptsValidSql() {
PooledDataSource pooledDataSource = new PooledDataSource("org.h2.Driver", PooledDataSource pooledDataSource = new PooledDataSource("org.h2.Driver",
"jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS TASKANA", "sa", "sa"); JDBC_URL, "sa", "sa");
Assertions.assertDoesNotThrow(() -> new DbSchemaCreator(pooledDataSource, "TASKANA").run()); Assertions.assertDoesNotThrow(() -> new DbSchemaCreator(pooledDataSource, "TASKANA").run());
Assertions.assertDoesNotThrow(() -> new SampleDataGenerator(pooledDataSource, "TASKANA").generateSampleData()); Assertions.assertDoesNotThrow(() -> new SampleDataGenerator(pooledDataSource, "TASKANA").generateSampleData());
pooledDataSource.forceCloseAll(); pooledDataSource.forceCloseAll();
} }
@Test
void tableExists() {
PooledDataSource pooledDataSource = new PooledDataSource("org.h2.Driver",
JDBC_URL, "sa", "sa");
Assertions.assertDoesNotThrow(() -> new DbSchemaCreator(pooledDataSource, "TASKANA").run());
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(pooledDataSource, "TASKANA");
Assertions.assertTrue(sampleDataGenerator.tableExists("TASK"));
Assertions.assertFalse(sampleDataGenerator.tableExists("TASKRANDOM"));
pooledDataSource.forceCloseAll();
}
} }

View File

@ -1,22 +0,0 @@
package pro.taskana.sampledata;
import java.sql.SQLException;
import javax.sql.DataSource;
/**
* This class cleans the complete database.
*/
public class DBCleaner {
public void clearDb(DataSource dataSource, String schema) throws SQLException {
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schema);
sampleDataGenerator.runScripts(sampleDataGenerator::clearDb);
}
public void dropDb(DataSource dataSource, String schema) throws SQLException {
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schema);
sampleDataGenerator.runScripts(sampleDataGenerator::dropDb);
}
}

View File

@ -1,8 +1,6 @@
package pro.taskana.sampledata; package pro.taskana.sampledata;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -21,51 +19,24 @@ final class SQLReplacer {
static final Pattern RELATIVE_DATE_PATTERN = Pattern.compile(RELATIVE_DATE_REGEX); static final Pattern RELATIVE_DATE_PATTERN = Pattern.compile(RELATIVE_DATE_REGEX);
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
static String getScriptAsSql(String dbProductName, LocalDateTime now, String scriptPath) {
return parseAndReplace(SQLReplacer.class.getResourceAsStream(scriptPath), now, dbProductName);
}
private SQLReplacer() { private SQLReplacer() {
} }
/** static String getScriptAsSql(String dbProductName, LocalDateTime now, String scriptPath) {
* This method resolves the custom sql function defined through this regex: {@value RELATIVE_DATE_REGEX}. return parseAndReplace(getScriptBufferedStream(scriptPath), now, dbProductName);
* Its parameter is a digit representing the relative offset of a given starting point date.
* <p/>
* Yes, this can be done as an actual sql function, but that'd lead to a little more complexity
* (and thus we'd have to maintain the code for db compatibility ...)
* Since we're already replacing the boolean attributes of sql files this addition is not a huge computational cost.
*
* @param now anchor for relative date conversion.
* @param sql sql statement which may contain the above declared custom function.
* @return sql statement with the given function resolved, if the 'sql' parameter contained any.
*/
private static String replaceRelativeTimeFunction(LocalDateTime now, String sql) {
Matcher m = RELATIVE_DATE_PATTERN.matcher(sql);
StringBuffer sb = new StringBuffer(sql.length());
while (m.find()) {
m.appendReplacement(sb,
"'" + now.plusDays(Long.parseLong(m.group(1))).format(DATE_TIME_FORMATTER) + "'");
}
m.appendTail(sb);
return sb.toString();
} }
private static String replaceBooleanWithInteger(String sql) { private static String replaceBooleanWithInteger(String sql) {
return sql.replaceAll("(?i)true", "1").replaceAll("(?i)false", "0"); return sql.replaceAll("(?i)true", "1").replaceAll("(?i)false", "0");
} }
private static String parseAndReplace(InputStream stream, LocalDateTime now, String dbProductname) { private static String parseAndReplace(BufferedReader bufferedReader, LocalDateTime now, String dbProductname) {
boolean isDb2 = isDb2(dbProductname); boolean isDb2 = isDb2(dbProductname);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream))) { String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator()));
String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator())); if (isDb2) {
if (isDb2) { sql = replaceBooleanWithInteger(sql);
sql = replaceBooleanWithInteger(sql);
}
return replaceRelativeTimeFunction(now, sql);
} catch (IOException e) {
throw new RuntimeException("Scriptfile not found", e);
} }
return replaceDatePlaceholder(now, sql);
} }
static boolean isPostgreSQL(String databaseProductName) { static boolean isPostgreSQL(String databaseProductName) {
@ -106,18 +77,13 @@ final class SQLReplacer {
return "'" + now.plusDays(days).format(DATE_TIME_FORMATTER) + "'"; return "'" + now.plusDays(days).format(DATE_TIME_FORMATTER) + "'";
} }
static String parseAndReplace(LocalDateTime now, String script) {
return replaceDatePlaceholder(now,
getScriptAsString(script));
}
private static String getScriptAsString(String script) {
return getScriptBufferedStream(script).lines().collect(Collectors.joining(System.lineSeparator()));
}
static BufferedReader getScriptBufferedStream(String script) { static BufferedReader getScriptBufferedStream(String script) {
return Optional.ofNullable(SampleDataGenerator.class.getResourceAsStream(script)).map( return Optional.ofNullable(SampleDataGenerator.class.getResourceAsStream(script)).map(
inputStream -> new BufferedReader( inputStream -> new BufferedReader(
new InputStreamReader(inputStream, StandardCharsets.UTF_8))).orElse(null); new InputStreamReader(inputStream, StandardCharsets.UTF_8))).orElse(null);
} }
static String getSanitizedTableName(String table) {
return table.replaceAll("[^a-zA-Z0-9_]", "__");
}
} }

View File

@ -17,6 +17,7 @@ import java.util.stream.Stream;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.apache.ibatis.jdbc.ScriptRunner; import org.apache.ibatis.jdbc.ScriptRunner;
import org.apache.ibatis.jdbc.SqlRunner;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -27,13 +28,12 @@ public class SampleDataGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleDataGenerator.class); private static final Logger LOGGER = LoggerFactory.getLogger(SampleDataGenerator.class);
private static final String DB_CLEAR_TABLES_SCRIPT = "/sql/clear/clear-db.sql"; private static final String CACHED_TEST = "TEST";
private static final String DB_DROP_TABLES_SCRIPT = "/sql/clear/drop-tables.sql"; private static final String CACHED_SAMPLE = "SAMPLE";
private static final String CHECK_HISTORY_EVENT_EXIST = "/sql/sample-data/check-history-event-exist.sql"; private static final String CACHED_EVENTSAMPLE = "EVENTSAMPLE";
public static final String CACHED_TEST = "TEST"; private static final String CACHED_MONITOR = "MONITOR";
public static final String CACHED_SAMPLE = "SAMPLE"; private static final String CACHED_CLEARDB = "CLEARDB";
public static final String CACHED_EVENTSAMPLE = "EVENTSAMPLE"; private static final String CACHED_DROPDB = "DROPDB";
public static final String CACHED_MONITOR = "MONITOR";
private final DataSource dataSource; private final DataSource dataSource;
private final LocalDateTime now; private final LocalDateTime now;
@ -44,7 +44,7 @@ public class SampleDataGenerator {
*/ */
private final String schema; private final String schema;
private static HashMap<String, List<String>> cachedScripts = new HashMap<String, List<String>>(); private static HashMap<String, List<String>> cachedScripts = new HashMap<>();
public SampleDataGenerator(DataSource dataSource, String schema) { public SampleDataGenerator(DataSource dataSource, String schema) {
this(dataSource, schema, LocalDateTime.now()); this(dataSource, schema, LocalDateTime.now());
@ -56,7 +56,67 @@ public class SampleDataGenerator {
this.now = now; this.now = now;
} }
public void runScripts(Consumer<ScriptRunner> consumer) { public void generateSampleData() {
runScripts((runner) -> {
clearDb();
Stream<String> scripts;
String cacheKey;
//dbtable constants?
if (tableExists("HISTORY_EVENTS")) {
scripts = SampleDataProvider.getDefaultScripts();
cacheKey = CACHED_EVENTSAMPLE;
} else {
scripts = SampleDataProvider.getScriptsWithEvents();
cacheKey = CACHED_SAMPLE;
}
executeAndCacheScripts(scripts, cacheKey);
});
}
public void generateTestData() {
Stream<String> scripts = SampleDataProvider.getTestDataScripts();
executeAndCacheScripts(scripts, CACHED_TEST);
}
public void generateMonitorData() {
Stream<String> scripts = SampleDataProvider.getMonitorDataScripts();
executeAndCacheScripts(scripts, CACHED_MONITOR);
}
public void clearDb() {
Stream<String> scripts = SampleDataProvider.getScriptsToClearDatabase();
executeAndCacheScripts(scripts, CACHED_CLEARDB);
}
public void dropDb() {
Stream<String> scripts = SampleDataProvider.getScriptsToDropDatabase();
executeAndCacheScripts(scripts, CACHED_DROPDB);
}
private List<String> parseScripts(Stream<String> scripts) {
try (Connection connection = dataSource.getConnection()) {
String dbProductName = connection.getMetaData().getDatabaseProductName();
return scripts.map(script -> SQLReplacer.getScriptAsSql(dbProductName, now, script))
.collect(Collectors.toList());
} catch (SQLException e) {
throw new RuntimeException("Connection to database failed.", e);
}
}
boolean tableExists(String table) {
try (Connection connection = dataSource.getConnection()) {
connection.setSchema(schema);
SqlRunner runner = new SqlRunner(connection);
String tableSafe = SQLReplacer.getSanitizedTableName(table);
String query = "SELECT 1 FROM " + tableSafe + " LIMIT 1;";
runner.run(query);
return true;
} catch (Exception e) {
return false;
}
}
private void runScripts(Consumer<ScriptRunner> consumer) {
try (Connection connection = dataSource.getConnection()) { try (Connection connection = dataSource.getConnection()) {
if (LOGGER.isTraceEnabled()) { if (LOGGER.isTraceEnabled()) {
LOGGER.trace(connection.getMetaData().toString()); LOGGER.trace(connection.getMetaData().toString());
@ -81,68 +141,15 @@ public class SampleDataGenerator {
} }
} }
public void generateSampleData() throws SQLException { private void executeAndCacheScripts(Stream<String> scripts, String cacheKey) {
runScripts((runner) -> { runScripts(runner -> cachedScripts.computeIfAbsent(cacheKey, key -> parseScripts(scripts)).stream()
clearDb(runner);
Stream<String> scripts;
String cacheKey;
try {
//TODO find a better method of testing if a table exists
runner.runScript(SQLReplacer.getScriptBufferedStream(CHECK_HISTORY_EVENT_EXIST));
scripts = SampleDataProvider.getScriptsWithEvents();
cacheKey = CACHED_SAMPLE;
} catch (Exception e) {
scripts = SampleDataProvider.getDefaultScripts();
cacheKey = CACHED_EVENTSAMPLE;
}
cacheAndExecute(scripts, cacheKey);
});
}
public List<String> parseScripts(Stream<String> scripts) {
try (Connection connection = dataSource.getConnection()) {
String dbProductName = connection.getMetaData().getDatabaseProductName();
return scripts.map(script -> SQLReplacer.getScriptAsSql(dbProductName, now, script))
.collect(Collectors.toList());
} catch (SQLException e) {
throw new RuntimeException("Connection to database failed.", e);
}
}
public void generateTestData() {
Stream<String> scripts = SampleDataProvider.getTestDataScripts();
cacheAndExecute(scripts, CACHED_TEST);
}
public void generateMonitorData() {
Stream<String> scripts = SampleDataProvider.getMonitorDataScripts();
cacheAndExecute(scripts, CACHED_MONITOR);
}
public void clearDb(ScriptRunner runner) {
runner.setStopOnError(false);
runner.runScript(SQLReplacer.getScriptBufferedStream(DB_CLEAR_TABLES_SCRIPT));
runner.setStopOnError(true);
}
private void cacheAndExecute(Stream<String> scripts, String cacheKey) {
if (!cachedScripts.containsKey(cacheKey)) {
cachedScripts.put(cacheKey, parseScripts(scripts));
}
runScripts(runner -> cachedScripts.get(cacheKey).stream()
.map(s -> s.getBytes(StandardCharsets.UTF_8)) .map(s -> s.getBytes(StandardCharsets.UTF_8))
.map(ByteArrayInputStream::new) .map(ByteArrayInputStream::new)
.map(InputStreamReader::new) .map(s -> new InputStreamReader(s, StandardCharsets.UTF_8))
.forEach(runner::runScript)); .forEach(runner::runScript));
} }
public void dropDb(ScriptRunner runner) { private ScriptRunner getScriptRunner(Connection connection, StringWriter outWriter,
runner.setStopOnError(false);
runner.runScript(SQLReplacer.getScriptBufferedStream(DB_DROP_TABLES_SCRIPT));
runner.setStopOnError(true);
}
ScriptRunner getScriptRunner(Connection connection, StringWriter outWriter,
StringWriter errorWriter) throws SQLException { StringWriter errorWriter) throws SQLException {
PrintWriter logWriter = new PrintWriter(outWriter); PrintWriter logWriter = new PrintWriter(outWriter);

View File

@ -7,6 +7,9 @@ import java.util.stream.Stream;
*/ */
public final class SampleDataProvider { public final class SampleDataProvider {
private static final String DB_CLEAR_TABLES_SCRIPT = "/sql/clear/clear-db.sql";
private static final String DB_DROP_TABLES_SCRIPT = "/sql/clear/drop-tables.sql";
private static final String CLEAR_HISTORY_EVENTS = "/sql/clear/clear-history-events.sql"; private static final String CLEAR_HISTORY_EVENTS = "/sql/clear/clear-history-events.sql";
private static final String HISTORY_EVENT = "/sql/sample-data/history-event.sql"; private static final String HISTORY_EVENT = "/sql/sample-data/history-event.sql";
@ -18,13 +21,13 @@ public final class SampleDataProvider {
private static final String SAMPLE_OBJECT_REFERENCE = "/sql/sample-data/object-reference.sql"; private static final String SAMPLE_OBJECT_REFERENCE = "/sql/sample-data/object-reference.sql";
private static final String SAMPLE_ATTACHMENT = "/sql/sample-data/attachment.sql"; private static final String SAMPLE_ATTACHMENT = "/sql/sample-data/attachment.sql";
static final String TASK = "/sql/test-data/task.sql"; static final String TEST_TASK = "/sql/test-data/task.sql";
static final String WORKBASKET = "/sql/test-data/workbasket.sql"; static final String TEST_WORKBASKET = "/sql/test-data/workbasket.sql";
static final String DISTRIBUTION_TARGETS = "/sql/test-data/distribution-targets.sql"; static final String TEST_DISTRIBUTION_TARGETS = "/sql/test-data/distribution-targets.sql";
static final String WORKBASKET_ACCESS_LIST = "/sql/test-data/workbasket-access-list.sql"; static final String TEST_WORKBASKET_ACCESS_LIST = "/sql/test-data/workbasket-access-list.sql";
static final String CLASSIFICATION = "/sql/test-data/classification.sql"; static final String TEST_CLASSIFICATION = "/sql/test-data/classification.sql";
static final String OBJECT_REFERENCE = "/sql/test-data/object-reference.sql"; static final String TEST_OBJECT_REFERENCE = "/sql/test-data/object-reference.sql";
static final String ATTACHMENT = "/sql/test-data/attachment.sql"; static final String TEST_ATTACHMENT = "/sql/test-data/attachment.sql";
static final String MONITOR_SAMPLE_DATA = "/sql/monitor-data/monitor-sample-data.sql"; static final String MONITOR_SAMPLE_DATA = "/sql/monitor-data/monitor-sample-data.sql";
@ -42,15 +45,23 @@ public final class SampleDataProvider {
return Stream.concat(getDefaultScripts(), Stream.of(CLEAR_HISTORY_EVENTS, HISTORY_EVENT)); return Stream.concat(getDefaultScripts(), Stream.of(CLEAR_HISTORY_EVENTS, HISTORY_EVENT));
} }
static Stream<String> getScriptsToClearDatabase() {
return Stream.concat(getDefaultScripts(), Stream.of(DB_CLEAR_TABLES_SCRIPT));
}
static Stream<String> getScriptsToDropDatabase() {
return Stream.concat(getDefaultScripts(), Stream.of(DB_DROP_TABLES_SCRIPT));
}
static Stream<String> getTestDataScripts() { static Stream<String> getTestDataScripts() {
return Stream.of( return Stream.of(
CLASSIFICATION, TEST_CLASSIFICATION,
WORKBASKET, TEST_WORKBASKET,
TASK, TEST_TASK,
WORKBASKET_ACCESS_LIST, TEST_WORKBASKET_ACCESS_LIST,
DISTRIBUTION_TARGETS, TEST_DISTRIBUTION_TARGETS,
OBJECT_REFERENCE, TEST_OBJECT_REFERENCE,
ATTACHMENT); TEST_ATTACHMENT);
} }
static Stream<String> getMonitorDataScripts() { static Stream<String> getMonitorDataScripts() {

View File

@ -1 +0,0 @@
SELECT 1 FROM HISTORY_EVENTS LIMIT 1;

View File

@ -14,26 +14,7 @@ import org.junit.jupiter.api.Test;
/** /**
* Test SampleDataGenerator. * Test SampleDataGenerator.
*/ */
class SampleDataGeneratorTest { class SQLReplacerTest {
@Test
void getScriptsNotNull() {
Assertions.assertNotNull(SampleDataProvider.getDefaultScripts());
Assertions.assertNotNull(SampleDataProvider.getScriptsWithEvents());
}
@Test
void getScriptsNotEmpty() {
Assertions.assertTrue(SampleDataProvider.getDefaultScripts().count() > 0);
Assertions.assertTrue(SampleDataProvider.getScriptsWithEvents().count() > 0);
}
@Test
void getScriptsFileExists() {
SampleDataProvider.getDefaultScripts()
.map(SQLReplacer::getScriptBufferedStream)
.forEach(Assertions::assertNotNull);
}
@Test @Test
void replaceRelativeTimeFunctionSameDate() { void replaceRelativeTimeFunctionSameDate() {

View File

@ -0,0 +1,30 @@
package pro.taskana.sampledata;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* Test SampleDataGenerator.
*/
class SampleDataProviderTest {
@Test
void getScriptsNotNull() {
Assertions.assertNotNull(SampleDataProvider.getDefaultScripts());
Assertions.assertNotNull(SampleDataProvider.getScriptsWithEvents());
}
@Test
void getScriptsNotEmpty() {
Assertions.assertTrue(SampleDataProvider.getDefaultScripts().count() > 0);
Assertions.assertTrue(SampleDataProvider.getScriptsWithEvents().count() > 0);
}
@Test
void getScriptsFileExists() {
SampleDataProvider.getDefaultScripts()
.map(SQLReplacer::getScriptBufferedStream)
.forEach(Assertions::assertNotNull);
}
}

View File

@ -8,7 +8,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException; import java.io.IOException;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
@ -37,12 +36,7 @@ class ClassificationControllerIntTest {
@Autowired RestHelper restHelper; @Autowired RestHelper restHelper;
static RestTemplate template; static RestTemplate template = RestHelper.getRestTemplate();
@BeforeAll
static void init() {
template = RestHelper.getRestTemplate();
}
@Test @Test
void testGetAllClassifications() { void testGetAllClassifications() {

View File

@ -14,7 +14,6 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.sql.SQLException;
import java.time.Instant; import java.time.Instant;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -41,7 +40,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import pro.taskana.ObjectReference; import pro.taskana.ObjectReference;
import pro.taskana.RestHelper; import pro.taskana.RestHelper;
import pro.taskana.TaskanaSpringBootTest; import pro.taskana.TaskanaSpringBootTest;
import pro.taskana.exceptions.SystemException;
import pro.taskana.rest.resource.ClassificationSummaryResource; import pro.taskana.rest.resource.ClassificationSummaryResource;
import pro.taskana.rest.resource.TaskResource; import pro.taskana.rest.resource.TaskResource;
import pro.taskana.rest.resource.TaskSummaryListResource; import pro.taskana.rest.resource.TaskSummaryListResource;
@ -71,13 +69,8 @@ class TaskControllerIntTest {
private DataSource dataSource; private DataSource dataSource;
void resetDb() { void resetDb() {
SampleDataGenerator sampleDataGenerator; SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
try { sampleDataGenerator.generateSampleData();
sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
sampleDataGenerator.generateSampleData();
} catch (SQLException e) {
throw new SystemException("tried to reset DB and caught Exception " + e, e);
}
} }
@Test @Test