TSK-1472: Replaced the DB check with productName by productId (#1353)

* TSK-1472: Moved initialization of the schema from the taskanaEngineConfiguration to taskanaEngineImpl.

* TSK-1472: Changed the check of current DB type from productName to productId to enable places where we don't want to open a connection to the DB not to do so.

* TSK-1472: Improvements after review
This commit is contained in:
tge20 2021-01-05 14:28:53 +01:00 committed by Mustapha Zorgati
parent 9af19203a1
commit 0dc26f5fe1
19 changed files with 157 additions and 154 deletions

View File

@ -21,6 +21,8 @@ import org.apache.ibatis.jdbc.ScriptRunner;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.common.internal.configuration.DB;
/** This class generates sample data for manual testing purposes. */ /** This class generates sample data for manual testing purposes. */
public class SampleDataGenerator { public class SampleDataGenerator {
@ -90,9 +92,10 @@ public class SampleDataGenerator {
private List<String> parseScripts(Stream<String> scripts) { private List<String> parseScripts(Stream<String> scripts) {
try (Connection connection = dataSource.getConnection()) { try (Connection connection = dataSource.getConnection()) {
String dbProductName = connection.getMetaData().getDatabaseProductName(); String dbProductId =
DB.getDatabaseProductId(connection.getMetaData().getDatabaseProductName());
return scripts return scripts
.map(script -> SqlReplacer.getScriptAsSql(dbProductName, now, script)) .map(script -> SqlReplacer.getScriptAsSql(dbProductId, now, script))
.collect(Collectors.toList()); .collect(Collectors.toList());
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeSqlException("Connection to database failed.", e); throw new RuntimeSqlException("Connection to database failed.", e);

View File

@ -23,8 +23,8 @@ final class SqlReplacer {
// to prevent initialization // to prevent initialization
private SqlReplacer() {} private SqlReplacer() {}
static String getScriptAsSql(String dbProductName, ZonedDateTime now, String scriptPath) { static String getScriptAsSql(String dbProductId, ZonedDateTime now, String scriptPath) {
return parseAndReplace(getScriptBufferedStream(scriptPath), now, dbProductName); return parseAndReplace(getScriptBufferedStream(scriptPath), now, dbProductId);
} }
/** /**
@ -65,10 +65,9 @@ final class SqlReplacer {
} }
private static String parseAndReplace( private static String parseAndReplace(
BufferedReader bufferedReader, ZonedDateTime now, String dbProductname) { BufferedReader bufferedReader, ZonedDateTime now, String dbProductId) {
boolean isDb2 = DB.isDb2(dbProductname);
String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator())); String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator()));
if (isDb2) { if (DB.isDb2(dbProductId)) {
sql = replaceBooleanWithInteger(sql); sql = replaceBooleanWithInteger(sql);
} }
return replaceDatePlaceholder(now, sql); return replaceDatePlaceholder(now, sql);

View File

@ -1,43 +1,58 @@
package pro.taskana.common.internal.configuration; package pro.taskana.common.internal.configuration;
import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.common.api.exceptions.UnsupportedDatabaseException; import pro.taskana.common.api.exceptions.UnsupportedDatabaseException;
/** Supported versions of databases. */ /** Supported versions of databases. */
public enum DB { public enum DB {
H2("H2", "h2"), H2("H2", "h2"),
DB2("DB2", "db2"), DB2("DB2", "db2"),
POSTGRESS("PostgreSQL", "postgres"); POSTGRES("PostgreSQL", "postgres");
public final String dbProductname; public final String dbProductName;
public final String dbProductId; public final String dbProductId;
DB(String dbProductname, String dbProductId) { DB(String dbProductName, String dbProductId) {
this.dbProductname = dbProductname; this.dbProductName = dbProductName;
this.dbProductId = dbProductId; this.dbProductId = dbProductId;
} }
public static boolean isDb2(String dbProductName) { public static boolean isH2(String dbProductId) {
return dbProductName != null && dbProductName.contains(DB2.dbProductname); return H2.dbProductId.equals(dbProductId);
} }
public static boolean isH2(String dbProductName) { public static boolean isDb2(String dbProductId) {
return dbProductName != null && dbProductName.contains(H2.dbProductname); return DB2.dbProductId.equals(dbProductId);
} }
public static boolean isPostgreSql(String dbProductName) { public static boolean isPostgres(String dbProductId) {
return POSTGRESS.dbProductname.equals(dbProductName); return POSTGRES.dbProductId.equals(dbProductId);
}
public static DB getDbForId(String databaseId) {
if (isH2(databaseId)) {
return H2;
} else if (isDb2(databaseId)) {
return DB2;
} else if (isPostgres(databaseId)) {
return POSTGRES;
}
throw new SystemException("Unknown database id: " + databaseId);
} }
public static String getDatabaseProductId(String dbProductName) { public static String getDatabaseProductId(String dbProductName) {
if (dbProductName.contains(H2.dbProductName)) {
if (isDb2(dbProductName)) {
return DB2.dbProductId;
} else if (isH2(dbProductName)) {
return H2.dbProductId; return H2.dbProductId;
} else if (isPostgreSql(dbProductName)) { } else if (dbProductName.contains(DB2.dbProductName)) {
return POSTGRESS.dbProductId; return DB2.dbProductId;
} else if (POSTGRES.dbProductName.equals(dbProductName)) {
return POSTGRES.dbProductId;
} else { } else {
throw new UnsupportedDatabaseException(dbProductName); throw new UnsupportedDatabaseException(dbProductName);
} }
} }
public String getProductId() {
return this.dbProductId;
}
} }

View File

@ -61,10 +61,11 @@ public class DbSchemaCreator {
connection.getMetaData().getDatabaseProductName(), connection.getMetaData().getDatabaseProductName(),
connection.getMetaData().getURL()); connection.getMetaData().getURL());
ScriptRunner runner = getScriptRunnerInstance(connection); ScriptRunner runner = getScriptRunnerInstance(connection);
String dbProductId =
DB.getDatabaseProductId(connection.getMetaData().getDatabaseProductName());
if (!isSchemaPreexisting(connection)) { if (!isSchemaPreexisting(connection, dbProductId)) {
String scriptPath = String scriptPath = selectDbScriptFileName(dbProductId);
selectDbScriptFileName(connection.getMetaData().getDatabaseProductName());
InputStream resourceAsStream = DbSchemaCreator.class.getResourceAsStream(scriptPath); InputStream resourceAsStream = DbSchemaCreator.class.getResourceAsStream(scriptPath);
BufferedReader reader = BufferedReader reader =
new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8)); new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8));
@ -120,18 +121,28 @@ public class DbSchemaCreator {
this.dataSource = dataSource; this.dataSource = dataSource;
} }
private static String selectDbScriptFileName(String dbProductName) { private static String selectDbScriptFileName(String dbProductId) {
return DB.isPostgreSql(dbProductName)
? DB_SCHEMA_POSTGRES switch (DB.getDbForId(dbProductId)) {
: DB.isH2(dbProductName) ? DB_SCHEMA_H2 : DB_SCHEMA_DB2; case DB2:
return DB_SCHEMA_DB2;
case POSTGRES:
return DB_SCHEMA_POSTGRES;
default:
return DB_SCHEMA_H2;
}
} }
private static String selectDbSchemaDetectionScript(String dbProductName) { private static String selectDbSchemaDetectionScript(String dbProductId) {
if (DB.isPostgreSql(dbProductName)) { switch (DB.getDbForId(dbProductId)) {
return DB_SCHEMA_DETECTION_POSTGRES; case DB2:
return DB_SCHEMA_DETECTION_DB2;
case POSTGRES:
return DB_SCHEMA_DETECTION_POSTGRES;
default:
return DB_SCHEMA_DETECTION_H2;
} }
return DB.isH2(dbProductName) ? DB_SCHEMA_DETECTION_H2 : DB_SCHEMA_DETECTION_DB2;
} }
private ScriptRunner getScriptRunnerInstance(Connection connection) { private ScriptRunner getScriptRunnerInstance(Connection connection) {
@ -142,18 +153,17 @@ public class DbSchemaCreator {
return runner; return runner;
} }
private boolean isSchemaPreexisting(Connection connection) { private boolean isSchemaPreexisting(Connection connection, String dbProductId) {
ScriptRunner runner = getScriptRunnerInstance(connection); ScriptRunner runner = getScriptRunnerInstance(connection);
StringWriter errorWriter = new StringWriter(); StringWriter errorWriter = new StringWriter();
runner.setErrorLogWriter(new PrintWriter(errorWriter)); runner.setErrorLogWriter(new PrintWriter(errorWriter));
try {
String scriptPath = String scriptPath = selectDbSchemaDetectionScript(dbProductId);
selectDbSchemaDetectionScript(connection.getMetaData().getDatabaseProductName()); try (InputStream resource = DbSchemaCreator.class.getResourceAsStream(scriptPath);
InputStream resourceAsStream = DbSchemaCreator.class.getResourceAsStream(scriptPath); InputStreamReader inputReader = new InputStreamReader(resource, StandardCharsets.UTF_8);
BufferedReader reader = BufferedReader reader = new BufferedReader(inputReader)) {
new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8));
runner.runScript(getSqlSchemaNameParsed(reader)); runner.runScript(getSqlSchemaNameParsed(reader));
} catch (RuntimeSqlException | SQLException e) { } catch (RuntimeSqlException | IOException e) {
LOGGER.debug("Schema does not exist."); LOGGER.debug("Schema does not exist.");
if (!errorWriter.toString().trim().isEmpty()) { if (!errorWriter.toString().trim().isEmpty()) {
LOGGER.debug(errorWriter.toString()); LOGGER.debug(errorWriter.toString());

View File

@ -8,6 +8,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import acceptance.AbstractAccTest; import acceptance.AbstractAccTest;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
@ -54,7 +55,7 @@ class SimpleHistoryServiceImplTest {
@Mock private SqlSession sqlSessionMock; @Mock private SqlSession sqlSessionMock;
@Test @Test
void testInitializeSimpleHistoryService() { void testInitializeSimpleHistoryService() throws SQLException {
when(sqlSessionManagerMock.getMapper(TaskHistoryEventMapper.class)) when(sqlSessionManagerMock.getMapper(TaskHistoryEventMapper.class))
.thenReturn(taskHistoryEventMapperMock); .thenReturn(taskHistoryEventMapperMock);
when(sqlSessionManagerMock.getMapper(WorkbasketHistoryEventMapper.class)) when(sqlSessionManagerMock.getMapper(WorkbasketHistoryEventMapper.class))

View File

@ -1,5 +1,6 @@
package pro.taskana.simplehistory.rest; package pro.taskana.simplehistory.rest;
import java.sql.SQLException;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
@ -90,7 +91,8 @@ public class TaskHistoryEventController extends AbstractPagingController {
public TaskHistoryEventController( public TaskHistoryEventController(
TaskanaEngineConfiguration taskanaEngineConfiguration, TaskanaEngineConfiguration taskanaEngineConfiguration,
SimpleHistoryServiceImpl simpleHistoryServiceImpl, SimpleHistoryServiceImpl simpleHistoryServiceImpl,
TaskHistoryEventRepresentationModelAssembler taskHistoryEventRepresentationModelAssembler) { TaskHistoryEventRepresentationModelAssembler taskHistoryEventRepresentationModelAssembler)
throws SQLException {
this.simpleHistoryService = simpleHistoryServiceImpl; this.simpleHistoryService = simpleHistoryServiceImpl;
this.simpleHistoryService.initialize(taskanaEngineConfiguration.buildTaskanaEngine()); this.simpleHistoryService.initialize(taskanaEngineConfiguration.buildTaskanaEngine());

View File

@ -60,7 +60,7 @@ public class TaskanaProducers {
@ApplicationScoped @ApplicationScoped
@Produces @Produces
public TaskanaEngine generateTaskEngine() { public TaskanaEngine generateTaskEngine() throws SQLException {
return taskanaEngineConfiguration.buildTaskanaEngine(); return taskanaEngineConfiguration.buildTaskanaEngine();
} }

View File

@ -39,8 +39,6 @@ import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.common.api.exceptions.WrongCustomHolidayFormatException; import pro.taskana.common.api.exceptions.WrongCustomHolidayFormatException;
import pro.taskana.common.internal.TaskanaEngineImpl; import pro.taskana.common.internal.TaskanaEngineImpl;
import pro.taskana.common.internal.configuration.DB; import pro.taskana.common.internal.configuration.DB;
import pro.taskana.common.internal.configuration.DbSchemaCreator;
import pro.taskana.common.internal.configuration.SecurityVerifier;
import pro.taskana.common.internal.util.CheckedFunction; import pro.taskana.common.internal.util.CheckedFunction;
import pro.taskana.common.internal.util.Pair; import pro.taskana.common.internal.util.Pair;
@ -53,8 +51,6 @@ public class TaskanaEngineConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineConfiguration.class); private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineConfiguration.class);
// must match the VERSION value in table
private static final String TASKANA_SCHEMA_VERSION = "4.0.0";
private static final String TASKANA_PROPERTIES = "/taskana.properties"; private static final String TASKANA_PROPERTIES = "/taskana.properties";
private static final String TASKANA_PROPERTY_SEPARATOR = "|"; private static final String TASKANA_PROPERTY_SEPARATOR = "|";
private static final String TASKANA_JOB_BATCH_SIZE = "taskana.jobs.batchSize"; private static final String TASKANA_JOB_BATCH_SIZE = "taskana.jobs.batchSize";
@ -84,7 +80,6 @@ public class TaskanaEngineConfiguration {
protected String propertiesFileName = TASKANA_PROPERTIES; protected String propertiesFileName = TASKANA_PROPERTIES;
// Taskana datasource configuration // Taskana datasource configuration
protected DataSource dataSource; protected DataSource dataSource;
protected DbSchemaCreator dbSchemaCreator;
protected String schemaName; protected String schemaName;
// Taskana role configuration // Taskana role configuration
protected String propertiesSeparator = TASKANA_PROPERTY_SEPARATOR; protected String propertiesSeparator = TASKANA_PROPERTY_SEPARATOR;
@ -92,7 +87,6 @@ public class TaskanaEngineConfiguration {
// global switch to enable JAAS based authentication and Taskana // global switch to enable JAAS based authentication and Taskana
// authorizations // authorizations
protected boolean securityEnabled; protected boolean securityEnabled;
protected SecurityVerifier securityVerifier;
protected boolean useManagedTransactions; protected boolean useManagedTransactions;
// List of configured domain names // List of configured domain names
protected List<String> domains = new ArrayList<>(); protected List<String> domains = new ArrayList<>();
@ -113,8 +107,7 @@ public class TaskanaEngineConfiguration {
private boolean taskCleanupJobAllCompletedSameParentBusiness = true; private boolean taskCleanupJobAllCompletedSameParentBusiness = true;
public TaskanaEngineConfiguration( public TaskanaEngineConfiguration(
DataSource dataSource, boolean useManagedTransactions, String schemaName) DataSource dataSource, boolean useManagedTransactions, String schemaName) {
throws SQLException {
this(dataSource, useManagedTransactions, true, schemaName); this(dataSource, useManagedTransactions, true, schemaName);
} }
@ -122,8 +115,7 @@ public class TaskanaEngineConfiguration {
DataSource dataSource, DataSource dataSource,
boolean useManagedTransactions, boolean useManagedTransactions,
boolean securityEnabled, boolean securityEnabled,
String schemaName) String schemaName) {
throws SQLException {
this(dataSource, useManagedTransactions, securityEnabled, null, null, schemaName); this(dataSource, useManagedTransactions, securityEnabled, null, null, schemaName);
} }
@ -133,8 +125,7 @@ public class TaskanaEngineConfiguration {
boolean securityEnabled, boolean securityEnabled,
String propertiesFileName, String propertiesFileName,
String propertySeparator, String propertySeparator,
String schemaName) String schemaName) {
throws SQLException {
this.useManagedTransactions = useManagedTransactions; this.useManagedTransactions = useManagedTransactions;
this.securityEnabled = securityEnabled; this.securityEnabled = securityEnabled;
@ -155,18 +146,6 @@ public class TaskanaEngineConfiguration {
initSchemaName(schemaName); initSchemaName(schemaName);
initTaskanaProperties(this.propertiesFileName, this.propertiesSeparator); initTaskanaProperties(this.propertiesFileName, this.propertiesSeparator);
dbSchemaCreator = new DbSchemaCreator(this.dataSource, this.getSchemaName());
dbSchemaCreator.run();
if (!dbSchemaCreator.isValidSchemaVersion(TASKANA_SCHEMA_VERSION)) {
throw new SystemException(
"The Database Schema Version doesn't match the expected minimal version "
+ TASKANA_SCHEMA_VERSION);
}
securityVerifier = new SecurityVerifier(this.dataSource, this.getSchemaName());
securityVerifier.checkSecureAccess(securityEnabled);
} }
public void initTaskanaProperties(String propertiesFile, String separator) { public void initTaskanaProperties(String propertiesFile, String separator) {
@ -210,8 +189,9 @@ public class TaskanaEngineConfiguration {
* This method creates the TaskanaEngine without an sqlSessionFactory. * This method creates the TaskanaEngine without an sqlSessionFactory.
* *
* @return the TaskanaEngine * @return the TaskanaEngine
* @throws SQLException if a database access error occurs
*/ */
public TaskanaEngine buildTaskanaEngine() { public TaskanaEngine buildTaskanaEngine() throws SQLException {
return TaskanaEngineImpl.createTaskanaEngine(this); return TaskanaEngineImpl.createTaskanaEngine(this);
} }
@ -491,8 +471,9 @@ public class TaskanaEngineConfiguration {
} }
try (Connection connection = dataSource.getConnection()) { try (Connection connection = dataSource.getConnection()) {
String databaseProductName = connection.getMetaData().getDatabaseProductName(); String databaseProductId =
if (DB.isPostgreSql(databaseProductName)) { DB.getDatabaseProductId(connection.getMetaData().getDatabaseProductName());
if (DB.isPostgres(databaseProductId)) {
this.schemaName = this.schemaName.toLowerCase(); this.schemaName = this.schemaName.toLowerCase();
} else { } else {
this.schemaName = this.schemaName.toUpperCase(); this.schemaName = this.schemaName.toUpperCase();

View File

@ -44,6 +44,8 @@ import pro.taskana.common.api.exceptions.TaskanaRuntimeException;
import pro.taskana.common.api.security.CurrentUserContext; import pro.taskana.common.api.security.CurrentUserContext;
import pro.taskana.common.api.security.GroupPrincipal; import pro.taskana.common.api.security.GroupPrincipal;
import pro.taskana.common.internal.configuration.DB; import pro.taskana.common.internal.configuration.DB;
import pro.taskana.common.internal.configuration.DbSchemaCreator;
import pro.taskana.common.internal.configuration.SecurityVerifier;
import pro.taskana.common.internal.persistence.InstantTypeHandler; import pro.taskana.common.internal.persistence.InstantTypeHandler;
import pro.taskana.common.internal.persistence.MapTypeHandler; import pro.taskana.common.internal.persistence.MapTypeHandler;
import pro.taskana.common.internal.security.CurrentUserContextImpl; import pro.taskana.common.internal.security.CurrentUserContextImpl;
@ -70,7 +72,8 @@ import pro.taskana.workbasket.internal.WorkbasketServiceImpl;
/** This is the implementation of TaskanaEngine. */ /** This is the implementation of TaskanaEngine. */
public class TaskanaEngineImpl implements TaskanaEngine { public class TaskanaEngineImpl implements TaskanaEngine {
private static final String DEFAULT = "default"; // must match the VERSION value in table
private static final String TASKANA_SCHEMA_VERSION = "4.0.0";
private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineImpl.class);
private static final SessionStack SESSION_STACK = new SessionStack(); private static final SessionStack SESSION_STACK = new SessionStack();
private final TaskRoutingManager taskRoutingManager; private final TaskRoutingManager taskRoutingManager;
@ -85,10 +88,13 @@ public class TaskanaEngineImpl implements TaskanaEngine {
protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE; protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE;
protected Connection connection = null; protected Connection connection = null;
protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration) { protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration)
throws SQLException {
this.taskanaEngineConfiguration = taskanaEngineConfiguration; this.taskanaEngineConfiguration = taskanaEngineConfiguration;
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions()); createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
this.sessionManager = createSqlSessionManager(); this.sessionManager = createSqlSessionManager();
initializeDbSchema(taskanaEngineConfiguration);
historyEventManager = HistoryEventManager.getInstance(this); historyEventManager = HistoryEventManager.getInstance(this);
taskRoutingManager = TaskRoutingManager.getInstance(this); taskRoutingManager = TaskRoutingManager.getInstance(this);
createTaskPreprocessorManager = CreateTaskPreprocessorManager.getInstance(); createTaskPreprocessorManager = CreateTaskPreprocessorManager.getInstance();
@ -103,7 +109,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
} }
public static TaskanaEngine createTaskanaEngine( public static TaskanaEngine createTaskanaEngine(
TaskanaEngineConfiguration taskanaEngineConfiguration) { TaskanaEngineConfiguration taskanaEngineConfiguration) throws SQLException {
return new TaskanaEngineImpl(taskanaEngineConfiguration); return new TaskanaEngineImpl(taskanaEngineConfiguration);
} }
@ -253,13 +259,12 @@ public class TaskanaEngineImpl implements TaskanaEngine {
protected SqlSessionManager createSqlSessionManager() { protected SqlSessionManager createSqlSessionManager() {
Environment environment = Environment environment =
new Environment( new Environment(
DEFAULT, this.transactionFactory, taskanaEngineConfiguration.getDatasource()); "default", this.transactionFactory, taskanaEngineConfiguration.getDatasource());
Configuration configuration = new Configuration(environment); Configuration configuration = new Configuration(environment);
// set databaseId // set databaseId
String databaseProductName;
try (Connection con = taskanaEngineConfiguration.getDatasource().getConnection()) { try (Connection con = taskanaEngineConfiguration.getDatasource().getConnection()) {
databaseProductName = con.getMetaData().getDatabaseProductName(); String databaseProductName = con.getMetaData().getDatabaseProductName();
String databaseProductId = DB.getDatabaseProductId(databaseProductName); String databaseProductId = DB.getDatabaseProductId(databaseProductName);
configuration.setDatabaseId(databaseProductId); configuration.setDatabaseId(databaseProductId);
@ -292,6 +297,23 @@ public class TaskanaEngineImpl implements TaskanaEngine {
return SqlSessionManager.newInstance(localSessionFactory); return SqlSessionManager.newInstance(localSessionFactory);
} }
private void initializeDbSchema(TaskanaEngineConfiguration taskanaEngineConfiguration)
throws SQLException {
DbSchemaCreator dbSchemaCreator =
new DbSchemaCreator(
taskanaEngineConfiguration.getDatasource(), taskanaEngineConfiguration.getSchemaName());
dbSchemaCreator.run();
if (!dbSchemaCreator.isValidSchemaVersion(TASKANA_SCHEMA_VERSION)) {
throw new SystemException(
"The Database Schema Version doesn't match the expected minimal version "
+ TASKANA_SCHEMA_VERSION);
}
new SecurityVerifier(
taskanaEngineConfiguration.getDatasource(), taskanaEngineConfiguration.getSchemaName())
.checkSecureAccess(taskanaEngineConfiguration.isSecurityEnabled());
}
/** /**
* creates the MyBatis transaction factory. * creates the MyBatis transaction factory.
* *

View File

@ -710,7 +710,7 @@ public class TaskQueryImpl implements TaskQuery {
@Override @Override
public TaskQuery orderByClassificationKey(SortDirection sortDirection) { public TaskQuery orderByClassificationKey(SortDirection sortDirection) {
return DB.DB2.dbProductId.equals(getDatabaseId()) return DB.isDb2(getDatabaseId())
? addOrderCriteria("TCLASSIFICATION_KEY", sortDirection) ? addOrderCriteria("TCLASSIFICATION_KEY", sortDirection)
: addOrderCriteria("t.CLASSIFICATION_KEY", sortDirection); : addOrderCriteria("t.CLASSIFICATION_KEY", sortDirection);
} }
@ -719,7 +719,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByClassificationName(SortDirection sortDirection) { public TaskQuery orderByClassificationName(SortDirection sortDirection) {
joinWithClassifications = true; joinWithClassifications = true;
addClassificationNameToSelectClauseForOrdering = true; addClassificationNameToSelectClauseForOrdering = true;
return DB.DB2.dbProductId.equals(getDatabaseId()) return DB.isDb2(getDatabaseId())
? addOrderCriteria("CNAME", sortDirection) ? addOrderCriteria("CNAME", sortDirection)
: addOrderCriteria("c.NAME", sortDirection); : addOrderCriteria("c.NAME", sortDirection);
} }
@ -866,7 +866,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentClassificationKey(SortDirection sortDirection) { public TaskQuery orderByAttachmentClassificationKey(SortDirection sortDirection) {
joinWithAttachments = true; joinWithAttachments = true;
addAttachmentColumnsToSelectClauseForOrdering = true; addAttachmentColumnsToSelectClauseForOrdering = true;
return DB.DB2.dbProductId.equals(getDatabaseId()) return DB.isDb2(getDatabaseId())
? addOrderCriteria("ACLASSIFICATION_KEY", sortDirection) ? addOrderCriteria("ACLASSIFICATION_KEY", sortDirection)
: addOrderCriteria("a.CLASSIFICATION_KEY", sortDirection); : addOrderCriteria("a.CLASSIFICATION_KEY", sortDirection);
} }
@ -875,7 +875,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentClassificationName(SortDirection sortDirection) { public TaskQuery orderByAttachmentClassificationName(SortDirection sortDirection) {
joinWithAttachments = true; joinWithAttachments = true;
addAttachmentClassificationNameToSelectClauseForOrdering = true; addAttachmentClassificationNameToSelectClauseForOrdering = true;
return DB.DB2.dbProductId.equals(getDatabaseId()) return DB.isDb2(getDatabaseId())
? addOrderCriteria("ACNAME", sortDirection) ? addOrderCriteria("ACNAME", sortDirection)
: addOrderCriteria("ac.NAME", sortDirection); : addOrderCriteria("ac.NAME", sortDirection);
} }
@ -884,7 +884,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentClassificationId(SortDirection sortDirection) { public TaskQuery orderByAttachmentClassificationId(SortDirection sortDirection) {
joinWithAttachments = true; joinWithAttachments = true;
addAttachmentColumnsToSelectClauseForOrdering = true; addAttachmentColumnsToSelectClauseForOrdering = true;
return DB.DB2.dbProductId.equals(getDatabaseId()) return DB.isDb2(getDatabaseId())
? addOrderCriteria("ACLASSIFICATION_ID", sortDirection) ? addOrderCriteria("ACLASSIFICATION_ID", sortDirection)
: addOrderCriteria("a.CLASSIFICATION_ID", sortDirection); : addOrderCriteria("a.CLASSIFICATION_ID", sortDirection);
} }
@ -1059,7 +1059,7 @@ public class TaskQueryImpl implements TaskQuery {
// optimized query for db2 can't be used for now in case of selectAndClaim because of temporary // optimized query for db2 can't be used for now in case of selectAndClaim because of temporary
// tables and the "for update" clause clashing in db2 // tables and the "for update" clause clashing in db2
public String getLinkToMapperScript() { public String getLinkToMapperScript() {
if (DB.DB2.dbProductId.equals(getDatabaseId()) && !selectAndClaim) { if (DB.isDb2(getDatabaseId()) && !selectAndClaim) {
return LINK_TO_MAPPER_DB2; return LINK_TO_MAPPER_DB2;
} else { } else {
return LINK_TO_MAPPER; return LINK_TO_MAPPER;
@ -1067,7 +1067,7 @@ public class TaskQueryImpl implements TaskQuery {
} }
public String getLinkToCounterTaskScript() { public String getLinkToCounterTaskScript() {
return DB.DB2.dbProductId.equals(getDatabaseId()) ? LINK_TO_COUNTER_DB2 : LINK_TO_COUNTER; return DB.isDb2(getDatabaseId()) ? LINK_TO_COUNTER_DB2 : LINK_TO_COUNTER;
} }
public boolean isUseDistinctKeyword() { public boolean isUseDistinctKeyword() {

View File

@ -6,9 +6,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -25,10 +25,10 @@ class TaskanaSecurityConfigAccTest {
DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource();
String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); String schemaName = TaskanaEngineTestConfiguration.getSchemaName();
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
sampleDataGenerator.dropDb();
DbSchemaCreator dbSchemaCreator = new DbSchemaCreator(dataSource, schemaName); DbSchemaCreator dbSchemaCreator = new DbSchemaCreator(dataSource, schemaName);
dbSchemaCreator.run(); dbSchemaCreator.run();
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
sampleDataGenerator.clearDb();
} }
@Test @Test
@ -37,17 +37,7 @@ class TaskanaSecurityConfigAccTest {
setSecurityFlag(true); setSecurityFlag(true);
ThrowingCallable createUnsecuredTaskanaEngineConfiguration = assertThatThrownBy(() -> createTaskanaEngine(false))
() -> {
TaskanaEngineConfiguration taskanaEngineConfiguration =
new TaskanaEngineConfiguration(
TaskanaEngineTestConfiguration.getDataSource(),
false,
false,
TaskanaEngineTestConfiguration.getSchemaName());
};
assertThatThrownBy(createUnsecuredTaskanaEngineConfiguration)
.isInstanceOf(SystemException.class) .isInstanceOf(SystemException.class)
.hasMessageContaining("Secured TASKANA mode is enforced, can't start in unsecured mode"); .hasMessageContaining("Secured TASKANA mode is enforced, can't start in unsecured mode");
} }
@ -58,17 +48,8 @@ class TaskanaSecurityConfigAccTest {
setSecurityFlag(false); setSecurityFlag(false);
ThrowingCallable createUnsecuredTaskanaEngineConfiguration =
() -> {
TaskanaEngineConfiguration taskanaEngineConfiguration =
new TaskanaEngineConfiguration(
TaskanaEngineTestConfiguration.getDataSource(),
false,
false,
TaskanaEngineTestConfiguration.getSchemaName());
};
assertThatCode(createUnsecuredTaskanaEngineConfiguration).doesNotThrowAnyException(); assertThatCode(() -> createTaskanaEngine(false)).doesNotThrowAnyException();
} }
@Test @Test
@ -77,17 +58,7 @@ class TaskanaSecurityConfigAccTest {
assertThat(retrieveSecurityFlag()).isNull(); assertThat(retrieveSecurityFlag()).isNull();
ThrowingCallable createUnsecuredTaskanaEngineConfiguration = assertThatCode(() -> createTaskanaEngine(false)).doesNotThrowAnyException();
() -> {
TaskanaEngineConfiguration taskanaEngineConfiguration =
new TaskanaEngineConfiguration(
TaskanaEngineTestConfiguration.getDataSource(),
false,
false,
TaskanaEngineTestConfiguration.getSchemaName());
};
assertThatCode(createUnsecuredTaskanaEngineConfiguration).doesNotThrowAnyException();
assertThat(retrieveSecurityFlag()).isFalse(); assertThat(retrieveSecurityFlag()).isFalse();
} }
@ -98,21 +69,20 @@ class TaskanaSecurityConfigAccTest {
assertThat(retrieveSecurityFlag()).isNull(); assertThat(retrieveSecurityFlag()).isNull();
ThrowingCallable createSecuredTaskanaEngineConfiguration = assertThatCode(() -> createTaskanaEngine(true)).doesNotThrowAnyException();
() -> {
TaskanaEngineConfiguration taskanaEngineConfiguration =
new TaskanaEngineConfiguration(
TaskanaEngineTestConfiguration.getDataSource(),
false,
true,
TaskanaEngineTestConfiguration.getSchemaName());
};
assertThatCode(createSecuredTaskanaEngineConfiguration).doesNotThrowAnyException();
assertThat(retrieveSecurityFlag()).isTrue(); assertThat(retrieveSecurityFlag()).isTrue();
} }
private void createTaskanaEngine(boolean securityEnabled) throws SQLException {
new TaskanaEngineConfiguration(
TaskanaEngineTestConfiguration.getDataSource(),
false,
securityEnabled,
TaskanaEngineTestConfiguration.getSchemaName())
.buildTaskanaEngine();
}
private Boolean retrieveSecurityFlag() throws Exception { private Boolean retrieveSecurityFlag() throws Exception {
try (Connection connection = TaskanaEngineTestConfiguration.getDataSource().getConnection()) { try (Connection connection = TaskanaEngineTestConfiguration.getDataSource().getConnection()) {

View File

@ -32,7 +32,7 @@ class ClassificationServiceImplIntAutoCommitTest {
private ClassificationService classificationService; private ClassificationService classificationService;
@BeforeAll @BeforeAll
static void beforeAll() throws Exception { static void beforeAll() {
DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource();
String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); String schemaName = TaskanaEngineTestConfiguration.getSchemaName();
sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
@ -41,7 +41,7 @@ class ClassificationServiceImplIntAutoCommitTest {
} }
@BeforeEach @BeforeEach
void setup() { void setup() throws Exception {
TaskanaEngine taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); TaskanaEngine taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
classificationService = taskanaEngine.getClassificationService(); classificationService = taskanaEngine.getClassificationService();
TaskanaEngineImpl taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; TaskanaEngineImpl taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;

View File

@ -17,7 +17,7 @@ public final class TaskanaEngineTestConfiguration {
private static final Logger LOGGER = private static final Logger LOGGER =
LoggerFactory.getLogger(TaskanaEngineTestConfiguration.class); LoggerFactory.getLogger(TaskanaEngineTestConfiguration.class);
private static final int POOL_TIME_TO_WAIT = 50; private static final int POOL_TIME_TO_WAIT = 50;
private static DataSource dataSource; private static final DataSource DATA_SOURCE;
private static String schemaName = null; private static String schemaName = null;
static { static {
@ -25,9 +25,9 @@ public final class TaskanaEngineTestConfiguration {
String propertiesFileName = userHomeDirectroy + "/taskanaUnitTest.properties"; String propertiesFileName = userHomeDirectroy + "/taskanaUnitTest.properties";
File f = new File(propertiesFileName); File f = new File(propertiesFileName);
if (f.exists() && !f.isDirectory()) { if (f.exists() && !f.isDirectory()) {
dataSource = createDataSourceFromProperties(propertiesFileName); DATA_SOURCE = createDataSourceFromProperties(propertiesFileName);
} else { } else {
dataSource = createDefaultDataSource(); DATA_SOURCE = createDefaultDataSource();
} }
} }
@ -45,7 +45,7 @@ public final class TaskanaEngineTestConfiguration {
* @return dataSource for unit test * @return dataSource for unit test
*/ */
public static DataSource getDataSource() { public static DataSource getDataSource() {
return dataSource; return DATA_SOURCE;
} }
/** /**

View File

@ -54,7 +54,7 @@ class TaskServiceImplIntAutocommitTest {
private WorkbasketService workbasketService; private WorkbasketService workbasketService;
@BeforeAll @BeforeAll
static void beforeAll() throws Exception { static void beforeAll() {
DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource(); DataSource dataSource = TaskanaEngineTestConfiguration.getDataSource();
String schemaName = TaskanaEngineTestConfiguration.getSchemaName(); String schemaName = TaskanaEngineTestConfiguration.getSchemaName();
sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName);
@ -63,7 +63,7 @@ class TaskServiceImplIntAutocommitTest {
} }
@BeforeEach @BeforeEach
void setup() { void setup() throws Exception {
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);

View File

@ -47,13 +47,13 @@ public class TaskanaConfig {
} }
@Bean @Bean
public SpringTaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource) public SpringTaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource) {
throws SQLException {
return new SpringTaskanaEngineConfiguration(dataSource, true, false, schemaName); return new SpringTaskanaEngineConfiguration(dataSource, true, false, schemaName);
} }
@Bean @Bean
public TaskanaEngine taskanaEngine(SpringTaskanaEngineConfiguration taskanaEngineConfiguration) { public TaskanaEngine taskanaEngine(SpringTaskanaEngineConfiguration taskanaEngineConfiguration)
throws SQLException {
return taskanaEngineConfiguration.buildTaskanaEngine(); return taskanaEngineConfiguration.buildTaskanaEngine();
} }

View File

@ -13,8 +13,7 @@ public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration
DataSource dataSource, DataSource dataSource,
boolean useManagedTransactions, boolean useManagedTransactions,
boolean securityEnabled, boolean securityEnabled,
String schemaName) String schemaName) {
throws SQLException {
super(dataSource, useManagedTransactions, securityEnabled, schemaName); super(dataSource, useManagedTransactions, securityEnabled, schemaName);
} }
@ -24,8 +23,7 @@ public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration
boolean securityEnabled, boolean securityEnabled,
String propertiesFileName, String propertiesFileName,
String propertiesSeparator, String propertiesSeparator,
String schemaName) String schemaName) {
throws SQLException {
super( super(
dataSource, dataSource,
useManagedTransactions, useManagedTransactions,
@ -41,7 +39,7 @@ public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration
* @return the TaskanaEngine * @return the TaskanaEngine
*/ */
@Override @Override
public TaskanaEngine buildTaskanaEngine() { public TaskanaEngine buildTaskanaEngine() throws SQLException {
this.useManagedTransactions = true; this.useManagedTransactions = true;
return new SpringTaskanaEngineImpl(this); return new SpringTaskanaEngineImpl(this);
} }

View File

@ -1,5 +1,6 @@
package pro.taskana.common.internal; package pro.taskana.common.internal;
import java.sql.SQLException;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory; import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
@ -8,7 +9,8 @@ import pro.taskana.SpringTaskanaEngineConfiguration;
/** This class configures the TaskanaEngine for spring. */ /** This class configures the TaskanaEngine for spring. */
public class SpringTaskanaEngineImpl extends TaskanaEngineImpl { public class SpringTaskanaEngineImpl extends TaskanaEngineImpl {
public SpringTaskanaEngineImpl(SpringTaskanaEngineConfiguration taskanaEngineConfiguration) { public SpringTaskanaEngineImpl(SpringTaskanaEngineConfiguration taskanaEngineConfiguration)
throws SQLException {
super(taskanaEngineConfiguration); super(taskanaEngineConfiguration);
} }

View File

@ -53,14 +53,14 @@ public class RestConfiguration {
} }
@Bean @Bean
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration) { public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration)
throws SQLException {
return taskanaEngineConfiguration.buildTaskanaEngine(); return taskanaEngineConfiguration.buildTaskanaEngine();
} }
@Bean @Bean
@ConditionalOnMissingBean(TaskanaEngineConfiguration.class) @ConditionalOnMissingBean(TaskanaEngineConfiguration.class)
public TaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource) public TaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource) {
throws SQLException {
return new SpringTaskanaEngineConfiguration(dataSource, true, true, schemaName); return new SpringTaskanaEngineConfiguration(dataSource, true, true, schemaName);
} }

View File

@ -29,10 +29,10 @@ class TestSchemaNameCustomizable {
void resetDb() throws SQLException { void resetDb() throws SQLException {
SampleDataGenerator sampleDataGenerator; SampleDataGenerator sampleDataGenerator;
try (Connection connection = dataSource.getConnection()) { try (Connection connection = dataSource.getConnection()) {
String databaseProductName = connection.getMetaData().getDatabaseProductName(); String databaseProductId =
isPostgres = DB.POSTGRESS.dbProductname.equals(databaseProductName); DB.getDatabaseProductId(connection.getMetaData().getDatabaseProductName());
if (isPostgres) { if (DB.isPostgres(databaseProductId)) {
schemaName = schemaName.toLowerCase(Locale.ENGLISH); schemaName = schemaName.toLowerCase(Locale.ENGLISH);
} }
} }