diff --git a/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java b/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java index 466108ee6..12edafa79 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/TaskMonitorService.java @@ -4,6 +4,7 @@ import java.util.List; import pro.taskana.model.DueWorkbasketCounter; import pro.taskana.model.Report; +import pro.taskana.model.ReportLineItemDefinition; import pro.taskana.model.TaskState; import pro.taskana.model.TaskStateCounter; @@ -50,14 +51,38 @@ public interface TaskMonitorService { List getTaskCountByWorkbasketAndDaysInPastAndState(long daysInPast, List states); /** - * Returns a {@link Report} for a given list of {@link Workbasket} objects and for a given list of {@link TaskState} - * objects. + * Returns a {@link Report} for a given list of {@link Workbasket}s and for a given list of {@link TaskState}s. The + * report only contains the number of all tasks of the respective workbasket as well as the total sum of all tasks. + * Only tasks with a state in the list of TaskStates are provided. Task with Timestamp DUE = null are not + * considered. * * @param workbaskets - * a list of {@link Workbasket} objects + * a list of {@link Workbasket} objects that should be listed in the report * @param states - * a list of {@link TaskState} objects - * @return a {@link Report} object + * a list of {@link TaskState} objects that specify the states of the tasks that are provided + * @return a {@link Report} object that only contains the number of all tasks of the respective workbasket as well + * as the total number of all tasks */ Report getWorkbasketLevelReport(List workbaskets, List states); + + /** + * Returns a {@link Report} for a given list of {@link Workbasket}s, a given list of {@link TaskState}s and a given + * list of {@link ReportLineItemDefinition}s. For each workbasket the report contains a list of ReportLineItems that + * subdivides the report in to different cluster grouped by the due date. Only tasks with a state in the list of + * TaskStates are provided. Tasks with Timestamp DUE = null are not considered. + * + * @param workbaskets + * a list of {@link Workbasket} objects that should be listed in the report + * @param states + * a list of {@link TaskState} objects that specify the states of the tasks that are provided + * @param reportLineItemDefinitions + * a list of {@link ReportLineItemDefinition} objects that specify the subdivision into different cluster + * of due dates. Days in past are represented as negative values and days in the future are represented + * as positive values. To avoid tasks are counted multiple times or not be listed in the report, these + * reportLineItemDefinitions should not overlap and should not have gaps. If the ReportLineDefinition + * should represent a single day, lowerLimit and upperLimit have to be equal. + * @return a {@link Report} object that represents an overview of all tasks in the + */ + Report getWorkbasketLevelReport(List workbaskets, List states, + List reportLineItemDefinitions); } diff --git a/lib/taskana-core/src/main/java/pro/taskana/configuration/TaskanaEngineConfiguration.java b/lib/taskana-core/src/main/java/pro/taskana/configuration/TaskanaEngineConfiguration.java index 3c4e8ff66..638886b80 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/configuration/TaskanaEngineConfiguration.java +++ b/lib/taskana-core/src/main/java/pro/taskana/configuration/TaskanaEngineConfiguration.java @@ -1,109 +1,109 @@ -package pro.taskana.configuration; - -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.apache.ibatis.datasource.pooled.PooledDataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.TaskanaEngine; -import pro.taskana.impl.TaskanaEngineImpl; - -/** - * This central class creates the TaskanaEngine and holds all the information about DB and Security. - */ -public class TaskanaEngineConfiguration { - - private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineConfiguration.class); - - private static final String USER_NAME = "sa"; - private static final String USER_PASSWORD = "sa"; - private static final String JDBC_H2_MEM_TASKANA = "jdbc:h2:mem:taskana"; - private static final String H2_DRIVER = "org.h2.Driver"; - protected DataSource dataSource; - protected DbSchemaCreator dbScriptRunner; - - // global switch to enable JAAS based authentication and Taskana - // authorizations - protected boolean securityEnabled; - protected boolean useManagedTransactions; - - public TaskanaEngineConfiguration() { - } - - public TaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions) - throws SQLException { - this(dataSource, useManagedTransactions, true); - } - - public TaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions, - boolean securityEnabled) throws SQLException { - this.useManagedTransactions = useManagedTransactions; - - if (dataSource != null) { - this.dataSource = dataSource; - } else { - // use default In Memory datasource - this.dataSource = createDefaultDataSource(); - } - dbScriptRunner = new DbSchemaCreator(this.dataSource); - dbScriptRunner.run(); - - this.securityEnabled = securityEnabled; - } - - public static DataSource createDefaultDataSource() { - LOGGER.warn("No datasource is provided. A inmemory db is used: " - + "'org.h2.Driver', 'jdbc:h2:mem:taskana', 'sa', 'sa'"); - return createDatasource(H2_DRIVER, JDBC_H2_MEM_TASKANA, USER_NAME, USER_PASSWORD); - } - - /** - * This method creates the TaskanaEngine without an sqlSessionFactory. - * - * @return the TaskanaEngine - */ - public TaskanaEngine buildTaskanaEngine() { - return new TaskanaEngineImpl(this); - } - - /** - * This method creates a PooledDataSource, if the needed properties are provided. - * - * @param driver - * the name of the jdbc driver - * @param jdbcUrl - * the url to which the jdbc driver connects - * @param username - * the user name for database access - * @param password - * the password for database access - * @return DataSource - */ - public static DataSource createDatasource(String driver, String jdbcUrl, String username, String password) { - return new PooledDataSource(driver, jdbcUrl, username, password); - } - - public boolean isSecurityEnabled() { - return this.securityEnabled; - } - - public DataSource getDatasource() { - return this.dataSource; - } - - public boolean getUseManagedTransactions() { - return this.useManagedTransactions; - } - - /** - * Helper method to determine whether all access ids (user Id and group ids) should be used in lower case. - * - * @return true if all access ids should be used in lower case, false otherwise - */ - public static boolean shouldUseLowerCaseForAccessIds() { - return true; - } -} +package pro.taskana.configuration; + +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.apache.ibatis.datasource.pooled.PooledDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.TaskanaEngine; +import pro.taskana.impl.TaskanaEngineImpl; + +/** + * This central class creates the TaskanaEngine and holds all the information about DB and Security. + */ +public class TaskanaEngineConfiguration { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineConfiguration.class); + + private static final String USER_NAME = "sa"; + private static final String USER_PASSWORD = "sa"; + private static final String JDBC_H2_MEM_TASKANA = "jdbc:h2:mem:taskana"; + private static final String H2_DRIVER = "org.h2.Driver"; + protected DataSource dataSource; + protected DbSchemaCreator dbScriptRunner; + + // global switch to enable JAAS based authentication and Taskana + // authorizations + protected boolean securityEnabled; + protected boolean useManagedTransactions; + + public TaskanaEngineConfiguration() { + } + + public TaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions) + throws SQLException { + this(dataSource, useManagedTransactions, true); + } + + public TaskanaEngineConfiguration(DataSource dataSource, boolean useManagedTransactions, + boolean securityEnabled) throws SQLException { + this.useManagedTransactions = useManagedTransactions; + + if (dataSource != null) { + this.dataSource = dataSource; + } else { + // use default In Memory datasource + this.dataSource = createDefaultDataSource(); + } + dbScriptRunner = new DbSchemaCreator(this.dataSource); + dbScriptRunner.run(); + + this.securityEnabled = securityEnabled; + } + + public static DataSource createDefaultDataSource() { + LOGGER.warn("No datasource is provided. A inmemory db is used: " + + "'org.h2.Driver', 'jdbc:h2:mem:taskana', 'sa', 'sa'"); + return createDatasource(H2_DRIVER, JDBC_H2_MEM_TASKANA, USER_NAME, USER_PASSWORD); + } + + /** + * This method creates the TaskanaEngine without an sqlSessionFactory. + * + * @return the TaskanaEngine + */ + public TaskanaEngine buildTaskanaEngine() { + return new TaskanaEngineImpl(this); + } + + /** + * This method creates a PooledDataSource, if the needed properties are provided. + * + * @param driver + * the name of the jdbc driver + * @param jdbcUrl + * the url to which the jdbc driver connects + * @param username + * the user name for database access + * @param password + * the password for database access + * @return DataSource + */ + public static DataSource createDatasource(String driver, String jdbcUrl, String username, String password) { + return new PooledDataSource(driver, jdbcUrl, username, password); + } + + public boolean isSecurityEnabled() { + return this.securityEnabled; + } + + public DataSource getDatasource() { + return this.dataSource; + } + + public boolean getUseManagedTransactions() { + return this.useManagedTransactions; + } + + /** + * Helper method to determine whether all access ids (user Id and group ids) should be used in lower case. + * + * @return true if all access ids should be used in lower case, false otherwise + */ + public static boolean shouldUseLowerCaseForAccessIds() { + return true; + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java b/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java new file mode 100644 index 000000000..69bb1c5ad --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/exceptions/UnsupportedDatabaseException.java @@ -0,0 +1,13 @@ +package pro.taskana.exceptions; + +/** + * This exception will be thrown if the database name doesn't match to one of the desired databases. + */ +public class UnsupportedDatabaseException extends RuntimeException { + + public UnsupportedDatabaseException(String name) { + super("Database with '" + name + "' not found"); + } + + private static final long serialVersionUID = 1L; +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java index fec8ed485..8a1760602 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskMonitorServiceImpl.java @@ -12,8 +12,11 @@ import pro.taskana.TaskanaEngine; import pro.taskana.Workbasket; import pro.taskana.impl.util.LoggerUtils; import pro.taskana.model.DueWorkbasketCounter; +import pro.taskana.model.MonitorQueryItem; import pro.taskana.model.Report; import pro.taskana.model.ReportLine; +import pro.taskana.model.ReportLineItem; +import pro.taskana.model.ReportLineItemDefinition; import pro.taskana.model.TaskState; import pro.taskana.model.TaskStateCounter; import pro.taskana.model.mappings.TaskMonitorMapper; @@ -99,21 +102,29 @@ public class TaskMonitorServiceImpl implements TaskMonitorService { @Override public Report getWorkbasketLevelReport(List workbaskets, List states) { + return getWorkbasketLevelReport(workbaskets, states, null); + } + + @Override + public Report getWorkbasketLevelReport(List workbaskets, List states, + List reportLineItemDefinitions) { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("entry to getWorkbasketLevelReport(workbaskets = {})", LoggerUtils.listToString(workbaskets)); + LOGGER.debug( + "entry to getWorkbasketLevelReport(workbaskets = {}, states = {}, reportLineItemDefinitions = {})", + LoggerUtils.listToString(workbaskets), LoggerUtils.listToString(states), + LoggerUtils.listToString(reportLineItemDefinitions)); } try { taskanaEngineImpl.openConnection(); - Report report = new Report(); - report.setDetailLines(taskMonitorMapper.getDetailLinesByWorkbasketIdsAndStates(workbaskets, states)); - int sumLineTotalCount = 0; - for (ReportLine reportLine : report.getDetailLines()) { - sumLineTotalCount += reportLine.getTotalCount(); + + Report report = createEmptyReport(workbaskets, reportLineItemDefinitions); + List monitorQueryItems = taskMonitorMapper + .findByWorkbasketIdsAndStates(workbaskets, states); + + for (MonitorQueryItem item : monitorQueryItems) { + report.getDetailLines().get(item.getKey()).addNumberOfTasks(item); } - ReportLine sumLine = new ReportLine(); - sumLine.setName("SumLine"); - sumLine.setTotalCount(sumLineTotalCount); - report.setSumLine(sumLine); + report.generateSumLine(); return report; } finally { @@ -123,4 +134,29 @@ public class TaskMonitorServiceImpl implements TaskMonitorService { } } } + + private Report createEmptyReport(List workbaskets, + List reportLineItemDefinitions) { + Report report = new Report(); + for (Workbasket workbasket : workbaskets) { + ReportLine reportLine = new ReportLine(); + if (reportLineItemDefinitions != null) { + for (ReportLineItemDefinition reportLineItemDefinition : reportLineItemDefinitions) { + ReportLineItem reportLineItem = new ReportLineItem(); + reportLineItem.setReportLineItemDefinition(reportLineItemDefinition); + reportLine.getLineItems().add(reportLineItem); + } + } + report.getDetailLines().put(workbasket.getKey(), reportLine); + } + if (reportLineItemDefinitions != null) { + for (ReportLineItemDefinition reportLineItemDefinition : reportLineItemDefinitions) { + ReportLineItem reportLineItem = new ReportLineItem(); + reportLineItem.setReportLineItemDefinition(reportLineItemDefinition); + report.getSumLine().getLineItems().add(reportLineItem); + } + } + return report; + + } } diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java index 01d43d753..a654db9f0 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java @@ -1,288 +1,317 @@ -package pro.taskana.impl; - -import java.util.Stack; - -import org.apache.ibatis.mapping.Environment; -import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; -import org.apache.ibatis.session.SqlSessionFactoryBuilder; -import org.apache.ibatis.session.SqlSessionManager; -import org.apache.ibatis.transaction.TransactionFactory; -import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; -import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.ClassificationService; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskService; -import pro.taskana.TaskanaEngine; -import pro.taskana.WorkbasketService; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.exceptions.AutocommitFailedException; -import pro.taskana.exceptions.ConnectionNotSetException; -import pro.taskana.impl.persistence.MapTypeHandler; -import pro.taskana.model.mappings.AttachmentMapper; -import pro.taskana.model.mappings.ClassificationMapper; -import pro.taskana.model.mappings.DistributionTargetMapper; -import pro.taskana.model.mappings.ObjectReferenceMapper; -import pro.taskana.model.mappings.QueryMapper; -import pro.taskana.model.mappings.TaskMapper; -import pro.taskana.model.mappings.TaskMonitorMapper; -import pro.taskana.model.mappings.WorkbasketAccessMapper; -import pro.taskana.model.mappings.WorkbasketMapper; - -/** - * This is the implementation of TaskanaEngine. - */ -public class TaskanaEngineImpl implements TaskanaEngine { - - private static final String DEFAULT = "default"; - private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineImpl.class); - protected static ThreadLocal> sessionStack = new ThreadLocal>(); - protected TaskanaEngineConfiguration taskanaEngineConfiguration; - protected TransactionFactory transactionFactory; - protected SqlSessionManager sessionManager; - protected SqlSessionFactory sessionFactory; - protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE; - protected java.sql.Connection connection = null; - - public TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration) { - this.taskanaEngineConfiguration = taskanaEngineConfiguration; - createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions()); - this.sessionManager = createSqlSessionManager(); - } - - @Override - public TaskService getTaskService() { - SqlSession session = this.sessionManager; - TaskServiceImpl taskServiceImpl = new TaskServiceImpl(this, session.getMapper(TaskMapper.class), - session.getMapper(ObjectReferenceMapper.class), session.getMapper(AttachmentMapper.class)); - return taskServiceImpl; - } - - @Override - public TaskMonitorService getTaskMonitorService() { - SqlSession session = this.sessionManager; - TaskMonitorServiceImpl taskMonitorServiceImpl = new TaskMonitorServiceImpl(this, - session.getMapper(TaskMonitorMapper.class)); - return taskMonitorServiceImpl; - } - - @Override - public WorkbasketService getWorkbasketService() { - SqlSession session = this.sessionManager; - WorkbasketServiceImpl workbasketServiceImpl = new WorkbasketServiceImpl(this, - session.getMapper(WorkbasketMapper.class), - session.getMapper(DistributionTargetMapper.class), - session.getMapper(WorkbasketAccessMapper.class)); - return workbasketServiceImpl; - } - - @Override - public ClassificationService getClassificationService() { - SqlSession session = this.sessionManager; - return new ClassificationServiceImpl(this, session.getMapper(ClassificationMapper.class)); - } - - @Override - public TaskanaEngineConfiguration getConfiguration() { - return this.taskanaEngineConfiguration; - } - - /** - * sets the connection management mode. - * - * @param mode - * - the connection management mode Valid values are: - *
    - *
  • PARTICIPATE - taskana participates in global transaction. This is the default mode.
  • - *
  • AUTOCOMMIT - taskana commits each API call separately
  • - *
  • EXPLICIT - commit processing is managed explicitly by the client
  • - *
