TSK-967: Refactor Taskana-Data module to merge SampleDataGenerator and TestDataGenerator
This commit is contained in:
parent
f8443897f6
commit
e8c0d473db
|
@ -22,10 +22,10 @@ import pro.taskana.TaskanaEngine;
|
|||
import pro.taskana.TaskanaEngine.ConnectionManagementMode;
|
||||
import pro.taskana.TimeInterval;
|
||||
import pro.taskana.configuration.TaskanaEngineConfiguration;
|
||||
import pro.taskana.database.TestDataGenerator;
|
||||
import pro.taskana.exceptions.ClassificationNotFoundException;
|
||||
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
|
||||
import pro.taskana.sampledata.DBCleaner;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
|
||||
/**
|
||||
* Base class for all acceptance tests.
|
||||
|
@ -34,7 +34,6 @@ public abstract class AbstractAccTest {
|
|||
|
||||
protected static TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
protected static TaskanaEngine taskanaEngine;
|
||||
protected static TestDataGenerator testDataGenerator = new TestDataGenerator();
|
||||
|
||||
@BeforeAll
|
||||
@BeforeClass
|
||||
|
@ -55,7 +54,7 @@ public abstract class AbstractAccTest {
|
|||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
||||
dbCleaner.clearDb(dataSource, schemaName);
|
||||
testDataGenerator.generateTestData(dataSource, schemaName);
|
||||
new SampleDataGenerator(dataSource, schemaName).generateTestData();
|
||||
}
|
||||
|
||||
protected ObjectReference createObjectReference(String company, String system, String systemInstance, String type,
|
||||
|
|
|
@ -10,9 +10,9 @@ import org.junit.jupiter.api.BeforeAll;
|
|||
|
||||
import pro.taskana.TaskanaEngine;
|
||||
import pro.taskana.configuration.TaskanaEngineConfiguration;
|
||||
import pro.taskana.database.TestDataGenerator;
|
||||
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
|
||||
import pro.taskana.sampledata.DBCleaner;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
|
||||
/**
|
||||
* Abstract test class for all report building tests.
|
||||
|
@ -42,7 +42,6 @@ public class AbstractReportAccTest {
|
|||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
||||
taskanaEngine.setConnectionManagementMode(TaskanaEngine.ConnectionManagementMode.AUTOCOMMIT);
|
||||
cleaner.clearDb(dataSource, schemaName);
|
||||
TestDataGenerator testDataGenerator = new TestDataGenerator();
|
||||
testDataGenerator.generateMonitoringTestData(dataSource);
|
||||
new SampleDataGenerator(dataSource, schemaName).generateMonitorData();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,196 +0,0 @@
|
|||
package pro.taskana.database;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.ibatis.jdbc.ScriptRunner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import pro.taskana.impl.TaskanaEngineImpl;
|
||||
|
||||
/**
|
||||
* Generates the test data for integration and acceptance tests.
|
||||
*/
|
||||
public class TestDataGenerator {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TestDataGenerator.class);
|
||||
private static final String SQL = "/sql";
|
||||
private static final String TASK = SQL + "/task.sql";
|
||||
private static final String WORKBASKET = SQL + "/workbasket.sql";
|
||||
private static final String DISTRIBUTION_TARGETS = SQL + "/distribution-targets.sql";
|
||||
private static final String WORKBASKET_ACCESS_LIST = SQL + "/workbasket-access-list.sql";
|
||||
private static final String CLASSIFICATION = SQL + "/classification.sql";
|
||||
private static final String OBJECT_REFERENCE = SQL + "/object-reference.sql";
|
||||
private static final String ATTACHMENT = SQL + "/attachment.sql";
|
||||
private static final String MONITOR_SAMPLE_DATA = SQL + "/monitor-sample-data.sql";
|
||||
private static SQLReplacer sqlReplacer;
|
||||
|
||||
private StringWriter outWriter = new StringWriter();
|
||||
private PrintWriter logWriter;
|
||||
private StringWriter errorWriter;
|
||||
private PrintWriter errorLogWriter;
|
||||
|
||||
public TestDataGenerator() {
|
||||
this.logWriter = new PrintWriter(this.outWriter);
|
||||
this.errorWriter = new StringWriter();
|
||||
this.errorLogWriter = new PrintWriter(this.errorWriter);
|
||||
}
|
||||
|
||||
public void generateTestData(DataSource dataSource, String schema) throws SQLException, IOException {
|
||||
ScriptRunner runner = null;
|
||||
try {
|
||||
Connection connection = dataSource.getConnection();
|
||||
LOGGER.debug(connection.getMetaData().toString());
|
||||
connection.setSchema(schema);
|
||||
runner = new ScriptRunner(connection);
|
||||
runner.setStopOnError(true);
|
||||
runner.setLogWriter(this.logWriter);
|
||||
runner.setErrorLogWriter(this.errorLogWriter);
|
||||
runner.setStopOnError(true);
|
||||
runner.setLogWriter(this.logWriter);
|
||||
runner.setErrorLogWriter(this.errorLogWriter);
|
||||
|
||||
if (sqlReplacer == null) {
|
||||
sqlReplacer = new SQLReplacer(connection.getMetaData().getDatabaseProductName());
|
||||
}
|
||||
|
||||
Stream.of(sqlReplacer.classificationSql, sqlReplacer.workbasketSql, sqlReplacer.taskSql,
|
||||
sqlReplacer.workbasketAccessListSql, sqlReplacer.distributionTargetSql, sqlReplacer.objectReferenceSql,
|
||||
sqlReplacer.attachmentSql)
|
||||
.map(s -> s.getBytes(StandardCharsets.UTF_8))
|
||||
.map(ByteArrayInputStream::new)
|
||||
.map(InputStreamReader::new)
|
||||
.forEach(runner::runScript);
|
||||
|
||||
} finally {
|
||||
if (runner != null) {
|
||||
runner.closeConnection();
|
||||
}
|
||||
LOGGER.debug(outWriter.toString());
|
||||
if (!errorWriter.toString().trim().isEmpty()) {
|
||||
LOGGER.error(errorWriter.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateMonitoringTestData(DataSource dataSource) throws IOException, SQLException {
|
||||
ScriptRunner runner = null;
|
||||
try {
|
||||
Connection connection = dataSource.getConnection();
|
||||
LOGGER.debug(connection.getMetaData().toString());
|
||||
runner = new ScriptRunner(connection);
|
||||
runner.setStopOnError(true);
|
||||
runner.setLogWriter(this.logWriter);
|
||||
runner.setErrorLogWriter(this.errorLogWriter);
|
||||
runner.setStopOnError(true);
|
||||
runner.setLogWriter(this.logWriter);
|
||||
runner.setErrorLogWriter(this.errorLogWriter);
|
||||
|
||||
if (sqlReplacer == null) {
|
||||
sqlReplacer = new SQLReplacer(connection.getMetaData().getDatabaseProductName());
|
||||
}
|
||||
|
||||
runner.runScript(
|
||||
new InputStreamReader(
|
||||
new ByteArrayInputStream(
|
||||
sqlReplacer.monitoringTestDataSql.getBytes(StandardCharsets.UTF_8))));
|
||||
} finally {
|
||||
if (runner != null) {
|
||||
runner.closeConnection();
|
||||
}
|
||||
LOGGER.debug(outWriter.toString());
|
||||
if (!errorWriter.toString().trim().isEmpty()) {
|
||||
LOGGER.error(errorWriter.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class replaces boolean values with int values if the database is db2.
|
||||
*/
|
||||
private static final class SQLReplacer {
|
||||
|
||||
private static final String RELATIVE_DATE_REGEX = "RELATIVE_DATE\\((-?\\d+)\\)";
|
||||
private static final Pattern RELATIVE_DATE_PATTERN = Pattern.compile(RELATIVE_DATE_REGEX);
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private String classificationSql;
|
||||
private String workbasketSql;
|
||||
private String taskSql;
|
||||
private String workbasketAccessListSql;
|
||||
private String distributionTargetSql;
|
||||
private String objectReferenceSql;
|
||||
private String attachmentSql;
|
||||
private String monitoringTestDataSql;
|
||||
|
||||
private SQLReplacer(String dbProductName) throws IOException {
|
||||
boolean isDb2 = TaskanaEngineImpl.isDb2(dbProductName);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
classificationSql = parseAndReplace(getClass().getResourceAsStream(CLASSIFICATION), now, isDb2);
|
||||
workbasketSql = parseAndReplace(getClass().getResourceAsStream(WORKBASKET), now, isDb2);
|
||||
taskSql = parseAndReplace(getClass().getResourceAsStream(TASK), now, isDb2);
|
||||
workbasketAccessListSql = parseAndReplace(getClass().getResourceAsStream(WORKBASKET_ACCESS_LIST), now,
|
||||
isDb2);
|
||||
distributionTargetSql = parseAndReplace(getClass().getResourceAsStream(DISTRIBUTION_TARGETS), now, isDb2);
|
||||
objectReferenceSql = parseAndReplace(getClass().getResourceAsStream(OBJECT_REFERENCE), now, isDb2);
|
||||
attachmentSql = parseAndReplace(getClass().getResourceAsStream(ATTACHMENT), now, isDb2);
|
||||
monitoringTestDataSql = parseAndReplace(getClass().getResourceAsStream(MONITOR_SAMPLE_DATA), now, isDb2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <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) {
|
||||
return sql.replaceAll("(?i)true", "1").replaceAll("(?i)false", "0");
|
||||
}
|
||||
|
||||
private static String parseAndReplace(InputStream stream, LocalDateTime now, boolean isDb2) throws IOException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
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;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* This class replaces boolean values with int values if the database is db2.
|
||||
*/
|
||||
final class SQLReplacer {
|
||||
|
||||
static final String RELATIVE_DATE_REGEX = "RELATIVE_DATE\\((-?\\d+)\\)";
|
||||
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.
|
||||
* <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) {
|
||||
return sql.replaceAll("(?i)true", "1").replaceAll("(?i)false", "0");
|
||||
}
|
||||
|
||||
private static String parseAndReplace(InputStream stream, 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);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isPostgreSQL(String databaseProductName) {
|
||||
return "PostgreSQL".equals(databaseProductName);
|
||||
}
|
||||
|
||||
static boolean isDb2(String dbProductName) {
|
||||
return dbProductName.contains("DB2");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <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.
|
||||
*/
|
||||
static String replaceDatePlaceholder(LocalDateTime now, String sql) {
|
||||
Matcher m = RELATIVE_DATE_PATTERN.matcher(sql);
|
||||
StringBuffer sb = new StringBuffer(sql.length());
|
||||
while (m.find()) {
|
||||
long daysToShift = Long.parseLong(m.group(1));
|
||||
String daysAsStringDate = formatToSqlDate(now, daysToShift);
|
||||
m.appendReplacement(sb, daysAsStringDate);
|
||||
}
|
||||
m.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String formatToSqlDate(LocalDateTime now, long days) {
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -1,19 +1,16 @@
|
|||
package pro.taskana.sampledata;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -32,10 +29,11 @@ public class SampleDataGenerator {
|
|||
|
||||
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";
|
||||
|
||||
static final String RELATIVE_DATE_REGEX = "RELATIVE_DATE\\((-?\\d+)\\)";
|
||||
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");
|
||||
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 final DataSource dataSource;
|
||||
private final LocalDateTime now;
|
||||
|
@ -46,6 +44,8 @@ public class SampleDataGenerator {
|
|||
*/
|
||||
private final String schema;
|
||||
|
||||
private static HashMap<String, List<String>> cachedScripts = new HashMap<String, List<String>>();
|
||||
|
||||
public SampleDataGenerator(DataSource dataSource, String schema) {
|
||||
this(dataSource, schema, LocalDateTime.now());
|
||||
}
|
||||
|
@ -56,9 +56,8 @@ public class SampleDataGenerator {
|
|||
this.now = now;
|
||||
}
|
||||
|
||||
public void runScripts(Consumer<ScriptRunner> consumer) throws SQLException {
|
||||
public void runScripts(Consumer<ScriptRunner> consumer) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
|
||||
if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace(connection.getMetaData().toString());
|
||||
}
|
||||
|
@ -77,33 +76,69 @@ public class SampleDataGenerator {
|
|||
LOGGER.error(trimmedErrorString);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to execute script.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void generateSampleData() throws SQLException {
|
||||
runScripts((runner) -> {
|
||||
clearDb(runner);
|
||||
executeScripts(runner, SampleDataProvider.getDataProvider(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);
|
||||
});
|
||||
}
|
||||
|
||||
private void executeScripts(ScriptRunner runner, Stream<String> scriptsList) {
|
||||
scriptsList
|
||||
.map(s -> SampleDataGenerator.parseAndReplace(now, s))
|
||||
.map(StringReader::new)
|
||||
.map(BufferedReader::new)
|
||||
.forEachOrdered(runner::runScript);
|
||||
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(getScriptBufferedStream(DB_CLEAR_TABLES_SCRIPT));
|
||||
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(ByteArrayInputStream::new)
|
||||
.map(InputStreamReader::new)
|
||||
.forEach(runner::runScript));
|
||||
}
|
||||
|
||||
public void dropDb(ScriptRunner runner) {
|
||||
runner.setStopOnError(false);
|
||||
runner.runScript(getScriptBufferedStream(DB_DROP_TABLES_SCRIPT));
|
||||
runner.runScript(SQLReplacer.getScriptBufferedStream(DB_DROP_TABLES_SCRIPT));
|
||||
runner.setStopOnError(true);
|
||||
}
|
||||
|
||||
|
@ -115,55 +150,9 @@ public class SampleDataGenerator {
|
|||
ScriptRunner runner = new ScriptRunner(connection);
|
||||
|
||||
connection.setSchema(schema);
|
||||
String databaseProductName = connection.getMetaData().getDatabaseProductName();
|
||||
|
||||
runner.setLogWriter(logWriter);
|
||||
runner.setErrorLogWriter(errorLogWriter);
|
||||
return runner;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <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.
|
||||
*/
|
||||
static String replaceDatePlaceholder(LocalDateTime now, String sql) {
|
||||
Matcher m = RELATIVE_DATE_PATTERN.matcher(sql);
|
||||
StringBuffer sb = new StringBuffer(sql.length());
|
||||
while (m.find()) {
|
||||
long daysToShift = Long.parseLong(m.group(1));
|
||||
String daysAsStringDate = formatToSqlDate(now, daysToShift);
|
||||
m.appendReplacement(sb, daysAsStringDate);
|
||||
}
|
||||
m.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String formatToSqlDate(LocalDateTime now, long days) {
|
||||
return "'" + now.plusDays(days).format(DATE_TIME_FORMATTER) + "'";
|
||||
}
|
||||
|
||||
private static String parseAndReplace(LocalDateTime now, String script) {
|
||||
return replaceDatePlaceholder(now,
|
||||
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);
|
||||
}
|
||||
|
||||
private static boolean isPostgreSQL(String databaseProductName) {
|
||||
return "PostgreSQL".equals(databaseProductName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package pro.taskana.sampledata;
|
|||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.ibatis.jdbc.ScriptRunner;
|
||||
|
||||
/**
|
||||
* Provides a sample data set.
|
||||
*/
|
||||
|
@ -11,37 +9,51 @@ public final class SampleDataProvider {
|
|||
|
||||
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 CHECK_HISTORY_EVENT_EXIST = "/sql/sample-data/check-history-event-exist.sql";
|
||||
|
||||
private static final String TASK = "/sql/sample-data/task.sql";
|
||||
private static final String WORKBASKET = "/sql/sample-data/workbasket.sql";
|
||||
private static final String DISTRIBUTION_TARGETS = "/sql/sample-data/distribution-targets.sql";
|
||||
private static final String WORKBASKET_ACCESS_LIST = "/sql/sample-data/workbasket-access-list.sql";
|
||||
private static final String CLASSIFICATION = "/sql/sample-data/classification.sql";
|
||||
private static final String OBJECT_REFERENCE = "/sql/sample-data/object-reference.sql";
|
||||
private static final String ATTACHMENT = "/sql/sample-data/attachment.sql";
|
||||
private static final String SAMPLE_TASK = "/sql/sample-data/task.sql";
|
||||
private static final String SAMPLE_WORKBASKET = "/sql/sample-data/workbasket.sql";
|
||||
private static final String SAMPLE_DISTRIBUTION_TARGETS = "/sql/sample-data/distribution-targets.sql";
|
||||
private static final String SAMPLE_WORKBASKET_ACCESS_LIST = "/sql/sample-data/workbasket-access-list.sql";
|
||||
private static final String SAMPLE_CLASSIFICATION = "/sql/sample-data/classification.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";
|
||||
|
||||
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 MONITOR_SAMPLE_DATA = "/sql/monitor-data/monitor-sample-data.sql";
|
||||
|
||||
private SampleDataProvider() {
|
||||
}
|
||||
|
||||
static Stream<String> getScripts() {
|
||||
static Stream<String> getDefaultScripts() {
|
||||
return Stream.of(
|
||||
WORKBASKET, DISTRIBUTION_TARGETS, CLASSIFICATION, TASK, ATTACHMENT, WORKBASKET_ACCESS_LIST,
|
||||
OBJECT_REFERENCE);
|
||||
SAMPLE_WORKBASKET, SAMPLE_DISTRIBUTION_TARGETS, SAMPLE_CLASSIFICATION, SAMPLE_TASK, SAMPLE_ATTACHMENT,
|
||||
SAMPLE_WORKBASKET_ACCESS_LIST,
|
||||
SAMPLE_OBJECT_REFERENCE);
|
||||
}
|
||||
|
||||
static Stream<String> getScriptsWithEvents() {
|
||||
return Stream.concat(getScripts(), Stream.of(CLEAR_HISTORY_EVENTS, HISTORY_EVENT));
|
||||
return Stream.concat(getDefaultScripts(), Stream.of(CLEAR_HISTORY_EVENTS, HISTORY_EVENT));
|
||||
}
|
||||
|
||||
public static Stream<String> getDataProvider(ScriptRunner runner) {
|
||||
static Stream<String> getTestDataScripts() {
|
||||
return Stream.of(
|
||||
CLASSIFICATION,
|
||||
WORKBASKET,
|
||||
TASK,
|
||||
WORKBASKET_ACCESS_LIST,
|
||||
DISTRIBUTION_TARGETS,
|
||||
OBJECT_REFERENCE,
|
||||
ATTACHMENT);
|
||||
}
|
||||
|
||||
try {
|
||||
//TODO find a better method of testing if a table exists
|
||||
runner.runScript(SampleDataGenerator.getScriptBufferedStream(CHECK_HISTORY_EVENT_EXIST));
|
||||
return SampleDataProvider.getScriptsWithEvents();
|
||||
} catch (Exception e) {
|
||||
return SampleDataProvider.getScripts();
|
||||
}
|
||||
static Stream<String> getMonitorDataScripts() {
|
||||
return Stream.of(MONITOR_SAMPLE_DATA);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package pro.taskana.sampledata;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static pro.taskana.sampledata.SampleDataGenerator.DATE_TIME_FORMATTER;
|
||||
import static pro.taskana.sampledata.SampleDataGenerator.RELATIVE_DATE_PATTERN;
|
||||
import static pro.taskana.sampledata.SQLReplacer.DATE_TIME_FORMATTER;
|
||||
import static pro.taskana.sampledata.SQLReplacer.RELATIVE_DATE_PATTERN;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -18,20 +18,20 @@ class SampleDataGeneratorTest {
|
|||
|
||||
@Test
|
||||
void getScriptsNotNull() {
|
||||
Assertions.assertNotNull(SampleDataProvider.getScripts());
|
||||
Assertions.assertNotNull(SampleDataProvider.getDefaultScripts());
|
||||
Assertions.assertNotNull(SampleDataProvider.getScriptsWithEvents());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getScriptsNotEmpty() {
|
||||
Assertions.assertTrue(SampleDataProvider.getScripts().count() > 0);
|
||||
Assertions.assertTrue(SampleDataProvider.getDefaultScripts().count() > 0);
|
||||
Assertions.assertTrue(SampleDataProvider.getScriptsWithEvents().count() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getScriptsFileExists() {
|
||||
SampleDataProvider.getScripts()
|
||||
.map(SampleDataGenerator::getScriptBufferedStream)
|
||||
SampleDataProvider.getDefaultScripts()
|
||||
.map(SQLReplacer::getScriptBufferedStream)
|
||||
.forEach(Assertions::assertNotNull);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ class SampleDataGeneratorTest {
|
|||
void replaceRelativeTimeFunctionSameDate() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String dateFormatted = now.format(DATE_TIME_FORMATTER);
|
||||
String sqlStringReplaced = SampleDataGenerator.replaceDatePlaceholder(now,
|
||||
String sqlStringReplaced = SQLReplacer.replaceDatePlaceholder(now,
|
||||
"... RELATIVE_DATE(0) ...");
|
||||
assertThat(sqlStringReplaced, CoreMatchers.containsString(dateFormatted));
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class SampleDataGeneratorTest {
|
|||
void replaceRelativeTimeFunctionPosDate() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String dateFormatted = now.plusDays(5).format(DATE_TIME_FORMATTER);
|
||||
String sqlStringReplaced = SampleDataGenerator.replaceDatePlaceholder(now,
|
||||
String sqlStringReplaced = SQLReplacer.replaceDatePlaceholder(now,
|
||||
"... RELATIVE_DATE(5) ...");
|
||||
assertThat(sqlStringReplaced, CoreMatchers.containsString(dateFormatted));
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ class SampleDataGeneratorTest {
|
|||
void replaceRelativeTimeFunctionNegDate() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String dateFormatted = now.plusDays(-10).format(DATE_TIME_FORMATTER);
|
||||
String sqlStringReplaced = SampleDataGenerator.replaceDatePlaceholder(now,
|
||||
String sqlStringReplaced = SQLReplacer.replaceDatePlaceholder(now,
|
||||
"... RELATIVE_DATE(-10) ...");
|
||||
assertThat(sqlStringReplaced, CoreMatchers.containsString(dateFormatted));
|
||||
}
|
||||
|
|
|
@ -132,12 +132,12 @@ class AsyncUpdateJobIntTest {
|
|||
"TKI:000000000000000000000000000000000101", "TKI:000000000000000000000000000000000102",
|
||||
"TKI:000000000000000000000000000000000103"));
|
||||
for (String taskId : affectedTasks) {
|
||||
verifyTaskIsModifiedAfter(taskId, before);
|
||||
verifyTaskIsModifiedAfterOrEquals(taskId, before);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void verifyTaskIsModifiedAfter(String taskId, Instant before)
|
||||
private void verifyTaskIsModifiedAfterOrEquals(String taskId, Instant before)
|
||||
throws InvalidArgumentException {
|
||||
|
||||
ResponseEntity<TaskResource> taskResponse = template.exchange(
|
||||
|
@ -149,7 +149,9 @@ class AsyncUpdateJobIntTest {
|
|||
TaskResource taskResource = taskResponse.getBody();
|
||||
Task task = taskResourceAssembler.toModel(taskResource);
|
||||
|
||||
assertFalse("Task " + task.getId() + " has not been refreshed.", before.isAfter(task.getModified()));
|
||||
Instant modified = task.getModified();
|
||||
boolean isAfterOrEquals = before.isAfter(modified) || before.equals(modified);
|
||||
assertFalse("Task " + task.getId() + " has not been refreshed.", isAfterOrEquals);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue