TSK-110: Generate workbasket level report for total count

- Add Report, ReportLine, ReportLineItem and ReportLineItemDefintion
- Create Report in TaskMonitorService by workbaskets and states
- Add unit test and integration tests
- Enable JAAS for the integration tests
This commit is contained in:
Konstantin Kläger 2017-12-18 16:08:31 +01:00 committed by Holger Hagen
parent 429b2327e4
commit 29fccd25e6
10 changed files with 909 additions and 328 deletions

View File

@ -1,51 +1,64 @@
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);
}
package pro.taskana;
import java.util.List;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.Report;
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);
/**
* Returns a {@link Report} for a given list of {@link Workbasket} objects and for a given list of {@link TaskState}
* objects.
*
* @param workbaskets
* a list of {@link Workbasket} objects
* @param states
* a list of {@link TaskState} objects
* @return a {@link Report} object
*/
Report getWorkbasketLevelReport(List<Workbasket> workbaskets, List<TaskState> states);
}

View File

@ -1,103 +1,131 @@
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));
}
}
}
}
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.Workbasket;
import pro.taskana.impl.util.LoggerUtils;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.Report;
import pro.taskana.model.ReportLine;
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));
}
}
}
@Override
public Report getWorkbasketLevelReport(List<Workbasket> workbaskets, List<TaskState> states) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("entry to getWorkbasketLevelReport(workbaskets = {})", LoggerUtils.listToString(workbaskets));
}
try {
taskanaEngineImpl.openConnection();
Report report = new Report();
report.setDetailLines(taskMonitorMapper.getDetailLinesByWorkbasketIdsAndStates(workbaskets, states));
int sumLineTotalCount = 0;
for (ReportLine reportLine : report.getDetailLines()) {
sumLineTotalCount += reportLine.getTotalCount();
}
ReportLine sumLine = new ReportLine();
sumLine.setName("SumLine");
sumLine.setTotalCount(sumLineTotalCount);
report.setSumLine(sumLine);
return report;
} finally {
taskanaEngineImpl.returnConnection();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("exit from getTaskCountByWorkbaskets().");
}
}
}
}

View File

@ -0,0 +1,35 @@
package pro.taskana.model;
import java.util.ArrayList;
import java.util.List;
/**
* A Report represents a table that consists of {@link ReportLine} objects.
*/
public class Report {
private List<ReportLine> detailLines;
private ReportLine sumLine;
public Report() {
this.detailLines = new ArrayList<>();
this.sumLine = new ReportLine();
}
public List<ReportLine> getDetailLines() {
return detailLines;
}
public void setDetailLines(List<ReportLine> detailLines) {
this.detailLines = detailLines;
}
public ReportLine getSumLine() {
return sumLine;
}
public void setSumLine(ReportLine sumLine) {
this.sumLine = sumLine;
}
}

View File

