diff --git a/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMapper.java b/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMapper.java index 07b89d4d0..4190ca327 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/mappings/TaskMapper.java @@ -12,7 +12,6 @@ import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; -import org.apache.ibatis.type.ClobTypeHandler; import org.apache.ibatis.type.JdbcType; import pro.taskana.TaskState; @@ -225,11 +224,4 @@ public interface TaskMapper { void updateClassificationCategoryOnChange(@Param("taskIds") List taskIds, @Param("newCategory") String newCategory); - @Select("select CUSTOM_ATTRIBUTES from task where id = #{taskId}") - @Results(value = { - @Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB, - javaType = String.class, typeHandler = ClobTypeHandler.class) - }) - String getCustomAttributesAsString(@Param("taskId") String taskId); - } diff --git a/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java index f5daf9513..e72297937 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/CreateTaskAccTest.java @@ -10,6 +10,7 @@ import static org.junit.Assert.fail; import java.sql.SQLException; import java.util.Map; +import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSession; import org.h2.store.fs.FileUtils; import org.junit.AfterClass; @@ -30,11 +31,11 @@ import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; import pro.taskana.exceptions.WorkbasketNotFoundException; -import pro.taskana.security.CurrentUserContext; import pro.taskana.impl.TaskanaEngineImpl; import pro.taskana.impl.TaskanaEngineProxyForTest; import pro.taskana.mappings.AttachmentMapper; -import pro.taskana.mappings.TaskMapper; +import pro.taskana.mappings.TaskTestMapper; +import pro.taskana.security.CurrentUserContext; import pro.taskana.security.JAASRunner; import pro.taskana.security.WithAccessId; @@ -115,7 +116,12 @@ public class CreateTaskAccTest extends AbstractAccTest { TaskanaEngineProxyForTest engineProxy = new TaskanaEngineProxyForTest((TaskanaEngineImpl) taskanaEngine); try { SqlSession session = engineProxy.getSqlSession(); - TaskMapper mapper = session.getMapper(TaskMapper.class); + Configuration config = session.getConfiguration(); + if (!config.hasMapper(TaskTestMapper.class)) { + config.addMapper(TaskTestMapper.class); + } + TaskTestMapper mapper = session.getMapper(TaskTestMapper.class); + engineProxy.openConnection(); String customProperties = mapper.getCustomAttributesAsString(createdTask.getId()); assertTrue(customProperties.contains("\"Property_13\":\"Property Value of Property_13\"")); diff --git a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java index 4b7a76d1c..eb9f169cd 100644 --- a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java @@ -1,13 +1,18 @@ package acceptance.task; import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.sql.SQLException; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; import org.h2.store.fs.FileUtils; import org.junit.AfterClass; import org.junit.Assert; @@ -17,10 +22,20 @@ import org.junit.runner.RunWith; import acceptance.AbstractAccTest; import pro.taskana.BaseQuery.SortDirection; import pro.taskana.KeyDomain; +import pro.taskana.Task; import pro.taskana.TaskService; import pro.taskana.TaskSummary; +import pro.taskana.exceptions.ClassificationNotFoundException; import pro.taskana.exceptions.InvalidArgumentException; +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.TaskImpl; +import pro.taskana.impl.TaskanaEngineImpl; +import pro.taskana.impl.TaskanaEngineProxyForTest; +import pro.taskana.mappings.TaskTestMapper; import pro.taskana.security.JAASRunner; import pro.taskana.security.WithAccessId; @@ -418,6 +433,51 @@ public class QueryTasksAccTest extends AbstractAccTest { assertThat(result2.size(), equalTo(2)); } + @WithAccessId( + userName = "user_1_1", + groupNames = {"group_1"}) + @Test + public void testQueryTaskByCustomAttributes() + throws SQLException, NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException, + WorkbasketNotFoundException, TaskAlreadyExistException, InvalidWorkbasketException, TaskNotFoundException { + + TaskService taskService = taskanaEngine.getTaskService(); + Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A"); + newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567")); + newTask.setClassificationKey("T2100"); + Map customAttributesForCreate = createSimpleCustomProperties(20000); // about 1 Meg + newTask.setCustomAttributes(customAttributesForCreate); + Task createdTask = taskService.createTask(newTask); + + assertNotNull(createdTask); + // query the task by custom attributes + TaskanaEngineProxyForTest engineProxy = new TaskanaEngineProxyForTest((TaskanaEngineImpl) taskanaEngine); + try { + SqlSession session = engineProxy.getSqlSession(); + Configuration config = session.getConfiguration(); + if (!config.hasMapper(TaskTestMapper.class)) { + config.addMapper(TaskTestMapper.class); + } + + TaskTestMapper mapper = session.getMapper(TaskTestMapper.class); + engineProxy.openConnection(); + List queryResult = mapper.selectTasksByCustomAttributeLike("%Property Value of Property_1339%"); + + assertTrue(queryResult.size() == 1); + Task retrievedTask = queryResult.get(0); + + assertTrue(createdTask.getId().equals(retrievedTask.getId())); + + // verify that the map is correctly retrieved from the database + Map customAttributesFromDb = retrievedTask.getCustomAttributes(); + assertNotNull(customAttributesFromDb); + assertTrue(customAttributesForCreate.equals(customAttributesFromDb)); + + } finally { + engineProxy.returnConnection(); + } + } + @AfterClass public static void cleanUpClass() { FileUtils.deleteRecursive("~/data", true); diff --git a/lib/taskana-core/src/test/java/pro/taskana/mappings/TaskTestMapper.java b/lib/taskana-core/src/test/java/pro/taskana/mappings/TaskTestMapper.java new file mode 100644 index 000000000..39deba930 --- /dev/null +++ b/lib/taskana-core/src/test/java/pro/taskana/mappings/TaskTestMapper.java @@ -0,0 +1,74 @@ +package pro.taskana.mappings; + +import java.util.List; +import java.util.Map; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.type.ClobTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import pro.taskana.impl.TaskImpl; +import pro.taskana.impl.persistence.MapTypeHandler; + +/** + * This class contains specific mybatis mappings for task tests. + */ +public interface TaskTestMapper { + + @Select("select CUSTOM_ATTRIBUTES from task where id = #{taskId}") + @Results(value = { + @Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB, + javaType = String.class, typeHandler = ClobTypeHandler.class) + }) + String getCustomAttributesAsString(@Param("taskId") String taskId); + + @Select("SELECT ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, CLASSIFICATION_CATEGORY, CLASSIFICATION_KEY, CLASSIFICATION_ID, WORKBASKET_ID, WORKBASKET_KEY, DOMAIN, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_ATTRIBUTES, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10 " + + "FROM TASK " + + "WHERE CUSTOM_ATTRIBUTES like #{searchText}") + @Results(value = { + @Result(property = "id", column = "ID"), + @Result(property = "created", column = "CREATED"), + @Result(property = "claimed", column = "CLAIMED"), + @Result(property = "completed", column = "COMPLETED"), + @Result(property = "modified", column = "MODIFIED"), + @Result(property = "planned", column = "PLANNED"), + @Result(property = "due", column = "DUE"), + @Result(property = "name", column = "NAME"), + @Result(property = "creator", column = "CREATOR"), + @Result(property = "description", column = "DESCRIPTION"), + @Result(property = "note", column = "NOTE"), + @Result(property = "priority", column = "PRIORITY"), + @Result(property = "state", column = "STATE"), + @Result(property = "classificationSummaryImpl.category", column = "CLASSIFICATION_CATEGORY"), + @Result(property = "classificationSummaryImpl.id", column = "CLASSIFICATION_ID"), + @Result(property = "classificationSummaryImpl.key", column = "CLASSIFICATION_KEY"), + @Result(property = "domain", column = "DOMAIN"), + @Result(property = "businessProcessId", column = "BUSINESS_PROCESS_ID"), + @Result(property = "parentBusinessProcessId", column = "PARENT_BUSINESS_PROCESS_ID"), + @Result(property = "owner", column = "OWNER"), + @Result(property = "primaryObjRef.company", column = "POR_COMPANY"), + @Result(property = "primaryObjRef.system", column = "POR_SYSTEM"), + @Result(property = "primaryObjRef.systemInstance", column = "POR_INSTANCE"), + @Result(property = "primaryObjRef.type", column = "POR_TYPE"), + @Result(property = "primaryObjRef.value", column = "POR_VALUE"), + @Result(property = "isRead", column = "IS_READ"), + @Result(property = "isTransferred", column = "IS_TRANSFERRED"), + @Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB, + javaType = Map.class, typeHandler = MapTypeHandler.class), + @Result(property = "custom1", column = "CUSTOM_1"), + @Result(property = "custom2", column = "CUSTOM_2"), + @Result(property = "custom3", column = "CUSTOM_3"), + @Result(property = "custom4", column = "CUSTOM_4"), + @Result(property = "custom5", column = "CUSTOM_5"), + @Result(property = "custom6", column = "CUSTOM_6"), + @Result(property = "custom7", column = "CUSTOM_7"), + @Result(property = "custom8", column = "CUSTOM_8"), + @Result(property = "custom9", column = "CUSTOM_9"), + @Result(property = "custom10", column = "CUSTOM_10") + }) + List selectTasksByCustomAttributeLike(@Param("searchText") String searchText); + +}