From bf152674d3e36fe1f676b3d457d5357db5c31e6e Mon Sep 17 00:00:00 2001 From: Benjamin Eckstein <13351939+benjamineckstein@users.noreply.github.com> Date: Mon, 9 Dec 2019 15:19:08 +0100 Subject: [PATCH] TSK-967: Refactor the DBCleaner --- .../pro/taskana/impl/TaskServiceImpl.java | 2 + .../test/java/acceptance/AbstractAccTest.java | 9 +- .../GetClassificationAccTest.java | 7 + .../report/AbstractReportAccTest.java | 7 +- .../acceptance/task/UpdateTaskAccTest.java | 6 +- ...ificationServiceImplIntAutoCommitTest.java | 11 +- ...ssificationServiceImplIntExplicitTest.java | 9 +- .../TaskServiceImplIntAutocommitTest.java | 6 +- .../TaskServiceImplIntExplicitTest.java | 16 +- ...orkbasketServiceImplIntAutocommitTest.java | 9 +- .../WorkbasketServiceImplIntExplicitTest.java | 11 +- .../sampledata/SampleDataGeneratorTest.java | 16 +- .../pro/taskana/sampledata/DBCleaner.java | 22 --- .../pro/taskana/sampledata/SQLReplacer.java | 56 ++----- .../sampledata/SampleDataGenerator.java | 139 +++++++++--------- .../sampledata/SampleDataProvider.java | 39 +++-- .../sample-data/check-history-event-exist.sql | 1 - ...eneratorTest.java => SQLReplacerTest.java} | 21 +-- .../sampledata/SampleDataProviderTest.java | 30 ++++ .../rest/ClassificationControllerIntTest.java | 8 +- .../taskana/rest/TaskControllerIntTest.java | 11 +- 21 files changed, 205 insertions(+), 231 deletions(-) delete mode 100644 lib/taskana-data/src/main/java/pro/taskana/sampledata/DBCleaner.java delete mode 100644 lib/taskana-data/src/main/resources/sql/sample-data/check-history-event-exist.sql rename lib/taskana-data/src/test/java/pro/taskana/sampledata/{SampleDataGeneratorTest.java => SQLReplacerTest.java} (80%) create mode 100644 lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataProviderTest.java diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java index 363f1428d..0f2a616a8 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java @@ -1198,6 +1198,8 @@ public class TaskServiceImpl implements TaskService { PrioDurationHolder prioDurationFromAttachments) throws InvalidArgumentException, ConcurrencyException, ClassificationNotFoundException { 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()) || oldTaskImpl.getClaimed() != null && !oldTaskImpl.getClaimed().equals(newTaskImpl.getClaimed()) || oldTaskImpl.getState() != null && !oldTaskImpl.getState().equals(newTaskImpl.getState())) { diff --git a/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java b/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java index f2d7640b0..e4a73319b 100644 --- a/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java @@ -24,7 +24,6 @@ import pro.taskana.TimeInterval; import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator; /** @@ -44,17 +43,17 @@ public abstract class AbstractAccTest { public static void resetDb(boolean dropTables) throws SQLException, IOException { DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - DBCleaner dbCleaner = new DBCleaner(); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); if (dropTables) { - dbCleaner.dropDb(dataSource, schemaName); + sampleDataGenerator.dropDb(); } dataSource = TaskanaEngineConfigurationTest.getDataSource(); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, schemaName); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - dbCleaner.clearDb(dataSource, schemaName); - new SampleDataGenerator(dataSource, schemaName).generateTestData(); + sampleDataGenerator.clearDb(); + sampleDataGenerator.generateTestData(); } protected ObjectReference createObjectReference(String company, String system, String systemInstance, String type, diff --git a/lib/taskana-core/src/test/java/acceptance/classification/GetClassificationAccTest.java b/lib/taskana-core/src/test/java/acceptance/classification/GetClassificationAccTest.java index d8d8e2b57..815acce36 100644 --- a/lib/taskana-core/src/test/java/acceptance/classification/GetClassificationAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/classification/GetClassificationAccTest.java @@ -81,6 +81,13 @@ public class GetClassificationAccTest extends AbstractAccTest { assertEquals("custom8", classification.getCustom8()); } + @Test + void testGetClassificationWithSpecialCharacter() throws ClassificationNotFoundException { + Classification classification = classificationService.getClassification( + "CLI:100000000000000000000000000000000009"); + assertEquals("Zustimmungserklärung", classification.getName()); + } + @Test public void testGetClassificationAsSummary() throws ClassificationNotFoundException { ClassificationSummary classification = classificationService diff --git a/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java index 5a821da03..01c3d5ebe 100644 --- a/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/report/AbstractReportAccTest.java @@ -11,7 +11,6 @@ import org.junit.jupiter.api.BeforeAll; import pro.taskana.TaskanaEngine; import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.sampledata.DBCleaner; import pro.taskana.sampledata.SampleDataGenerator; /** @@ -35,13 +34,13 @@ public class AbstractReportAccTest { private static void resetDb() throws SQLException, IOException { DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - DBCleaner cleaner = new DBCleaner(); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false, schemaName); taskanaEngineConfiguration.setGermanPublicHolidaysEnabled(false); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, schemaName); - new SampleDataGenerator(dataSource, schemaName).generateMonitorData(); + sampleDataGenerator.clearDb(); + sampleDataGenerator.generateMonitorData(); } } diff --git a/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAccTest.java index 57e5f7461..9c8510408 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/UpdateTaskAccTest.java @@ -120,11 +120,11 @@ public class UpdateTaskAccTest extends AbstractAccTest { Task task2 = taskService.getTask("TKI:000000000000000000000000000000000000"); task.setCustomAttribute("1", "willi"); - Task updatedTask = null; - updatedTask = taskService.updateTask(task); - updatedTask = taskService.getTask(updatedTask.getId()); + Task updatedTask = taskService.updateTask(task); + taskService.getTask(updatedTask.getId()); task2.setCustomAttribute("2", "Walter"); + //TODO flaky test ... if speed is too high, Assertions.assertThrows(ConcurrencyException.class, () -> taskService.updateTask(task2), "The task has already been updated by another user"); diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntAutoCommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntAutoCommitTest.java index 241116706..fd47825c5 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntAutoCommitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntAutoCommitTest.java @@ -32,7 +32,7 @@ import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.impl.TaskanaEngineImpl; 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. @@ -49,11 +49,10 @@ public class ClassificationServiceImplIntAutoCommitTest { private TaskanaEngineImpl taskanaEngineImpl; @BeforeClass - public static void resetDb() throws SQLException { + public static void resetDb() { DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - cleaner.dropDb(ds, schemaName); + new SampleDataGenerator(ds, schemaName).dropDb(); } @Before @@ -66,8 +65,8 @@ public class ClassificationServiceImplIntAutoCommitTest { classificationService = taskanaEngine.getClassificationService(); taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, schemaName); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.clearDb(); } @Test diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntExplicitTest.java index 29b0f9cca..358febb5f 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntExplicitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/ClassificationServiceImplIntExplicitTest.java @@ -39,7 +39,7 @@ import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.impl.ClassificationImpl; import pro.taskana.impl.TaskanaEngineImpl; 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. @@ -60,9 +60,8 @@ public class ClassificationServiceImplIntExplicitTest { @BeforeClass public static void resetDb() throws SQLException { DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - cleaner.dropDb(ds, schemaName); + new SampleDataGenerator(ds, schemaName).dropDb(); } @Before @@ -75,8 +74,8 @@ public class ClassificationServiceImplIntExplicitTest { classificationService = taskanaEngine.getClassificationService(); taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, schemaName); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.clearDb(); } @Test diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java index 733239058..8a3b2ec00 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java @@ -50,7 +50,7 @@ import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; 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.JAASExtension; import pro.taskana.security.WithAccessId; @@ -90,8 +90,8 @@ class TaskServiceImplIntAutocommitTest { taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService(); classificationService = taskanaEngine.getClassificationService(); workbasketService = taskanaEngine.getWorkbasketService(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, schemaName); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.clearDb(); } @Test diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java index 450c6daaf..a6798944d 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java @@ -56,7 +56,7 @@ import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.WorkbasketSummaryImpl; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; 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.JAASExtension; import pro.taskana.security.WithAccessId; @@ -71,8 +71,6 @@ class TaskServiceImplIntExplicitTest { private static DataSource dataSource; - private static DBCleaner cleaner; - private static TaskServiceImpl taskServiceImpl; private static TaskanaEngineConfiguration taskanaEngineConfiguration; @@ -101,15 +99,15 @@ class TaskServiceImplIntExplicitTest { classificationService = taskanaEngine.getClassificationService(); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); workbasketService = taskanaEngine.getWorkbasketService(); - cleaner = new DBCleaner(); DbSchemaCreator creator = new DbSchemaCreator(dataSource, dataSource.getConnection().getSchema()); creator.run(); } @BeforeEach - void resetDb() throws SQLException { + void resetDb() { String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - cleaner.clearDb(dataSource, schemaName); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.clearDb(); } @WithAccessId(userName = "Elena", groupNames = {"businessadmin"}) @@ -195,7 +193,7 @@ class TaskServiceImplIntExplicitTest { ((WorkbasketSummaryImpl) (test.getWorkbasketSummary())).setId("2"); Assertions.assertThrows(WorkbasketNotFoundException.class, () -> - taskServiceImpl.createTask(test)); + taskServiceImpl.createTask(test)); } @WithAccessId(userName = "Elena", groupNames = {"businessadmin"}) @@ -223,7 +221,7 @@ class TaskServiceImplIntExplicitTest { task.setClassificationKey(classification.getKey()); Assertions.assertThrows(ClassificationNotFoundException.class, () -> - taskServiceImpl.createTask(task)); + taskServiceImpl.createTask(task)); } @WithAccessId(userName = "Elena", groupNames = {"DummyGroup", "businessadmin"}) @@ -351,7 +349,7 @@ class TaskServiceImplIntExplicitTest { taskanaEngineImpl.setConnection(connection); Assertions.assertThrows(TaskNotFoundException.class, () -> - taskServiceImpl.transfer(UUID.randomUUID() + "_X", "1")); + taskServiceImpl.transfer(UUID.randomUUID() + "_X", "1")); } @WithAccessId(userName = "User", groupNames = {"businessadmin"}) diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java index 673691383..3d0a47fed 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java @@ -40,7 +40,7 @@ import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; import pro.taskana.impl.util.IdGenerator; import pro.taskana.mappings.WorkbasketMapper; -import pro.taskana.sampledata.DBCleaner; +import pro.taskana.sampledata.SampleDataGenerator; import pro.taskana.security.JAASRunner; import pro.taskana.security.WithAccessId; @@ -62,9 +62,8 @@ public class WorkbasketServiceImplIntAutocommitTest { @BeforeClass public static void resetDb() throws SQLException { DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - cleaner.dropDb(ds, schemaName); + new SampleDataGenerator(ds, schemaName).dropDb(); } @Before @@ -76,8 +75,8 @@ public class WorkbasketServiceImplIntAutocommitTest { taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); workBasketService = taskanaEngine.getWorkbasketService(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, schemaName); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.clearDb(); now = Instant.now(); } diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java index 0a88a6e50..b03272ca7 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java @@ -33,7 +33,7 @@ import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; 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.WithAccessId; @@ -54,11 +54,10 @@ public class WorkbasketServiceImplIntExplicitTest { private WorkbasketService workBasketService; @BeforeClass - public static void resetDb() throws SQLException { + public static void resetDb() { DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); String schemaName = TaskanaEngineConfigurationTest.getSchemaName(); - cleaner.dropDb(ds, schemaName); + new SampleDataGenerator(ds, schemaName).dropDb(); } @Before @@ -70,8 +69,8 @@ public class WorkbasketServiceImplIntExplicitTest { taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, schemaName); + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.clearDb(); } @WithAccessId(userName = "Elena", groupNames = {"businessadmin"}) diff --git a/lib/taskana-core/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java b/lib/taskana-core/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java index d0aa0c42d..814d4c414 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java @@ -11,13 +11,27 @@ import pro.taskana.configuration.DbSchemaCreator; */ 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 void getScriptsValidSql() { 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 SampleDataGenerator(pooledDataSource, "TASKANA").generateSampleData()); 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(); + } + } diff --git a/lib/taskana-data/src/main/java/pro/taskana/sampledata/DBCleaner.java b/lib/taskana-data/src/main/java/pro/taskana/sampledata/DBCleaner.java deleted file mode 100644 index cff236c53..000000000 --- a/lib/taskana-data/src/main/java/pro/taskana/sampledata/DBCleaner.java +++ /dev/null @@ -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); - - } -} diff --git a/lib/taskana-data/src/main/java/pro/taskana/sampledata/SQLReplacer.java b/lib/taskana-data/src/main/java/pro/taskana/sampledata/SQLReplacer.java index 56ac4d7a4..17024909a 100644 --- a/lib/taskana-data/src/main/java/pro/taskana/sampledata/SQLReplacer.java +++ b/lib/taskana-data/src/main/java/pro/taskana/sampledata/SQLReplacer.java @@ -1,8 +1,6 @@ package pro.taskana.sampledata; import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; @@ -21,51 +19,24 @@ final class SQLReplacer { 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 String getScriptAsSql(String dbProductName, LocalDateTime now, String scriptPath) { - return parseAndReplace(SQLReplacer.class.getResourceAsStream(scriptPath), now, dbProductName); - } - private SQLReplacer() { } - /** - * This method resolves the custom sql function defined through this regex: {@value RELATIVE_DATE_REGEX}. - * Its parameter is a digit representing the relative offset of a given starting point date. - *

- * 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(); + static String getScriptAsSql(String dbProductName, LocalDateTime now, String scriptPath) { + return parseAndReplace(getScriptBufferedStream(scriptPath), now, dbProductName); } private static String replaceBooleanWithInteger(String sql) { 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); - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream))) { - String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator())); - if (isDb2) { - sql = replaceBooleanWithInteger(sql); - } - return replaceRelativeTimeFunction(now, sql); - } catch (IOException e) { - throw new RuntimeException("Scriptfile not found", e); + String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator())); + if (isDb2) { + sql = replaceBooleanWithInteger(sql); } + return replaceDatePlaceholder(now, sql); } static boolean isPostgreSQL(String databaseProductName) { @@ -106,18 +77,13 @@ final class SQLReplacer { 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) { return Optional.ofNullable(SampleDataGenerator.class.getResourceAsStream(script)).map( inputStream -> new BufferedReader( new InputStreamReader(inputStream, StandardCharsets.UTF_8))).orElse(null); } + + static String getSanitizedTableName(String table) { + return table.replaceAll("[^a-zA-Z0-9_]", "__"); + } } diff --git a/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataGenerator.java b/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataGenerator.java index ca77b4b71..cd52578f8 100644 --- a/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataGenerator.java +++ b/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataGenerator.java @@ -17,6 +17,7 @@ import java.util.stream.Stream; import javax.sql.DataSource; import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.jdbc.SqlRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,13 +28,12 @@ public class SampleDataGenerator { 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 DB_DROP_TABLES_SCRIPT = "/sql/clear/drop-tables.sql"; - private static final String CHECK_HISTORY_EVENT_EXIST = "/sql/sample-data/check-history-event-exist.sql"; - public static final String CACHED_TEST = "TEST"; - public static final String CACHED_SAMPLE = "SAMPLE"; - public static final String CACHED_EVENTSAMPLE = "EVENTSAMPLE"; - public static final String CACHED_MONITOR = "MONITOR"; + private static final String CACHED_TEST = "TEST"; + private static final String CACHED_SAMPLE = "SAMPLE"; + private static final String CACHED_EVENTSAMPLE = "EVENTSAMPLE"; + private static final String CACHED_MONITOR = "MONITOR"; + private static final String CACHED_CLEARDB = "CLEARDB"; + private static final String CACHED_DROPDB = "DROPDB"; private final DataSource dataSource; private final LocalDateTime now; @@ -44,7 +44,7 @@ public class SampleDataGenerator { */ private final String schema; - private static HashMap> cachedScripts = new HashMap>(); + private static HashMap> cachedScripts = new HashMap<>(); public SampleDataGenerator(DataSource dataSource, String schema) { this(dataSource, schema, LocalDateTime.now()); @@ -56,7 +56,67 @@ public class SampleDataGenerator { this.now = now; } - public void runScripts(Consumer consumer) { + public void generateSampleData() { + runScripts((runner) -> { + clearDb(); + Stream 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 scripts = SampleDataProvider.getTestDataScripts(); + executeAndCacheScripts(scripts, CACHED_TEST); + } + + public void generateMonitorData() { + Stream scripts = SampleDataProvider.getMonitorDataScripts(); + executeAndCacheScripts(scripts, CACHED_MONITOR); + } + + public void clearDb() { + Stream scripts = SampleDataProvider.getScriptsToClearDatabase(); + executeAndCacheScripts(scripts, CACHED_CLEARDB); + } + + public void dropDb() { + Stream scripts = SampleDataProvider.getScriptsToDropDatabase(); + executeAndCacheScripts(scripts, CACHED_DROPDB); + } + + private List parseScripts(Stream 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 consumer) { try (Connection connection = dataSource.getConnection()) { if (LOGGER.isTraceEnabled()) { LOGGER.trace(connection.getMetaData().toString()); @@ -81,68 +141,15 @@ public class SampleDataGenerator { } } - public void generateSampleData() throws SQLException { - runScripts((runner) -> { - clearDb(runner); - Stream 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 parseScripts(Stream 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 scripts = SampleDataProvider.getTestDataScripts(); - cacheAndExecute(scripts, CACHED_TEST); - } - - public void generateMonitorData() { - Stream 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 scripts, String cacheKey) { - if (!cachedScripts.containsKey(cacheKey)) { - cachedScripts.put(cacheKey, parseScripts(scripts)); - } - runScripts(runner -> cachedScripts.get(cacheKey).stream() + private void executeAndCacheScripts(Stream scripts, String cacheKey) { + runScripts(runner -> cachedScripts.computeIfAbsent(cacheKey, key -> parseScripts(scripts)).stream() .map(s -> s.getBytes(StandardCharsets.UTF_8)) .map(ByteArrayInputStream::new) - .map(InputStreamReader::new) + .map(s -> new InputStreamReader(s, StandardCharsets.UTF_8)) .forEach(runner::runScript)); } - public void dropDb(ScriptRunner runner) { - runner.setStopOnError(false); - runner.runScript(SQLReplacer.getScriptBufferedStream(DB_DROP_TABLES_SCRIPT)); - runner.setStopOnError(true); - } - - ScriptRunner getScriptRunner(Connection connection, StringWriter outWriter, + private ScriptRunner getScriptRunner(Connection connection, StringWriter outWriter, StringWriter errorWriter) throws SQLException { PrintWriter logWriter = new PrintWriter(outWriter); diff --git a/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataProvider.java b/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataProvider.java index e4293340a..cebecb8a4 100644 --- a/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataProvider.java +++ b/lib/taskana-data/src/main/java/pro/taskana/sampledata/SampleDataProvider.java @@ -7,6 +7,9 @@ import java.util.stream.Stream; */ 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 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_ATTACHMENT = "/sql/sample-data/attachment.sql"; - static final String TASK = "/sql/test-data/task.sql"; - static final String WORKBASKET = "/sql/test-data/workbasket.sql"; - static final String DISTRIBUTION_TARGETS = "/sql/test-data/distribution-targets.sql"; - static final String WORKBASKET_ACCESS_LIST = "/sql/test-data/workbasket-access-list.sql"; - static final String CLASSIFICATION = "/sql/test-data/classification.sql"; - static final String OBJECT_REFERENCE = "/sql/test-data/object-reference.sql"; - static final String ATTACHMENT = "/sql/test-data/attachment.sql"; + static final String TEST_TASK = "/sql/test-data/task.sql"; + static final String TEST_WORKBASKET = "/sql/test-data/workbasket.sql"; + static final String TEST_DISTRIBUTION_TARGETS = "/sql/test-data/distribution-targets.sql"; + static final String TEST_WORKBASKET_ACCESS_LIST = "/sql/test-data/workbasket-access-list.sql"; + static final String TEST_CLASSIFICATION = "/sql/test-data/classification.sql"; + static final String TEST_OBJECT_REFERENCE = "/sql/test-data/object-reference.sql"; + static final String TEST_ATTACHMENT = "/sql/test-data/attachment.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)); } + static Stream getScriptsToClearDatabase() { + return Stream.concat(getDefaultScripts(), Stream.of(DB_CLEAR_TABLES_SCRIPT)); + } + + static Stream getScriptsToDropDatabase() { + return Stream.concat(getDefaultScripts(), Stream.of(DB_DROP_TABLES_SCRIPT)); + } + static Stream getTestDataScripts() { return Stream.of( - CLASSIFICATION, - WORKBASKET, - TASK, - WORKBASKET_ACCESS_LIST, - DISTRIBUTION_TARGETS, - OBJECT_REFERENCE, - ATTACHMENT); + TEST_CLASSIFICATION, + TEST_WORKBASKET, + TEST_TASK, + TEST_WORKBASKET_ACCESS_LIST, + TEST_DISTRIBUTION_TARGETS, + TEST_OBJECT_REFERENCE, + TEST_ATTACHMENT); } static Stream getMonitorDataScripts() { diff --git a/lib/taskana-data/src/main/resources/sql/sample-data/check-history-event-exist.sql b/lib/taskana-data/src/main/resources/sql/sample-data/check-history-event-exist.sql deleted file mode 100644 index 697c955b2..000000000 --- a/lib/taskana-data/src/main/resources/sql/sample-data/check-history-event-exist.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT 1 FROM HISTORY_EVENTS LIMIT 1; diff --git a/lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java b/lib/taskana-data/src/test/java/pro/taskana/sampledata/SQLReplacerTest.java similarity index 80% rename from lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java rename to lib/taskana-data/src/test/java/pro/taskana/sampledata/SQLReplacerTest.java index 72c909b7b..37ef1759f 100644 --- a/lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataGeneratorTest.java +++ b/lib/taskana-data/src/test/java/pro/taskana/sampledata/SQLReplacerTest.java @@ -14,26 +14,7 @@ import org.junit.jupiter.api.Test; /** * Test SampleDataGenerator. */ -class SampleDataGeneratorTest { - - @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); - } +class SQLReplacerTest { @Test void replaceRelativeTimeFunctionSameDate() { diff --git a/lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataProviderTest.java b/lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataProviderTest.java new file mode 100644 index 000000000..0d8242f87 --- /dev/null +++ b/lib/taskana-data/src/test/java/pro/taskana/sampledata/SampleDataProviderTest.java @@ -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); + } + +} diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java index 6224a5175..78a0cd4c3 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java @@ -8,7 +8,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; @@ -37,12 +36,7 @@ class ClassificationControllerIntTest { @Autowired RestHelper restHelper; - static RestTemplate template; - - @BeforeAll - static void init() { - template = RestHelper.getRestTemplate(); - } + static RestTemplate template = RestHelper.getRestTemplate(); @Test void testGetAllClassifications() { diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/TaskControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/TaskControllerIntTest.java index e57601da7..780e87c59 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/TaskControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/TaskControllerIntTest.java @@ -14,7 +14,6 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; -import java.sql.SQLException; import java.time.Instant; import javax.sql.DataSource; @@ -41,7 +40,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import pro.taskana.ObjectReference; import pro.taskana.RestHelper; import pro.taskana.TaskanaSpringBootTest; -import pro.taskana.exceptions.SystemException; import pro.taskana.rest.resource.ClassificationSummaryResource; import pro.taskana.rest.resource.TaskResource; import pro.taskana.rest.resource.TaskSummaryListResource; @@ -71,13 +69,8 @@ class TaskControllerIntTest { private DataSource dataSource; void resetDb() { - SampleDataGenerator sampleDataGenerator; - try { - sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); - sampleDataGenerator.generateSampleData(); - } catch (SQLException e) { - throw new SystemException("tried to reset DB and caught Exception " + e, e); - } + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.generateSampleData(); } @Test