@ -0,0 +1,44 @@
package pro.taskana.model;
import java.util.ArrayList;
import java.util.List;
/**
* Each ReportLine consists of a name, a list of {@link ReportLineItem} objects and a totalCount that represents the
* count of all tasks.
*/
public class ReportLine {
private String name;
private List<ReportLineItem> lineItems;
private int totalCount;
public ReportLine() {
this.lineItems = new ArrayList<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ReportLineItem> getLineItems() {
return lineItems;
}
public void setLineItems(List<ReportLineItem> lineItems) {
this.lineItems = lineItems;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
}

View File

@ -0,0 +1,28 @@
package pro.taskana.model;
/**
* Each ReportLineItem consists of a {@link ReportLineItemDefinition} that defines the upper and lower limits of this
* item and a count value that represents the count of tasks of this item.
*/
public class ReportLineItem {
private ReportLineItemDefinition reportLineItemDefinition;
private int count;
public ReportLineItemDefinition getReportLineItemDefinition() {
return reportLineItemDefinition;
}
public void setReportLineItemDefinition(ReportLineItemDefinition reportLineItemDefinition) {
this.reportLineItemDefinition = reportLineItemDefinition;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}

View File

@ -0,0 +1,28 @@
package pro.taskana.model;
/**
* A ReportLineItemDefinition has a lower and an upper limit which subdivide the count of tasks in a workbasket into
* different sections.
*/
public class ReportLineItemDefinition {
private int lowerLimit;
private int upperLimit;
public int getLowerLimit() {
return lowerLimit;
}
public void setLowerLimit(int lowerLimit) {
this.lowerLimit = lowerLimit;
}
public int getUpperLimit() {
return upperLimit;
}
public void setUpperLimit(int upperLimit) {
this.upperLimit = upperLimit;
}
}

View File

@ -1,52 +1,66 @@
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);
}
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.Workbasket;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.ReportLine;
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);
@Select("<script>"
+ "SELECT WORKBASKET_KEY, COUNT(WORKBASKET_KEY) as counter "
+ "FROM TASK "
+ "WHERE WORKBASKET_KEY IN (<foreach collection='workbaskets' item='workbasket' separator=','>#{workbasket.key}</foreach>) "
+ "AND STATE IN (<foreach collection='status' item='state' separator=','>#{state}</foreach>) "
+ "GROUP BY WORKBASKET_KEY"
+ "</script>")
@Results({ @Result(column = "WORKBASKET_KEY", property = "name"),
@Result(column = "counter", property = "totalCount") })
List<ReportLine> getDetailLinesByWorkbasketIdsAndStates(@Param("workbaskets") List<Workbasket> workbaskets,
@Param("status") List<TaskState> states);
}

View File

@ -1,122 +1,146 @@
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));
}
}
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.Assert;
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.Workbasket;
import pro.taskana.WorkbasketService;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.model.DueWorkbasketCounter;
import pro.taskana.model.Report;
import pro.taskana.model.ReportLine;
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));
}
@Test
public void testGetWorkbasketLevelReport() {
List<Workbasket> workbaskets = Arrays.asList(new WorkbasketImpl(), new WorkbasketImpl());
List<TaskState> states = Arrays.asList(TaskState.CLAIMED, TaskState.READY);
Report expectedResult = new Report();
List<ReportLine> expectedDetailLines = new ArrayList<>();
doReturn(expectedDetailLines).when(taskMonitorMapperMock).getDetailLinesByWorkbasketIdsAndStates(any(), any());
Report actualResult = cut.getWorkbasketLevelReport(workbaskets, states);
verify(taskanaEngineImpl, times(1)).openConnection();
verify(taskMonitorMapperMock, times(1)).getDetailLinesByWorkbasketIdsAndStates(any(), any());
verify(taskanaEngineImpl, times(1)).returnConnection();
verifyNoMoreInteractions(taskanaEngineConfigurationMock, taskanaEngineMock, taskanaEngineImpl,
taskMonitorMapperMock, objectReferenceMapperMock, workbasketServiceMock);
Assert.assertNotNull(actualResult);
assertThat(actualResult.getDetailLines(), equalTo(expectedResult.getDetailLines()));
}
}

View File

