TSK-315 Store custom properties as JSON Map in DB
This commit is contained in:
parent
603afc8a2d
commit
a00289c0ab
|
@ -128,7 +128,11 @@
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>1.7.25</version>
|
<version>1.7.25</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
<version>20180130</version>
|
||||||
|
</dependency>
|
||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
|
|
@ -103,7 +103,7 @@ public interface Attachment {
|
||||||
*
|
*
|
||||||
* @return customAttributes as {@link Map}
|
* @return customAttributes as {@link Map}
|
||||||
*/
|
*/
|
||||||
Map<String, Object> getCustomAttributes();
|
Map<String, String> getCustomAttributes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the custom attribute Map of the attachment.
|
* Sets the custom attribute Map of the attachment.
|
||||||
|
@ -111,7 +111,8 @@ public interface Attachment {
|
||||||
* @param customAttributes
|
* @param customAttributes
|
||||||
* a {@link Map} that contains the custom attributes of the attachment as key, value pairs
|
* a {@link Map} that contains the custom attributes of the attachment as key, value pairs
|
||||||
*/
|
*/
|
||||||
void setCustomAttributes(Map<String, Object> customAttributes);
|
void setCustomAttributes(Map<String, String> customAttributes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a summary of the current Attachment.
|
* Return a summary of the current Attachment.
|
||||||
*
|
*
|
||||||
|
|
|
@ -220,7 +220,15 @@ public interface Task {
|
||||||
*
|
*
|
||||||
* @return customAttributes as {@link Map}
|
* @return customAttributes as {@link Map}
|
||||||
*/
|
*/
|
||||||
Map<String, Object> getCustomAttributes();
|
Map<String, String> getCustomAttributes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a collection of customAttributes.
|
||||||
|
*
|
||||||
|
* @param customAttributes
|
||||||
|
* a {@link Map} that contains the custom attributes
|
||||||
|
*/
|
||||||
|
void setCustomAttributes(Map<String, String> customAttributes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value for the 1. customAttribute.
|
* Return the value for the 1. customAttribute.
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class AttachmentImpl implements Attachment {
|
||||||
private ObjectReference objectReference;
|
private ObjectReference objectReference;
|
||||||
private String channel;
|
private String channel;
|
||||||
private Instant received;
|
private Instant received;
|
||||||
private Map<String, Object> customAttributes = Collections.emptyMap();
|
private Map<String, String> customAttributes = Collections.emptyMap();
|
||||||
|
|
||||||
AttachmentImpl() {
|
AttachmentImpl() {
|
||||||
}
|
}
|
||||||
|
@ -116,12 +116,12 @@ public class AttachmentImpl implements Attachment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getCustomAttributes() {
|
public Map<String, String> getCustomAttributes() {
|
||||||
return customAttributes;
|
return customAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCustomAttributes(Map<String, Object> customAttributes) {
|
public void setCustomAttributes(Map<String, String> customAttributes) {
|
||||||
this.customAttributes = customAttributes;
|
this.customAttributes = customAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class TaskImpl implements Task {
|
||||||
private boolean isRead;
|
private boolean isRead;
|
||||||
private boolean isTransferred;
|
private boolean isTransferred;
|
||||||
// All objects have to be serializable
|
// All objects have to be serializable
|
||||||
private Map<String, Object> customAttributes = Collections.emptyMap();
|
private Map<String, String> customAttributes = Collections.emptyMap();
|
||||||
private List<Attachment> attachments = new ArrayList<>();
|
private List<Attachment> attachments = new ArrayList<>();
|
||||||
private String custom1;
|
private String custom1;
|
||||||
private String custom2;
|
private String custom2;
|
||||||
|
@ -294,11 +294,12 @@ public class TaskImpl implements Task {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getCustomAttributes() {
|
public Map<String, String> getCustomAttributes() {
|
||||||
return customAttributes;
|
return customAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCustomAttributes(Map<String, Object> customAttributes) {
|
@Override
|
||||||
|
public void setCustomAttributes(Map<String, String> customAttributes) {
|
||||||
this.customAttributes = customAttributes;
|
this.customAttributes = customAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
package pro.taskana.impl.persistence;
|
package pro.taskana.impl.persistence;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.sql.Blob;
|
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.Clob;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -15,6 +10,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.apache.ibatis.type.BaseTypeHandler;
|
import org.apache.ibatis.type.BaseTypeHandler;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -32,15 +28,11 @@ public class MapTypeHandler extends BaseTypeHandler<Map> {
|
||||||
public void setNonNullParameter(PreparedStatement ps, int i, Map parameter, JdbcType jdbcType) throws SQLException {
|
public void setNonNullParameter(PreparedStatement ps, int i, Map parameter, JdbcType jdbcType) throws SQLException {
|
||||||
if (parameter != null && parameter.size() > 0) {
|
if (parameter != null && parameter.size() > 0) {
|
||||||
LOGGER.debug("Input-Map before serializing: ", parameter);
|
LOGGER.debug("Input-Map before serializing: ", parameter);
|
||||||
// Convert Map to byte array
|
// Convert Map to JSON string
|
||||||
try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) {
|
JSONObject jsonObj = new JSONObject(parameter);
|
||||||
ObjectOutputStream out = new ObjectOutputStream(byteOut);
|
Clob content = ps.getConnection().createClob();
|
||||||
out.writeObject(parameter);
|
content.setString(1, jsonObj.toString());
|
||||||
ps.setBlob(i, new ByteArrayInputStream(byteOut.toByteArray()));
|
ps.setClob(i, content);
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.error("During serialization of 'customAttributes' an error occured: ", e);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ps.setNull(i, Types.BLOB);
|
ps.setNull(i, Types.BLOB);
|
||||||
}
|
}
|
||||||
|
@ -48,49 +40,36 @@ public class MapTypeHandler extends BaseTypeHandler<Map> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
public Map getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||||
Blob fieldValue = rs.getBlob(columnName);
|
Clob fieldValue = rs.getClob(columnName);
|
||||||
if (fieldValue != null) {
|
if (fieldValue != null) {
|
||||||
// Parse byte array to Map
|
return convertClobToMap(fieldValue);
|
||||||
Map result = null;
|
|
||||||
try (ObjectInputStream in = new ObjectInputStream(fieldValue.getBinaryStream())) {
|
|
||||||
result = (Map) in.readObject();
|
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
|
||||||
LOGGER.error("During deserialization of 'customAttributes' an error occured: ", e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
public Map getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||||
Blob fieldValue = rs.getBlob(columnIndex);
|
Clob fieldValue = rs.getClob(columnIndex);
|
||||||
if (fieldValue != null) {
|
if (fieldValue != null) {
|
||||||
// Parse byte array to Map
|
return convertClobToMap(fieldValue);
|
||||||
Map result = null;
|
|
||||||
try (ObjectInputStream in = new ObjectInputStream(fieldValue.getBinaryStream())) {
|
|
||||||
result = (Map) in.readObject();
|
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
|
||||||
LOGGER.error("During deserialization of 'customAttributes' an error occured: ", e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
public Map getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||||
Blob fieldValue = cs.getBlob(columnIndex);
|
Clob fieldValue = cs.getClob(columnIndex);
|
||||||
if (fieldValue != null) {
|
if (fieldValue != null) {
|
||||||
// Parse byte array to Map
|
return convertClobToMap(fieldValue);
|
||||||
Map result = null;
|
|
||||||
try (ObjectInputStream in = new ObjectInputStream(fieldValue.getBinaryStream())) {
|
|
||||||
result = (Map) in.readObject();
|
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
|
||||||
LOGGER.error("During deserialization of 'customAttributes' an error occured: ", e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map convertClobToMap(Clob fieldValue) throws SQLException {
|
||||||
|
String content = fieldValue.getSubString(1L, (int) fieldValue.length());
|
||||||
|
JSONObject jsonObj = new JSONObject(content);
|
||||||
|
Map result = jsonObj.toMap();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Result;
|
||||||
import org.apache.ibatis.annotations.Results;
|
import org.apache.ibatis.annotations.Results;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
import org.apache.ibatis.annotations.Update;
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
import org.apache.ibatis.type.ClobTypeHandler;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
|
||||||
import pro.taskana.impl.AttachmentImpl;
|
import pro.taskana.impl.AttachmentImpl;
|
||||||
|
@ -23,7 +24,7 @@ public interface AttachmentMapper {
|
||||||
|
|
||||||
@Insert("INSERT INTO ATTACHMENT (ID, TASK_ID, CREATED, MODIFIED, CLASSIFICATION_KEY, CLASSIFICATION_ID, REF_COMPANY, REF_SYSTEM, REF_INSTANCE, REF_TYPE, REF_VALUE, CHANNEL, RECEIVED, CUSTOM_ATTRIBUTES) "
|
@Insert("INSERT INTO ATTACHMENT (ID, TASK_ID, CREATED, MODIFIED, CLASSIFICATION_KEY, CLASSIFICATION_ID, REF_COMPANY, REF_SYSTEM, REF_INSTANCE, REF_TYPE, REF_VALUE, CHANNEL, RECEIVED, CUSTOM_ATTRIBUTES) "
|
||||||
+ "VALUES (#{att.id}, #{att.taskId}, #{att.created}, #{att.modified}, #{att.classificationSummary.key}, #{att.classificationSummary.id}, #{att.objectReference.company}, #{att.objectReference.system}, #{att.objectReference.systemInstance}, "
|
+ "VALUES (#{att.id}, #{att.taskId}, #{att.created}, #{att.modified}, #{att.classificationSummary.key}, #{att.classificationSummary.id}, #{att.objectReference.company}, #{att.objectReference.system}, #{att.objectReference.systemInstance}, "
|
||||||
+ " #{att.objectReference.type}, #{att.objectReference.value}, #{att.channel}, #{att.received}, #{att.customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler} )")
|
+ " #{att.objectReference.type}, #{att.objectReference.value}, #{att.channel}, #{att.received}, #{att.customAttributes,jdbcType=CLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler} )")
|
||||||
void insert(@Param("att") AttachmentImpl att);
|
void insert(@Param("att") AttachmentImpl att);
|
||||||
|
|
||||||
@Select("SELECT ID, TASK_ID, CREATED, MODIFIED, CLASSIFICATION_KEY, CLASSIFICATION_ID, REF_COMPANY, REF_SYSTEM, REF_INSTANCE, REF_TYPE, REF_VALUE, CHANNEL, RECEIVED, CUSTOM_ATTRIBUTES "
|
@Select("SELECT ID, TASK_ID, CREATED, MODIFIED, CLASSIFICATION_KEY, CLASSIFICATION_ID, REF_COMPANY, REF_SYSTEM, REF_INSTANCE, REF_TYPE, REF_VALUE, CHANNEL, RECEIVED, CUSTOM_ATTRIBUTES "
|
||||||
|
@ -43,7 +44,7 @@ public interface AttachmentMapper {
|
||||||
@Result(property = "objectReference.value", column = "REF_VALUE"),
|
@Result(property = "objectReference.value", column = "REF_VALUE"),
|
||||||
@Result(property = "channel", column = "CHANNEL"),
|
@Result(property = "channel", column = "CHANNEL"),
|
||||||
@Result(property = "received", column = "RECEIVED"),
|
@Result(property = "received", column = "RECEIVED"),
|
||||||
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB,
|
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
|
||||||
javaType = Map.class, typeHandler = MapTypeHandler.class)
|
javaType = Map.class, typeHandler = MapTypeHandler.class)
|
||||||
})
|
})
|
||||||
List<AttachmentImpl> findAttachmentsByTaskId(@Param("taskId") String taskId);
|
List<AttachmentImpl> findAttachmentsByTaskId(@Param("taskId") String taskId);
|
||||||
|
@ -65,7 +66,7 @@ public interface AttachmentMapper {
|
||||||
@Result(property = "objectReference.value", column = "REF_VALUE"),
|
@Result(property = "objectReference.value", column = "REF_VALUE"),
|
||||||
@Result(property = "channel", column = "CHANNEL"),
|
@Result(property = "channel", column = "CHANNEL"),
|
||||||
@Result(property = "received", column = "RECEIVED"),
|
@Result(property = "received", column = "RECEIVED"),
|
||||||
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB,
|
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
|
||||||
javaType = Map.class, typeHandler = MapTypeHandler.class)
|
javaType = Map.class, typeHandler = MapTypeHandler.class)
|
||||||
})
|
})
|
||||||
AttachmentImpl getAttachment(@Param("attachmentId") String attachmentId);
|
AttachmentImpl getAttachment(@Param("attachmentId") String attachmentId);
|
||||||
|
@ -93,7 +94,14 @@ public interface AttachmentMapper {
|
||||||
@Update("UPDATE ATTACHMENT SET TASK_ID = #{taskId}, CREATED = #{created}, MODIFIED = #{modified},"
|
@Update("UPDATE ATTACHMENT SET TASK_ID = #{taskId}, CREATED = #{created}, MODIFIED = #{modified},"
|
||||||
+ " CLASSIFICATION_KEY = #{classificationSummary.key}, CLASSIFICATION_ID = #{classificationSummary.id}, REF_COMPANY = #{objectReference.company}, REF_SYSTEM = #{objectReference.system},"
|
+ " CLASSIFICATION_KEY = #{classificationSummary.key}, CLASSIFICATION_ID = #{classificationSummary.id}, REF_COMPANY = #{objectReference.company}, REF_SYSTEM = #{objectReference.system},"
|
||||||
+ " REF_INSTANCE = #{objectReference.systemInstance}, REF_TYPE = #{objectReference.type}, REF_VALUE = #{objectReference.value},"
|
+ " REF_INSTANCE = #{objectReference.systemInstance}, REF_TYPE = #{objectReference.type}, REF_VALUE = #{objectReference.value},"
|
||||||
+ " CHANNEL = #{channel}, RECEIVED = #{received}, CUSTOM_ATTRIBUTES = #{customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}"
|
+ " CHANNEL = #{channel}, RECEIVED = #{received}, CUSTOM_ATTRIBUTES = #{customAttributes,jdbcType=CLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}"
|
||||||
+ " WHERE ID = #{id}")
|
+ " WHERE ID = #{id}")
|
||||||
void update(AttachmentImpl attachment);
|
void update(AttachmentImpl attachment);
|
||||||
|
|
||||||
|
@Select("select CUSTOM_ATTRIBUTES from attachment where id = #{attachmentId}")
|
||||||
|
@Results(value = {
|
||||||
|
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
|
||||||
|
javaType = String.class, typeHandler = ClobTypeHandler.class)
|
||||||
|
})
|
||||||
|
String getCustomAttributesAsString(@Param("attachmentId") String attachmentId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Result;
|
||||||
import org.apache.ibatis.annotations.Results;
|
import org.apache.ibatis.annotations.Results;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
import org.apache.ibatis.annotations.Update;
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
import org.apache.ibatis.type.ClobTypeHandler;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
|
||||||
import pro.taskana.impl.MinimalTaskSummary;
|
import pro.taskana.impl.MinimalTaskSummary;
|
||||||
|
@ -63,7 +64,7 @@ public interface TaskMapper {
|
||||||
@Result(property = "primaryObjRef.value", column = "POR_VALUE"),
|
@Result(property = "primaryObjRef.value", column = "POR_VALUE"),
|
||||||
@Result(property = "isRead", column = "IS_READ"),
|
@Result(property = "isRead", column = "IS_READ"),
|
||||||
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
|
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
|
||||||
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.BLOB,
|
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
|
||||||
javaType = Map.class, typeHandler = MapTypeHandler.class),
|
javaType = Map.class, typeHandler = MapTypeHandler.class),
|
||||||
@Result(property = "custom1", column = "CUSTOM_1"),
|
@Result(property = "custom1", column = "CUSTOM_1"),
|
||||||
@Result(property = "custom2", column = "CUSTOM_2"),
|
@Result(property = "custom2", column = "CUSTOM_2"),
|
||||||
|
@ -83,7 +84,7 @@ public interface TaskMapper {
|
||||||
+ "VALUES(#{id}, #{created}, #{claimed}, #{completed}, #{modified}, #{planned}, #{due}, #{name}, #{creator}, #{description}, #{note}, #{priority}, #{state}, #{classificationSummary.category}, "
|
+ "VALUES(#{id}, #{created}, #{claimed}, #{completed}, #{modified}, #{planned}, #{due}, #{name}, #{creator}, #{description}, #{note}, #{priority}, #{state}, #{classificationSummary.category}, "
|
||||||
+ "#{classificationSummary.key}, #{classificationSummary.id}, #{workbasketSummary.id}, #{workbasketSummary.key}, #{workbasketSummary.domain}, #{businessProcessId}, "
|
+ "#{classificationSummary.key}, #{classificationSummary.id}, #{workbasketSummary.id}, #{workbasketSummary.key}, #{workbasketSummary.domain}, #{businessProcessId}, "
|
||||||
+ "#{parentBusinessProcessId}, #{owner}, #{primaryObjRef.company}, #{primaryObjRef.system}, #{primaryObjRef.systemInstance}, #{primaryObjRef.type}, #{primaryObjRef.value}, "
|
+ "#{parentBusinessProcessId}, #{owner}, #{primaryObjRef.company}, #{primaryObjRef.system}, #{primaryObjRef.systemInstance}, #{primaryObjRef.type}, #{primaryObjRef.value}, "
|
||||||
+ "#{isRead}, #{isTransferred}, #{customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, "
|
+ "#{isRead}, #{isTransferred}, #{customAttributes,jdbcType=CLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, "
|
||||||
+ "#{custom1}, #{custom2}, #{custom3}, #{custom4}, #{custom5}, #{custom6}, #{custom7}, #{custom8}, #{custom9}, #{custom10})")
|
+ "#{custom1}, #{custom2}, #{custom3}, #{custom4}, #{custom5}, #{custom6}, #{custom7}, #{custom8}, #{custom9}, #{custom10})")
|
||||||
@Options(keyProperty = "id", keyColumn = "ID")
|
@Options(keyProperty = "id", keyColumn = "ID")
|
||||||
void insert(TaskImpl task);
|
void insert(TaskImpl task);
|
||||||
|
@ -93,7 +94,7 @@ public interface TaskMapper {
|
||||||
+ "WORKBASKET_ID = #{workbasketSummary.id}, WORKBASKET_KEY = #{workbasketSummary.key}, DOMAIN = #{workbasketSummary.domain}, "
|
+ "WORKBASKET_ID = #{workbasketSummary.id}, WORKBASKET_KEY = #{workbasketSummary.key}, DOMAIN = #{workbasketSummary.domain}, "
|
||||||
+ "BUSINESS_PROCESS_ID = #{businessProcessId}, PARENT_BUSINESS_PROCESS_ID = #{parentBusinessProcessId}, OWNER = #{owner}, POR_COMPANY = #{primaryObjRef.company}, POR_SYSTEM = #{primaryObjRef.system}, "
|
+ "BUSINESS_PROCESS_ID = #{businessProcessId}, PARENT_BUSINESS_PROCESS_ID = #{parentBusinessProcessId}, OWNER = #{owner}, POR_COMPANY = #{primaryObjRef.company}, POR_SYSTEM = #{primaryObjRef.system}, "
|
||||||
+ "POR_INSTANCE = #{primaryObjRef.systemInstance}, POR_TYPE = #{primaryObjRef.type}, POR_VALUE = #{primaryObjRef.value}, IS_READ = #{isRead}, IS_TRANSFERRED = #{isTransferred}, "
|
+ "POR_INSTANCE = #{primaryObjRef.systemInstance}, POR_TYPE = #{primaryObjRef.type}, POR_VALUE = #{primaryObjRef.value}, IS_READ = #{isRead}, IS_TRANSFERRED = #{isTransferred}, "
|
||||||
+ "CUSTOM_ATTRIBUTES = #{customAttributes,jdbcType=BLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, CUSTOM_1 = #{custom1}, CUSTOM_2 = #{custom2}, "
|
+ "CUSTOM_ATTRIBUTES = #{customAttributes,jdbcType=CLOB,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler}, CUSTOM_1 = #{custom1}, CUSTOM_2 = #{custom2}, "
|
||||||
+ "CUSTOM_3 = #{custom3}, CUSTOM_4 = #{custom4}, CUSTOM_5 = #{custom5}, CUSTOM_6 = #{custom6}, CUSTOM_7 = #{custom7}, CUSTOM_8 = #{custom8}, CUSTOM_9 = #{custom9}, CUSTOM_10 = #{custom10} "
|
+ "CUSTOM_3 = #{custom3}, CUSTOM_4 = #{custom4}, CUSTOM_5 = #{custom5}, CUSTOM_6 = #{custom6}, CUSTOM_7 = #{custom7}, CUSTOM_8 = #{custom8}, CUSTOM_9 = #{custom9}, CUSTOM_10 = #{custom10} "
|
||||||
+ "WHERE ID = #{id}")
|
+ "WHERE ID = #{id}")
|
||||||
void update(TaskImpl task);
|
void update(TaskImpl task);
|
||||||
|
@ -223,4 +224,12 @@ public interface TaskMapper {
|
||||||
+ "</script>")
|
+ "</script>")
|
||||||
void updateClassificationCategoryOnChange(@Param("taskIds") List<String> taskIds,
|
void updateClassificationCategoryOnChange(@Param("taskIds") List<String> taskIds,
|
||||||
@Param("newCategory") String newCategory);
|
@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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ CREATE TABLE TASK (
|
||||||
POR_VALUE VARCHAR(128) NOT NULL,
|
POR_VALUE VARCHAR(128) NOT NULL,
|
||||||
IS_READ BOOLEAN NOT NULL,
|
IS_READ BOOLEAN NOT NULL,
|
||||||
IS_TRANSFERRED BOOLEAN NOT NULL,
|
IS_TRANSFERRED BOOLEAN NOT NULL,
|
||||||
CUSTOM_ATTRIBUTES BLOB NULL,
|
CUSTOM_ATTRIBUTES CLOB NULL,
|
||||||
CUSTOM_1 VARCHAR(255) NULL,
|
CUSTOM_1 VARCHAR(255) NULL,
|
||||||
CUSTOM_2 VARCHAR(255) NULL,
|
CUSTOM_2 VARCHAR(255) NULL,
|
||||||
CUSTOM_3 VARCHAR(255) NULL,
|
CUSTOM_3 VARCHAR(255) NULL,
|
||||||
|
@ -152,7 +152,7 @@ CREATE TABLE ATTACHMENT(
|
||||||
REF_VALUE VARCHAR(128) NOT NULL,
|
REF_VALUE VARCHAR(128) NOT NULL,
|
||||||
CHANNEL VARCHAR(64) NULL,
|
CHANNEL VARCHAR(64) NULL,
|
||||||
RECEIVED TIMESTAMP NULL,
|
RECEIVED TIMESTAMP NULL,
|
||||||
CUSTOM_ATTRIBUTES BLOB NULL,
|
CUSTOM_ATTRIBUTES CLOB NULL,
|
||||||
PRIMARY KEY (ID),
|
PRIMARY KEY (ID),
|
||||||
CONSTRAINT ATT_CLASS FOREIGN KEY (CLASSIFICATION_ID) REFERENCES CLASSIFICATION ON DELETE NO ACTION
|
CONSTRAINT ATT_CLASS FOREIGN KEY (CLASSIFICATION_ID) REFERENCES CLASSIFICATION ON DELETE NO ACTION
|
||||||
);
|
);
|
||||||
|
|
|
@ -68,8 +68,8 @@ public abstract class AbstractAccTest {
|
||||||
return objectReference;
|
return objectReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, Object> createSimpleCustomProperties(int propertiesCount) {
|
protected Map<String, String> createSimpleCustomProperties(int propertiesCount) {
|
||||||
HashMap<String, Object> properties = new HashMap<>();
|
HashMap<String, String> properties = new HashMap<>();
|
||||||
for (int i = 1; i <= propertiesCount; i++) {
|
for (int i = 1; i <= propertiesCount; i++) {
|
||||||
properties.put("Property_" + i, "Property Value of Property_" + i);
|
properties.put("Property_" + i, "Property Value of Property_" + i);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public abstract class AbstractAccTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Attachment createAttachment(String classificationKey, ObjectReference objRef,
|
protected Attachment createAttachment(String classificationKey, ObjectReference objRef,
|
||||||
String channel, String receivedDate, Map<String, Object> customAttributes)
|
String channel, String receivedDate, Map<String, String> customAttributes)
|
||||||
throws ClassificationNotFoundException, NotAuthorizedException {
|
throws ClassificationNotFoundException, NotAuthorizedException {
|
||||||
Attachment attachment = taskanaEngine.getTaskService().newAttachment();
|
Attachment attachment = taskanaEngine.getTaskService().newAttachment();
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,13 @@ import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.h2.store.fs.FileUtils;
|
import org.h2.store.fs.FileUtils;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -28,6 +31,10 @@ import pro.taskana.exceptions.TaskNotFoundException;
|
||||||
import pro.taskana.exceptions.WorkbasketNotFoundException;
|
import pro.taskana.exceptions.WorkbasketNotFoundException;
|
||||||
import pro.taskana.impl.TaskState;
|
import pro.taskana.impl.TaskState;
|
||||||
import pro.taskana.security.CurrentUserContext;
|
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.security.JAASRunner;
|
import pro.taskana.security.JAASRunner;
|
||||||
import pro.taskana.security.WithAccessId;
|
import pro.taskana.security.WithAccessId;
|
||||||
|
|
||||||
|
@ -73,6 +80,68 @@ public class CreateTaskAccTest extends AbstractAccTest {
|
||||||
assertEquals(false, createdTask.isTransferred());
|
assertEquals(false, createdTask.isTransferred());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WithAccessId(
|
||||||
|
userName = "user_1_1",
|
||||||
|
groupNames = {"group_1"})
|
||||||
|
@Test
|
||||||
|
public void testCreateSimpleTaskWithCustomAttributes()
|
||||||
|
throws SQLException, NotAuthorizedException, InvalidArgumentException, ClassificationNotFoundException,
|
||||||
|
WorkbasketNotFoundException, TaskAlreadyExistException, InvalidWorkbasketException, TaskNotFoundException {
|
||||||
|
|
||||||
|
TaskService taskService = taskanaEngine.getTaskService();
|
||||||
|
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
|
||||||
|
newTask.setClassificationKey("T2100");
|
||||||
|
newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||||
|
Map<String, String> customAttributesForCreate = createSimpleCustomProperties(13);
|
||||||
|
newTask.setCustomAttributes(customAttributesForCreate);
|
||||||
|
Task createdTask = taskService.createTask(newTask);
|
||||||
|
|
||||||
|
assertNotNull(createdTask);
|
||||||
|
assertEquals("T-Vertragstermin VERA", createdTask.getName());
|
||||||
|
assertEquals("1234567", createdTask.getPrimaryObjRef().getValue());
|
||||||
|
assertNotNull(createdTask.getCreated());
|
||||||
|
assertNotNull(createdTask.getModified());
|
||||||
|
assertNotNull(createdTask.getBusinessProcessId());
|
||||||
|
assertEquals(null, createdTask.getClaimed());
|
||||||
|
assertEquals(null, createdTask.getCompleted());
|
||||||
|
assertEquals(createdTask.getCreated(), createdTask.getModified());
|
||||||
|
assertEquals(createdTask.getCreated(), createdTask.getPlanned());
|
||||||
|
assertEquals(TaskState.READY, createdTask.getState());
|
||||||
|
assertEquals(null, createdTask.getParentBusinessProcessId());
|
||||||
|
assertEquals(2, createdTask.getPriority());
|
||||||
|
assertEquals(false, createdTask.isRead());
|
||||||
|
assertEquals(false, createdTask.isTransferred());
|
||||||
|
// verify that the database content is as expected
|
||||||
|
TaskanaEngineProxyForTest engineProxy = new TaskanaEngineProxyForTest((TaskanaEngineImpl) taskanaEngine);
|
||||||
|
try {
|
||||||
|
SqlSession session = engineProxy.getSqlSession();
|
||||||
|
TaskMapper mapper = session.getMapper(TaskMapper.class);
|
||||||
|
engineProxy.openConnection();
|
||||||
|
String customProperties = mapper.getCustomAttributesAsString(createdTask.getId());
|
||||||
|
assertTrue(customProperties.contains("\"Property_13\":\"Property Value of Property_13\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_12\":\"Property Value of Property_12\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_11\":\"Property Value of Property_11\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_10\":\"Property Value of Property_10\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_9\":\"Property Value of Property_9\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_8\":\"Property Value of Property_8\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_7\":\"Property Value of Property_7\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_6\":\"Property Value of Property_6\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_5\":\"Property Value of Property_5\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_4\":\"Property Value of Property_4\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_3\":\"Property Value of Property_3\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_2\":\"Property Value of Property_2\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_1\":\"Property Value of Property_1\""));
|
||||||
|
} finally {
|
||||||
|
engineProxy.returnConnection();
|
||||||
|
}
|
||||||
|
// verify that the map is correctly retrieved from the database
|
||||||
|
Task retrievedTask = taskService.getTask(createdTask.getId());
|
||||||
|
Map<String, String> customAttributesFromDb = retrievedTask.getCustomAttributes();
|
||||||
|
assertNotNull(customAttributesFromDb);
|
||||||
|
assertTrue(customAttributesFromDb.equals(customAttributesForCreate));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@WithAccessId(
|
@WithAccessId(
|
||||||
userName = "user_1_1",
|
userName = "user_1_1",
|
||||||
groupNames = {"group_1"})
|
groupNames = {"group_1"})
|
||||||
|
@ -85,15 +154,36 @@ public class CreateTaskAccTest extends AbstractAccTest {
|
||||||
TaskService taskService = taskanaEngine.getTaskService();
|
TaskService taskService = taskanaEngine.getTaskService();
|
||||||
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
|
Task newTask = taskService.newTask("USER_1_1", "DOMAIN_A");
|
||||||
newTask.setClassificationKey("L12010");
|
newTask.setClassificationKey("L12010");
|
||||||
|
Map<String, String> customAttributesForCreate = createSimpleCustomProperties(27);
|
||||||
newTask.addAttachment(createAttachment("DOCTYPE_DEFAULT",
|
newTask.addAttachment(createAttachment("DOCTYPE_DEFAULT",
|
||||||
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
|
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId",
|
||||||
"12345678901234567890123456789012345678901234567890"),
|
"12345678901234567890123456789012345678901234567890"),
|
||||||
"E-MAIL", "2018-01-15", createSimpleCustomProperties(3)));
|
"E-MAIL", "2018-01-15", customAttributesForCreate));
|
||||||
newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
newTask.setPrimaryObjRef(createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||||
Task createdTask = taskService.createTask(newTask);
|
Task createdTask = taskService.createTask(newTask);
|
||||||
assertNotNull(createdTask.getId());
|
assertNotNull(createdTask.getId());
|
||||||
assertThat(createdTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
|
assertThat(createdTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
|
||||||
|
|
||||||
|
// verify that the database content is as expected
|
||||||
|
TaskanaEngineProxyForTest engineProxy = new TaskanaEngineProxyForTest((TaskanaEngineImpl) taskanaEngine);
|
||||||
|
try {
|
||||||
|
SqlSession session = engineProxy.getSqlSession();
|
||||||
|
AttachmentMapper mapper = session.getMapper(AttachmentMapper.class);
|
||||||
|
engineProxy.openConnection();
|
||||||
|
String customProperties = mapper.getCustomAttributesAsString(createdTask.getAttachments().get(0).getId());
|
||||||
|
assertTrue(customProperties.contains("\"Property_26\":\"Property Value of Property_26\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_25\":\"Property Value of Property_25\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_21\":\"Property Value of Property_21\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_19\":\"Property Value of Property_19\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_16\":\"Property Value of Property_16\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_12\":\"Property Value of Property_12\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_11\":\"Property Value of Property_11\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_7\":\"Property Value of Property_7\""));
|
||||||
|
assertTrue(customProperties.contains("\"Property_6\":\"Property Value of Property_6\""));
|
||||||
|
} finally {
|
||||||
|
engineProxy.returnConnection();
|
||||||
|
}
|
||||||
|
|
||||||
Task readTask = taskService.getTask(createdTask.getId());
|
Task readTask = taskService.getTask(createdTask.getId());
|
||||||
assertNotNull(readTask);
|
assertNotNull(readTask);
|
||||||
assertThat(readTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
|
assertThat(readTask.getCreator(), equalTo(CurrentUserContext.getUserid()));
|
||||||
|
@ -104,6 +194,10 @@ public class CreateTaskAccTest extends AbstractAccTest {
|
||||||
assertEquals(readTask.getAttachments().get(0).getCreated(), readTask.getAttachments().get(0).getModified());
|
assertEquals(readTask.getAttachments().get(0).getCreated(), readTask.getAttachments().get(0).getModified());
|
||||||
assertNotNull(readTask.getAttachments().get(0).getClassificationSummary());
|
assertNotNull(readTask.getAttachments().get(0).getClassificationSummary());
|
||||||
assertNotNull(readTask.getAttachments().get(0).getObjectReference());
|
assertNotNull(readTask.getAttachments().get(0).getObjectReference());
|
||||||
|
// verify that the map is correctly retrieved from the database
|
||||||
|
Map<String, String> customAttributesFromDb = readTask.getAttachments().get(0).getCustomAttributes();
|
||||||
|
assertNotNull(customAttributesFromDb);
|
||||||
|
assertTrue(customAttributesFromDb.equals(customAttributesForCreate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithAccessId(
|
@WithAccessId(
|
||||||
|
|
Loading…
Reference in New Issue