TSK-109: Separate monitor and task operations

- Add TaskMonitorService and move the needed methods from TaskService
- Update TaskanaEngine with TaskMonitorService
- Update MonitorController and RestApplication
- Add TaskMonitorMapper
This commit is contained in:
Konstantin Kläger 2017-12-15 11:35:17 +01:00 committed by Holger Hagen
parent f1ddf6780c
commit 75e35a7593
12 changed files with 703 additions and 497 deletions

View File

@ -0,0 +1,51 @@
package pro.taskana;
import java.util.List;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
/**
* The Task Monitor Service manages operations on tasks regarding the monitoring.
*/
public interface TaskMonitorService {
/**
* This method counts all tasks with a given state.
*
* @param states
* the countable states
* @return a List of {@link TaskStateCounter} objects that specifies how many tasks in the specified states exist in
* the available work baskets
*/
List<TaskStateCounter> getTaskCountForState(List<TaskState> states);
/**
* Count all Tasks in a given work basket where the due date is after "daysInPast" days from today in the past and
* the tasks are in specified states.
*
* @param workbasketId
* the id of the work basket
* @param daysInPast
* identifies the days in the past from today
* @param states
* {@link List} of {@link TaskState} that identifies the states of the tasks to be searched for
* @return the number of Task objects in the given work basket that match the query parameters
*/
long getTaskCountForWorkbasketByDaysInPastAndState(String workbasketId, long daysInPast, List<TaskState> states);
/**
* Count all Tasks for all work basket objects where the due date is after "daysInPast" days from today in the past
* and the tasks are in specified states.
*
* @param daysInPast
* identifies the days in the past from today
* @param states
* {@link List} of {@link TaskState} objects that identifies the states of the tasks searched
* @return a list of of {@link DueWorkbasketCounter} objects that specifies how many tasks in the requested states
* with appropriate due date exist in the various work baskets
*/
List<DueWorkbasketCounter> getTaskCountByWorkbasketAndDaysInPastAndState(long daysInPast, List<TaskState> states);
}

View File

@ -8,10 +8,8 @@ import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.Task;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
import pro.taskana.model.TaskSummary;
/**
@ -55,29 +53,35 @@ public interface TaskService {
/**
* Complete a claimed Task as owner/admin and update State and Timestamps.
*
* @param taskId - Id of the Task which should be completed.
*
* @param taskId
* - Id of the Task which should be completed.
* @return Task - updated task after completion.
*
* @throws InvalidStateException when Task wasn´t claimed before.
* @throws TaskNotFoundException if the given Task can´t be found in DB.
* @throws InvalidOwnerException if current user is not the task-owner or administrator.
* @throws InvalidStateException
* when Task wasn´t claimed before.
* @throws TaskNotFoundException
* if the given Task can´t be found in DB.
* @throws InvalidOwnerException
* if current user is not the task-owner or administrator.
*/
Task completeTask(String taskId) throws TaskNotFoundException, InvalidOwnerException, InvalidStateException;
/**
* Complete a claimed Task and update State and Timestamps.
*
* @param taskId - Id of the Task which should be completed.
* @param isForced - Flag which can complete a Task in every case if Task does exist.
*
* @param taskId
* - Id of the Task which should be completed.
* @param isForced
* - Flag which can complete a Task in every case if Task does exist.
* @return Task - updated task after completion.
*
* @throws InvalidStateException when Task wasn´t claimed before.
* @throws TaskNotFoundException if the given Task can´t be found in DB.
* @throws InvalidOwnerException if current user is not the task-owner or administrator.
* @throws InvalidStateException
* when Task wasn´t claimed before.
* @throws TaskNotFoundException
* if the given Task can´t be found in DB.
* @throws InvalidOwnerException
* if current user is not the task-owner or administrator.
*/
Task completeTask(String taskId, boolean isForced) throws TaskNotFoundException, InvalidOwnerException, InvalidStateException;
Task completeTask(String taskId, boolean isForced)
throws TaskNotFoundException, InvalidOwnerException, InvalidStateException;
/**
* Create and persist a task.
@ -106,43 +110,6 @@ public interface TaskService {
*/
Task getTaskById(String taskId) throws TaskNotFoundException;
/**
* This method counts all tasks with a given state.
*
* @param states
* the countable states
* @return a List of {@link TaskStateCounter} objects that specifies how many tasks in the specified states exist in
* the available work baskets
*/
List<TaskStateCounter> getTaskCountForState(List<TaskState> states);
/**
* Count all Tasks in a given work basket where the due date is after "daysInPast" days from today in the past and
* the tasks are in specified states.
*
* @param workbasketId
* the id of the work basket
* @param daysInPast
* identifies the days in the past from today
* @param states
* {@link List} of {@link TaskState} that identifies the states of the tasks to be searched for
* @return the number of {@link Task} objects in the given work basket that match the query parameters
*/
long getTaskCountForWorkbasketByDaysInPastAndState(String workbasketId, long daysInPast, List<TaskState> states);
/**
* Count all Tasks for all work basket objects where the due date is after "daysInPast" days from today in the past
* and the tasks are in specified states.
*
* @param daysInPast
* identifies the days in the past from today
* @param states
* {@link List} of {@link TaskState} objects that identifies the states of the tasks searched
* @return a list of of {@link DueWorkbasketCounter} objects that specifies how many tasks in the requested states
* with appropriate due date exist in the various work baskets
*/
List<DueWorkbasketCounter> getTaskCountByWorkbasketAndDaysInPastAndState(long daysInPast, List<TaskState> states);
/**
* Transfer a task to another work basket. The transfer sets the transferred flag and resets the read flag.
*

View File

@ -9,24 +9,35 @@ public interface TaskanaEngine {
/**
* The TaskService can be used for operations on all Tasks.
*
* @return the TaskService
*/
TaskService getTaskService();
/**
* The TaskMonitorService can be used for monitoring Tasks.
*
* @return the TaskMonitorService
*/
TaskMonitorService getTaskMonitorService();
/**
* The WorkbasketService can be used for operations on all Workbaskets.
*
* @return the TaskService
*/
WorkbasketService getWorkbasketService();
/**
* The ClassificationService can be used for operations on all Categories.
*
* @return the TaskService
*/
ClassificationService getClassificationService();
/**
* The Taskana configuration.
*
* @return the TaskanaConfiguration
*/
TaskanaEngineConfiguration getConfiguration();
@ -34,33 +45,35 @@ public interface TaskanaEngine {
/**
* sets the connection management mode for taskana.
*
* @param mode See ConnectionManagementMode
* @param mode
* See ConnectionManagementMode
*/
void setConnectionManagementMode(ConnectionManagementMode mode);
/**
* Set the connection to be used by taskana in mode CONNECTION_MANAGED_EXTERNALLY.
* If this Api is called, taskana uses the connection passed by the client for all subsequent API calls
* until the client resets this connection.
* Control over commit and rollback of the connection is the responsibility of the client.
* In order to close the connection, closeConnection() or setConnection(null) has to be called.
* Set the connection to be used by taskana in mode CONNECTION_MANAGED_EXTERNALLY. If this Api is called, taskana
* uses the connection passed by the client for all subsequent API calls until the client resets this connection.
* Control over commit and rollback of the connection is the responsibility of the client. In order to close the
* connection, closeConnection() or setConnection(null) has to be called.
*
* @param connection - The java.sql.Connection that is controlled by the client
* @param connection
* - The java.sql.Connection that is controlled by the client
*/
void setConnection(java.sql.Connection connection);
/**
* Closes the client's connection, sets it to null and switches to mode PARTICIPATE.
* Only applicable in mode EXPLICIT. Has the same effect as setConnection(null).
* Closes the client's connection, sets it to null and switches to mode PARTICIPATE. Only applicable in mode
* EXPLICIT. Has the same effect as setConnection(null).
*/
void closeConnection();
/**
* Connection management mode.
* Controls the connection handling of taskana
* 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
* Connection management mode. Controls the connection handling of taskana
* <ul>
* <li>PARTICIPATE - taskana participates in global transaction. This is the default mode</li>
* <li>AUTOCOMMIT - taskana commits each API call separately</li>
* <li>EXPLICIT - commit processing is managed explicitly by the client</li>
* </ul>
*/
enum ConnectionManagementMode {
PARTICIPATE,

View File

@ -0,0 +1,103 @@
package pro.taskana.impl;
import java.sql.Date;
import java.time.LocalDate;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskanaEngine;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
import pro.taskana.model.mappings.TaskMonitorMapper;
/**
* This is the implementation of TaskMonitorService.
*/
public class TaskMonitorServiceImpl implements TaskMonitorService {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class);
private TaskanaEngineImpl taskanaEngineImpl;
private TaskMonitorMapper taskMonitorMapper;
public TaskMonitorServiceImpl(TaskanaEngine taskanaEngine, TaskMonitorMapper taskMonitorMapper) {
super();
this.taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
this.taskMonitorMapper = taskMonitorMapper;
}
@Override
public List<TaskStateCounter> getTaskCountForState(List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("entry to getTaskCountForState(states = {})", LoggerUtils.listToString(states));
}
List<TaskStateCounter> result = null;
try {
taskanaEngineImpl.openConnection();
result = taskMonitorMapper.getTaskCountForState(states);
return result;
} finally {
taskanaEngineImpl.returnConnection();
if (LOGGER.isDebugEnabled()) {
int numberOfResultObjects = result == null ? 0 : result.size();
LOGGER.debug("exit from getTaskCountForState(). Returning {} resulting Objects: {} ",
numberOfResultObjects, LoggerUtils.listToString(result));
}
}
}
@Override
public long getTaskCountForWorkbasketByDaysInPastAndState(String workbasketId, long daysInPast,
List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"entry to getTaskCountForWorkbasketByDaysInPastAndState(workbasketId {}, daysInPast={}, states = {})",
workbasketId, daysInPast, LoggerUtils.listToString(states));
}
long result = -1;
try {
taskanaEngineImpl.openConnection();
LocalDate time = LocalDate.now();
time = time.minusDays(daysInPast);
Date fromDate = Date.valueOf(time);
result = taskMonitorMapper.getTaskCountForWorkbasketByDaysInPastAndState(workbasketId, fromDate, states);
return result;
} finally {
taskanaEngineImpl.returnConnection();
LOGGER.debug("exit from getTaskCountForWorkbasketByDaysInPastAndState(). Returning result {} ", result);
}
}
@Override
public List<DueWorkbasketCounter> getTaskCountByWorkbasketAndDaysInPastAndState(long daysInPast,
List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("entry to getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast = {}, states = {})",
daysInPast, LoggerUtils.listToString(states));
}
List<DueWorkbasketCounter> result = null;
try {
taskanaEngineImpl.openConnection();
LocalDate time = LocalDate.now();
time = time.minusDays(daysInPast);
Date fromDate = Date.valueOf(time);
result = taskMonitorMapper.getTaskCountByWorkbasketIdAndDaysInPastAndState(fromDate, states);
return result;
} finally {
taskanaEngineImpl.returnConnection();
if (LOGGER.isDebugEnabled()) {
int numberOfResultObjects = result == null ? 0 : result.size();
LOGGER.debug(
"exit from getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast,states). Returning {} resulting Objects: {} ",
numberOfResultObjects, LoggerUtils.listToString(result));
}
}
}
}