@ -0,0 +1,179 @@
package pro.taskana.impl.integration;
import java.io.FileNotFoundException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import javax.security.auth.login.LoginException;
import javax.sql.DataSource;
import org.h2.store.fs.FileUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import pro.taskana.Classification;
import pro.taskana.ClassificationService;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaEngine.ConnectionManagementMode;
import pro.taskana.Workbasket;
import pro.taskana.WorkbasketService;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.ClassificationAlreadyExistException;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.InvalidWorkbasketException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskAlreadyExistException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.JunitHelper;
import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.TaskServiceImpl;
import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.WorkbasketImpl;
import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.util.IdGenerator;
import pro.taskana.model.Report;
import pro.taskana.model.TaskState;
import pro.taskana.model.WorkbasketAccessItem;
import pro.taskana.model.WorkbasketType;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
/**
* Integration Test for TaskMonitorServiceImpl transactions with connection management mode AUTOCOMMIT.
*/
@RunWith(JAASRunner.class)
public class TaskMonitorServiceImplIntAutocommitTest {
private DataSource dataSource;
private TaskServiceImpl taskServiceImpl;
private TaskanaEngineConfiguration taskanaEngineConfiguration;
private TaskanaEngine taskanaEngine;
private TaskanaEngineImpl taskanaEngineImpl;
private ClassificationService classificationService;
private WorkbasketService workBasketService;
private TaskMonitorService taskMonitorService;
@BeforeClass
public static void resetDb() throws SQLException {
DataSource ds = TaskanaEngineConfigurationTest.getDataSource();
DBCleaner cleaner = new DBCleaner();
cleaner.clearDb(ds, true);
}
@Before
public void setup() throws FileNotFoundException, SQLException, LoginException {
dataSource = TaskanaEngineConfigurationTest.getDataSource();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService();
taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
classificationService = taskanaEngine.getClassificationService();
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
workBasketService = taskanaEngine.getWorkbasketService();
taskMonitorService = taskanaEngine.getTaskMonitorService();
DBCleaner cleaner = new DBCleaner();
cleaner.clearDb(dataSource, false);
}
@WithAccessId(userName = "Elena")
@Test
public void testGetWorkbasketLevelReport() throws ClassificationAlreadyExistException, WorkbasketNotFoundException,
ClassificationNotFoundException, NotAuthorizedException, TaskAlreadyExistException, InvalidWorkbasketException,
InvalidArgumentException, TaskNotFoundException, InvalidStateException, InvalidOwnerException {
generateSampleAccessItems();
WorkbasketImpl workbasket1 = (WorkbasketImpl) workBasketService.newWorkbasket();
workbasket1.setName("wb1");
workbasket1.setId("1");
workbasket1.setKey("1");
workbasket1.setDomain("novatec");
workbasket1.setType(WorkbasketType.GROUP);
workBasketService.createWorkbasket(workbasket1);
WorkbasketImpl workbasket2 = (WorkbasketImpl) workBasketService.newWorkbasket();
workbasket2.setName("wb2");
workbasket2.setId("2");
workbasket2.setKey("2");
workbasket2.setDomain("novatec");
workbasket2.setType(WorkbasketType.GROUP);
workBasketService.createWorkbasket(workbasket2);
Classification classification = classificationService.newClassification();
classification.setKey("TEST");
classification.setDomain("novatec");
classificationService.createClassification(classification);
TaskImpl task1 = (TaskImpl) taskServiceImpl.newTask();
task1.setWorkbasketKey(workbasket1.getKey());
task1.setClassificationKey(classification.getKey());
task1.setPrimaryObjRef(JunitHelper.createDefaultObjRef());
task1 = (TaskImpl) taskServiceImpl.createTask(task1);
TaskImpl task2 = (TaskImpl) taskServiceImpl.newTask();
task2.setWorkbasketKey(workbasket2.getKey());
task2.setClassificationKey(classification.getKey());
task2.setPrimaryObjRef(JunitHelper.createDefaultObjRef());
task2 = (TaskImpl) taskServiceImpl.createTask(task2);
TaskImpl task3 = (TaskImpl) taskServiceImpl.newTask();
task3.setWorkbasketKey(workbasket2.getKey());
task3.setClassificationKey(classification.getKey());
task3.setPrimaryObjRef(JunitHelper.createDefaultObjRef());
task3 = (TaskImpl) taskServiceImpl.createTask(task3);
List<Workbasket> workbaskets = Arrays.asList(workbasket1, workbasket2);
List<TaskState> states = Arrays.asList(TaskState.READY, TaskState.CLAIMED);
Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states);
int countWorkbasket1 = report.getDetailLines().get(0).getTotalCount();
int countWorkbasket2 = report.getDetailLines().get(1).getTotalCount();
int totalCount = report.getSumLine().getTotalCount();
Assert.assertNotNull(report);
Assert.assertEquals(countWorkbasket1, 1);
Assert.assertEquals(countWorkbasket2, 2);
Assert.assertEquals(countWorkbasket1 + countWorkbasket2, totalCount);
}
private void generateSampleAccessItems() {
WorkbasketAccessItem accessItem = new WorkbasketAccessItem();
accessItem.setId(IdGenerator.generateWithPrefix("WAI"));
accessItem.setWorkbasketKey("1");
accessItem.setAccessId("Elena");
accessItem.setPermAppend(true);
accessItem.setPermRead(true);
workBasketService.createWorkbasketAuthorization(accessItem);
WorkbasketAccessItem accessItem2 = new WorkbasketAccessItem();
accessItem2.setId(IdGenerator.generateWithPrefix("WAI"));
accessItem2.setWorkbasketKey("2");
accessItem2.setAccessId("Elena");
accessItem2.setPermAppend(true);
accessItem2.setPermRead(true);
workBasketService.createWorkbasketAuthorization(accessItem2);
}
@After
public void cleanUp() {
taskanaEngineImpl.setConnection(null);
}
@AfterClass
public static void cleanUpClass() {
FileUtils.deleteRecursive("~/data", true);
}
}

