Closes #2374: Deadlock when creating HistoryEvents from many connections simultaneously
-Write operations are now performed with the regular TaskanEngine and its' SqlSession and TransactionFactory which provides the needed transactionality and doesn't open multiple connections
This commit is contained in:
parent
4e1325c254
commit
8b9ca2550e
|
@ -1,31 +0,0 @@
|
|||
package pro.taskana.simplehistory;
|
||||
|
||||
import pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.spi.history.api.TaskanaHistory;
|
||||
|
||||
/** The TaskanaHistoryEngine represents an overall set of all needed services. */
|
||||
public interface TaskanaHistoryEngine {
|
||||
/**
|
||||
* The TaskanaHistory can be used for operations on all history events.
|
||||
*
|
||||
* @return the HistoryService
|
||||
*/
|
||||
TaskanaHistory getTaskanaHistoryService();
|
||||
|
||||
/**
|
||||
* check whether the current user is member of one of the roles specified.
|
||||
*
|
||||
* @param roles The roles that are checked for membership of the current user
|
||||
* @return true if the current user is a member of at least one of the specified groups
|
||||
*/
|
||||
boolean isUserInRole(TaskanaRole... roles);
|
||||
|
||||
/**
|
||||
* Checks whether current user is member of any of the specified roles.
|
||||
*
|
||||
* @param roles The roles that are checked for membership of the current user
|
||||
* @throws NotAuthorizedException If the current user is not member of any specified role
|
||||
*/
|
||||
void checkRoleMembership(TaskanaRole... roles) throws NotAuthorizedException;
|
||||
}
|
|
@ -2,7 +2,6 @@ package pro.taskana.simplehistory.impl;
|
|||
|
||||
import static pro.taskana.common.api.BaseQuery.toLowerCopy;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
@ -12,6 +11,7 @@ import pro.taskana.classification.api.ClassificationCustomField;
|
|||
import pro.taskana.common.api.TimeInterval;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQuery;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQueryColumnName;
|
||||
import pro.taskana.spi.history.api.events.classification.ClassificationHistoryEvent;
|
||||
|
@ -33,7 +33,7 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
private static final String SQL_EXCEPTION_MESSAGE =
|
||||
"Method openConnection() could not open a connection to the database.";
|
||||
|
||||
private final TaskanaHistoryEngineImpl taskanaHistoryEngine;
|
||||
private final InternalTaskanaEngine internalTaskanaEngine;
|
||||
|
||||
private final List<String> orderBy = new ArrayList<>();
|
||||
private final List<String> orderColumns = new ArrayList<>();
|
||||
|
@ -82,8 +82,8 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
private String[] custom7Like;
|
||||
private String[] custom8Like;
|
||||
|
||||
public ClassificationHistoryQueryImpl(TaskanaHistoryEngineImpl internalTaskanaHistoryEngine) {
|
||||
this.taskanaHistoryEngine = internalTaskanaHistoryEngine;
|
||||
public ClassificationHistoryQueryImpl(InternalTaskanaEngine internalTaskanaEngine) {
|
||||
this.internalTaskanaEngine = internalTaskanaEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -415,16 +415,13 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
|
||||
@Override
|
||||
public List<ClassificationHistoryEvent> list() {
|
||||
List<ClassificationHistoryEvent> result = new ArrayList<>();
|
||||
List<ClassificationHistoryEvent> result;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_MAPPER, this);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_MAPPER, this);
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,15 +429,12 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
public List<ClassificationHistoryEvent> list(int offset, int limit) {
|
||||
List<ClassificationHistoryEvent> result = new ArrayList<>();
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
internalTaskanaEngine.openConnection();
|
||||
RowBounds rowBounds = new RowBounds(offset, limit);
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_MAPPER, this, rowBounds);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_MAPPER, this, rowBounds);
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,17 +448,14 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
this.addOrderCriteria(columnName.toString(), sortDirection);
|
||||
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_VALUE_MAPPER, this);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_VALUE_MAPPER, this);
|
||||
return result;
|
||||
} finally {
|
||||
this.orderBy.addAll(cacheOrderBy);
|
||||
this.columnName = null;
|
||||
this.orderColumns.remove(orderColumns.size() - 1);
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,15 +464,12 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
ClassificationHistoryEvent result = null;
|
||||
try {
|
||||
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectOne(LINK_TO_MAPPER, this);
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectOne(LINK_TO_MAPPER, this);
|
||||
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,14 +477,11 @@ public class ClassificationHistoryQueryImpl implements ClassificationHistoryQuer
|
|||
public long count() {
|
||||
Long rowCount = null;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
rowCount = taskanaHistoryEngine.getSqlSession().selectOne(LINK_TO_COUNTER, this);
|
||||
internalTaskanaEngine.openConnection();
|
||||
rowCount = internalTaskanaEngine.getSqlSession().selectOne(LINK_TO_COUNTER, this);
|
||||
return (rowCount == null) ? 0L : rowCount;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
return -1;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
package pro.taskana.simplehistory.impl;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQuery;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQueryMapper;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQuery;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQuery;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQueryMapper;
|
||||
import pro.taskana.spi.history.api.TaskanaHistory;
|
||||
import pro.taskana.spi.history.api.events.classification.ClassificationHistoryEvent;
|
||||
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
|
||||
|
@ -27,110 +34,149 @@ import pro.taskana.user.internal.UserMapper;
|
|||
public class SimpleHistoryServiceImpl implements TaskanaHistory {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleHistoryServiceImpl.class);
|
||||
private TaskanaHistoryEngineImpl taskanaHistoryEngine;
|
||||
private TaskHistoryEventMapper taskHistoryEventMapper;
|
||||
private WorkbasketHistoryEventMapper workbasketHistoryEventMapper;
|
||||
private ClassificationHistoryEventMapper classificationHistoryEventMapper;
|
||||
private UserMapper userMapper;
|
||||
|
||||
private InternalTaskanaEngine internalTaskanaEngine;
|
||||
|
||||
public void initialize(TaskanaEngine taskanaEngine) {
|
||||
|
||||
this.taskanaHistoryEngine = getTaskanaEngine(taskanaEngine);
|
||||
LOGGER.info(
|
||||
"Simple history service implementation initialized with schemaName: {} ",
|
||||
taskanaEngine.getConfiguration().getSchemaName());
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Simple history service implementation initialized with schemaName: {} ",
|
||||
taskanaEngine.getConfiguration().getSchemaName());
|
||||
Field sessionManager = null;
|
||||
try {
|
||||
Field internalTaskanaEngineImpl =
|
||||
TaskanaEngineImpl.class.getDeclaredField("internalTaskanaEngineImpl");
|
||||
internalTaskanaEngineImpl.setAccessible(true);
|
||||
this.internalTaskanaEngine =
|
||||
(InternalTaskanaEngine) internalTaskanaEngineImpl.get(taskanaEngine);
|
||||
sessionManager = TaskanaEngineImpl.class.getDeclaredField("sessionManager");
|
||||
sessionManager.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new SystemException("SQL Session could not be retrieved. Aborting Startup");
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SystemException(e.getMessage());
|
||||
}
|
||||
try {
|
||||
SqlSession sqlSession = (SqlSession) sessionManager.get(taskanaEngine);
|
||||
if (!sqlSession
|
||||
.getConfiguration()
|
||||
.getMapperRegistry()
|
||||
.hasMapper(TaskHistoryEventMapper.class)) {
|
||||
sqlSession.getConfiguration().addMapper(TaskHistoryEventMapper.class);
|
||||
}
|
||||
if (!sqlSession
|
||||
.getConfiguration()
|
||||
.getMapperRegistry()
|
||||
.hasMapper(WorkbasketHistoryEventMapper.class)) {
|
||||
|
||||
this.taskHistoryEventMapper =
|
||||
this.taskanaHistoryEngine.getSqlSession().getMapper(TaskHistoryEventMapper.class);
|
||||
this.workbasketHistoryEventMapper =
|
||||
this.taskanaHistoryEngine.getSqlSession().getMapper(WorkbasketHistoryEventMapper.class);
|
||||
this.classificationHistoryEventMapper =
|
||||
this.taskanaHistoryEngine.getSqlSession().getMapper(ClassificationHistoryEventMapper.class);
|
||||
this.userMapper = taskanaHistoryEngine.getSqlSession().getMapper(UserMapper.class);
|
||||
sqlSession.getConfiguration().addMapper(WorkbasketHistoryEventMapper.class);
|
||||
}
|
||||
if (!sqlSession
|
||||
.getConfiguration()
|
||||
.getMapperRegistry()
|
||||
.hasMapper(ClassificationHistoryEventMapper.class)) {
|
||||
|
||||
sqlSession.getConfiguration().addMapper(ClassificationHistoryEventMapper.class);
|
||||
}
|
||||
|
||||
if (!sqlSession
|
||||
.getConfiguration()
|
||||
.getMapperRegistry()
|
||||
.hasMapper(ClassificationHistoryQueryMapper.class)) {
|
||||
|
||||
sqlSession.getConfiguration().addMapper(ClassificationHistoryQueryMapper.class);
|
||||
}
|
||||
|
||||
if (!sqlSession
|
||||
.getConfiguration()
|
||||
.getMapperRegistry()
|
||||
.hasMapper(TaskHistoryQueryMapper.class)) {
|
||||
|
||||
sqlSession.getConfiguration().addMapper(TaskHistoryQueryMapper.class);
|
||||
}
|
||||
|
||||
if (!sqlSession
|
||||
.getConfiguration()
|
||||
.getMapperRegistry()
|
||||
.hasMapper(WorkbasketHistoryQueryMapper.class)) {
|
||||
|
||||
sqlSession.getConfiguration().addMapper(WorkbasketHistoryQueryMapper.class);
|
||||
}
|
||||
|
||||
this.taskHistoryEventMapper = sqlSession.getMapper(TaskHistoryEventMapper.class);
|
||||
this.workbasketHistoryEventMapper = sqlSession.getMapper(WorkbasketHistoryEventMapper.class);
|
||||
this.classificationHistoryEventMapper =
|
||||
sqlSession.getMapper(ClassificationHistoryEventMapper.class);
|
||||
this.userMapper = sqlSession.getMapper(UserMapper.class);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SystemException(
|
||||
"TASKANA engine of Session Manager could not be retrieved. Aborting Startup");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(TaskHistoryEvent event) {
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
if (event.getCreated() == null) {
|
||||
Instant now = Instant.now();
|
||||
event.setCreated(now);
|
||||
}
|
||||
taskHistoryEventMapper.insert(event);
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Error while inserting task history event into database", e);
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
|
||||
if (event.getCreated() == null) {
|
||||
Instant now = Instant.now();
|
||||
event.setCreated(now);
|
||||
}
|
||||
taskHistoryEventMapper.insert(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(WorkbasketHistoryEvent event) {
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
if (event.getCreated() == null) {
|
||||
Instant now = Instant.now();
|
||||
event.setCreated(now);
|
||||
}
|
||||
workbasketHistoryEventMapper.insert(event);
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Error while inserting workbasket history event into database", e);
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
|
||||
if (event.getCreated() == null) {
|
||||
Instant now = Instant.now();
|
||||
event.setCreated(now);
|
||||
}
|
||||
workbasketHistoryEventMapper.insert(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(ClassificationHistoryEvent event) {
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
if (event.getCreated() == null) {
|
||||
Instant now = Instant.now();
|
||||
event.setCreated(now);
|
||||
}
|
||||
classificationHistoryEventMapper.insert(event);
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Error while inserting classification history event into database", e);
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
|
||||
if (event.getCreated() == null) {
|
||||
Instant now = Instant.now();
|
||||
event.setCreated(now);
|
||||
}
|
||||
classificationHistoryEventMapper.insert(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteHistoryEventsByTaskIds(List<String> taskIds)
|
||||
throws InvalidArgumentException, NotAuthorizedException {
|
||||
taskanaHistoryEngine.checkRoleMembership(TaskanaRole.ADMIN);
|
||||
|
||||
internalTaskanaEngine.openConnection();
|
||||
internalTaskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN);
|
||||
|
||||
if (taskIds == null) {
|
||||
throw new InvalidArgumentException("List of taskIds must not be null.");
|
||||
}
|
||||
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
taskHistoryEventMapper.deleteMultipleByTaskIds(taskIds);
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Caught exception while trying to delete history events", e);
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
}
|
||||
taskHistoryEventMapper.deleteMultipleByTaskIds(taskIds);
|
||||
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
|
||||
public TaskHistoryEvent getTaskHistoryEvent(String historyEventId)
|
||||
throws TaskanaHistoryEventNotFoundException {
|
||||
TaskHistoryEvent resultEvent = null;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
internalTaskanaEngine.openConnection();
|
||||
resultEvent = taskHistoryEventMapper.findById(historyEventId);
|
||||
|
||||
if (resultEvent == null) {
|
||||
throw new TaskanaHistoryEventNotFoundException(historyEventId);
|
||||
}
|
||||
|
||||
if (taskanaHistoryEngine.getConfiguration().isAddAdditionalUserInfo()) {
|
||||
if (internalTaskanaEngine.getEngine().getConfiguration().isAddAdditionalUserInfo()) {
|
||||
User user = userMapper.findById(resultEvent.getUserId());
|
||||
if (user != null) {
|
||||
resultEvent.setUserLongName(user.getLongName());
|
||||
|
@ -138,30 +184,20 @@ public class SimpleHistoryServiceImpl implements TaskanaHistory {
|
|||
}
|
||||
return resultEvent;
|
||||
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Caught exception while trying to retrieve a history event", e);
|
||||
return resultEvent;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public TaskHistoryQuery createTaskHistoryQuery() {
|
||||
return new TaskHistoryQueryImpl(taskanaHistoryEngine);
|
||||
return new TaskHistoryQueryImpl(internalTaskanaEngine);
|
||||
}
|
||||
|
||||
public WorkbasketHistoryQuery createWorkbasketHistoryQuery() {
|
||||
return new WorkbasketHistoryQueryImpl(taskanaHistoryEngine);
|
||||
return new WorkbasketHistoryQueryImpl(internalTaskanaEngine);
|
||||
}
|
||||
|
||||
public ClassificationHistoryQuery createClassificationHistoryQuery() {
|
||||
return new ClassificationHistoryQueryImpl(taskanaHistoryEngine);
|
||||
}
|
||||
|
||||
/*
|
||||
* ATTENTION: This method exists for testing purposes.
|
||||
*/
|
||||
TaskanaHistoryEngineImpl getTaskanaEngine(TaskanaEngine taskanaEngine) {
|
||||
return TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngine);
|
||||
return new ClassificationHistoryQueryImpl(internalTaskanaEngine);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package pro.taskana.simplehistory.impl;
|
|||
|
||||
import static pro.taskana.common.api.BaseQuery.toLowerCopy;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
@ -10,6 +9,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQuery;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryColumnName;
|
||||
import pro.taskana.spi.history.api.events.task.TaskHistoryCustomField;
|
||||
|
@ -30,7 +30,7 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
private static final String SQL_EXCEPTION_MESSAGE =
|
||||
"Method openConnection() could not open a connection to the database.";
|
||||
|
||||
private final TaskanaHistoryEngineImpl taskanaHistoryEngine;
|
||||
private final InternalTaskanaEngine internalTaskanaEngine;
|
||||
private final List<String> orderBy;
|
||||
private final List<String> orderColumns;
|
||||
private boolean joinWithUserInfo;
|
||||
|
@ -83,11 +83,12 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
private String[] custom3Like;
|
||||
private String[] custom4Like;
|
||||
|
||||
public TaskHistoryQueryImpl(TaskanaHistoryEngineImpl taskanaHistoryEngine) {
|
||||
this.taskanaHistoryEngine = taskanaHistoryEngine;
|
||||
public TaskHistoryQueryImpl(InternalTaskanaEngine internalTaskanaEngine) {
|
||||
this.internalTaskanaEngine = internalTaskanaEngine;
|
||||
this.orderBy = new ArrayList<>();
|
||||
this.orderColumns = new ArrayList<>();
|
||||
this.joinWithUserInfo = taskanaHistoryEngine.getConfiguration().isAddAdditionalUserInfo();
|
||||
this.joinWithUserInfo =
|
||||
internalTaskanaEngine.getEngine().getConfiguration().isAddAdditionalUserInfo();
|
||||
}
|
||||
|
||||
public String[] getIdIn() {
|
||||
|
@ -631,14 +632,11 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
public List<TaskHistoryEvent> list() {
|
||||
List<TaskHistoryEvent> result = new ArrayList<>();
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_MAPPER, this);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_MAPPER, this);
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,15 +644,12 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
public List<TaskHistoryEvent> list(int offset, int limit) {
|
||||
List<TaskHistoryEvent> result = new ArrayList<>();
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
internalTaskanaEngine.openConnection();
|
||||
RowBounds rowBounds = new RowBounds(offset, limit);
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_MAPPER, this, rowBounds);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_MAPPER, this, rowBounds);
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,15 +667,12 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
}
|
||||
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_VALUE_MAPPER, this);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_VALUE_MAPPER, this);
|
||||
return result;
|
||||
} finally {
|
||||
this.orderColumns.remove(orderColumns.size() - 1);
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -688,16 +680,13 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
public TaskHistoryEvent single() {
|
||||
TaskHistoryEvent result = null;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectOne(LINK_TO_MAPPER, this);
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectOne(LINK_TO_MAPPER, this);
|
||||
|
||||
return result;
|
||||
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -705,14 +694,11 @@ public class TaskHistoryQueryImpl implements TaskHistoryQuery {
|
|||
public long count() {
|
||||
Long rowCount;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
rowCount = taskanaHistoryEngine.getSqlSession().selectOne(LINK_TO_COUNTER, this);
|
||||
internalTaskanaEngine.openConnection();
|
||||
rowCount = internalTaskanaEngine.getSqlSession().selectOne(LINK_TO_COUNTER, this);
|
||||
return (rowCount == null) ? 0L : rowCount;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
return -1;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,255 +0,0 @@
|
|||
package pro.taskana.simplehistory.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
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.apache.ibatis.type.JdbcType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import pro.taskana.TaskanaConfiguration;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.OracleSqlSessionFactory;
|
||||
import pro.taskana.common.internal.configuration.DB;
|
||||
import pro.taskana.common.internal.persistence.InstantTypeHandler;
|
||||
import pro.taskana.common.internal.persistence.MapTypeHandler;
|
||||
import pro.taskana.common.internal.persistence.StringTypeHandler;
|
||||
import pro.taskana.simplehistory.TaskanaHistoryEngine;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryQueryMapper;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQueryMapper;
|
||||
import pro.taskana.spi.history.api.TaskanaHistory;
|
||||
import pro.taskana.user.internal.UserMapper;
|
||||
|
||||
/** This is the implementation of TaskanaHistoryEngine. */
|
||||
public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {
|
||||
|
||||
protected static final ThreadLocal<Deque<SqlSessionManager>> SESSION_STACK = new ThreadLocal<>();
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaHistoryEngineImpl.class);
|
||||
private static final String DEFAULT = "default";
|
||||
private final SqlSessionManager sessionManager;
|
||||
private final TaskanaConfiguration taskanaConfiguration;
|
||||
private final TaskanaEngine taskanaEngine;
|
||||
private TransactionFactory transactionFactory;
|
||||
private TaskanaHistory taskanaHistoryService;
|
||||
|
||||
protected TaskanaHistoryEngineImpl(TaskanaEngine taskanaEngine) {
|
||||
this.taskanaConfiguration = taskanaEngine.getConfiguration();
|
||||
this.taskanaEngine = taskanaEngine;
|
||||
|
||||
createTransactionFactory(taskanaConfiguration.isUseManagedTransactions());
|
||||
sessionManager = createSqlSessionManager();
|
||||
}
|
||||
|
||||
public static TaskanaHistoryEngineImpl createTaskanaEngine(TaskanaEngine taskanaEngine) {
|
||||
return new TaskanaHistoryEngineImpl(taskanaEngine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskanaHistory getTaskanaHistoryService() {
|
||||
if (taskanaHistoryService == null) {
|
||||
SimpleHistoryServiceImpl historyService = new SimpleHistoryServiceImpl();
|
||||
historyService.initialize(taskanaEngine);
|
||||
taskanaHistoryService = historyService;
|
||||
}
|
||||
return taskanaHistoryService;
|
||||
}
|
||||
|
||||
public boolean isUserInRole(TaskanaRole... roles) {
|
||||
if (!getConfiguration().isSecurityEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Set<String> rolesMembers =
|
||||
Arrays.stream(roles)
|
||||
.map(role -> getConfiguration().getRoleMap().get(role))
|
||||
.collect(HashSet::new, Set::addAll, Set::addAll);
|
||||
|
||||
return taskanaEngine.getCurrentUserContext().getAccessIds().stream()
|
||||
.anyMatch(rolesMembers::contains);
|
||||
}
|
||||
|
||||
public void checkRoleMembership(TaskanaRole... roles) throws NotAuthorizedException {
|
||||
if (!isUserInRole(roles)) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Throwing NotAuthorizedException because accessIds {} are not member of roles {}",
|
||||
taskanaEngine.getCurrentUserContext().getAccessIds(),
|
||||
Arrays.toString(roles));
|
||||
}
|
||||
throw new NotAuthorizedException(taskanaEngine.getCurrentUserContext().getUserid(), roles);
|
||||
}
|
||||
}
|
||||
|
||||
public TaskanaConfiguration getConfiguration() {
|
||||
return this.taskanaConfiguration;
|
||||
}
|
||||
|
||||
protected SqlSessionManager createSqlSessionManager() {
|
||||
Environment environment =
|
||||
new Environment(DEFAULT, this.transactionFactory, taskanaConfiguration.getDataSource());
|
||||
Configuration configuration = new Configuration(environment);
|
||||
|
||||
// set databaseId
|
||||
DB db;
|
||||
try (Connection con = taskanaConfiguration.getDataSource().getConnection()) {
|
||||
db = DB.getDB(con);
|
||||
configuration.setDatabaseId(db.dbProductId);
|
||||
} catch (SQLException e) {
|
||||
throw new SystemException("Could not open a connection to set the databaseId", e);
|
||||
}
|
||||
|
||||
// register type handlers
|
||||
if (DB.ORACLE == db) {
|
||||
// Use NULL instead of OTHER when jdbcType is not specified for null values,
|
||||
// otherwise oracle driver will chunck on null values
|
||||
configuration.setJdbcTypeForNull(JdbcType.NULL);
|
||||
configuration.getTypeHandlerRegistry().register(String.class, new StringTypeHandler());
|
||||
}
|
||||
configuration.getTypeHandlerRegistry().register(new MapTypeHandler());
|
||||
configuration.getTypeHandlerRegistry().register(Instant.class, new InstantTypeHandler());
|
||||
configuration.getTypeHandlerRegistry().register(JdbcType.TIMESTAMP, new InstantTypeHandler());
|
||||
|
||||
// add mappers
|
||||
configuration.addMapper(TaskHistoryEventMapper.class);
|
||||
configuration.addMapper(TaskHistoryQueryMapper.class);
|
||||
configuration.addMapper(WorkbasketHistoryEventMapper.class);
|
||||
configuration.addMapper(WorkbasketHistoryQueryMapper.class);
|
||||
configuration.addMapper(ClassificationHistoryEventMapper.class);
|
||||
configuration.addMapper(ClassificationHistoryQueryMapper.class);
|
||||
configuration.addMapper(UserMapper.class);
|
||||
|
||||
SqlSessionFactory localSessionFactory;
|
||||
if (DB.ORACLE == db) {
|
||||
localSessionFactory =
|
||||
new SqlSessionFactoryBuilder() {
|
||||
@Override
|
||||
public SqlSessionFactory build(Configuration config) {
|
||||
return new OracleSqlSessionFactory(config);
|
||||
}
|
||||
}.build(configuration);
|
||||
} else {
|
||||
localSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
|
||||
}
|
||||
return SqlSessionManager.newInstance(localSessionFactory);
|
||||
}
|
||||
|
||||
protected static void pushSessionToStack(SqlSessionManager session) {
|
||||
getSessionStack().push(session);
|
||||
}
|
||||
|
||||
protected static void popSessionFromStack() {
|
||||
Deque<SqlSessionManager> stack = getSessionStack();
|
||||
if (!stack.isEmpty()) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Deque<SqlSessionManager> getSessionStack() {
|
||||
Deque<SqlSessionManager> stack = SESSION_STACK.get();
|
||||
if (stack == null) {
|
||||
stack = new ArrayDeque<>();
|
||||
SESSION_STACK.set(stack);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
protected static SqlSessionManager getSessionFromStack() {
|
||||
Deque<SqlSessionManager> stack = getSessionStack();
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return stack.peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the connection to the database. to be called at the begin of each Api call that accesses
|
||||
* the database
|
||||
*
|
||||
* @throws SQLException thrown if the connection could not be opened.
|
||||
*/
|
||||
void openConnection() throws SQLException {
|
||||
initSqlSession();
|
||||
this.sessionManager.getConnection().setSchema(taskanaConfiguration.getSchemaName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
popSessionFromStack();
|
||||
if (getSessionStack().isEmpty()
|
||||
&& this.sessionManager != null
|
||||
&& this.sessionManager.isManagedSessionStarted()) {
|
||||
try {
|
||||
this.sessionManager.commit();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
this.sessionManager.close();
|
||||
}
|
||||
}
|
||||
|
||||
/** Initializes the SqlSessionManager. */
|
||||
void initSqlSession() {
|
||||
this.sessionManager.startManagedSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the SqlSession used by taskana.
|
||||
*
|
||||
* @return the myBatis SqlSession object used by taskana
|
||||
*/
|
||||
SqlSession getSqlSession() {
|
||||
return this.sessionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the MyBatis transaction factory.
|
||||
*
|
||||
* @param useManagedTransactions true if TASKANA should use a ManagedTransactionFactory.
|
||||
*/
|
||||
private void createTransactionFactory(boolean useManagedTransactions) {
|
||||
if (useManagedTransactions) {
|
||||
this.transactionFactory = new ManagedTransactionFactory();
|
||||
} else {
|
||||
this.transactionFactory = new JdbcTransactionFactory();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package pro.taskana.simplehistory.impl;
|
|||
|
||||
import static pro.taskana.common.api.BaseQuery.toLowerCopy;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
@ -11,6 +10,7 @@ import org.slf4j.LoggerFactory;
|
|||
import pro.taskana.common.api.TimeInterval;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQuery;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryQueryColumnName;
|
||||
import pro.taskana.spi.history.api.events.workbasket.WorkbasketHistoryEvent;
|
||||
|
@ -30,7 +30,7 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
private static final String SQL_EXCEPTION_MESSAGE =
|
||||
"Method openConnection() could not open a connection to the database.";
|
||||
|
||||
private final TaskanaHistoryEngineImpl taskanaHistoryEngine;
|
||||
private final InternalTaskanaEngine internalTaskanaEngine;
|
||||
private final List<String> orderColumns;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -71,8 +71,8 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
private String[] orgLevel3Like;
|
||||
private String[] orgLevel4Like;
|
||||
|
||||
public WorkbasketHistoryQueryImpl(TaskanaHistoryEngineImpl internalTaskanaHistoryEngine) {
|
||||
this.taskanaHistoryEngine = internalTaskanaHistoryEngine;
|
||||
public WorkbasketHistoryQueryImpl(InternalTaskanaEngine internalTaskanaEngine) {
|
||||
this.internalTaskanaEngine = internalTaskanaEngine;
|
||||
this.orderBy = new ArrayList<>();
|
||||
this.orderColumns = new ArrayList<>();
|
||||
}
|
||||
|
@ -475,14 +475,11 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
public List<WorkbasketHistoryEvent> list() {
|
||||
List<WorkbasketHistoryEvent> result = new ArrayList<>();
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_MAPPER, this);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_MAPPER, this);
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,15 +487,12 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
public List<WorkbasketHistoryEvent> list(int offset, int limit) {
|
||||
List<WorkbasketHistoryEvent> result = new ArrayList<>();
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
internalTaskanaEngine.openConnection();
|
||||
RowBounds rowBounds = new RowBounds(offset, limit);
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_MAPPER, this, rowBounds);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_MAPPER, this, rowBounds);
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,17 +506,14 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
this.addOrderCriteria(columnName.toString(), sortDirection);
|
||||
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectList(LINK_TO_VALUE_MAPPER, this);
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectList(LINK_TO_VALUE_MAPPER, this);
|
||||
return result;
|
||||
} finally {
|
||||
this.orderBy = cacheOrderBy;
|
||||
this.columnName = null;
|
||||
this.orderColumns.remove(orderColumns.size() - 1);
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,15 +521,12 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
public WorkbasketHistoryEvent single() {
|
||||
WorkbasketHistoryEvent result = null;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
result = taskanaHistoryEngine.getSqlSession().selectOne(LINK_TO_MAPPER, this);
|
||||
internalTaskanaEngine.openConnection();
|
||||
result = internalTaskanaEngine.getSqlSession().selectOne(LINK_TO_MAPPER, this);
|
||||
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
return result;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,14 +534,11 @@ public class WorkbasketHistoryQueryImpl implements WorkbasketHistoryQuery {
|
|||
public long count() {
|
||||
Long rowCount;
|
||||
try {
|
||||
taskanaHistoryEngine.openConnection();
|
||||
rowCount = taskanaHistoryEngine.getSqlSession().selectOne(LINK_TO_COUNTER, this);
|
||||
internalTaskanaEngine.openConnection();
|
||||
rowCount = internalTaskanaEngine.getSqlSession().selectOne(LINK_TO_COUNTER, this);
|
||||
return (rowCount == null) ? 0L : rowCount;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error(SQL_EXCEPTION_MESSAGE, e.getCause());
|
||||
return -1;
|
||||
} finally {
|
||||
taskanaHistoryEngine.returnConnection();
|
||||
internalTaskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,32 +25,31 @@ import pro.taskana.common.internal.jobs.AbstractTaskanaJob;
|
|||
import pro.taskana.common.internal.transaction.TaskanaTransactionProvider;
|
||||
import pro.taskana.common.internal.util.CollectionUtil;
|
||||
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
|
||||
import pro.taskana.simplehistory.impl.TaskanaHistoryEngineImpl;
|
||||
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
|
||||
import pro.taskana.spi.history.api.events.task.TaskHistoryEventType;
|
||||
|
||||
public class HistoryCleanupJob extends AbstractTaskanaJob {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HistoryCleanupJob.class);
|
||||
|
||||
private final TaskanaHistoryEngineImpl taskanaHistoryEngine =
|
||||
TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngineImpl);
|
||||
|
||||
private final boolean allCompletedSameParentBusiness =
|
||||
taskanaEngineImpl
|
||||
.getConfiguration()
|
||||
.isSimpleHistoryCleanupJobAllCompletedSameParentBusiness();
|
||||
|
||||
private final Duration minimumAge =
|
||||
taskanaEngineImpl.getConfiguration().getSimpleHistoryCleanupJobMinimumAge();
|
||||
private final int batchSize =
|
||||
taskanaEngineImpl.getConfiguration().getSimpleHistoryCleanupJobBatchSize();
|
||||
private SimpleHistoryServiceImpl simpleHistoryService = null;
|
||||
|
||||
public HistoryCleanupJob(
|
||||
TaskanaEngine taskanaEngine,
|
||||
TaskanaTransactionProvider txProvider,
|
||||
ScheduledJob scheduledJob) {
|
||||
super(taskanaEngine, txProvider, scheduledJob, true);
|
||||
if (simpleHistoryService == null) {
|
||||
simpleHistoryService = new SimpleHistoryServiceImpl();
|
||||
simpleHistoryService.initialize(taskanaEngine);
|
||||
}
|
||||
}
|
||||
|
||||
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
|
||||
|
@ -62,9 +61,6 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
|
|||
Instant createdBefore = Instant.now().minus(minimumAge);
|
||||
LOGGER.info("Running job to delete all history events created before ({})", createdBefore);
|
||||
try {
|
||||
SimpleHistoryServiceImpl simpleHistoryService =
|
||||
(SimpleHistoryServiceImpl) taskanaHistoryEngine.getTaskanaHistoryService();
|
||||
|
||||
List<TaskHistoryEvent> historyEventCandidatesToClean =
|
||||
simpleHistoryService
|
||||
.createTaskHistoryQuery()
|
||||
|
@ -181,9 +177,6 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
|
|||
|
||||
private int deleteEvents(List<String> taskIdsToDeleteHistoryEventsFor)
|
||||
throws InvalidArgumentException, NotAuthorizedException {
|
||||
SimpleHistoryServiceImpl simpleHistoryService =
|
||||
(SimpleHistoryServiceImpl) taskanaHistoryEngine.getTaskanaHistoryService();
|
||||
|
||||
int deletedTasksCount =
|
||||
(int)
|
||||
simpleHistoryService
|
||||
|
|
|
@ -19,7 +19,6 @@ import pro.taskana.common.internal.util.IdGenerator;
|
|||
import pro.taskana.common.test.config.DataSourceGenerator;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
|
||||
import pro.taskana.simplehistory.impl.TaskanaHistoryEngineImpl;
|
||||
import pro.taskana.simplehistory.impl.classification.ClassificationHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryEventMapper;
|
||||
|
@ -33,7 +32,6 @@ import pro.taskana.task.internal.models.ObjectReferenceImpl;
|
|||
public abstract class AbstractAccTest {
|
||||
|
||||
protected static TaskanaConfiguration taskanaConfiguration;
|
||||
protected static TaskanaHistoryEngineImpl taskanaHistoryEngine;
|
||||
protected static TaskanaEngine taskanaEngine;
|
||||
protected static SimpleHistoryServiceImpl historyService;
|
||||
|
||||
|
@ -116,7 +114,6 @@ public abstract class AbstractAccTest {
|
|||
taskanaConfiguration = configuration;
|
||||
taskanaEngine =
|
||||
TaskanaEngine.buildTaskanaEngine(taskanaConfiguration, ConnectionManagementMode.AUTOCOMMIT);
|
||||
taskanaHistoryEngine = TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngine);
|
||||
taskService = taskanaEngine.getTaskService();
|
||||
historyService = new SimpleHistoryServiceImpl();
|
||||
historyService.initialize(taskanaEngine);
|
||||
|
@ -129,10 +126,10 @@ public abstract class AbstractAccTest {
|
|||
protected TaskHistoryQueryMapper getHistoryQueryMapper()
|
||||
throws NoSuchFieldException, IllegalAccessException {
|
||||
|
||||
Field sessionManagerField = TaskanaHistoryEngineImpl.class.getDeclaredField("sessionManager");
|
||||
Field sessionManagerField = TaskanaEngineImpl.class.getDeclaredField("sessionManager");
|
||||
sessionManagerField.setAccessible(true);
|
||||
SqlSessionManager sqlSessionManager =
|
||||
(SqlSessionManager) sessionManagerField.get(taskanaHistoryEngine);
|
||||
(SqlSessionManager) sessionManagerField.get(taskanaEngine);
|
||||
|
||||
return sqlSessionManager.getMapper(TaskHistoryQueryMapper.class);
|
||||
}
|
||||
|
@ -160,32 +157,32 @@ public abstract class AbstractAccTest {
|
|||
|
||||
protected static WorkbasketHistoryEventMapper getWorkbasketHistoryEventMapper() {
|
||||
try {
|
||||
Field sessionManager = TaskanaHistoryEngineImpl.class.getDeclaredField("sessionManager");
|
||||
Field sessionManager = TaskanaEngineImpl.class.getDeclaredField("sessionManager");
|
||||
sessionManager.setAccessible(true);
|
||||
SqlSessionManager manager = (SqlSessionManager) sessionManager.get(taskanaHistoryEngine);
|
||||
SqlSessionManager manager = (SqlSessionManager) sessionManager.get(taskanaEngine);
|
||||
return manager.getMapper(WorkbasketHistoryEventMapper.class);
|
||||
} catch (Exception e) {
|
||||
throw new JUnitException(
|
||||
String.format(
|
||||
"Could not extract %s from %s",
|
||||
WorkbasketHistoryEventMapper.class, TaskanaHistoryEngineImpl.class));
|
||||
WorkbasketHistoryEventMapper.class, TaskanaEngineImpl.class));
|
||||
}
|
||||
}
|
||||
|
||||
protected static ClassificationHistoryEventMapper getClassificationHistoryEventMapper() {
|
||||
try {
|
||||
Field sessionManager = TaskanaHistoryEngineImpl.class.getDeclaredField("sessionManager");
|
||||
Field sessionManager = TaskanaEngineImpl.class.getDeclaredField("sessionManager");
|
||||
|
||||
sessionManager.setAccessible(true);
|
||||
|
||||
SqlSessionManager manager = (SqlSessionManager) sessionManager.get(taskanaHistoryEngine);
|
||||
SqlSessionManager manager = (SqlSessionManager) sessionManager.get(taskanaEngine);
|
||||
return manager.getMapper(ClassificationHistoryEventMapper.class);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new JUnitException(
|
||||
String.format(
|
||||
"Could not extract %s from %s",
|
||||
ClassificationHistoryEventMapper.class, TaskanaHistoryEngineImpl.class));
|
||||
ClassificationHistoryEventMapper.class, TaskanaEngineImpl.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ class CreateHistoryEventOnClassificationDeletionAccTest extends AbstractAccTest
|
|||
|
||||
final String classificationId = "CLI:200000000000000000000000000000000015";
|
||||
|
||||
taskService.createTaskQuery().list();
|
||||
historyService.deleteHistoryEventsByTaskIds(List.of("test12"));
|
||||
|
||||
List<ClassificationHistoryEvent> events =
|
||||
historyService
|
||||
.createClassificationHistoryQuery()
|
||||
|
|
|
@ -26,10 +26,10 @@ import pro.taskana.testapi.builder.TaskBuilder;
|
|||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.api.models.WorkbasketSummary;
|
||||
|
||||
@TaskanaIntegrationTest
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskanaHistory.class,
|
||||
serviceProviders = SimpleHistoryServiceImpl.class)
|
||||
@TaskanaIntegrationTest
|
||||
@ExtendWith(JaasExtension.class)
|
||||
class CreateHistoryEventOnTaskDeletionAccTest {
|
||||
@TaskanaInject TaskanaEngine taskanaEngine;
|
||||
|
@ -47,8 +47,6 @@ class CreateHistoryEventOnTaskDeletionAccTest {
|
|||
@WithAccessId(user = "admin")
|
||||
@BeforeAll
|
||||
void setUp() throws Exception {
|
||||
historyService = new SimpleHistoryServiceImpl();
|
||||
historyService.initialize(taskanaEngine);
|
||||
|
||||
defaultClassificationSummary =
|
||||
DefaultTestEntities.defaultTestClassification()
|
||||
|
@ -60,11 +58,15 @@ class CreateHistoryEventOnTaskDeletionAccTest {
|
|||
task2 = createTask().state(TaskState.COMPLETED).buildAndStore(taskService);
|
||||
task3 = createTask().state(TaskState.COMPLETED).buildAndStore(taskService);
|
||||
task4 = createTask().state(TaskState.COMPLETED).buildAndStore(taskService);
|
||||
|
||||
historyService = new SimpleHistoryServiceImpl();
|
||||
historyService.initialize(taskanaEngine);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_CreateDeleteHistoryEvent_When_TaskIsDeleted() throws Exception {
|
||||
|
||||
historyService.deleteHistoryEventsByTaskIds(List.of(task4.getId()));
|
||||
|
||||
taskService.deleteTask(task4.getId());
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.util.IdGenerator;
|
||||
import pro.taskana.spi.history.api.events.classification.ClassificationHistoryEvent;
|
||||
import pro.taskana.spi.history.api.events.classification.ClassificationHistoryEventType;
|
||||
|
@ -24,13 +25,13 @@ class ClassificationHistoryQueryImplTest {
|
|||
|
||||
private ClassificationHistoryQueryImpl historyQueryImpl;
|
||||
|
||||
@Mock private TaskanaHistoryEngineImpl taskanaHistoryEngineMock;
|
||||
@Mock private InternalTaskanaEngine internalTaskanaEngineMock;
|
||||
|
||||
@Mock private SqlSession sqlSessionMock;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
historyQueryImpl = new ClassificationHistoryQueryImpl(taskanaHistoryEngineMock);
|
||||
historyQueryImpl = new ClassificationHistoryQueryImpl(internalTaskanaEngineMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -40,9 +41,9 @@ class ClassificationHistoryQueryImplTest {
|
|||
createHistoryEvent(
|
||||
ClassificationHistoryEventType.CREATED.getName(), "admin", "someDetails"));
|
||||
|
||||
doNothing().when(taskanaHistoryEngineMock).openConnection();
|
||||
doNothing().when(taskanaHistoryEngineMock).returnConnection();
|
||||
when(taskanaHistoryEngineMock.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
doNothing().when(internalTaskanaEngineMock).openConnection();
|
||||
doNothing().when(internalTaskanaEngineMock).returnConnection();
|
||||
when(internalTaskanaEngineMock.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
when(sqlSessionMock.selectList(any(), any())).thenReturn(new ArrayList<>(returnList));
|
||||
|
||||
List<ClassificationHistoryEvent> result =
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.mockito.Spy;
|
|||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import pro.taskana.TaskanaConfiguration;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryEventMapper;
|
||||
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
|
||||
import pro.taskana.simplehistory.impl.workbasket.WorkbasketHistoryEventMapper;
|
||||
|
@ -40,13 +41,12 @@ class SimpleHistoryServiceImplTest {
|
|||
@Mock private WorkbasketHistoryEventMapper workbasketHistoryEventMapperMock;
|
||||
|
||||
@Mock private WorkbasketHistoryQueryMapper workbasketHistoryQueryMapperMock;
|
||||
|
||||
@Mock private TaskanaHistoryEngineImpl taskanaHistoryEngineMock;
|
||||
|
||||
@Mock private TaskanaConfiguration taskanaConfiguration;
|
||||
|
||||
@Mock private TaskanaEngine taskanaEngine;
|
||||
|
||||
@Mock private InternalTaskanaEngine internalTaskanaEngine;
|
||||
|
||||
@Mock private SqlSessionManager sqlSessionManagerMock;
|
||||
|
||||
@Mock private SqlSession sqlSessionMock;
|
||||
|
@ -58,9 +58,7 @@ class SimpleHistoryServiceImplTest {
|
|||
"wbKey1", "taskId1", "type1", "wbKey2", "someUserId", "someDetails");
|
||||
|
||||
cutSpy.create(expectedWb);
|
||||
verify(taskanaHistoryEngineMock, times(1)).openConnection();
|
||||
verify(taskHistoryEventMapperMock, times(1)).insert(expectedWb);
|
||||
verify(taskanaHistoryEngineMock, times(1)).returnConnection();
|
||||
assertThat(expectedWb.getCreated()).isNotNull();
|
||||
}
|
||||
|
||||
|
@ -71,9 +69,7 @@ class SimpleHistoryServiceImplTest {
|
|||
"wbKey1", WorkbasketHistoryEventType.CREATED.getName(), "someUserId", "someDetails");
|
||||
|
||||
cutSpy.create(expectedEvent);
|
||||
verify(taskanaHistoryEngineMock, times(1)).openConnection();
|
||||
verify(workbasketHistoryEventMapperMock, times(1)).insert(expectedEvent);
|
||||
verify(taskanaHistoryEngineMock, times(1)).returnConnection();
|
||||
assertThat(expectedEvent.getCreated()).isNotNull();
|
||||
}
|
||||
|
||||
|
@ -84,20 +80,21 @@ class SimpleHistoryServiceImplTest {
|
|||
AbstractAccTest.createTaskHistoryEvent(
|
||||
"wbKey1", "taskId1", "type1", "wbKey2", "someUserId", "someDetails"));
|
||||
|
||||
when(taskanaHistoryEngineMock.getConfiguration()).thenReturn(taskanaConfiguration);
|
||||
when(taskanaConfiguration.isAddAdditionalUserInfo()).thenReturn(false);
|
||||
|
||||
when(taskanaHistoryEngineMock.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
when(internalTaskanaEngine.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
when(sqlSessionMock.selectList(any(), any())).thenReturn(new ArrayList<>(returnList));
|
||||
|
||||
when(internalTaskanaEngine.getEngine()).thenReturn(taskanaEngine);
|
||||
when(taskanaEngine.getConfiguration()).thenReturn(taskanaConfiguration);
|
||||
final List<TaskHistoryEvent> result =
|
||||
cutSpy.createTaskHistoryQuery().taskIdIn("taskId1").list();
|
||||
|
||||
verify(taskanaHistoryEngineMock, times(1)).openConnection();
|
||||
verify(taskanaHistoryEngineMock, times(1)).getSqlSession();
|
||||
verify(internalTaskanaEngine, times(1)).openConnection();
|
||||
verify(internalTaskanaEngine, times(1)).getSqlSession();
|
||||
verify(sqlSessionMock, times(1)).selectList(any(), any());
|
||||
|
||||
verify(taskanaHistoryEngineMock, times(1)).returnConnection();
|
||||
verify(internalTaskanaEngine, times(1)).returnConnection();
|
||||
assertThat(result).hasSize(returnList.size());
|
||||
assertThat(result.get(0).getWorkbasketKey()).isEqualTo(returnList.get(0).getWorkbasketKey());
|
||||
}
|
||||
|
@ -108,16 +105,15 @@ class SimpleHistoryServiceImplTest {
|
|||
returnList.add(
|
||||
AbstractAccTest.createWorkbasketHistoryEvent(
|
||||
"wbKey1", WorkbasketHistoryEventType.CREATED.getName(), "someUserId", "someDetails"));
|
||||
when(taskanaHistoryEngineMock.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
when(sqlSessionMock.selectList(any(), any())).thenReturn(new ArrayList<>(returnList));
|
||||
|
||||
when(internalTaskanaEngine.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
final List<WorkbasketHistoryEvent> result =
|
||||
cutSpy.createWorkbasketHistoryQuery().keyIn("wbKey1").list();
|
||||
|
||||
verify(taskanaHistoryEngineMock, times(1)).openConnection();
|
||||
verify(taskanaHistoryEngineMock, times(1)).getSqlSession();
|
||||
verify(internalTaskanaEngine, times(1)).openConnection();
|
||||
verify(internalTaskanaEngine, times(1)).getSqlSession();
|
||||
verify(sqlSessionMock, times(1)).selectList(any(), any());
|
||||
verify(taskanaHistoryEngineMock, times(1)).returnConnection();
|
||||
verify(internalTaskanaEngine, times(1)).returnConnection();
|
||||
assertThat(result).hasSize(returnList.size());
|
||||
assertThat(result.get(0).getKey()).isEqualTo(returnList.get(0).getKey());
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import pro.taskana.common.api.TimeInterval;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.common.internal.util.IdGenerator;
|
||||
import pro.taskana.spi.history.api.events.workbasket.WorkbasketHistoryEvent;
|
||||
import pro.taskana.spi.history.api.events.workbasket.WorkbasketHistoryEventType;
|
||||
|
@ -24,7 +25,7 @@ import pro.taskana.spi.history.api.events.workbasket.WorkbasketHistoryEventType;
|
|||
@ExtendWith(MockitoExtension.class)
|
||||
class WorkbasketHistoryQueryImplTest {
|
||||
|
||||
@Mock private TaskanaHistoryEngineImpl taskanaHistoryEngineMock;
|
||||
@Mock private InternalTaskanaEngine internalTaskanaEngineMock;
|
||||
|
||||
private WorkbasketHistoryQueryImpl historyQueryImpl;
|
||||
|
||||
|
@ -32,7 +33,7 @@ class WorkbasketHistoryQueryImplTest {
|
|||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
historyQueryImpl = new WorkbasketHistoryQueryImpl(taskanaHistoryEngineMock);
|
||||
historyQueryImpl = new WorkbasketHistoryQueryImpl(internalTaskanaEngineMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -47,9 +48,9 @@ class WorkbasketHistoryQueryImplTest {
|
|||
null));
|
||||
TimeInterval interval = new TimeInterval(Instant.now().minusNanos(1000), Instant.now());
|
||||
|
||||
doNothing().when(taskanaHistoryEngineMock).openConnection();
|
||||
doNothing().when(taskanaHistoryEngineMock).returnConnection();
|
||||
when(taskanaHistoryEngineMock.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
doNothing().when(internalTaskanaEngineMock).openConnection();
|
||||
doNothing().when(internalTaskanaEngineMock).returnConnection();
|
||||
when(internalTaskanaEngineMock.getSqlSession()).thenReturn(sqlSessionMock);
|
||||
when(sqlSessionMock.selectList(any(), any())).thenReturn(new ArrayList<>(returnList));
|
||||
|
||||
List<WorkbasketHistoryEvent> result =
|
||||
|
|
|
@ -2,7 +2,6 @@ package pro.taskana.simplehistory.rest;
|
|||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -14,7 +13,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import pro.taskana.TaskanaConfiguration;
|
||||
import pro.taskana.common.api.BaseQuery.SortDirection;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
|
@ -35,19 +33,17 @@ import pro.taskana.spi.history.api.exceptions.TaskanaHistoryEventNotFoundExcepti
|
|||
@RestController
|
||||
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
|
||||
public class TaskHistoryEventController {
|
||||
|
||||
private final SimpleHistoryServiceImpl simpleHistoryService;
|
||||
private final TaskHistoryEventRepresentationModelAssembler assembler;
|
||||
|
||||
@Autowired
|
||||
public TaskHistoryEventController(
|
||||
TaskanaConfiguration taskanaConfiguration,
|
||||
TaskanaEngine taskanaEngine,
|
||||
SimpleHistoryServiceImpl simpleHistoryServiceImpl,
|
||||
TaskHistoryEventRepresentationModelAssembler assembler)
|
||||
throws SQLException {
|
||||
TaskHistoryEventRepresentationModelAssembler assembler) {
|
||||
|
||||
this.simpleHistoryService = simpleHistoryServiceImpl;
|
||||
this.simpleHistoryService.initialize(TaskanaEngine.buildTaskanaEngine(taskanaConfiguration));
|
||||
this.simpleHistoryService.initialize(taskanaEngine);
|
||||
this.assembler = assembler;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package pro.taskana.common.api;
|
|||
|
||||
import java.sql.SQLException;
|
||||
import java.util.function.Supplier;
|
||||
import org.apache.ibatis.transaction.TransactionFactory;
|
||||
import pro.taskana.TaskanaConfiguration;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
|
@ -93,7 +94,7 @@ public interface TaskanaEngine {
|
|||
*/
|
||||
@SuppressWarnings("checkstyle:JavadocMethod")
|
||||
static TaskanaEngine buildTaskanaEngine(TaskanaConfiguration configuration) throws SQLException {
|
||||
return buildTaskanaEngine(configuration, ConnectionManagementMode.PARTICIPATE);
|
||||
return buildTaskanaEngine(configuration, ConnectionManagementMode.PARTICIPATE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +109,26 @@ public interface TaskanaEngine {
|
|||
static TaskanaEngine buildTaskanaEngine(
|
||||
TaskanaConfiguration configuration, ConnectionManagementMode connectionManagementMode)
|
||||
throws SQLException {
|
||||
return TaskanaEngineImpl.createTaskanaEngine(configuration, connectionManagementMode);
|
||||
return buildTaskanaEngine(configuration, connectionManagementMode, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an {@linkplain TaskanaEngine} based on {@linkplain TaskanaConfiguration},
|
||||
* SqlConnectionMode and TransactionFactory.
|
||||
*
|
||||
* @param configuration complete taskanaConfig to build the engine
|
||||
* @param connectionManagementMode connectionMode for the SqlSession
|
||||
* @param transactionFactory the TransactionFactory
|
||||
* @return a {@linkplain TaskanaEngineImpl}
|
||||
* @throws SQLException when the db schema could not be initialized
|
||||
*/
|
||||
static TaskanaEngine buildTaskanaEngine(
|
||||
TaskanaConfiguration configuration,
|
||||
ConnectionManagementMode connectionManagementMode,
|
||||
TransactionFactory transactionFactory)
|
||||
throws SQLException {
|
||||
return TaskanaEngineImpl.createTaskanaEngine(
|
||||
configuration, connectionManagementMode, transactionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -112,7 +112,9 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
protected Connection connection;
|
||||
|
||||
protected TaskanaEngineImpl(
|
||||
TaskanaConfiguration taskanaConfiguration, ConnectionManagementMode connectionManagementMode)
|
||||
TaskanaConfiguration taskanaConfiguration,
|
||||
ConnectionManagementMode connectionManagementMode,
|
||||
TransactionFactory transactionFactory)
|
||||
throws SQLException {
|
||||
LOGGER.info(
|
||||
"initializing TASKANA with this configuration: {} and this mode: {}",
|
||||
|
@ -146,7 +148,11 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
|
||||
currentUserContext =
|
||||
new CurrentUserContextImpl(TaskanaConfiguration.shouldUseLowerCaseForAccessIds());
|
||||
createTransactionFactory(taskanaConfiguration.isUseManagedTransactions());
|
||||
if (transactionFactory == null) {
|
||||
createTransactionFactory(taskanaConfiguration.isUseManagedTransactions());
|
||||
} else {
|
||||
this.transactionFactory = transactionFactory;
|
||||
}
|
||||
sessionManager = createSqlSessionManager();
|
||||
|
||||
initializeDbSchema(taskanaConfiguration);
|
||||
|
@ -156,7 +162,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
new TaskanaConfiguration.Builder(this.taskanaConfiguration)
|
||||
.jobSchedulerEnabled(false)
|
||||
.build();
|
||||
TaskanaEngine taskanaEngine = TaskanaEngine.buildTaskanaEngine(configuration, EXPLICIT);
|
||||
TaskanaEngine taskanaEngine =
|
||||
TaskanaEngine.buildTaskanaEngine(configuration, EXPLICIT, transactionFactory);
|
||||
RealClock clock =
|
||||
new RealClock(
|
||||
this.taskanaConfiguration.getJobSchedulerInitialStartDelay(),
|
||||
|
@ -186,9 +193,12 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
}
|
||||
|
||||
public static TaskanaEngine createTaskanaEngine(
|
||||
TaskanaConfiguration taskanaConfiguration, ConnectionManagementMode connectionManagementMode)
|
||||
TaskanaConfiguration taskanaConfiguration,
|
||||
ConnectionManagementMode connectionManagementMode,
|
||||
TransactionFactory transactionFactory)
|
||||
throws SQLException {
|
||||
return new TaskanaEngineImpl(taskanaConfiguration, connectionManagementMode);
|
||||
return new TaskanaEngineImpl(
|
||||
taskanaConfiguration, connectionManagementMode, transactionFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -246,7 +256,11 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
connection.setAutoCommit(false);
|
||||
connection.setSchema(taskanaConfiguration.getSchemaName());
|
||||
mode = EXPLICIT;
|
||||
sessionManager.startManagedSession(connection);
|
||||
if (transactionFactory.getClass().getSimpleName().equals("SpringManagedTransactionFactory")) {
|
||||
sessionManager.startManagedSession();
|
||||
} else {
|
||||
sessionManager.startManagedSession(connection);
|
||||
}
|
||||
} else if (this.connection != null) {
|
||||
closeConnection();
|
||||
}
|
||||
|
|
|
@ -10,9 +10,7 @@ public class SpringTaskanaEngineImpl extends TaskanaEngineImpl implements Spring
|
|||
public SpringTaskanaEngineImpl(
|
||||
TaskanaConfiguration taskanaConfiguration, ConnectionManagementMode mode)
|
||||
throws SQLException {
|
||||
super(taskanaConfiguration, mode);
|
||||
this.transactionFactory = new SpringManagedTransactionFactory();
|
||||
this.sessionManager = createSqlSessionManager();
|
||||
super(taskanaConfiguration, mode, new SpringManagedTransactionFactory());
|
||||
}
|
||||
|
||||
public static SpringTaskanaEngine createTaskanaEngine(
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
|||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import pro.taskana.TaskanaConfiguration;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.internal.SpringTaskanaEngine;
|
||||
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
|
||||
|
@ -44,7 +45,7 @@ public class ExampleRestConfiguration {
|
|||
@DependsOn("generateSampleData")
|
||||
public TaskanaEngine getTaskanaEngine(TaskanaConfiguration taskanaConfiguration)
|
||||
throws SQLException {
|
||||
return TaskanaEngine.buildTaskanaEngine(taskanaConfiguration);
|
||||
return SpringTaskanaEngine.buildTaskanaEngine(taskanaConfiguration);
|
||||
}
|
||||
|
||||
// only required to let the adapter example connect to the same database
|
||||
|
|
Loading…
Reference in New Issue