View File

@ -1,9 +1,7 @@
package pro.taskana.impl;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@ -24,11 +22,9 @@ import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.util.IdGenerator;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.ObjectReference;
import pro.taskana.model.Task;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
import pro.taskana.model.TaskSummary;
import pro.taskana.model.WorkbasketAuthorization;
import pro.taskana.model.mappings.ObjectReferenceMapper;
@ -116,7 +112,8 @@ public class TaskServiceImpl implements TaskService {
}
@Override
public Task completeTask(String taskId, boolean isForced) throws TaskNotFoundException, InvalidOwnerException, InvalidStateException {
public Task completeTask(String taskId, boolean isForced)
throws TaskNotFoundException, InvalidOwnerException, InvalidStateException {
LOGGER.debug("entry to completeTask(id = {}, isForced {})", taskId, isForced);
Task task = null;
try {
@ -125,11 +122,15 @@ public class TaskServiceImpl implements TaskService {
// check pre-conditions for non-forced invocation
if (!isForced) {
if (task.getClaimed() == null || task.getState() != TaskState.CLAIMED) {
LOGGER.warn("Method completeTask() does expect a task which need to be CLAIMED before. TaskId={}", taskId);
LOGGER.warn("Method completeTask() does expect a task which need to be CLAIMED before. TaskId={}",
taskId);
throw new InvalidStateException(taskId);
} else if (CurrentUserContext.getUserid() != task.getOwner()) {
LOGGER.warn("Method completeTask() does expect to be invoced by the task-owner or a administrator. TaskId={}, TaskOwner={}, CurrentUser={}", taskId, task.getOwner(), CurrentUserContext.getUserid());
throw new InvalidOwnerException("TaskOwner is" + task.getOwner() + ", but current User is " + CurrentUserContext.getUserid());
LOGGER.warn(
"Method completeTask() does expect to be invoced by the task-owner or a administrator. TaskId={}, TaskOwner={}, CurrentUser={}",
taskId, task.getOwner(), CurrentUserContext.getUserid());
throw new InvalidOwnerException(
"TaskOwner is" + task.getOwner() + ", but current User is " + CurrentUserContext.getUserid());
}
} else {
// CLAIM-forced, if task was not already claimed before.
@ -195,48 +196,6 @@ public class TaskServiceImpl implements TaskService {
}
}
@Override
public List<TaskStateCounter> getTaskCountForState(List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("entry to getTaskCountForState(states = {})", LoggerUtils.listToString(states));
}
List<TaskStateCounter> result = null;
try {
taskanaEngineImpl.openConnection();
result = taskMapper.getTaskCountForState(states);
return result;
} finally {
taskanaEngineImpl.returnConnection();
if (LOGGER.isDebugEnabled()) {
int numberOfResultObjects = result == null ? 0 : result.size();
LOGGER.debug("exit from getTaskCountForState(). Returning {} resulting Objects: {} ",
numberOfResultObjects, LoggerUtils.listToString(result));
}
}
}
@Override
public long getTaskCountForWorkbasketByDaysInPastAndState(String workbasketId, long daysInPast,
List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"entry to getTaskCountForWorkbasketByDaysInPastAndState(workbasketId {}, daysInPast={}, states = {})",
workbasketId, daysInPast, LoggerUtils.listToString(states));
}
long result = -1;
try {
taskanaEngineImpl.openConnection();
LocalDate time = LocalDate.now();
time = time.minusDays(daysInPast);
Date fromDate = Date.valueOf(time);
result = taskMapper.getTaskCountForWorkbasketByDaysInPastAndState(workbasketId, fromDate, states);
return result;
} finally {
taskanaEngineImpl.returnConnection();
LOGGER.debug("exit from getTaskCountForWorkbasketByDaysInPastAndState(). Returning result {} ", result);
}
}
@Override
public Task transfer(String taskId, String destinationWorkbasketId)
throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException {
@ -275,32 +234,6 @@ public class TaskServiceImpl implements TaskService {
}
}
@Override
public List<DueWorkbasketCounter> getTaskCountByWorkbasketAndDaysInPastAndState(long daysInPast,
List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("entry to getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast = {}, states = {})",
daysInPast, LoggerUtils.listToString(states));
}
List<DueWorkbasketCounter> result = null;
try {
taskanaEngineImpl.openConnection();
LocalDate time = LocalDate.now();
time = time.minusDays(daysInPast);
Date fromDate = Date.valueOf(time);
result = taskMapper.getTaskCountByWorkbasketIdAndDaysInPastAndState(fromDate, states);
return result;
} finally {
taskanaEngineImpl.returnConnection();
if (LOGGER.isDebugEnabled()) {
int numberOfResultObjects = result == null ? 0 : result.size();
LOGGER.debug(
"exit from getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast,states). Returning {} resulting Objects: {} ",
numberOfResultObjects, LoggerUtils.listToString(result));
}
}
}
@Override
public Task setTaskRead(String taskId, boolean isRead) throws TaskNotFoundException {
LOGGER.debug("entry to setTaskRead(taskId = {}, isRead = {})", taskId, isRead);

View File

@ -15,6 +15,7 @@ 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;
@ -27,6 +28,7 @@ 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;
@ -36,14 +38,21 @@ import pro.taskana.model.mappings.WorkbasketMapper;
public class TaskanaEngineImpl implements TaskanaEngine {
private static final String DEFAULT = "default";
private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineImpl.class);
protected static ThreadLocal<Stack<SqlSessionManager>> sessionStack = new ThreadLocal<Stack<SqlSessionManager>>();
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) {
@ -55,16 +64,26 @@ public class TaskanaEngineImpl implements TaskanaEngine {
@Override
public TaskService getTaskService() {
SqlSession session = this.sessionManager;
TaskServiceImpl taskServiceImpl = new TaskServiceImpl(this, session.getMapper(TaskMapper.class), session.getMapper(ObjectReferenceMapper.class));
TaskServiceImpl taskServiceImpl = new TaskServiceImpl(this, session.getMapper(TaskMapper.class),
session.getMapper(ObjectReferenceMapper.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));
WorkbasketServiceImpl workbasketServiceImpl = new WorkbasketServiceImpl(this,
session.getMapper(WorkbasketMapper.class),
session.getMapper(DistributionTargetMapper.class),
session.getMapper(WorkbasketAccessMapper.class));
return workbasketServiceImpl;
}
@ -82,16 +101,18 @@ public class TaskanaEngineImpl implements TaskanaEngine {
/**
* 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
* @param mode
* - the connection management mode Valid values are:
* <ul>
* <li>PARTICIPATE - taskana participates in global transaction. This is the default mode.</li>
* <li>AUTOCOMMIT - taskana commits each API call separately</li>
* <li>EXPLICIT - commit processing is managed explicitly by the client</li>
* </ul>
*/
@Override
public void setConnectionManagementMode(ConnectionManagementMode mode) {
if (this.mode == ConnectionManagementMode.EXPLICIT && connection != null
&& mode != ConnectionManagementMode.EXPLICIT) {
&& mode != ConnectionManagementMode.EXPLICIT) {
if (sessionManager.isManagedSessionStarted()) {
sessionManager.close();
}
@ -101,13 +122,13 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
/**
* 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
* 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) {
@ -125,9 +146,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
/**
* 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)
* 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() {
@ -141,9 +161,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
/**
* Open the connection to the database.
* to be called at the begin of each Api call that accesses the database
*
* Open the connection to the database. to be called at the begin of each Api call that accesses the database
*/
void openConnection() {
initSqlSession();
@ -153,8 +171,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
/**
* Initializes the SqlSessionManager.
*
* Initializes the SqlSessionManager.
*/
void initSqlSession() {
if (mode == ConnectionManagementMode.EXPLICIT && this.connection == null) {
@ -167,17 +184,15 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
/**
* 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
* 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()) {
&& this.sessionManager != null && this.sessionManager.isManagedSessionStarted()) {
if (this.mode == ConnectionManagementMode.AUTOCOMMIT) {
try {
this.sessionManager.commit();
@ -193,23 +208,25 @@ public class TaskanaEngineImpl implements TaskanaEngine {
/**
* retrieve the SqlSession used by taskana.
* @return the myBatis SqlSession object 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
* 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());
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);
@ -224,6 +241,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
/**
* creates the MyBatis transaction factory.
*
* @param useContainerManagedTransactions
*/
private void createTransactionFactory(boolean useContainerManagedTransactions) {
@ -235,15 +253,15 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
/**
* 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()
* 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<SqlSessionManager> getSessionStack() {

View File

@ -1,15 +1,26 @@
package pro.taskana.model.mappings;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.type.JdbcType;
import pro.taskana.Classification;
import pro.taskana.impl.persistence.MapTypeHandler;
import pro.taskana.model.*;
import java.sql.Date;
import java.util.List;
import java.util.Map;
import pro.taskana.model.ClassificationImpl;
import pro.taskana.model.ObjectReference;
import pro.taskana.model.Task;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskSummary;
/**
* This class is the mybatis mapping of task.
@ -17,136 +28,114 @@ import java.util.Map;
public interface TaskMapper {
String OBJECTREFERENCEMAPPER_FINDBYID = "pro.taskana.model.mappings.ObjectReferenceMapper.findById";
String CLASSIFICATION_FINDBYKEYROOTDOMAIN = "pro.taskana.model.mappings.ClassificationMapper.findByKeyRootDomain";
@Select("SELECT ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, DESCRIPTION, PRIORITY, STATE, CLASSIFICATION_KEY, WORKBASKETID, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, PRIMARY_OBJ_REF_ID, IS_READ, IS_TRANSFERRED, CUSTOM_ATTRIBUTES, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10 "
+ "FROM TASK "
+ "WHERE ID = #{id}")
+ "FROM TASK "
+ "WHERE ID = #{id}")
@Results(value = {
@Result(property = "id", column = "ID"),
@Result(property = "created", column = "CREATED"),
@Result(property = "claimed", column = "CLAIMED"),
@Result(property = "completed", column = "COMPLETED"),
@Result(property = "modified", column = "MODIFIED"),
@Result(property = "planned", column = "PLANNED"),
@Result(property = "due", column = "DUE"),
@Result(property = "name", column = "NAME"),
@Result(property = "description", column = "DESCRIPTION"),
@Result(property = "priority", column = "PRIORITY"),
@Result(property = "state", column = "STATE"),
@Result(property = "classification", column = "CLASSIFICATION_KEY", javaType = ClassificationImpl.class, one = @One(select = CLASSIFICATION_FINDBYKEYROOTDOMAIN)),
@Result(property = "workbasketId", column = "WORKBASKETID"),
@Result(property = "businessProcessId", column = "BUSINESS_PROCESS_ID"),
@Result(property = "parentBusinessProcessId", column = "PARENT_BUSINESS_PROCESS_ID"),
@Result(property = "owner", column = "OWNER"),
@Result(property = "primaryObjRef", column = "PRIMARY_OBJ_REF_ID", javaType = ObjectReference.class, one = @One(select = OBJECTREFERENCEMAPPER_FINDBYID)),
@Result(property = "isRead", column = "IS_READ"),
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB, javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "custom1", column = "CUSTOM_1"),
@Result(property = "custom2", column = "CUSTOM_2"),
@Result(property = "custom3", column = "CUSTOM_3"),
@Result(property = "custom4", column = "CUSTOM_4"),
@Result(property = "custom5", column = "CUSTOM_5"),
@Result(property = "custom6", column = "CUSTOM_6"),
@Result(property = "custom7", column = "CUSTOM_7"),
@Result(property = "custom8", column = "CUSTOM_8"),
@Result(property = "custom9", column = "CUSTOM_9"),
@Result(property = "custom10", column = "CUSTOM_10")
@Result(property = "id", column = "ID"),
@Result(property = "created", column = "CREATED"),
@Result(property = "claimed", column = "CLAIMED"),
@Result(property = "completed", column = "COMPLETED"),
@Result(property = "modified", column = "MODIFIED"),
@Result(property = "planned", column = "PLANNED"),
@Result(property = "due", column = "DUE"),
@Result(property = "name", column = "NAME"),
@Result(property = "description", column = "DESCRIPTION"),
@Result(property = "priority", column = "PRIORITY"),
@Result(property = "state", column = "STATE"),
@Result(property = "classification", column = "CLASSIFICATION_KEY", javaType = ClassificationImpl.class,
one = @One(select = CLASSIFICATION_FINDBYKEYROOTDOMAIN)),
@Result(property = "workbasketId", column = "WORKBASKETID"),
@Result(property = "businessProcessId", column = "BUSINESS_PROCESS_ID"),
@Result(property = "parentBusinessProcessId", column = "PARENT_BUSINESS_PROCESS_ID"),
@Result(property = "owner", column = "OWNER"),
@Result(property = "primaryObjRef", column = "PRIMARY_OBJ_REF_ID", javaType = ObjectReference.class,
one = @One(select = OBJECTREFERENCEMAPPER_FINDBYID)),
@Result(property = "isRead", column = "IS_READ"),
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB,
javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "custom1", column = "CUSTOM_1"),
@Result(property = "custom2", column = "CUSTOM_2"),
@Result(property = "custom3", column = "CUSTOM_3"),
@Result(property = "custom4", column = "CUSTOM_4"),
@Result(property = "custom5", column = "CUSTOM_5"),
@Result(property = "custom6", column = "CUSTOM_6"),
@Result(property = "custom7", column = "CUSTOM_7"),
@Result(property = "custom8", column = "CUSTOM_8"),
@Result(property = "custom9", column = "CUSTOM_9"),
@Result(property = "custom10", column = "CUSTOM_10")
})
Task findById(@Param("id") String id);
@Select("<script>"
+ "SELECT STATE, COUNT (STATE) as counter "
+ "FROM TASK "
+ "WHERE STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>) "
+ "GROUP BY STATE"
+ "</script>")
@Results({ @Result(column = "STATE", property = "state"), @Result(column = "counter", property = "counter") })
List<TaskStateCounter> getTaskCountForState(@Param("status") List<TaskState> status);
@Select("<script>"
+ "SELECT COUNT (*) "
+ "FROM TASK "
+ "WHERE WORKBASKETID = #{workbasketId} "
+ "AND DUE >= #{fromDate} "
+ "AND STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>)"
+ "</script>")
long getTaskCountForWorkbasketByDaysInPastAndState(@Param("workbasketId") String workbasketId, @Param("fromDate") Date fromDate, @Param("status") List<TaskState> states);
@Select("<script>"
+ "SELECT CAST(DUE AS DATE) as DUE_DATE, WORKBASKETID, COUNT (*) as counter "
+ "FROM TASK "
+ "WHERE DUE >= #{fromDate} "
+ "AND STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>) "
+ "GROUP BY DUE_DATE, WORKBASKETID"
+ "</script>")
@Results({ @Result(column = "DUE_DATE", property = "due"),
@Result(column = "WORKBASKETID", property = "workbasketId"),
@Result(column = "counter", property = "taskCounter") })
List<DueWorkbasketCounter> getTaskCountByWorkbasketIdAndDaysInPastAndState(@Param("fromDate") Date fromDate, @Param("status") List<TaskState> states);
@Insert("INSERT INTO TASK(ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, DESCRIPTION, PRIORITY, STATE, CLASSIFICATION_KEY, WORKBASKETID, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, PRIMARY_OBJ_REF_ID, IS_READ, IS_TRANSFERRED, CUSTOM_ATTRIBUTES, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10) "
+ "VALUES(#{id}, #{created}, #{claimed}, #{completed}, #{modified}, #{planned}, #{due}, #{name}, #{description}, #{priority}, #{state}, #{classification.key}, #{workbasketId}, #{businessProcessId}, #{parentBusinessProcessId}, #{owner}, #{primaryObjRef.id}, #{isRead}, #{isTransferred}, #{customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, #{custom1}, #{custom2}, #{custom3}, #{custom4}, #{custom5}, #{custom6}, #{custom7}, #{custom8}, #{custom9}, #{custom10})")
+ "VALUES(#{id}, #{created}, #{claimed}, #{completed}, #{modified}, #{planned}, #{due}, #{name}, #{description}, #{priority}, #{state}, #{classification.key}, #{workbasketId}, #{businessProcessId}, #{parentBusinessProcessId}, #{owner}, #{primaryObjRef.id}, #{isRead}, #{isTransferred}, #{customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, #{custom1}, #{custom2}, #{custom3}, #{custom4}, #{custom5}, #{custom6}, #{custom7}, #{custom8}, #{custom9}, #{custom10})")
@Options(keyProperty = "id", keyColumn = "ID")
void insert(Task task);
@Update("UPDATE TASK SET CLAIMED = #{claimed}, COMPLETED = #{completed}, MODIFIED = #{modified}, PLANNED = #{planned}, DUE = #{due}, NAME = #{name}, DESCRIPTION = #{description}, PRIORITY = #{priority}, STATE = #{state}, CLASSIFICATION_KEY = #{classification.key}, WORKBASKETID = #{workbasketId}, BUSINESS_PROCESS_ID = #{businessProcessId}, PARENT_BUSINESS_PROCESS_ID = #{parentBusinessProcessId}, OWNER = #{owner}, PRIMARY_OBJ_REF_ID = #{primaryObjRef.id}, IS_READ = #{isRead}, IS_TRANSFERRED = #{isTransferred}, CUSTOM_ATTRIBUTES = #{customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, CUSTOM_1 = #{custom1}, CUSTOM_2 = #{custom2}, CUSTOM_3 = #{custom3}, CUSTOM_4 = #{custom4}, CUSTOM_5 = #{custom5}, CUSTOM_6 = #{custom6}, CUSTOM_7 = #{custom7}, CUSTOM_8 = #{custom8}, CUSTOM_9 = #{custom9}, CUSTOM_10 = #{custom10} "
+ "WHERE ID = #{id}")
+ "WHERE ID = #{id}")
void update(Task task);
@Delete("DELETE FROM TASK WHERE ID = #{id}")
void delete(String id);
@Select("SELECT ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, DESCRIPTION, PRIORITY, STATE, CLASSIFICATION_KEY, WORKBASKETID, OWNER, PRIMARY_OBJ_REF_ID, IS_READ, IS_TRANSFERRED, CUSTOM_ATTRIBUTES, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10 "
+ "FROM TASK "
+ "WHERE WORKBASKETID = #{workbasketId} "
+ "AND STATE = #{taskState}")
+ "FROM TASK "
+ "WHERE WORKBASKETID = #{workbasketId} "
+ "AND STATE = #{taskState}")
@Results(value = {
@Result(property = "id", column = "ID"),
@Result(property = "created", column = "CREATED"),
@Result(property = "claimed", column = "CLAIMED"),
@Result(property = "completed", column = "COMPLETED"),
@Result(property = "modified", column = "MODIFIED"),
@Result(property = "planned", column = "PLANNED"),
@Result(property = "due", column = "DUE"),
@Result(property = "name", column = "NAME"),
@Result(property = "description", column = "DESCRIPTION"),
@Result(property = "priority", column = "PRIORITY"),
@Result(property = "state", column = "STATE"),
@Result(property = "classification", column = "CLASSIFICATION_KEY", javaType = Classification.class, one = @One(select = CLASSIFICATION_FINDBYKEYROOTDOMAIN)),
@Result(property = "workbasketId", column = "WORKBASKETID"),
@Result(property = "owner", column = "OWNER"),
@Result(property = "primaryObjRef", column = "PRIMARY_OBJ_REF_ID", javaType = ObjectReference.class, one = @One(select = OBJECTREFERENCEMAPPER_FINDBYID)),
@Result(property = "isRead", column = "IS_READ"),
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB, javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "custom1", column = "CUSTOM_1"),
@Result(property = "custom2", column = "CUSTOM_2"),
@Result(property = "custom3", column = "CUSTOM_3"),
@Result(property = "custom4", column = "CUSTOM_4"),
@Result(property = "custom5", column = "CUSTOM_5"),
@Result(property = "custom6", column = "CUSTOM_6"),
@Result(property = "custom7", column = "CUSTOM_7"),
@Result(property = "custom8", column = "CUSTOM_8"),
@Result(property = "custom9", column = "CUSTOM_9"),
@Result(property = "custom10", column = "CUSTOM_10")
@Result(property = "id", column = "ID"),
@Result(property = "created", column = "CREATED"),
@Result(property = "claimed", column = "CLAIMED"),
@Result(property = "completed", column = "COMPLETED"),
@Result(property = "modified", column = "MODIFIED"),
@Result(property = "planned", column = "PLANNED"),
@Result(property = "due", column = "DUE"),
@Result(property = "name", column = "NAME"),
@Result(property = "description", column = "DESCRIPTION"),
@Result(property = "priority", column = "PRIORITY"),
@Result(property = "state", column = "STATE"),
@Result(property = "classification", column = "CLASSIFICATION_KEY", javaType = Classification.class,
one = @One(select = CLASSIFICATION_FINDBYKEYROOTDOMAIN)),
@Result(property = "workbasketId", column = "WORKBASKETID"),
@Result(property = "owner", column = "OWNER"),
@Result(property = "primaryObjRef", column = "PRIMARY_OBJ_REF_ID", javaType = ObjectReference.class,
one = @One(select = OBJECTREFERENCEMAPPER_FINDBYID)),
@Result(property = "isRead", column = "IS_READ"),
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB,
javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "custom1", column = "CUSTOM_1"),
@Result(property = "custom2", column = "CUSTOM_2"),
@Result(property = "custom3", column = "CUSTOM_3"),
@Result(property = "custom4", column = "CUSTOM_4"),
@Result(property = "custom5", column = "CUSTOM_5"),
@Result(property = "custom6", column = "CUSTOM_6"),
@Result(property = "custom7", column = "CUSTOM_7"),
@Result(property = "custom8", column = "CUSTOM_8"),
@Result(property = "custom9", column = "CUSTOM_9"),
@Result(property = "custom10", column = "CUSTOM_10")
})
List<Task> findTasksByWorkbasketIdAndState(@Param("workbasketId") String workbasketId, @Param("taskState") TaskState taskState);
List<Task> findTasksByWorkbasketIdAndState(@Param("workbasketId") String workbasketId,
@Param("taskState") TaskState taskState);
@Select("SELECT TASK.ID AS taskId, TASK.NAME AS taskName, TASK.WORKBASKETID AS workId, TASK.CLASSIFICATION_KEY AS classificationKey, "
+ "WORKBASKET.NAME AS workName, CLASSIFICATION.NAME AS classificationName "
+ "FROM TASK "
+ "LEFT JOIN WORKBASKET ON WORKBASKET.ID = TASK.WORKBASKETID "
+ "LEFT JOIN CLASSIFICATION ON CLASSIFICATION.KEY = TASK.CLASSIFICATION_KEY "
+ "WHERE TASK.WORKBASKETID = #{workbasketId}")
+ "WORKBASKET.NAME AS workName, CLASSIFICATION.NAME AS classificationName "
+ "FROM TASK "
+ "LEFT JOIN WORKBASKET ON WORKBASKET.ID = TASK.WORKBASKETID "
+ "LEFT JOIN CLASSIFICATION ON CLASSIFICATION.KEY = TASK.CLASSIFICATION_KEY "
+ "WHERE TASK.WORKBASKETID = #{workbasketId}")
@Results({
@Result(property = "taskId", column = "taskId"),
@Result(property = "taskName", column = "taskName"),
@Result(property = "workbasketId", column = "workId"),
@Result(property = "workbasketName", column = "workName"),
@Result(property = "classificationKey", column = "classificationKey"),
@Result(property = "classificationName", column = "classificationName")
@Result(property = "taskId", column = "taskId"),
@Result(property = "taskName", column = "taskName"),
@Result(property = "workbasketId", column = "workId"),
@Result(property = "workbasketName", column = "workName"),
@Result(property = "classificationKey", column = "classificationKey"),
@Result(property = "classificationName", column = "classificationName")
})
List<TaskSummary> findTaskSummariesByWorkbasketId(@Param("workbasketId") String workbasketId);
}

View File

@ -0,0 +1,52 @@
package pro.taskana.model.mappings;
import java.sql.Date;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
/**
* This class is the mybatis mapping of task monitoring.
*/
public interface TaskMonitorMapper {
@Select("<script>"
+ "SELECT STATE, COUNT (STATE) as counter "
+ "FROM TASK "
+ "WHERE STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>) "
+ "GROUP BY STATE"
+ "</script>")
@Results({ @Result(column = "STATE", property = "state"), @Result(column = "counter", property = "counter") })
List<TaskStateCounter> getTaskCountForState(@Param("status") List<TaskState> status);
@Select("<script>"
+ "SELECT COUNT (*) "
+ "FROM TASK "
+ "WHERE WORKBASKETID = #{workbasketId} "
+ "AND DUE >= #{fromDate} "
+ "AND STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>)"
+ "</script>")
long getTaskCountForWorkbasketByDaysInPastAndState(@Param("workbasketId") String workbasketId,
@Param("fromDate") Date fromDate, @Param("status") List<TaskState> states);
@Select("<script>"
+ "SELECT CAST(DUE AS DATE) as DUE_DATE, WORKBASKETID, COUNT (*) as counter "
+ "FROM TASK "
+ "WHERE DUE >= #{fromDate} "
+ "AND STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>) "
+ "GROUP BY DUE_DATE, WORKBASKETID"
+ "</script>")
@Results({ @Result(column = "DUE_DATE", property = "due"),
@Result(column = "WORKBASKETID", property = "workbasketId"),
@Result(column = "counter", property = "taskCounter") })
List<DueWorkbasketCounter> getTaskCountByWorkbasketIdAndDaysInPastAndState(@Param("fromDate") Date fromDate,
@Param("status") List<TaskState> states);
}

View File

@ -0,0 +1,122 @@
package pro.taskana.impl;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import pro.taskana.WorkbasketService;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
import pro.taskana.model.mappings.ObjectReferenceMapper;
import pro.taskana.model.mappings.TaskMonitorMapper;
/**
* Unit Test for TaskMonitorServiceImpl.
*/
@RunWith(MockitoJUnitRunner.class)
public class TaskMonitorServiceImplTest {
@InjectMocks
private TaskMonitorServiceImpl cut;
@Mock
private TaskanaEngineConfiguration taskanaEngineConfigurationMock;
@Mock
private TaskanaEngineImpl taskanaEngineMock;
@Mock
private TaskanaEngineImpl taskanaEngineImpl;
@Mock
private TaskMonitorMapper taskMonitorMapperMock;
@Mock
private ObjectReferenceMapper objectReferenceMapperMock;
@Mock
private WorkbasketService workbasketServiceMock;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
Mockito.doNothing().when(taskanaEngineImpl).openConnection();
Mockito.doNothing().when(taskanaEngineImpl).returnConnection();
}
@Test
public void testGetTaskCountForState() {
List<TaskState> taskStates = Arrays.asList(TaskState.CLAIMED, TaskState.COMPLETED);
List<TaskStateCounter> expectedResult = new ArrayList<>();
doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountForState(taskStates);
List<TaskStateCounter> actualResult = cut.getTaskCountForState(taskStates);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMonitorMapperMock, times(1)).getTaskCountForState(taskStates);
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMonitorMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualResult, equalTo(expectedResult));
}
@Test
public void testGetTaskCountForWorkbasketByDaysInPastAndState() {
List<TaskState> taskStates = Arrays.asList(TaskState.CLAIMED, TaskState.COMPLETED);
final long daysInPast = 10L;
final long expectedResult = 5L;
String workbasketId = "1";
doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountForWorkbasketByDaysInPastAndState(any(), any(),
any());
long actualResult = cut.getTaskCountForWorkbasketByDaysInPastAndState(workbasketId, daysInPast, taskStates);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMonitorMapperMock, times(1)).getTaskCountForWorkbasketByDaysInPastAndState(any(), any(), any());
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMonitorMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualResult, equalTo(expectedResult));
}
@Test
public void testGetTaskCountByWorkbasketAndDaysInPastAndState() {
final long daysInPast = 10L;
List<TaskState> taskStates = Arrays.asList(TaskState.CLAIMED, TaskState.COMPLETED);
List<DueWorkbasketCounter> expectedResult = new ArrayList<>();
doReturn(expectedResult).when(taskMonitorMapperMock).getTaskCountByWorkbasketIdAndDaysInPastAndState(
any(Date.class),
any());
List<DueWorkbasketCounter> actualResult = cut.getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast,
taskStates);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMonitorMapperMock, times(1)).getTaskCountByWorkbasketIdAndDaysInPastAndState(any(Date.class), any());
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMonitorMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualResult, equalTo(expectedResult));
}
}

View File

@ -13,7 +13,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
@ -44,11 +43,9 @@ import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.model.ClassificationImpl;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.ObjectReference;
import pro.taskana.model.Task;
import pro.taskana.model.TaskState;
import pro.taskana.model.TaskStateCounter;
import pro.taskana.model.TaskSummary;
import pro.taskana.model.Workbasket;
import pro.taskana.model.WorkbasketAuthorization;
@ -232,7 +229,7 @@ public class TaskServiceImplTest {
expectedObjectReference.setId("1");
expectedObjectReference.setType("DUMMY");
Classification classification = (Classification) new ClassificationImpl();
Classification classification = new ClassificationImpl();
classification.setName("Name");
classification.setCategory("MANUAL");
Workbasket wb = new Workbasket();
@ -378,7 +375,8 @@ public class TaskServiceImplTest {
}
@Test
public void testCompleteTaskDefault() throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, InterruptedException {
public void testCompleteTaskDefault()
throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, InterruptedException {
TaskServiceImpl cutSpy = Mockito.spy(cut);
final long sleepTime = 100L;
final boolean isForced = false;
@ -394,11 +392,12 @@ public class TaskServiceImplTest {
// Just Verify unforced call of complex-complete()
verify(cutSpy, times(1)).completeTask(task.getId(), isForced);
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
}
@Test
public void testCompleteTaskNotForcedWorking() throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, InterruptedException {
public void testCompleteTaskNotForcedWorking()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, InterruptedException {
TaskServiceImpl cutSpy = Mockito.spy(cut);
final long sleepTime = 100L;
final boolean isForced = false;
@ -427,7 +426,8 @@ public class TaskServiceImplTest {
}
@Test(expected = InvalidStateException.class)
public void testCompleteTaskNotForcedNotClaimedBefore() throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
public void testCompleteTaskNotForcedNotClaimedBefore()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
final boolean isForced = false;
TaskServiceImpl cutSpy = Mockito.spy(cut);
Task task = createUnitTestTask("1", "Unit Test Task 1", "1");
@ -442,13 +442,14 @@ public class TaskServiceImplTest {
verify(cutSpy, times(1)).getTaskById(task.getId());
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
throw e;
}
}
@Test(expected = InvalidOwnerException.class)
public void testCompleteTaskNotForcedInvalidOwnerException() throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
public void testCompleteTaskNotForcedInvalidOwnerException()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
final boolean isForced = false;
TaskServiceImpl cutSpy = Mockito.spy(cut);
Task task = createUnitTestTask("1", "Unit Test Task 1", "1");
@ -470,25 +471,27 @@ public class TaskServiceImplTest {
}
@Test(expected = TaskNotFoundException.class)
public void testCompleteTaskTaskNotFound() throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
public void testCompleteTaskTaskNotFound()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException {
TaskServiceImpl cutSpy = Mockito.spy(cut);
final boolean isForced = false;
String taskId = "1";
doThrow(TaskNotFoundException.class).when(cutSpy).getTaskById(taskId);
try {
try {
cutSpy.completeTask(taskId, isForced);
} catch (InvalidOwnerException e) {
verify(taskanaEngineImpl, times(1)).openConnection();
verify(cutSpy, times(1)).getTaskById(taskId);
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
throw e;
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
throw e;
}
}
@Test
public void testCompleteForcedAndAlreadyClaimed() throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, InterruptedException {
public void testCompleteForcedAndAlreadyClaimed()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, InterruptedException {
final boolean isForced = true;
final long sleepTime = 100L;
TaskServiceImpl cutSpy = Mockito.spy(cut);
@ -507,7 +510,7 @@ public class TaskServiceImplTest {
verify(taskMapperMock, times(1)).update(task);
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualTask.getState(), equalTo(TaskState.COMPLETED));
assertThat(actualTask.getCreated(), not(equalTo(task.getModified())));
@ -516,7 +519,8 @@ public class TaskServiceImplTest {
}
@Test
public void testCompleteForcedNotClaimed() throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, InterruptedException {
public void testCompleteForcedNotClaimed()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, InterruptedException {
TaskServiceImpl cutSpy = Mockito.spy(cut);
final boolean isForced = true;
final long sleepTime = 100L;
@ -540,7 +544,7 @@ public class TaskServiceImplTest {
verify(taskMapperMock, times(1)).update(claimedTask);
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualTask.getState(), equalTo(TaskState.COMPLETED));
assertThat(actualTask.getCreated(), not(equalTo(claimedTask.getModified())));
assertThat(actualTask.getCompleted(), not(equalTo(null)));
@ -713,61 +717,6 @@ public class TaskServiceImplTest {
}
}
@Test
public void testGetTaskCountForState() {
TaskServiceImpl cutSpy = Mockito.spy(cut);
List<TaskState> taskStates = Arrays.asList(TaskState.CLAIMED, TaskState.COMPLETED);
List<TaskStateCounter> expectedResult = new ArrayList<>();
doReturn(expectedResult).when(taskMapperMock).getTaskCountForState(taskStates);
List<TaskStateCounter> actualResult = cutSpy.getTaskCountForState(taskStates);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMapperMock, times(1)).getTaskCountForState(taskStates);
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualResult, equalTo(expectedResult));
}
@Test
public void testGetTaskCountForWorkbasketByDaysInPastAndState() {
List<TaskState> taskStates = Arrays.asList(TaskState.CLAIMED, TaskState.COMPLETED);
final long daysInPast = 10L;
final long expectedResult = 5L;
String workbasketId = "1";
doReturn(expectedResult).when(taskMapperMock).getTaskCountForWorkbasketByDaysInPastAndState(any(), any(),
any());
long actualResult = cut.getTaskCountForWorkbasketByDaysInPastAndState(workbasketId, daysInPast, taskStates);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMapperMock, times(1)).getTaskCountForWorkbasketByDaysInPastAndState(any(), any(), any());
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualResult, equalTo(expectedResult));
}
@Test
public void testGetTaskCountByWorkbasketAndDaysInPastAndState() {
final long daysInPast = 10L;
List<TaskState> taskStates = Arrays.asList(TaskState.CLAIMED, TaskState.COMPLETED);
List<DueWorkbasketCounter> expectedResult = new ArrayList<>();
doReturn(expectedResult).when(taskMapperMock).getTaskCountByWorkbasketIdAndDaysInPastAndState(any(Date.class),
any());
List<DueWorkbasketCounter> actualResult = cut.getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast,
taskStates);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMapperMock, times(1)).getTaskCountByWorkbasketIdAndDaysInPastAndState(any(Date.class), any());
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMapperMock, objectReferenceMapperMock, workbasketServiceMock);
assertThat(actualResult, equalTo(expectedResult));
}
@Test
public void testSetTaskReadWIthExistingTask() throws TaskNotFoundException, ClassificationAlreadyExistException {
TaskServiceImpl cutSpy = Mockito.spy(cut);
@ -910,7 +859,7 @@ public class TaskServiceImplTest {
Timestamp now = new Timestamp(System.currentTimeMillis());
task.setCreated(now);
task.setModified(now);
Classification classification = (Classification) new ClassificationImpl();
Classification classification = new ClassificationImpl();
task.setClassification(classification);
return task;
}

View File

@ -12,7 +12,8 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import pro.taskana.TaskService;
import pro.taskana.TaskMonitorService;
import pro.taskana.WorkbasketService;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.TaskState;
@ -25,76 +26,78 @@ import pro.taskana.rest.model.WorkbasketCounterDto;
@RequestMapping(path = "/v1/monitor", produces = { MediaType.APPLICATION_JSON_VALUE })
public class MonitorController {
@Autowired
private TaskService taskService;
@Autowired
private TaskMonitorService taskMonitorService;
@Autowired
private WorkbasketService workbasketService;
@Autowired
private WorkbasketService workbasketService;
@RequestMapping(value = "/countByState")
public ResponseEntity<List<TaskStateCounter>> getTaskcountForState(
@RequestParam(value = "states") List<TaskState> taskStates) {
try {
List<TaskStateCounter> taskCount = taskService.getTaskCountForState(taskStates);
return ResponseEntity.status(HttpStatus.OK).body(taskCount);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
@RequestMapping(value = "/countByState")
public ResponseEntity<List<TaskStateCounter>> getTaskcountForState(
@RequestParam(value = "states") List<TaskState> taskStates) {
try {
List<TaskStateCounter> taskCount = taskMonitorService.getTaskCountForState(taskStates);
return ResponseEntity.status(HttpStatus.OK).body(taskCount);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
@RequestMapping(value = "/taskcountByWorkbasketDaysAndState")
public ResponseEntity<?> getTaskCountByWorkbasketAndDaysInPastAndState(
@RequestParam(value = "daysInPast") Long daysInPast,
@RequestParam(value = "states") List<TaskState> states) {
try {
WorkbasketCounterDto WorkbasketCounterDto = new WorkbasketCounterDto();
@RequestMapping(value = "/taskcountByWorkbasketDaysAndState")
public ResponseEntity<?> getTaskCountByWorkbasketAndDaysInPastAndState(
@RequestParam(value = "daysInPast") Long daysInPast,
@RequestParam(value = "states") List<TaskState> states) {
try {
WorkbasketCounterDto WorkbasketCounterDto = new WorkbasketCounterDto();
LocalDate date = LocalDate.now();
date = date.minusDays(daysInPast);
List<String> dates = new ArrayList<>();
LocalDate date = LocalDate.now();
date = date.minusDays(daysInPast);
List<String> dates = new ArrayList<>();
for (int i = 0; i < (daysInPast * 2 + 1); i++) {
dates.add(date.format(new DateTimeFormatterBuilder().appendPattern("dd.MM.yyyy").toFormatter()));
date = date.plusDays(1);
}
WorkbasketCounterDto.setDates(dates);
for (int i = 0; i < (daysInPast * 2 + 1); i++) {
dates.add(date.format(new DateTimeFormatterBuilder().appendPattern("dd.MM.yyyy").toFormatter()));
date = date.plusDays(1);
}
WorkbasketCounterDto.setDates(dates);
List<WorkbasketCounterDataDto> data = new ArrayList<>();
List<WorkbasketCounterDataDto> data = new ArrayList<>();
for (Workbasket workbasket : workbasketService.getWorkbaskets()) {
WorkbasketCounterDataDto counterDto = new WorkbasketCounterDataDto();
counterDto.setLabel(workbasket.getName());
List<Integer> zeroData = new ArrayList<>();
for (int i = 0; i < dates.size(); i++) {
zeroData.add(0);
}
counterDto.setData(zeroData);
data.add(counterDto);
}
for (Workbasket workbasket : workbasketService.getWorkbaskets()) {
WorkbasketCounterDataDto counterDto = new WorkbasketCounterDataDto();
counterDto.setLabel(workbasket.getName());
List<Integer> zeroData = new ArrayList<>();
for (int i = 0; i < dates.size(); i++) {
zeroData.add(0);
}
counterDto.setData(zeroData);
data.add(counterDto);
}
List<DueWorkbasketCounter> dwcList = taskService.getTaskCountByWorkbasketAndDaysInPastAndState(daysInPast,
states);
List<DueWorkbasketCounter> dwcList = taskMonitorService.getTaskCountByWorkbasketAndDaysInPastAndState(
daysInPast,
states);
for (DueWorkbasketCounter item : dwcList) {
String formattedDate = item.getDue().toLocalDate()
.format(new DateTimeFormatterBuilder().appendPattern("dd.MM.yyyy").toFormatter());
for (int i = 0; i < dates.size(); i++) {
if (formattedDate.equalsIgnoreCase(dates.get(i))) {
for (int j = 0; j < data.size(); j++) {
if (data.get(j).getLabel().equalsIgnoreCase(
workbasketService.getWorkbasket(item.getWorkbasketId()).getName())) {
data.get(j).getData().set(i, (int) item.getTaskCounter());
}
}
}
}
}
for (DueWorkbasketCounter item : dwcList) {
String formattedDate = item.getDue()
.toLocalDate()
.format(new DateTimeFormatterBuilder().appendPattern("dd.MM.yyyy").toFormatter());
for (int i = 0; i < dates.size(); i++) {
if (formattedDate.equalsIgnoreCase(dates.get(i))) {
for (int j = 0; j < data.size(); j++) {
if (data.get(j).getLabel().equalsIgnoreCase(
workbasketService.getWorkbasket(item.getWorkbasketId()).getName())) {
data.get(j).getData().set(i, (int) item.getTaskCounter());
}
}
}
}
}
WorkbasketCounterDto.setData(data);
WorkbasketCounterDto.setData(data);
return ResponseEntity.status(HttpStatus.OK).body(WorkbasketCounterDto);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
return ResponseEntity.status(HttpStatus.OK).body(WorkbasketCounterDto);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}

View File

@ -18,6 +18,7 @@ import org.springframework.http.converter.json.SpringHandlerInstantiator;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import pro.taskana.ClassificationService;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskService;
import pro.taskana.TaskanaEngine;
import pro.taskana.WorkbasketService;
@ -29,72 +30,77 @@ import pro.taskana.sampledata.SampleDataGenerator;
@SpringBootApplication
public class RestApplication {
private static final Logger logger = LoggerFactory.getLogger(RestApplication.class);
private static final Logger logger = LoggerFactory.getLogger(RestApplication.class);
public static void main(String[] args) {
SpringApplication.run(RestApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(RestApplication.class, args);
}
@Bean
public ClassificationService getClassificationService() throws Exception {
return getTaskanaEngine().getClassificationService();
}
@Bean
public ClassificationService getClassificationService() throws Exception {
return getTaskanaEngine().getClassificationService();
}
@Bean
public TaskService getTaskService() throws Exception {
return getTaskanaEngine().getTaskService();
}
@Bean
public TaskService getTaskService() throws Exception {
return getTaskanaEngine().getTaskService();
}
@Bean
public WorkbasketService getWorkbasketService() throws Exception {
return getTaskanaEngine().getWorkbasketService();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngine getTaskanaEngine() throws SQLException {
return getTaskanaEngineConfiguration().buildTaskanaEngine();
}
@Bean
public TaskMonitorService getTaskMonitorService() throws Exception {
return getTaskanaEngine().getTaskMonitorService();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngineConfiguration getTaskanaEngineConfiguration() throws SQLException {
TaskanaEngineConfiguration taskanaEngineConfiguration = new TaskanaEngineConfiguration(null, true);
return taskanaEngineConfiguration;
}
@Bean
public WorkbasketService getWorkbasketService() throws Exception {
return getTaskanaEngine().getWorkbasketService();
}
@PostConstruct
public void createSampleData() {
try {
new SampleDataGenerator(getTaskanaEngineConfiguration().createDefaultDataSource()).generateSampleData();
} catch (SQLException e) {
logger.error("Could not create sample data.", e);
}
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngine getTaskanaEngine() throws SQLException {
return getTaskanaEngineConfiguration().buildTaskanaEngine();
}
/**
* Needed to override JSON De-/Serializer in Jackson.
*
* @param handlerInstantiator
* @return
*/
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder(HandlerInstantiator handlerInstantiator) {
Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
b.indentOutput(true).mixIn(Workbasket.class, WorkbasketMixIn.class);
b.handlerInstantiator(handlerInstantiator);
return b;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngineConfiguration getTaskanaEngineConfiguration() throws SQLException {
TaskanaEngineConfiguration taskanaEngineConfiguration = new TaskanaEngineConfiguration(null, true);
return taskanaEngineConfiguration;
}
/**
* Needed for injection into jackson deserilizer.
*
* @param context
* @return
*/
@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext context) {
return new SpringHandlerInstantiator(context.getAutowireCapableBeanFactory());
}
@PostConstruct
public void createSampleData() {
try {
new SampleDataGenerator(getTaskanaEngineConfiguration().createDefaultDataSource()).generateSampleData();
} catch (SQLException e) {
logger.error("Could not create sample data.", e);
}
}
/**
* Needed to override JSON De-/Serializer in Jackson.
*
* @param handlerInstantiator
* @return
*/
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder(HandlerInstantiator handlerInstantiator) {
Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
b.indentOutput(true).mixIn(Workbasket.class, WorkbasketMixIn.class);
b.handlerInstantiator(handlerInstantiator);
return b;
}
/**
* Needed for injection into jackson deserilizer.
*
* @param context
* @return
*/
@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext context) {
return new SpringHandlerInstantiator(context.getAutowireCapableBeanFactory());
}
}