View File

@ -0,0 +1,188 @@
package pro.taskana.impl.integration;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import javax.security.auth.login.LoginException;
import javax.sql.DataSource;
import org.h2.store.fs.FileUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import pro.taskana.Classification;
import pro.taskana.ClassificationService;
import pro.taskana.TaskMonitorService;
import pro.taskana.TaskanaEngine;
import pro.taskana.TaskanaEngine.ConnectionManagementMode;
import pro.taskana.Workbasket;
import pro.taskana.WorkbasketService;
import pro.taskana.configuration.TaskanaEngineConfiguration;
import pro.taskana.exceptions.ClassificationAlreadyExistException;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.InvalidOwnerException;
import pro.taskana.exceptions.InvalidStateException;
import pro.taskana.exceptions.InvalidWorkbasketException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.exceptions.TaskAlreadyExistException;
import pro.taskana.exceptions.TaskNotFoundException;
import pro.taskana.exceptions.WorkbasketNotFoundException;
import pro.taskana.impl.JunitHelper;
import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.TaskServiceImpl;
import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.WorkbasketImpl;
import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
import pro.taskana.impl.util.IdGenerator;
import pro.taskana.model.Report;
import pro.taskana.model.TaskState;
import pro.taskana.model.WorkbasketAccessItem;
import pro.taskana.model.WorkbasketType;
import pro.taskana.security.JAASRunner;
import pro.taskana.security.WithAccessId;
/**
* Integration Test for TaskMonitorServiceImpl transactions with connection management mode EXPLICIT.
*/
@RunWith(JAASRunner.class)
public class TaskMonitorServiceImplIntExplicitTest {
private DataSource dataSource;
private TaskServiceImpl taskServiceImpl;
private TaskanaEngineConfiguration taskanaEngineConfiguration;
private TaskanaEngine taskanaEngine;
private TaskanaEngineImpl taskanaEngineImpl;
private ClassificationService classificationService;
private WorkbasketService workBasketService;
private TaskMonitorService taskMonitorService;
@BeforeClass
public static void resetDb() throws SQLException {
DataSource ds = TaskanaEngineConfigurationTest.getDataSource();
DBCleaner cleaner = new DBCleaner();
cleaner.clearDb(ds, true);
}
@Before
public void setup() throws FileNotFoundException, SQLException, LoginException {
dataSource = TaskanaEngineConfigurationTest.getDataSource();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskServiceImpl = (TaskServiceImpl) taskanaEngine.getTaskService();
taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine;
classificationService = taskanaEngine.getClassificationService();
taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT);
workBasketService = taskanaEngine.getWorkbasketService();
DBCleaner cleaner = new DBCleaner();
cleaner.clearDb(dataSource, false);
}
@WithAccessId(userName = "Elena")
@Test
public void testGetWorkbasketLevelReport() throws SQLException, ClassificationAlreadyExistException,
WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, TaskNotFoundException,
TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, InvalidOwnerException,
InvalidStateException {
Connection connection = dataSource.getConnection();
taskanaEngineImpl.setConnection(connection);
taskMonitorService = taskanaEngine.getTaskMonitorService();
generateSampleAccessItems();
WorkbasketImpl workbasket1 = (WorkbasketImpl) workBasketService.newWorkbasket();
workbasket1.setName("wb1");
workbasket1.setId("1");
workbasket1.setKey("1");
workbasket1.setDomain("novatec");
workbasket1.setType(WorkbasketType.GROUP);
workBasketService.createWorkbasket(workbasket1);
WorkbasketImpl workbasket2 = (WorkbasketImpl) workBasketService.newWorkbasket();
workbasket2.setName("wb2");
workbasket2.setId("2");
workbasket2.setKey("2");
workbasket2.setDomain("novatec");
workbasket2.setType(WorkbasketType.GROUP);
workBasketService.createWorkbasket(workbasket2);
Classification classification = classificationService.newClassification();
classification.setKey("TEST");
classification.setDomain("novatec");
classificationService.createClassification(classification);
TaskImpl task1 = (TaskImpl) taskServiceImpl.newTask();
task1.setWorkbasketKey(workbasket1.getKey());
task1.setClassificationKey(classification.getKey());
task1.setPrimaryObjRef(JunitHelper.createDefaultObjRef());
task1 = (TaskImpl) taskServiceImpl.createTask(task1);
connection.commit();
TaskImpl task2 = (TaskImpl) taskServiceImpl.newTask();
task2.setWorkbasketKey(workbasket2.getId());
task2.setClassificationKey(classification.getKey());
task2.setPrimaryObjRef(JunitHelper.createDefaultObjRef());
task2 = (TaskImpl) taskServiceImpl.createTask(task2);
connection.commit();
TaskImpl task3 = (TaskImpl) taskServiceImpl.newTask();
task3.setWorkbasketKey(workbasket2.getId());
task3.setClassificationKey(classification.getKey());
task3.setPrimaryObjRef(JunitHelper.createDefaultObjRef());
task3 = (TaskImpl) taskServiceImpl.createTask(task3);
connection.commit();
List<Workbasket> workbaskets = Arrays.asList(workbasket1, workbasket2);
List<TaskState> states = Arrays.asList(TaskState.READY, TaskState.CLAIMED);
Report report = taskMonitorService.getWorkbasketLevelReport(workbaskets, states);
int countWorkbasket1 = report.getDetailLines().get(0).getTotalCount();
int countWorkbasket2 = report.getDetailLines().get(1).getTotalCount();
int totalCount = report.getSumLine().getTotalCount();
Assert.assertNotNull(report);
Assert.assertEquals(countWorkbasket1, 1);
Assert.assertEquals(countWorkbasket2, 2);
Assert.assertEquals(countWorkbasket1 + countWorkbasket2, totalCount);
connection.commit();
}
private void generateSampleAccessItems() {
WorkbasketAccessItem accessItem = new WorkbasketAccessItem();
accessItem.setId(IdGenerator.generateWithPrefix("WAI"));
accessItem.setWorkbasketKey("1");
accessItem.setAccessId("Elena");
accessItem.setPermAppend(true);
accessItem.setPermRead(true);
workBasketService.createWorkbasketAuthorization(accessItem);
WorkbasketAccessItem accessItem2 = new WorkbasketAccessItem();
accessItem2.setId(IdGenerator.generateWithPrefix("WAI"));
accessItem2.setWorkbasketKey("2");
accessItem2.setAccessId("Elena");
accessItem2.setPermAppend(true);
accessItem2.setPermRead(true);
workBasketService.createWorkbasketAuthorization(accessItem2);
}
@After
public void cleanUp() {
taskanaEngineImpl.setConnection(null);
}
@AfterClass
public static void cleanUpClass() {
FileUtils.deleteRecursive("~/data", true);
}
}