- */ - @Override - public void setConnectionManagementMode(ConnectionManagementMode mode) { - if (this.mode == ConnectionManagementMode.EXPLICIT && connection != null - && mode != ConnectionManagementMode.EXPLICIT) { - if (sessionManager.isManagedSessionStarted()) { - sessionManager.close(); - } - connection = null; - } - this.mode = mode; - } - - /** - * Set the database connection to be used by taskana. If this Api is called, taskana uses the connection passed by - * the client for database access in all subsequent API calls until the client resets this connection. Control over - * commit and rollback is the responsibility of the client. In order to close the connection, the client can call - * TaskanaEngine.closeConnection() or TaskanaEngine.setConnection(null). Both calls have the same effect. - * - * @param connection - * TODO - */ - @Override - public void setConnection(java.sql.Connection connection) { - if (connection != null) { - this.connection = connection; - mode = ConnectionManagementMode.EXPLICIT; - sessionManager.startManagedSession(connection); - } else if (this.connection != null) { - this.connection = null; - if (sessionManager.isManagedSessionStarted()) { - sessionManager.close(); - } - mode = ConnectionManagementMode.PARTICIPATE; - } - } - - /** - * closes the connection to the database in mode EXPLICIT. In mode EXPLICIT, closes the client's connection, sets it - * to null and switches to mode PARTICIPATE Has the same effect as setConnection(null) - */ - @Override - public void closeConnection() { - if (this.mode == ConnectionManagementMode.EXPLICIT) { - this.connection = null; - if (sessionManager.isManagedSessionStarted()) { - sessionManager.close(); - } - mode = ConnectionManagementMode.PARTICIPATE; - } - } - - /** - * Open the connection to the database. to be called at the begin of each Api call that accesses the database - */ - void openConnection() { - initSqlSession(); - if (mode != ConnectionManagementMode.EXPLICIT) { - pushSessionToStack(this.sessionManager); - } - } - - /** - * Initializes the SqlSessionManager. - */ - void initSqlSession() { - if (mode == ConnectionManagementMode.EXPLICIT && this.connection == null) { - throw new ConnectionNotSetException(); - } else if (mode != ConnectionManagementMode.EXPLICIT) { - if (!this.sessionManager.isManagedSessionStarted()) { - this.sessionManager.startManagedSession(); - } - } - } - - /** - * Returns the database connection into the pool. In the case of nested calls, simply pops the latest session from - * the session stack. Closes the connection if the session stack is empty. In mode AUTOCOMMIT commits before the - * connection is closed. To be called at the end of each Api call that accesses the database - */ - void returnConnection() { - if (this.mode != ConnectionManagementMode.EXPLICIT) { - popSessionFromStack(); - if (getSessionStack().isEmpty() - && this.sessionManager != null && this.sessionManager.isManagedSessionStarted()) { - if (this.mode == ConnectionManagementMode.AUTOCOMMIT) { - try { - this.sessionManager.commit(); - } catch (Exception e) { - LOGGER.error("closeSession(): Tried to Autocommit and caught exception" + e); - throw new AutocommitFailedException(e); - } - } - this.sessionManager.close(); - } - } - } - - /** - * retrieve the SqlSession used by taskana. - * - * @return the myBatis SqlSession object used by taskana - */ - SqlSession getSqlSession() { - return this.sessionManager; - } - - /** - * This method creates the sqlSessionManager of myBatis. It integrates all the SQL mappers - * - * @return a {@link SqlSessionFactory} - */ - private SqlSessionManager createSqlSessionManager() { - Environment environment = new Environment(DEFAULT, this.transactionFactory, - taskanaEngineConfiguration.getDatasource()); - Configuration configuration = new Configuration(environment); - // add mappers - configuration.addMapper(TaskMapper.class); - configuration.addMapper(TaskMonitorMapper.class); - configuration.addMapper(WorkbasketMapper.class); - configuration.addMapper(DistributionTargetMapper.class); - configuration.addMapper(ClassificationMapper.class); - configuration.addMapper(WorkbasketAccessMapper.class); - configuration.addMapper(ObjectReferenceMapper.class); - configuration.addMapper(QueryMapper.class); - configuration.addMapper(AttachmentMapper.class); - configuration.getTypeHandlerRegistry().register(MapTypeHandler.class); - SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(configuration); - SqlSessionManager sessionManager = SqlSessionManager.newInstance(sessionFactory); - return sessionManager; - } - - /** - * creates the MyBatis transaction factory. - * - * @param useManagedTransactions - */ - private void createTransactionFactory(boolean useManagedTransactions) { - if (useManagedTransactions) { - this.transactionFactory = new ManagedTransactionFactory(); - } else { - this.transactionFactory = new JdbcTransactionFactory(); - } - } - - /** - * With sessionStack, we maintain a Stack of SqlSessionManager objects on a per thread basis. SqlSessionManager is - * the MyBatis object that wraps database connections. The purpose of this stack is to keep track of nested calls. - * Each external API call is wrapped into taskanaEngineImpl.openConnection(); ..... - * taskanaEngineImpl.returnConnection(); calls. In order to avoid duplicate opening / closing of connections, we use - * the sessionStack in the following way: Each time, an openConnection call is received, we push the current - * sessionManager onto the stack. On the first call to openConnection, we call sessionManager.startManagedSession() - * to open a database connection. On each call to returnConnection() we pop one instance of sessionManager from the - * stack. When the stack becomes empty, we close the database connection by calling sessionManager.close() - * - * @return Stack of SqlSessionManager - */ - protected static Stack getSessionStack() { - Stack stack = sessionStack.get(); - if (stack == null) { - stack = new Stack(); - sessionStack.set(stack); - } - return stack; - } - - protected static SqlSessionManager getSessionFromStack() { - Stack stack = getSessionStack(); - if (stack.isEmpty()) { - return null; - } - return stack.peek(); - } - - protected static void pushSessionToStack(SqlSessionManager session) { - getSessionStack().push(session); - } - - protected static void popSessionFromStack() { - Stack stack = getSessionStack(); - if (!stack.isEmpty()) { - stack.pop(); - } - } -} +package pro.taskana.impl; + +import java.sql.SQLException; +import java.util.Stack; + +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.session.SqlSessionManager; +import org.apache.ibatis.transaction.TransactionFactory; +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.ClassificationService; +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskService; +import pro.taskana.TaskanaEngine; +import pro.taskana.WorkbasketService; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.exceptions.AutocommitFailedException; +import pro.taskana.exceptions.ConnectionNotSetException; +import pro.taskana.exceptions.UnsupportedDatabaseException; +import pro.taskana.impl.persistence.MapTypeHandler; +import pro.taskana.model.mappings.AttachmentMapper; +import pro.taskana.model.mappings.ClassificationMapper; +import pro.taskana.model.mappings.DistributionTargetMapper; +import pro.taskana.model.mappings.ObjectReferenceMapper; +import pro.taskana.model.mappings.QueryMapper; +import pro.taskana.model.mappings.TaskMapper; +import pro.taskana.model.mappings.TaskMonitorMapper; +import pro.taskana.model.mappings.WorkbasketAccessMapper; +import pro.taskana.model.mappings.WorkbasketMapper; + +/** + * This is the implementation of TaskanaEngine. + */ +public class TaskanaEngineImpl implements TaskanaEngine { + + private static final String DEFAULT = "default"; + private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineImpl.class); + protected static ThreadLocal> sessionStack = new ThreadLocal>(); + protected TaskanaEngineConfiguration taskanaEngineConfiguration; + protected TransactionFactory transactionFactory; + protected SqlSessionManager sessionManager; + protected SqlSessionFactory sessionFactory; + protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE; + protected java.sql.Connection connection = null; + + public TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration) { + this.taskanaEngineConfiguration = taskanaEngineConfiguration; + createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions()); + this.sessionManager = createSqlSessionManager(); + } + + @Override + public TaskService getTaskService() { + SqlSession session = this.sessionManager; + TaskServiceImpl taskServiceImpl = new TaskServiceImpl(this, session.getMapper(TaskMapper.class), + session.getMapper(ObjectReferenceMapper.class), session.getMapper(AttachmentMapper.class)); + return taskServiceImpl; + } + + @Override + public TaskMonitorService getTaskMonitorService() { + SqlSession session = this.sessionManager; + TaskMonitorServiceImpl taskMonitorServiceImpl = new TaskMonitorServiceImpl(this, + session.getMapper(TaskMonitorMapper.class)); + return taskMonitorServiceImpl; + } + + @Override + public WorkbasketService getWorkbasketService() { + SqlSession session = this.sessionManager; + WorkbasketServiceImpl workbasketServiceImpl = new WorkbasketServiceImpl(this, + session.getMapper(WorkbasketMapper.class), + session.getMapper(DistributionTargetMapper.class), + session.getMapper(WorkbasketAccessMapper.class)); + return workbasketServiceImpl; + } + + @Override + public ClassificationService getClassificationService() { + SqlSession session = this.sessionManager; + return new ClassificationServiceImpl(this, session.getMapper(ClassificationMapper.class)); + } + + @Override + public TaskanaEngineConfiguration getConfiguration() { + return this.taskanaEngineConfiguration; + } + + /** + * sets the connection management mode. + * + * @param mode + * - the connection management mode Valid values are: + *
    + *
  • PARTICIPATE - taskana participates in global transaction. This is the default mode.
  • + *
  • AUTOCOMMIT - taskana commits each API call separately
  • + *
  • EXPLICIT - commit processing is managed explicitly by the client
  • + *
+ */ + @Override + public void setConnectionManagementMode(ConnectionManagementMode mode) { + if (this.mode == ConnectionManagementMode.EXPLICIT && connection != null + && mode != ConnectionManagementMode.EXPLICIT) { + if (sessionManager.isManagedSessionStarted()) { + sessionManager.close(); + } + connection = null; + } + this.mode = mode; + } + + /** + * Set the database connection to be used by taskana. If this Api is called, taskana uses the connection passed by + * the client for database access in all subsequent API calls until the client resets this connection. Control over + * commit and rollback is the responsibility of the client. In order to close the connection, the client can call + * TaskanaEngine.closeConnection() or TaskanaEngine.setConnection(null). Both calls have the same effect. + * + * @param connection + * TODO + */ + @Override + public void setConnection(java.sql.Connection connection) { + if (connection != null) { + this.connection = connection; + mode = ConnectionManagementMode.EXPLICIT; + sessionManager.startManagedSession(connection); + } else if (this.connection != null) { + this.connection = null; + if (sessionManager.isManagedSessionStarted()) { + sessionManager.close(); + } + mode = ConnectionManagementMode.PARTICIPATE; + } + } + + /** + * closes the connection to the database in mode EXPLICIT. In mode EXPLICIT, closes the client's connection, sets it + * to null and switches to mode PARTICIPATE Has the same effect as setConnection(null) + */ + @Override + public void closeConnection() { + if (this.mode == ConnectionManagementMode.EXPLICIT) { + this.connection = null; + if (sessionManager.isManagedSessionStarted()) { + sessionManager.close(); + } + mode = ConnectionManagementMode.PARTICIPATE; + } + } + + /** + * Open the connection to the database. to be called at the begin of each Api call that accesses the database + */ + void openConnection() { + initSqlSession(); + if (mode != ConnectionManagementMode.EXPLICIT) { + pushSessionToStack(this.sessionManager); + } + } + + /** + * Initializes the SqlSessionManager. + */ + void initSqlSession() { + if (mode == ConnectionManagementMode.EXPLICIT && this.connection == null) { + throw new ConnectionNotSetException(); + } else if (mode != ConnectionManagementMode.EXPLICIT) { + if (!this.sessionManager.isManagedSessionStarted()) { + this.sessionManager.startManagedSession(); + } + } + } + + /** + * Returns the database connection into the pool. In the case of nested calls, simply pops the latest session from + * the session stack. Closes the connection if the session stack is empty. In mode AUTOCOMMIT commits before the + * connection is closed. To be called at the end of each Api call that accesses the database + */ + void returnConnection() { + if (this.mode != ConnectionManagementMode.EXPLICIT) { + popSessionFromStack(); + if (getSessionStack().isEmpty() + && this.sessionManager != null && this.sessionManager.isManagedSessionStarted()) { + if (this.mode == ConnectionManagementMode.AUTOCOMMIT) { + try { + this.sessionManager.commit(); + } catch (Exception e) { + LOGGER.error("closeSession(): Tried to Autocommit and caught exception" + e); + throw new AutocommitFailedException(e); + } + } + this.sessionManager.close(); + } + } + } + + /** + * retrieve the SqlSession used by taskana. + * + * @return the myBatis SqlSession object used by taskana + */ + SqlSession getSqlSession() { + return this.sessionManager; + } + + /** + * This method creates the sqlSessionManager of myBatis. It integrates all the SQL mappers and sets the databaseId + * attribute. + * + * @return a {@link SqlSessionFactory} + */ + private SqlSessionManager createSqlSessionManager() { + Environment environment = new Environment(DEFAULT, this.transactionFactory, + taskanaEngineConfiguration.getDatasource()); + Configuration configuration = new Configuration(environment); + + // set databaseId + String databaseProductName; + try { + databaseProductName = taskanaEngineConfiguration.getDatasource() + .getConnection() + .getMetaData() + .getDatabaseProductName(); + if (databaseProductName.contains("DB2")) { + configuration.setDatabaseId("db2"); + } else if (databaseProductName.contains("H2")) { + configuration.setDatabaseId("h2"); + } else { + LOGGER.error( + "Method createSqlSessionManager() didn't find database with name {}. Throwing UnsupportedDatabaseException", + databaseProductName); + throw new UnsupportedDatabaseException(databaseProductName); + } + + } catch (SQLException e) { + LOGGER.error( + "Method createSqlSessionManager() could not open a connection to the database. No databaseId has been set.", + e); + throw new RuntimeException(e); + } + + // add mappers + configuration.addMapper(TaskMapper.class); + configuration.addMapper(TaskMonitorMapper.class); + configuration.addMapper(WorkbasketMapper.class); + configuration.addMapper(DistributionTargetMapper.class); + configuration.addMapper(ClassificationMapper.class); + configuration.addMapper(WorkbasketAccessMapper.class); + configuration.addMapper(ObjectReferenceMapper.class); + configuration.addMapper(QueryMapper.class); + configuration.addMapper(AttachmentMapper.class); + configuration.getTypeHandlerRegistry().register(MapTypeHandler.class); + SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(configuration); + SqlSessionManager sessionManager = SqlSessionManager.newInstance(sessionFactory); + return sessionManager; + } + + /** + * creates the MyBatis transaction factory. + * + * @param useManagedTransactions + */ + private void createTransactionFactory(boolean useManagedTransactions) { + if (useManagedTransactions) { + this.transactionFactory = new ManagedTransactionFactory(); + } else { + this.transactionFactory = new JdbcTransactionFactory(); + } + } + + /** + * With sessionStack, we maintain a Stack of SqlSessionManager objects on a per thread basis. SqlSessionManager is + * the MyBatis object that wraps database connections. The purpose of this stack is to keep track of nested calls. + * Each external API call is wrapped into taskanaEngineImpl.openConnection(); ..... + * taskanaEngineImpl.returnConnection(); calls. In order to avoid duplicate opening / closing of connections, we use + * the sessionStack in the following way: Each time, an openConnection call is received, we push the current + * sessionManager onto the stack. On the first call to openConnection, we call sessionManager.startManagedSession() + * to open a database connection. On each call to returnConnection() we pop one instance of sessionManager from the + * stack. When the stack becomes empty, we close the database connection by calling sessionManager.close() + * + * @return Stack of SqlSessionManager + */ + protected static Stack getSessionStack() { + Stack stack = sessionStack.get(); + if (stack == null) { + stack = new Stack(); + sessionStack.set(stack); + } + return stack; + } + + protected static SqlSessionManager getSessionFromStack() { + Stack stack = getSessionStack(); + if (stack.isEmpty()) { + return null; + } + return stack.peek(); + } + + protected static void pushSessionToStack(SqlSessionManager session) { + getSessionStack().push(session); + } + + protected static void popSessionFromStack() { + Stack stack = getSessionStack(); + if (!stack.isEmpty()) { + stack.pop(); + } + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/MonitorQueryItem.java b/lib/taskana-core/src/main/java/pro/taskana/model/MonitorQueryItem.java new file mode 100644 index 000000000..b2d47b7b6 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/model/MonitorQueryItem.java @@ -0,0 +1,36 @@ +package pro.taskana.model; + +/** + * The MonitorQueryItem entity contains the number of tasks for a key (e.g. workbasketKey) and age in days. + */ +public class MonitorQueryItem { + + private String key; + private int ageInDays; + private int numberOfTasks; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public int getAgeInDays() { + return ageInDays; + } + + public void setAgeInDays(int ageInDays) { + this.ageInDays = ageInDays; + } + + public int getNumberOfTasks() { + return numberOfTasks; + } + + public void setNumberOfTasks(int numberOfTasks) { + this.numberOfTasks = numberOfTasks; + } + +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/Report.java b/lib/taskana-core/src/main/java/pro/taskana/model/Report.java index 57deafe85..0093d1c80 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/Report.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/Report.java @@ -1,26 +1,30 @@ package pro.taskana.model; -import java.util.ArrayList; -import java.util.List; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; /** - * A Report represents a table that consists of {@link ReportLine} objects. + * A Report represents a table that consists of {@link ReportLine} objects. The detailLines are the rows of the table + * that contains the total number of all tasks and could be optionally subdivided into different sections. The sumLine + * contains the sums of all tasks and if the detailLines are subdivided into different sections the sumLine also + * contains the number of tasks of the respective section. */ public class Report { - private List detailLines; + private Map detailLines; private ReportLine sumLine; public Report() { - this.detailLines = new ArrayList<>(); + this.detailLines = new LinkedHashMap<>(); this.sumLine = new ReportLine(); } - public List getDetailLines() { + public Map getDetailLines() { return detailLines; } - public void setDetailLines(List detailLines) { + public void setDetailLines(Map detailLines) { this.detailLines = detailLines; } @@ -31,4 +35,20 @@ public class Report { public void setSumLine(ReportLine sumLine) { this.sumLine = sumLine; } + + public void generateSumLine() { + int totalNumberOfTasks = 0; + for (ReportLine reportLine : this.getDetailLines().values()) { + Iterator reportLineItemIterator = reportLine.getLineItems().iterator(); + Iterator sumLineItemIterator = this.sumLine.getLineItems().iterator(); + while (reportLineItemIterator.hasNext() && sumLineItemIterator.hasNext()) { + int numberOfTasks = reportLineItemIterator.next().getNumberOfTasks(); + sumLineItemIterator.next().addNumberOfTasks(numberOfTasks); + } + totalNumberOfTasks += reportLine.getTotalNumberOfTasks(); + } + this.sumLine.setTotalNumberOfTasks(totalNumberOfTasks); + + } + } diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/ReportLine.java b/lib/taskana-core/src/main/java/pro/taskana/model/ReportLine.java index 0477dcbbe..cc88cd340 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/ReportLine.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/ReportLine.java @@ -1,43 +1,47 @@ -package pro.taskana.model; - -import java.util.ArrayList; -import java.util.List; - -/** - * Each ReportLine consists of a name, a list of {@link ReportLineItem} objects and a totalCount that represents the - * count of all tasks. - */ -public class ReportLine { - - private String name; - private List lineItems; - private int totalCount; - - public ReportLine() { - this.lineItems = new ArrayList<>(); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public List getLineItems() { - return lineItems; - } - - public void setLineItems(List lineItems) { - this.lineItems = lineItems; - } - - public int getTotalCount() { - return totalCount; - } - - public void setTotalCount(int totalCount) { - this.totalCount = totalCount; - } -} +package pro.taskana.model; + +import java.util.ArrayList; +import java.util.List; + +/** + * Each ReportLine consists of a list of {@link ReportLineItem} objects and the number of all tasks of this ReportLine. + */ +public class ReportLine { + + private List lineItems; + private int totalNumberOfTasks; + + public ReportLine() { + this.lineItems = new ArrayList<>(); + this.totalNumberOfTasks = 0; + } + + public List getLineItems() { + return lineItems; + } + + public void setLineItems(List lineItems) { + this.lineItems = lineItems; + } + + public int getTotalNumberOfTasks() { + return totalNumberOfTasks; + } + + public void setTotalNumberOfTasks(int totalNumberOfTasks) { + this.totalNumberOfTasks = totalNumberOfTasks; + } + + public void addNumberOfTasks(MonitorQueryItem item) { + this.totalNumberOfTasks += item.getNumberOfTasks(); + for (ReportLineItem reportLineItem : lineItems) { + int lowerAgeLimit = reportLineItem.getReportLineItemDefinition().getLowerAgeLimit(); + int upperAgeLimit = reportLineItem.getReportLineItemDefinition().getUpperAgeLimit(); + if (lowerAgeLimit <= item.getAgeInDays() && upperAgeLimit >= item.getAgeInDays()) { + reportLineItem.addNumberOfTasks(item.getNumberOfTasks()); + break; + } + } + + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItem.java b/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItem.java index f5a30f918..daa3c4b08 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItem.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItem.java @@ -1,13 +1,17 @@ package pro.taskana.model; /** - * Each ReportLineItem consists of a {@link ReportLineItemDefinition} that defines the upper and lower limits of this - * item and a count value that represents the count of tasks of this item. + * Each ReportLineItem consists of a {@link ReportLineItemDefinition} that defines the upper and lower age limits of + * this item and a number of tasks of this item. */ public class ReportLineItem { private ReportLineItemDefinition reportLineItemDefinition; - private int count; + private int numberOfTasks; + + public ReportLineItem() { + this.numberOfTasks = 0; + } public ReportLineItemDefinition getReportLineItemDefinition() { return reportLineItemDefinition; @@ -17,11 +21,15 @@ public class ReportLineItem { this.reportLineItemDefinition = reportLineItemDefinition; } - public int getCount() { - return count; + public int getNumberOfTasks() { + return numberOfTasks; } - public void setCount(int count) { - this.count = count; + public void setNumberOfTasks(int numberOfTasks) { + this.numberOfTasks = numberOfTasks; } + public void addNumberOfTasks(int numberOfTasks) { + this.numberOfTasks += numberOfTasks; + } + } diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItemDefinition.java b/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItemDefinition.java index e74c1e349..bb9fc6bda 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItemDefinition.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/ReportLineItemDefinition.java @@ -1,27 +1,43 @@ package pro.taskana.model; /** - * A ReportLineItemDefinition has a lower and an upper limit which subdivide the count of tasks in a workbasket into - * different sections. + * A ReportLineItemDefinition has a lower and an upper age limit which subdivide the count of tasks into different + * sections. Days in past are represented as negative values and days in the future are represented as positive values. + * To avoid tasks are counted multiple times or not be listed in the report, these reportLineItemDefinitions should not + * overlap and should not have gaps. If the ReportLineDefinition should represent a single day, lowerAgeLimit and + * upperAgeLimit have to be equal. */ public class ReportLineItemDefinition { - private int lowerLimit; - private int upperLimit; + private int lowerAgeLimit; + private int upperAgeLimit; - public int getLowerLimit() { - return lowerLimit; + public ReportLineItemDefinition() { } - public void setLowerLimit(int lowerLimit) { - this.lowerLimit = lowerLimit; + public ReportLineItemDefinition(int ageInDays) { + this.lowerAgeLimit = ageInDays; + this.upperAgeLimit = ageInDays; } - public int getUpperLimit() { - return upperLimit; + public ReportLineItemDefinition(int lowerAgeLimit, int upperAgeLimit) { + this.lowerAgeLimit = lowerAgeLimit; + this.upperAgeLimit = upperAgeLimit; } - public void setUpperLimit(int upperLimit) { - this.upperLimit = upperLimit; + public int getLowerAgeLimit() { + return lowerAgeLimit; + } + + public void setLowerAgeLimit(int lowerAgeLimit) { + this.lowerAgeLimit = lowerAgeLimit; + } + + public int getUpperAgeLimit() { + return upperAgeLimit; + } + + public void setUpperAgeLimit(int upperAgeLimit) { + this.upperAgeLimit = upperAgeLimit; } } diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/TaskMonitorMapper.java b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/TaskMonitorMapper.java index 603b4e4f1..8d1b83e4c 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/TaskMonitorMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/TaskMonitorMapper.java @@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Select; import pro.taskana.Workbasket; import pro.taskana.model.DueWorkbasketCounter; -import pro.taskana.model.ReportLine; +import pro.taskana.model.MonitorQueryItem; import pro.taskana.model.TaskState; import pro.taskana.model.TaskStateCounter; @@ -52,14 +52,21 @@ public interface TaskMonitorMapper { @Param("status") List states); @Select("") - @Results({ @Result(column = "WORKBASKET_KEY", property = "name"), - @Result(column = "counter", property = "totalCount") }) - List getDetailLinesByWorkbasketIdsAndStates(@Param("workbaskets") List workbaskets, - @Param("status") List states); + @Results({ + @Result(column = "WORKBASKET_KEY", property = "key"), + @Result(column = "AGE_IN_DAYS", property = "ageInDays"), + @Result(column = "NUMBER_OF_TASKS", property = "numberOfTasks") }) + List findByWorkbasketIdsAndStates( + @Param("workbaskets") List workbaskets, + @Param("states") List states); + } diff --git a/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java b/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java index 4ad74b863..dcf6ce4a2 100644 --- a/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/AbstractAccTest.java @@ -1,93 +1,93 @@ -package acceptance; - -import java.sql.SQLException; -import java.time.Instant; -import java.time.LocalDate; -import java.time.ZoneOffset; -import java.util.HashMap; -import java.util.Map; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; - -import pro.taskana.Attachment; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.database.TestDataGenerator; -import pro.taskana.exceptions.ClassificationNotFoundException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.model.ObjectReference; - -/** - * Base class for all acceptance tests. - */ -public abstract class AbstractAccTest { - - protected static TaskanaEngineConfiguration taskanaEngineConfiguration; - protected static TaskanaEngine taskanaEngine; - - @BeforeClass - public static void setupTest() throws Exception { - resetDb(); - } - - public static void resetDb() throws SQLException { - DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, true); - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - cleaner.clearDb(dataSource, false); - TestDataGenerator testDataGenerator = new TestDataGenerator(); - testDataGenerator.generateTestData(dataSource); - } - - protected ObjectReference createObjectReference(String company, String system, String systemInstance, String type, - String value) { - ObjectReference objectReference = new ObjectReference(); - objectReference.setCompany(company); - objectReference.setSystem(system); - objectReference.setSystemInstance(systemInstance); - objectReference.setType(type); - objectReference.setValue(value); - return objectReference; - } - - protected Map createSimpleCustomProperties(int propertiesCount) { - HashMap properties = new HashMap<>(); - for (int i = 1; i <= propertiesCount; i++) { - properties.put("Property_" + i, "Property Value of Property_" + i); - } - return properties; - } - - protected Attachment createAttachment(String classificationKey, ObjectReference objRef, - String channel, String receivedDate, Map customAttributes) - throws ClassificationNotFoundException, NotAuthorizedException { - Attachment attachment = taskanaEngine.getTaskService().newAttachment(); - - attachment.setClassificationSummary( - taskanaEngine.getClassificationService().getClassification(classificationKey, "DOMAIN_A").asSummary()); - attachment.setObjectReference(objRef); - attachment.setChannel(channel); - Instant receivedTimestamp = null; - if (receivedDate != null && receivedDate.length() < 11) { - // contains only the date, not the time - LocalDate date = LocalDate.parse(receivedDate); - receivedTimestamp = date.atStartOfDay().toInstant(ZoneOffset.UTC); - } else { - receivedTimestamp = Instant.parse(receivedDate); - } - attachment.setReceived(receivedTimestamp); - attachment.setCustomAttributes(customAttributes); - - return attachment; - } -} +package acceptance; + +import java.sql.SQLException; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import org.junit.BeforeClass; + +import pro.taskana.Attachment; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.ClassificationNotFoundException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.model.ObjectReference; + +/** + * Base class for all acceptance tests. + */ +public abstract class AbstractAccTest { + + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateTestData(dataSource); + } + + protected ObjectReference createObjectReference(String company, String system, String systemInstance, String type, + String value) { + ObjectReference objectReference = new ObjectReference(); + objectReference.setCompany(company); + objectReference.setSystem(system); + objectReference.setSystemInstance(systemInstance); + objectReference.setType(type); + objectReference.setValue(value); + return objectReference; + } + + protected Map createSimpleCustomProperties(int propertiesCount) { + HashMap properties = new HashMap<>(); + for (int i = 1; i <= propertiesCount; i++) { + properties.put("Property_" + i, "Property Value of Property_" + i); + } + return properties; + } + + protected Attachment createAttachment(String classificationKey, ObjectReference objRef, + String channel, String receivedDate, Map customAttributes) + throws ClassificationNotFoundException, NotAuthorizedException { + Attachment attachment = taskanaEngine.getTaskService().newAttachment(); + + attachment.setClassificationSummary( + taskanaEngine.getClassificationService().getClassification(classificationKey, "DOMAIN_A").asSummary()); + attachment.setObjectReference(objRef); + attachment.setChannel(channel); + Instant receivedTimestamp = null; + if (receivedDate != null && receivedDate.length() < 11) { + // contains only the date, not the time + LocalDate date = LocalDate.parse(receivedDate); + receivedTimestamp = date.atStartOfDay().toInstant(ZoneOffset.UTC); + } else { + receivedTimestamp = Instant.parse(receivedDate); + } + attachment.setReceived(receivedTimestamp); + attachment.setCustomAttributes(customAttributes); + + return attachment; + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/task/ProvideWorkbasketLevelReportAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/ProvideWorkbasketLevelReportAccTest.java new file mode 100644 index 000000000..0c8ad3e1a --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/task/ProvideWorkbasketLevelReportAccTest.java @@ -0,0 +1,175 @@ +package acceptance.task; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.sql.DataSource; + +import org.h2.store.fs.FileUtils; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import pro.taskana.TaskMonitorService; +import pro.taskana.TaskanaEngine; +import pro.taskana.TaskanaEngine.ConnectionManagementMode; +import pro.taskana.Workbasket; +import pro.taskana.WorkbasketService; +import pro.taskana.configuration.TaskanaEngineConfiguration; +import pro.taskana.database.TestDataGenerator; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.WorkbasketNotFoundException; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.WorkbasketImpl; +import pro.taskana.impl.configuration.DBCleaner; +import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; +import pro.taskana.model.Report; +import pro.taskana.model.ReportLineItemDefinition; +import pro.taskana.model.TaskState; +import pro.taskana.security.JAASRunner; +import pro.taskana.security.WithAccessId; + +/** + * Acceptance test for all "workbasket level report" scenarios. + */ +@RunWith(JAASRunner.class) +public class ProvideWorkbasketLevelReportAccTest { + + protected static TaskanaEngineConfiguration taskanaEngineConfiguration; + protected static TaskanaEngine taskanaEngine; + + @BeforeClass + public static void setupTest() throws Exception { + resetDb(); + } + + public static void resetDb() throws SQLException, IOException { + DataSource dataSource = TaskanaEngineConfigurationTest.getDataSource(); + DBCleaner cleaner = new DBCleaner(); + cleaner.clearDb(dataSource, true); + dataSource = TaskanaEngineConfigurationTest.getDataSource(); + taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); + taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); + ((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); + cleaner.clearDb(dataSource, false); + TestDataGenerator testDataGenerator = new TestDataGenerator(); + testDataGenerator.generateMonitoringTestData(dataSource); + } + + @WithAccessId(userName = "monitor_user_1") + @Test + public void testGetTotalNumbersOfTasksOfWorkbasketLevelReport() + throws WorkbasketNotFoundException, NotAuthorizedException { + + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbaskets = getListOfWorkbaskets(); + List states = Arrays.asList(TaskState.READY, TaskState.CLAIMED); + Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states); + + Assert.assertNotNull(report); + Assert.assertEquals(20, report.getDetailLines().get(workbaskets.get(0).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(20, report.getDetailLines().get(workbaskets.get(1).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(10, report.getDetailLines().get(workbaskets.get(2).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(0, report.getDetailLines().get(workbaskets.get(3).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(50, report.getSumLine().getTotalNumberOfTasks()); + + } + + @WithAccessId(userName = "monitor_user_1") + @Test + public void testGetWorkbasketLevelReportWithReportLineItemDefinitions() + throws WorkbasketNotFoundException, NotAuthorizedException { + + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + + List workbaskets = getListOfWorkbaskets(); + List states = Arrays.asList(TaskState.READY, TaskState.CLAIMED); + List reportLineItemDefinitions = getListOfReportLineItemDefinitions(); + + Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states, reportLineItemDefinitions); + + int sumLineCount = report.getSumLine().getLineItems().get(0).getNumberOfTasks() + + report.getSumLine().getLineItems().get(1).getNumberOfTasks() + + report.getSumLine().getLineItems().get(2).getNumberOfTasks() + + report.getSumLine().getLineItems().get(3).getNumberOfTasks() + + report.getSumLine().getLineItems().get(4).getNumberOfTasks() + + report.getSumLine().getLineItems().get(5).getNumberOfTasks() + + report.getSumLine().getLineItems().get(6).getNumberOfTasks(); + + Assert.assertNotNull(report); + + Assert.assertEquals(20, report.getDetailLines().get(workbaskets.get(0).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(20, report.getDetailLines().get(workbaskets.get(1).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(10, report.getDetailLines().get(workbaskets.get(2).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(0, report.getDetailLines().get(workbaskets.get(3).getKey()).getTotalNumberOfTasks()); + + Assert.assertEquals(22, report.getSumLine().getLineItems().get(0).getNumberOfTasks()); + Assert.assertEquals(5, report.getSumLine().getLineItems().get(1).getNumberOfTasks()); + Assert.assertEquals(3, report.getSumLine().getLineItems().get(2).getNumberOfTasks()); + Assert.assertEquals(4, report.getSumLine().getLineItems().get(3).getNumberOfTasks()); + Assert.assertEquals(1, report.getSumLine().getLineItems().get(4).getNumberOfTasks()); + Assert.assertEquals(4, report.getSumLine().getLineItems().get(5).getNumberOfTasks()); + Assert.assertEquals(11, report.getSumLine().getLineItems().get(6).getNumberOfTasks()); + + Assert.assertEquals(50, report.getSumLine().getTotalNumberOfTasks()); + Assert.assertEquals(50, sumLineCount); + + } + + @WithAccessId(userName = "monitor_user_1") + @Test + public void testGetWorkbasketLevelReportIfWorkbasketContainsNoTask() + throws WorkbasketNotFoundException, NotAuthorizedException { + TaskMonitorService taskMonitorService = taskanaEngine.getTaskMonitorService(); + WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); + + List workbaskets = new ArrayList<>(); + WorkbasketImpl workbasket = (WorkbasketImpl) workbasketService + .getWorkbasket("WBI:000000000000000000000000000000000004"); + workbaskets.add(workbasket); + List states = Arrays.asList(TaskState.READY, TaskState.CLAIMED); + Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states); + + Assert.assertNotNull(report); + Assert.assertEquals(0, report.getDetailLines().get(workbaskets.get(0).getKey()).getTotalNumberOfTasks()); + Assert.assertEquals(0, report.getSumLine().getTotalNumberOfTasks()); + } + + private List getListOfWorkbaskets() throws WorkbasketNotFoundException, NotAuthorizedException { + WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); + + WorkbasketImpl workbasket1 = (WorkbasketImpl) workbasketService + .getWorkbasket("WBI:000000000000000000000000000000000001"); + WorkbasketImpl workbasket2 = (WorkbasketImpl) workbasketService + .getWorkbasket("WBI:000000000000000000000000000000000002"); + WorkbasketImpl workbasket3 = (WorkbasketImpl) workbasketService + .getWorkbasket("WBI:000000000000000000000000000000000003"); + WorkbasketImpl workbasket4 = (WorkbasketImpl) workbasketService + .getWorkbasket("WBI:000000000000000000000000000000000004"); + + return Arrays.asList(workbasket1, workbasket2, workbasket3, workbasket4); + } + + private List getListOfReportLineItemDefinitions() { + List reportLineItemDefinitions = new ArrayList<>(); + reportLineItemDefinitions.add(new ReportLineItemDefinition(Integer.MIN_VALUE, -6)); + reportLineItemDefinitions.add(new ReportLineItemDefinition(-5, -2)); + reportLineItemDefinitions.add(new ReportLineItemDefinition(-1)); + reportLineItemDefinitions.add(new ReportLineItemDefinition(0)); + reportLineItemDefinitions.add(new ReportLineItemDefinition(1)); + reportLineItemDefinitions.add(new ReportLineItemDefinition(2, 5)); + reportLineItemDefinitions.add(new ReportLineItemDefinition(6, Integer.MAX_VALUE)); + return reportLineItemDefinitions; + } + + @AfterClass + public static void cleanUpClass() { + FileUtils.deleteRecursive("~/data", true); + } +} diff --git a/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java b/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java index fc6181f24..fa482370f 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java +++ b/lib/taskana-core/src/test/java/pro/taskana/database/TestDataGenerator.java @@ -1,69 +1,123 @@ -package pro.taskana.database; - -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.sql.Connection; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.apache.ibatis.jdbc.ScriptRunner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.configuration.DbSchemaCreator; - -/** - * Generates the test data for integration and acceptance tests. - */ -public class TestDataGenerator { - - private static final Logger LOGGER = LoggerFactory.getLogger(DbSchemaCreator.class); - - 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) throws 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); - runner.runScript(new InputStreamReader(this.getClass().getResourceAsStream("/sql/task.sql"))); - runner.runScript(new InputStreamReader(this.getClass().getResourceAsStream("/sql/workbasket.sql"))); - runner.runScript( - new InputStreamReader(this.getClass().getResourceAsStream("/sql/distribution-targets.sql"))); - runner.runScript( - new InputStreamReader(this.getClass().getResourceAsStream("/sql/classification.sql"))); - runner.runScript( - new InputStreamReader(this.getClass().getResourceAsStream("/sql/workbasket-access-list.sql"))); - runner.runScript( - new InputStreamReader(this.getClass().getResourceAsStream("/sql/object-reference.sql"))); - } finally { - - runner.closeConnection(); - LOGGER.debug(outWriter.toString()); - if (!errorWriter.toString().trim().isEmpty()) { - LOGGER.error(errorWriter.toString()); - } - } - } -} +package pro.taskana.database; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +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.Arrays; +import java.util.List; + +import javax.sql.DataSource; + +import org.apache.ibatis.jdbc.ScriptRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.configuration.DbSchemaCreator; + +/** + * Generates the test data for integration and acceptance tests. + */ +public class TestDataGenerator { + + private static final Logger LOGGER = LoggerFactory.getLogger(DbSchemaCreator.class); + 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) throws 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); + runner.runScript(new InputStreamReader(this.getClass().getResourceAsStream("/sql/task.sql"))); + runner.runScript(new InputStreamReader(this.getClass().getResourceAsStream("/sql/workbasket.sql"))); + runner.runScript( + new InputStreamReader(this.getClass().getResourceAsStream("/sql/distribution-targets.sql"))); + runner.runScript( + new InputStreamReader(this.getClass().getResourceAsStream("/sql/classification.sql"))); + runner.runScript( + new InputStreamReader(this.getClass().getResourceAsStream("/sql/workbasket-access-list.sql"))); + runner.runScript( + new InputStreamReader(this.getClass().getResourceAsStream("/sql/object-reference.sql"))); + } finally { + + 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); + runner.runScript( + new InputStreamReader( + new ByteArrayInputStream( + generateMonitoringSqlData().getBytes(StandardCharsets.UTF_8.name())))); + } finally { + + runner.closeConnection(); + LOGGER.debug(outWriter.toString()); + if (!errorWriter.toString().trim().isEmpty()) { + LOGGER.error(errorWriter.toString()); + } + } + } + + private String generateMonitoringSqlData() throws IOException { + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(this.getClass().getResourceAsStream("/sql/monitor-sample-data.sql"))); + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + StringBuilder sql = new StringBuilder(); + String line; + + List ages = Arrays.asList(-1500, -1200, -1000, -1000, -1000, -500, -500, -300, -200, -100, -50, -20, + -15, -15, -14, -13, -12, -10, -8, -6, -6, -6, -5, -5, -5, -5, -2, -1, -1, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 100, 150, 150, 1000, 10000, 100000); + int i = 0; + while ((line = bufferedReader.readLine()) != null) { + if (line.contains("dueDate")) { + line = line.replace("dueDate", "\'" + now.plusDays(ages.get(i)).format(formatter) + "\' "); + i++; + } + sql.append(line).append("\n"); + } + bufferedReader.close(); + return sql.toString(); + } + +} diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java index e804c2148..9f14893c3 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/TaskMonitorServiceImplTest.java @@ -1,6 +1,7 @@ package pro.taskana.impl; import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; @@ -13,7 +14,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,8 +27,9 @@ import pro.taskana.Workbasket; import pro.taskana.WorkbasketService; import pro.taskana.configuration.TaskanaEngineConfiguration; import pro.taskana.model.DueWorkbasketCounter; +import pro.taskana.model.MonitorQueryItem; import pro.taskana.model.Report; -import pro.taskana.model.ReportLine; +import pro.taskana.model.ReportLineItemDefinition; import pro.taskana.model.TaskState; import pro.taskana.model.TaskStateCounter; import pro.taskana.model.mappings.ObjectReferenceMapper; @@ -125,23 +126,66 @@ public class TaskMonitorServiceImplTest { } @Test - public void testGetWorkbasketLevelReport() { - List workbaskets = Arrays.asList(new WorkbasketImpl(), new WorkbasketImpl()); + public void testGetTotalNumbersOfWorkbasketLevelReport() { + Workbasket workbasket = new WorkbasketImpl(); + workbasket.setName("workbasket"); + workbasket.setKey("wb1"); + List workbaskets = Arrays.asList(workbasket); List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); - Report expectedResult = new Report(); - List expectedDetailLines = new ArrayList<>(); - doReturn(expectedDetailLines).when(taskMonitorMapperMock).getDetailLinesByWorkbasketIdsAndStates(any(), any()); + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("wb1"); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).findByWorkbasketIdsAndStates(workbaskets, + states); Report actualResult = cut.getWorkbasketLevelReport(workbaskets, states); verify(taskanaEngineImpl, times(1)).openConnection(); - verify(taskMonitorMapperMock, times(1)).getDetailLinesByWorkbasketIdsAndStates(any(), any()); + verify(taskMonitorMapperMock, times(1)).findByWorkbasketIdsAndStates(any(), any()); verify(taskanaEngineImpl, times(1)).returnConnection(); verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl, taskMonitorMapperMock, objectReferenceMapperMock, workbasketServiceMock); - Assert.assertNotNull(actualResult); - assertThat(actualResult.getDetailLines(), equalTo(expectedResult.getDetailLines())); + + assertNotNull(actualResult); + assertThat(actualResult.getDetailLines().get(workbasket.getKey()).getTotalNumberOfTasks(), equalTo(1)); + assertThat(actualResult.getSumLine().getTotalNumberOfTasks(), equalTo(1)); + } + + @Test + public void testGetWorkbasketLevelReportWithReportLineItemDefinitions() { + Workbasket workbasket = new WorkbasketImpl(); + workbasket.setName("workbasket"); + workbasket.setKey("wb1"); + List workbaskets = Arrays.asList(workbasket); + List states = Arrays.asList(TaskState.CLAIMED, TaskState.READY); + List reportLineItemDefinitions = Arrays.asList(new ReportLineItemDefinition(), + new ReportLineItemDefinition()); + + List expectedResult = new ArrayList<>(); + MonitorQueryItem monitorQueryItem = new MonitorQueryItem(); + monitorQueryItem.setKey("wb1"); + monitorQueryItem.setAgeInDays(0); + monitorQueryItem.setNumberOfTasks(1); + expectedResult.add(monitorQueryItem); + doReturn(expectedResult).when(taskMonitorMapperMock).findByWorkbasketIdsAndStates(workbaskets, + states); + + Report actualResult = cut.getWorkbasketLevelReport(workbaskets, states, reportLineItemDefinitions); + + verify(taskanaEngineImpl, times(1)).openConnection(); + verify(taskMonitorMapperMock, times(1)).findByWorkbasketIdsAndStates(any(), any()); + verify(taskanaEngineImpl, times(1)).returnConnection(); + verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl, + taskMonitorMapperMock, objectReferenceMapperMock, workbasketServiceMock); + + assertNotNull(actualResult); + assertThat(actualResult.getDetailLines().get(workbasket.getKey()).getTotalNumberOfTasks(), equalTo(1)); + assertThat(actualResult.getDetailLines().get(workbasket.getKey()).getLineItems().get(0).getNumberOfTasks(), + equalTo(1)); + assertThat(actualResult.getSumLine().getTotalNumberOfTasks(), equalTo(1)); } } diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskMonitorServiceImplIntAutocommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskMonitorServiceImplIntAutocommitTest.java deleted file mode 100644 index f50415d6a..000000000 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskMonitorServiceImplIntAutocommitTest.java +++ /dev/null @@ -1,177 +0,0 @@ -package pro.taskana.impl.integration; - -import java.io.FileNotFoundException; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; - -import javax.security.auth.login.LoginException; -import javax.sql.DataSource; - -import org.h2.store.fs.FileUtils; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import pro.taskana.Classification; -import pro.taskana.ClassificationService; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.Workbasket; -import pro.taskana.WorkbasketService; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.exceptions.ClassificationAlreadyExistException; -import pro.taskana.exceptions.ClassificationNotFoundException; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.InvalidOwnerException; -import pro.taskana.exceptions.InvalidStateException; -import pro.taskana.exceptions.InvalidWorkbasketException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.exceptions.TaskAlreadyExistException; -import pro.taskana.exceptions.TaskNotFoundException; -import pro.taskana.exceptions.WorkbasketNotFoundException; -import pro.taskana.impl.JunitHelper; -import pro.taskana.impl.TaskImpl; -import pro.taskana.impl.TaskServiceImpl; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.WorkbasketImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.util.IdGenerator; -import pro.taskana.model.Report; -import pro.taskana.model.TaskState; -import pro.taskana.model.WorkbasketAccessItem; -import pro.taskana.model.WorkbasketType; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Integration Test for TaskMonitorServiceImpl transactions with connection management mode AUTOCOMMIT. - */ -@RunWith(JAASRunner.class) -public class TaskMonitorServiceImplIntAutocommitTest { - - private DataSource dataSource; - private TaskServiceImpl taskServiceImpl; - private TaskanaEngineConfiguration taskanaEngineConfiguration; - private TaskanaEngine taskanaEngine; - private TaskanaEngineImpl taskanaEngineImpl; - private ClassificationService classificationService; - private WorkbasketService workBasketService; - private TaskMonitorService taskMonitorService; - - @BeforeClass - public static void resetDb() throws SQLException { - DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(ds, true); - } - - @Before - public void setup() throws FileNotFoundException, SQLException, LoginException { - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService(); - taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; - classificationService = taskanaEngine.getClassificationService(); - taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT); - workBasketService = taskanaEngine.getWorkbasketService(); - taskMonitorService = taskanaEngine.getTaskMonitorService(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, false); - } - - @WithAccessId(userName = "Elena") - @Test - public void testGetWorkbasketLevelReport() throws ClassificationAlreadyExistException, WorkbasketNotFoundException, - ClassificationNotFoundException, NotAuthorizedException, TaskAlreadyExistException, InvalidWorkbasketException, - InvalidArgumentException, TaskNotFoundException, InvalidStateException, InvalidOwnerException { - - generateSampleAccessItems(); - - WorkbasketImpl workbasket1 = (WorkbasketImpl) workBasketService.newWorkbasket(); - workbasket1.setName("wb1"); - workbasket1.setId("1"); - workbasket1.setKey("1"); - workbasket1.setDomain("novatec"); - workbasket1.setType(WorkbasketType.GROUP); - workBasketService.createWorkbasket(workbasket1); - - WorkbasketImpl workbasket2 = (WorkbasketImpl) workBasketService.newWorkbasket(); - workbasket2.setName("wb2"); - workbasket2.setId("2"); - workbasket2.setKey("2"); - workbasket2.setDomain("novatec"); - workbasket2.setType(WorkbasketType.GROUP); - workBasketService.createWorkbasket(workbasket2); - - Classification classification = classificationService.newClassification("novatec", "TEST", "type1"); - classificationService.createClassification(classification); - - TaskImpl task1 = (TaskImpl) taskServiceImpl.newTask(); - task1.setWorkbasketKey(workbasket1.getKey()); - task1.setClassificationKey(classification.getKey()); - task1.setPrimaryObjRef(JunitHelper.createDefaultObjRef()); - task1 = (TaskImpl) taskServiceImpl.createTask(task1); - - TaskImpl task2 = (TaskImpl) taskServiceImpl.newTask(); - task2.setWorkbasketKey(workbasket2.getKey()); - task2.setClassificationKey(classification.getKey()); - task2.setPrimaryObjRef(JunitHelper.createDefaultObjRef()); - task2 = (TaskImpl) taskServiceImpl.createTask(task2); - - TaskImpl task3 = (TaskImpl) taskServiceImpl.newTask(); - task3.setWorkbasketKey(workbasket2.getKey()); - task3.setClassificationKey(classification.getKey()); - task3.setPrimaryObjRef(JunitHelper.createDefaultObjRef()); - task3 = (TaskImpl) taskServiceImpl.createTask(task3); - - List workbaskets = Arrays.asList(workbasket1, workbasket2); - List states = Arrays.asList(TaskState.READY, TaskState.CLAIMED); - Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states); - - int countWorkbasket1 = report.getDetailLines().get(0).getTotalCount(); - int countWorkbasket2 = report.getDetailLines().get(1).getTotalCount(); - int totalCount = report.getSumLine().getTotalCount(); - - Assert.assertNotNull(report); - Assert.assertEquals(countWorkbasket1, 1); - Assert.assertEquals(countWorkbasket2, 2); - Assert.assertEquals(countWorkbasket1 + countWorkbasket2, totalCount); - } - - private void generateSampleAccessItems() { - WorkbasketAccessItem accessItem = new WorkbasketAccessItem(); - accessItem.setId(IdGenerator.generateWithPrefix("WAI")); - accessItem.setWorkbasketKey("1"); - accessItem.setAccessId("Elena"); - accessItem.setPermAppend(true); - accessItem.setPermRead(true); - workBasketService.createWorkbasketAuthorization(accessItem); - - WorkbasketAccessItem accessItem2 = new WorkbasketAccessItem(); - accessItem2.setId(IdGenerator.generateWithPrefix("WAI")); - accessItem2.setWorkbasketKey("2"); - accessItem2.setAccessId("Elena"); - accessItem2.setPermAppend(true); - accessItem2.setPermRead(true); - workBasketService.createWorkbasketAuthorization(accessItem2); - } - - @After - public void cleanUp() { - taskanaEngineImpl.setConnection(null); - } - - @AfterClass - public static void cleanUpClass() { - FileUtils.deleteRecursive("~/data", true); - } - -} diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskMonitorServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskMonitorServiceImplIntExplicitTest.java deleted file mode 100644 index 6966f4575..000000000 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskMonitorServiceImplIntExplicitTest.java +++ /dev/null @@ -1,186 +0,0 @@ -package pro.taskana.impl.integration; - -import java.io.FileNotFoundException; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; - -import javax.security.auth.login.LoginException; -import javax.sql.DataSource; - -import org.h2.store.fs.FileUtils; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import pro.taskana.Classification; -import pro.taskana.ClassificationService; -import pro.taskana.TaskMonitorService; -import pro.taskana.TaskanaEngine; -import pro.taskana.TaskanaEngine.ConnectionManagementMode; -import pro.taskana.Workbasket; -import pro.taskana.WorkbasketService; -import pro.taskana.configuration.TaskanaEngineConfiguration; -import pro.taskana.exceptions.ClassificationAlreadyExistException; -import pro.taskana.exceptions.ClassificationNotFoundException; -import pro.taskana.exceptions.InvalidArgumentException; -import pro.taskana.exceptions.InvalidOwnerException; -import pro.taskana.exceptions.InvalidStateException; -import pro.taskana.exceptions.InvalidWorkbasketException; -import pro.taskana.exceptions.NotAuthorizedException; -import pro.taskana.exceptions.TaskAlreadyExistException; -import pro.taskana.exceptions.TaskNotFoundException; -import pro.taskana.exceptions.WorkbasketNotFoundException; -import pro.taskana.impl.JunitHelper; -import pro.taskana.impl.TaskImpl; -import pro.taskana.impl.TaskServiceImpl; -import pro.taskana.impl.TaskanaEngineImpl; -import pro.taskana.impl.WorkbasketImpl; -import pro.taskana.impl.configuration.DBCleaner; -import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest; -import pro.taskana.impl.util.IdGenerator; -import pro.taskana.model.Report; -import pro.taskana.model.TaskState; -import pro.taskana.model.WorkbasketAccessItem; -import pro.taskana.model.WorkbasketType; -import pro.taskana.security.JAASRunner; -import pro.taskana.security.WithAccessId; - -/** - * Integration Test for TaskMonitorServiceImpl transactions with connection management mode EXPLICIT. - */ -@RunWith(JAASRunner.class) -public class TaskMonitorServiceImplIntExplicitTest { - - private DataSource dataSource; - private TaskServiceImpl taskServiceImpl; - private TaskanaEngineConfiguration taskanaEngineConfiguration; - private TaskanaEngine taskanaEngine; - private TaskanaEngineImpl taskanaEngineImpl; - private ClassificationService classificationService; - private WorkbasketService workBasketService; - private TaskMonitorService taskMonitorService; - - @BeforeClass - public static void resetDb() throws SQLException { - DataSource ds = TaskanaEngineConfigurationTest.getDataSource(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(ds, true); - } - - @Before - public void setup() throws FileNotFoundException, SQLException, LoginException { - dataSource = TaskanaEngineConfigurationTest.getDataSource(); - taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false); - taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine(); - taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService(); - taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; - classificationService = taskanaEngine.getClassificationService(); - taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); - workBasketService = taskanaEngine.getWorkbasketService(); - DBCleaner cleaner = new DBCleaner(); - cleaner.clearDb(dataSource, false); - } - - @WithAccessId(userName = "Elena") - @Test - public void testGetWorkbasketLevelReport() throws SQLException, ClassificationAlreadyExistException, - WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, TaskNotFoundException, - TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, InvalidOwnerException, - InvalidStateException { - Connection connection = dataSource.getConnection(); - taskanaEngineImpl.setConnection(connection); - - taskMonitorService = taskanaEngine.getTaskMonitorService(); - - generateSampleAccessItems(); - - WorkbasketImpl workbasket1 = (WorkbasketImpl) workBasketService.newWorkbasket(); - workbasket1.setName("wb1"); - workbasket1.setId("1"); - workbasket1.setKey("1"); - workbasket1.setDomain("novatec"); - workbasket1.setType(WorkbasketType.GROUP); - workBasketService.createWorkbasket(workbasket1); - - WorkbasketImpl workbasket2 = (WorkbasketImpl) workBasketService.newWorkbasket(); - workbasket2.setName("wb2"); - workbasket2.setId("2"); - workbasket2.setKey("2"); - workbasket2.setDomain("novatec"); - workbasket2.setType(WorkbasketType.GROUP); - workBasketService.createWorkbasket(workbasket2); - - Classification classification = classificationService.newClassification("novatec", "TEST", "type1"); - classificationService.createClassification(classification); - - TaskImpl task1 = (TaskImpl) taskServiceImpl.newTask(); - task1.setWorkbasketKey(workbasket1.getKey()); - task1.setClassificationKey(classification.getKey()); - task1.setPrimaryObjRef(JunitHelper.createDefaultObjRef()); - task1 = (TaskImpl) taskServiceImpl.createTask(task1); - connection.commit(); - - TaskImpl task2 = (TaskImpl) taskServiceImpl.newTask(); - task2.setWorkbasketKey(workbasket2.getId()); - task2.setClassificationKey(classification.getKey()); - task2.setPrimaryObjRef(JunitHelper.createDefaultObjRef()); - task2 = (TaskImpl) taskServiceImpl.createTask(task2); - connection.commit(); - - TaskImpl task3 = (TaskImpl) taskServiceImpl.newTask(); - task3.setWorkbasketKey(workbasket2.getId()); - task3.setClassificationKey(classification.getKey()); - task3.setPrimaryObjRef(JunitHelper.createDefaultObjRef()); - task3 = (TaskImpl) taskServiceImpl.createTask(task3); - connection.commit(); - - List workbaskets = Arrays.asList(workbasket1, workbasket2); - List states = Arrays.asList(TaskState.READY, TaskState.CLAIMED); - Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states); - - int countWorkbasket1 = report.getDetailLines().get(0).getTotalCount(); - int countWorkbasket2 = report.getDetailLines().get(1).getTotalCount(); - int totalCount = report.getSumLine().getTotalCount(); - - Assert.assertNotNull(report); - Assert.assertEquals(countWorkbasket1, 1); - Assert.assertEquals(countWorkbasket2, 2); - Assert.assertEquals(countWorkbasket1 + countWorkbasket2, totalCount); - connection.commit(); - } - - private void generateSampleAccessItems() { - WorkbasketAccessItem accessItem = new WorkbasketAccessItem(); - accessItem.setId(IdGenerator.generateWithPrefix("WAI")); - accessItem.setWorkbasketKey("1"); - accessItem.setAccessId("Elena"); - accessItem.setPermAppend(true); - accessItem.setPermRead(true); - workBasketService.createWorkbasketAuthorization(accessItem); - - WorkbasketAccessItem accessItem2 = new WorkbasketAccessItem(); - accessItem2.setId(IdGenerator.generateWithPrefix("WAI")); - accessItem2.setWorkbasketKey("2"); - accessItem2.setAccessId("Elena"); - accessItem2.setPermAppend(true); - accessItem2.setPermRead(true); - workBasketService.createWorkbasketAuthorization(accessItem2); - } - - @After - public void cleanUp() { - taskanaEngineImpl.setConnection(null); - } - - @AfterClass - public static void cleanUpClass() { - FileUtils.deleteRecursive("~/data", true); - } - -} diff --git a/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql b/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql new file mode 100644 index 000000000..481f3cc07 --- /dev/null +++ b/lib/taskana-core/src/test/resources/sql/monitor-sample-data.sql @@ -0,0 +1,63 @@ +-- Tasks +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000001', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task01', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000002', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task02', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000003', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task03', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000004', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task04', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000005', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task05', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000006', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task06', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000007', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task07', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000008', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task08', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000009', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task09', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000010', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task10', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000011', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task11', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000012', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task12', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000013', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task13', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000014', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task14', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000015', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task15', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000016', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task16', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000017', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task17', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000018', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task18', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000019', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task19', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000020', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task20', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000021', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task21', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000022', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task22', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000023', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task23', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000024', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task24', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000025', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task25', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000026', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task26', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000027', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task27', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000028', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task28', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000029', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task29', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000030', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task30', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000031', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task31', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000032', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task32', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000033', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task33', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000034', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task34', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000035', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task35', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000036', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task36', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000037', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task37', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000038', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task38', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000039', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task39', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000040', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task40', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_2', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000041', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task41', 'Some description.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000042', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task42', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000043', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task43', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000044', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task44', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000045', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task45', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000046', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task46', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000047', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task47', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000048', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task48', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000049', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task49', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); +INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000050', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, dueDate, 'Task50', 'Some description.', 'Some custom Note', 1, 'CLAIMED', 'T6310', 'USER_1_3', 'DOMAIN_A', 'BPI21', 'PBPI21', 'John', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); + +-- Workbaskets +INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000001', 'USER_1_1', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'USER_1_1', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 1', '', '', '', '', '', '', '', '', ''); +INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000002', 'USER_1_2', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'USER_1_2', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 2', '', '', '', '', '', '', '', '', ''); +INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000003', 'USER_1_3', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'USER_1_3', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 3', '', '', '', '', '', '', '', '', ''); +INSERT INTO WORKBASKET VALUES ('WBI:000000000000000000000000000000000004', 'USER_1_4', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'USER_1_4', 'MONITOR_TEST_DOMAIN', 'PERSONAL', 'Monitor Test Postkorb 4', '', '', '', '', '', '', '', '', ''); + +-- WorkbasketAccessLists +INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:000000000000000000000000000000000001', 'USER_1_1', 'monitor_user_1', true, true, true, true, false, false, false, false, false, false, false, false, false); +INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:000000000000000000000000000000000002', 'USER_1_2', 'monitor_user_1', true, true, true, true, false, false, false, false, false, false, false, false, false); +INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:000000000000000000000000000000000003', 'USER_1_3', 'monitor_user_1', true, true, true, true, false, false, false, false, false, false, false, false, false); +INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:000000000000000000000000000000000004', 'USER_1_4', 'monitor_user_1', true, true, true, true, false, false, false, false, false, false, false, false, false); diff --git a/lib/taskana-core/src/test/resources/sql/task.sql b/lib/taskana-core/src/test/resources/sql/task.sql index 181ce831e..dfff05690 100644 --- a/lib/taskana-core/src/test/resources/sql/task.sql +++ b/lib/taskana-core/src/test/resources/sql/task.sql @@ -19,3 +19,4 @@ INSERT INTO TASK VALUES('14', CURRENT_TIMESTAMP, null, null, CURRENT_TIMESTAMP, INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000000', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, 'Task99', 'Lorem ipsum was n Quatsch dolor sit amet.', 'Some custom Note', 1, 'READY', 'T6310', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'Konrad', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000001', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, 'Task01', 'Lorem ipsum was n Quatsch dolor sit amet.', 'Some custom Note', 2, 'READY', 'L110102', 'USER_1_1', 'DOMAIN_A', 'BPI21', 'PBPI21', 'Konrad', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); INSERT INTO TASK VALUES('TKI:000000000000000000000000000000000002', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, null, 'Task02', 'Lorem ipsum was n Quatsch dolor sit amet. Aber stimmt.', 'Some custom Note', 2, 'READY', 'A12', 'GPK_B_KSC', 'DOMAIN_B', 'BPI21', 'PBPI21', 'Konrad', 'MyCompany1', 'MySystem1', 'MyInstance1', 'MyType1', 'MyValue1', true, false, null, null, null, null, null, null, null, null, null, null, null); + diff --git a/lib/taskana-core/src/test/resources/sql/workbasket-access-list.sql b/lib/taskana-core/src/test/resources/sql/workbasket-access-list.sql index ae8b2d51b..422812198 100644 --- a/lib/taskana-core/src/test/resources/sql/workbasket-access-list.sql +++ b/lib/taskana-core/src/test/resources/sql/workbasket-access-list.sql @@ -36,3 +36,4 @@ INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:10000000000000000000000000000000 -- Access to other domains INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:100000000000000000000000000000000023', 'GPK_B_KSC_1', 'group_1', true, false, true, true, false, false, false, false, false, false, false, false, false); INSERT INTO WORKBASKET_ACCESS_LIST VALUES ('WAI:100000000000000000000000000000000024', 'GPK_B_KSC_2', 'group_2', true, false, true, true, false, false, false, false, false, false, false, false, false); + diff --git a/lib/taskana-core/src/test/resources/sql/workbasket.sql b/lib/taskana-core/src/test/resources/sql/workbasket.sql index 9bdd3c7ab..78d7f2672 100644 --- a/lib/taskana-core/src/test/resources/sql/workbasket.sql +++ b/lib/taskana-core/src/test/resources/sql/workbasket.sql @@ -18,3 +18,4 @@ INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000009', 'USER INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000011', 'GPK_B_KSC', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Gruppenpostkorb KSC B', 'DOMAIN_B', 'GROUP', 'Gruppenpostkorb KSC', '', '', '', '', '', '', '', '', ''); INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000012', 'GPK_B_KSC_1', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Gruppenpostkorb KSC B1', 'DOMAIN_B', 'GROUP', 'Gruppenpostkorb KSC 1', '', '', '', '', '', '', '', '', ''); INSERT INTO WORKBASKET VALUES ('WBI:100000000000000000000000000000000013', 'GPK_B_KSC_2', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'Gruppenpostkorb KSC B2', 'DOMAIN_B', 'GROUP', 'Gruppenpostkorb KSC 2', '', '', '', '', '', '', '', '', ''); + diff --git a/lib/taskana-spring/src/main/java/pro/taskana/SpringTaskanaEngineImpl.java b/lib/taskana-spring/src/main/java/pro/taskana/SpringTaskanaEngineImpl.java index 848f801c8..111979ce4 100644 --- a/lib/taskana-spring/src/main/java/pro/taskana/SpringTaskanaEngineImpl.java +++ b/lib/taskana-spring/src/main/java/pro/taskana/SpringTaskanaEngineImpl.java @@ -1,25 +1,26 @@ -package pro.taskana; - -import java.sql.SQLException; - -import javax.annotation.PostConstruct; - -import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; -import pro.taskana.configuration.SpringTaskanaEngineConfiguration; -import pro.taskana.impl.TaskanaEngineImpl; - -/** - * This class configures the TaskanaEngine for spring - */ -public class SpringTaskanaEngineImpl extends TaskanaEngineImpl { - - public SpringTaskanaEngineImpl(SpringTaskanaEngineConfiguration taskanaEngineConfiguration) { - super(taskanaEngineConfiguration); - } - - @PostConstruct - public void init() throws SQLException { - this.transactionFactory = new ManagedTransactionFactory(); - } - -} +package pro.taskana; + +import java.sql.SQLException; + +import javax.annotation.PostConstruct; + +import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; + +import pro.taskana.configuration.SpringTaskanaEngineConfiguration; +import pro.taskana.impl.TaskanaEngineImpl; + +/** + * This class configures the TaskanaEngine for spring + */ +public class SpringTaskanaEngineImpl extends TaskanaEngineImpl { + + public SpringTaskanaEngineImpl(SpringTaskanaEngineConfiguration taskanaEngineConfiguration) { + super(taskanaEngineConfiguration); + } + + @PostConstruct + public void init() throws SQLException { + this.transactionFactory = new ManagedTransactionFactory(); + } + +} diff --git a/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java b/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java index 2518ef153..de025dcc4 100644 --- a/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java +++ b/lib/taskana-spring/src/main/java/pro/taskana/configuration/SpringTaskanaEngineConfiguration.java @@ -1,42 +1,43 @@ -package pro.taskana.configuration; - -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import pro.taskana.SpringTaskanaEngineImpl; -import pro.taskana.TaskanaEngine; - -/** - * This class configures the TaskanaEngineConfiguration for spring - */ -public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration { - - private static final Logger logger = LoggerFactory.getLogger(SpringTaskanaEngineConfiguration.class); - - /** - * This method creates the Spring-based TaskanaEngine without an - * sqlSessionFactory - * - * @return the TaskanaEngine - */ - public TaskanaEngine buildTaskanaEngine() { - this.useManagedTransactions = true; - - dbScriptRunner = new DbSchemaCreator(this.dataSource); - try { - dbScriptRunner.run(); - } catch (SQLException e) { - logger.error("The taskana schema could not be created: ", e); - } - - return new SpringTaskanaEngineImpl(this); - } - - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - -} +package pro.taskana.configuration; + +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.SpringTaskanaEngineImpl; +import pro.taskana.TaskanaEngine; + +/** + * This class configures the TaskanaEngineConfiguration for spring + */ +public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration { + + private static final Logger logger = LoggerFactory.getLogger(SpringTaskanaEngineConfiguration.class); + + /** + * This method creates the Spring-based TaskanaEngine without an sqlSessionFactory + * + * @return the TaskanaEngine + */ + @Override + public TaskanaEngine buildTaskanaEngine() { + this.useManagedTransactions = true; + + dbScriptRunner = new DbSchemaCreator(this.dataSource); + try { + dbScriptRunner.run(); + } catch (SQLException e) { + logger.error("The taskana schema could not be created: ", e); + } + + return new SpringTaskanaEngineImpl(this); + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + +}