TSK-1646: Bugfix for creation / update of Task with invalid Attachment

This commit is contained in:
Tim Gerversmann 2021-05-24 18:41:03 +02:00 committed by Mustapha Zorgati
parent efc194f986
commit 1c83b7871f
17 changed files with 331 additions and 122 deletions

View File

@ -1,7 +1,7 @@
-- ATTACHMENT TABLE (ID , task_ID , CREATED , MODIFIED , classif key, classif Id , refCompany, ref sys, ref inst,ref type, ref val, channel,received, custAtts)
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000000','TKI:000000000000000000000000000000000000', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ1', 'val1', 'ch1', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000001','TKI:000000000000000000000000000000000001', '2018-01-29 15:55:01', '2018-01-30 15:55:00', 'L10303' , 'CLI:000000000000000000000000000000000002', 'novatec' , 'novasys', 'nvinst', 'typ2', 'val1', 'ch2', '2018-01-30 12:00:00', null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000001','TKI:000000000000000000000000000000000001', '2018-01-29 15:55:01', '2018-01-30 15:55:00', 'L10303' , 'CLI:100000000000000000000000000000000002', 'novatec' , 'novasys', 'nvinst', 'typ2', 'val1', 'ch2', '2018-01-30 12:00:00', null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000002','TKI:000000000000000000000000000000000001', '2018-01-29 15:55:02', '2018-01-30 15:55:00', 'L1050' , 'CLI:000000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ2', 'val2', 'ch2', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000003','TKI:000000000000000000000000000000000002', '2018-01-29 15:55:03', null , 'L11010' , 'CLI:000000000000000000000000000000000004', 'novatec' , 'novasys', 'nvinst', 'typ2', 'val2', 'ch3', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000004','TKI:000000000000000000000000000000000002', '2018-01-29 15:55:04', null , 'L110102' , 'CLI:000000000000000000000000000000000005', 'novatec' , 'novasys', 'nvinst', 'typ3', 'val2', 'ch4', null, null);
@ -14,8 +14,8 @@ INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000010','TKI:00
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000011','TKI:000000000000000000000000000000000053', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ4', 'val4', 'ch7', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000012','TKI:000000000000000000000000000000000054', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val4', 'ch7', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000013','TKI:000000000000000000000000000000000055', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val4', 'ch7', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000014','TKI:000000000000000000000000000000000010', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L11010' , 'CLI:100000000000000000000000000000000004', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val4', 'ch8', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000015','TKI:000000000000000000000000000000000011', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L10303' , 'CLI:100000000000000000000000000000000002', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val5', 'ch8', '2018-01-30 12:00:00', null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000014','TKI:000000000000000000000000000000000010', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L11010' , 'CLI:100000000000000000000000000000000004', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val4', 'ch8', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000015','TKI:000000000000000000000000000000000011', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L10303' , 'CLI:100000000000000000000000000000000002', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val5', 'ch8', '2018-01-30 12:00:00', null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000016','TKI:000000000000000000000000000000000012', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ5', 'val6', 'ch8', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000017','TKI:000000000000000000000000000000000067', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ1', 'val1', 'ch1', null, null);
INSERT INTO ATTACHMENT VALUES('TAI:000000000000000000000000000000000018','TKI:000000000000000000000000000000000067', '2018-01-29 15:55:00', '2018-01-30 15:55:00', 'L1050' , 'CLI:100000000000000000000000000000000003', 'novatec' , 'novasys', 'nvinst', 'typ1', 'val1', 'ch1', null, null);

View File

@ -22,7 +22,7 @@ INSERT INTO CLASSIFICATION VALUES('CLI:000000000000000000000000000000000024', 'T
INSERT INTO CLASSIFICATION VALUES('CLI:300000000000000000000000000000000017', 'L3060', '', '', 'EXTERNAL', 'TASK', '', FALSE, RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Widerruf neu', 'Widerruf neu', 1, 'P1D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
-- DOMAIN_A CLASSIFICATIONS
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000002', 'L10303', '', '', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Beratungsprotokoll', 'Beratungsprotokoll', 101, 'P1D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000002', 'L10303', '', '', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Beratungsprotokoll', 'Beratungsprotokoll', 101, 'P2D', '', 'VNR,RVNR,KOLVNR, ANR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000003', 'L1050', '', '', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Widerruf', 'Widerruf', 1, 'P13D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000004', 'L11010', '', '', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Dynamikänderung', 'Dynamikänderung', 1, 'P14D', '', 'VNR,RVNR,KOLVNR', '', '', '', '', '', '', '');
INSERT INTO CLASSIFICATION VALUES('CLI:100000000000000000000000000000000005', 'L110102', 'CLI:100000000000000000000000000000000004', 'L11010', 'EXTERNAL', 'TASK', 'DOMAIN_A', TRUE, RELATIVE_DATE(0) , RELATIVE_DATE(0) , 'Dynamik-Ablehnung', 'Dynamik-Ablehnung', 5, 'P15D', '', 'VNR,RVNR,KOLVNR', 'TEXT_1', '', '', '', '', '', '');

View File

@ -9,6 +9,7 @@ import javax.enterprise.event.Observes;
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.InvalidOwnerException;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskAlreadyExistException;
@ -27,7 +28,7 @@ public class ExampleBootstrap {
public void init(@Observes @Initialized(ApplicationScoped.class) Object init)
throws TaskNotFoundException, NotAuthorizedException, WorkbasketNotFoundException,
ClassificationNotFoundException, InvalidStateException, InvalidOwnerException,
TaskAlreadyExistException, InvalidArgumentException {
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException {
System.out.println("---------------------------> Start App");
ObjectReference objRef = new ObjectReference();
objRef.setCompany("aCompany");

View File

@ -8,6 +8,7 @@ import pro.taskana.classification.api.exceptions.ClassificationNotFoundException
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.TaskAlreadyExistException;
import pro.taskana.task.api.models.ObjectReference;
import pro.taskana.task.api.models.Task;
@ -37,7 +38,7 @@ public class TaskanaEjb {
public void triggerRollback()
throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException,
TaskAlreadyExistException, InvalidArgumentException {
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException {
final Task task = taskService.newTask(null);
ObjectReference objRef = new ObjectReference();
objRef.setCompany("aCompany");

View File

@ -143,10 +143,12 @@ public interface TaskService {
* @throws ClassificationNotFoundException thrown if the Classification referenced by the task is
* not found
* @throws InvalidArgumentException thrown if the primary ObjectReference is invalid
* @throws AttachmentPersistenceException if an Attachment with ID will be added multiple times
* without using the task-methods
*/
Task createTask(Task taskToCreate)
throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException,
TaskAlreadyExistException, InvalidArgumentException;
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException;
/**
* Gets the details of a task by Id without checking permissions.

View File

@ -28,7 +28,7 @@ public class ObjectReference {
// check that all values in the ObjectReference are set correctly
if (objectReference == null) {
throw new InvalidArgumentException(
String.format("ObectReferenc %s of %s must not be null.", objRefType, objName));
String.format("%s of %s must not be null.", objRefType, objName));
} else if (objectReference.getCompany() == null || objectReference.getCompany().length() == 0) {
throw new InvalidArgumentException(
String.format("Company of %s of %s must not be empty", objRefType, objName));

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.ibatis.exceptions.PersistenceException;
@ -76,18 +77,70 @@ public class AttachmentHandler {
}
void insertAndDeleteAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl)
throws AttachmentPersistenceException {
throws AttachmentPersistenceException, InvalidArgumentException,
ClassificationNotFoundException {
List<Attachment> newAttachments =
newTaskImpl.getAttachments().stream().filter(Objects::nonNull).collect(Collectors.toList());
newTaskImpl.setAttachments(newAttachments);
for (Attachment attachment : newAttachments) {
verifyAttachment((AttachmentImpl) attachment, newTaskImpl.getDomain());
initAttachment((AttachmentImpl) attachment, newTaskImpl);
}
deleteRemovedAttachmentsOnTaskUpdate(newTaskImpl, oldTaskImpl);
insertNewAttachmentsOnTaskUpdate(newTaskImpl, oldTaskImpl);
updateModifiedAttachmentsOnTaskUpdate(newTaskImpl, oldTaskImpl);
}
void updateModifiedAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl) {
void insertNewAttachmentsOnTaskCreation(TaskImpl task)
throws InvalidArgumentException, AttachmentPersistenceException,
ClassificationNotFoundException {
List<Attachment> attachments = task.getAttachments();
if (attachments != null) {
for (Attachment attachment : attachments) {
AttachmentImpl attachmentImpl = (AttachmentImpl) attachment;
verifyAttachment(attachmentImpl, task.getDomain());
initAttachment(attachmentImpl, task);
try {
attachmentMapper.insert(attachmentImpl);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"TaskService.createTask() for TaskId={} INSERTED an Attachment={}.",
task.getId(),
attachmentImpl);
}
} catch (PersistenceException e) {
throw new AttachmentPersistenceException(
String.format(
"Cannot insert the Attachement %s for Task %s because it already exists.",
attachmentImpl.getId(), task.getId()),
e.getCause());
}
}
}
}
private void insertNewAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl)
throws AttachmentPersistenceException {
Set<String> oldAttachmentIds =
oldTaskImpl.getAttachments().stream()
.map(AttachmentSummary::getId)
.collect(Collectors.toSet());
List<Attachment> newAttachments =
newTaskImpl.getAttachments().stream()
.filter(a -> !oldAttachmentIds.contains(a.getId()))
.collect(Collectors.toList());
for (Attachment attachment : newAttachments) {
insertNewAttachmentOnTaskUpdate(newTaskImpl, attachment);
}
}
private void updateModifiedAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl) {
List<Attachment> newAttachments = newTaskImpl.getAttachments();
List<Attachment> oldAttachments = oldTaskImpl.getAttachments();
if (newAttachments != null
@ -107,43 +160,7 @@ public class AttachmentHandler {
}
}
void insertNewAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl)
throws AttachmentPersistenceException {
List<String> oldAttachmentIds =
oldTaskImpl.getAttachments().stream()
.map(AttachmentSummary::getId)
.collect(Collectors.toList());
List<AttachmentPersistenceException> exceptions = new ArrayList<>();
newTaskImpl
.getAttachments()
.forEach(
a -> {
if (!oldAttachmentIds.contains(a.getId())) {
try {
insertNewAttachmentOnTaskUpdate(newTaskImpl, a);
} catch (AttachmentPersistenceException excpt) {
exceptions.add(excpt);
LOGGER.warn("attempted to insert attachment {} and caught exception", a, excpt);
}
}
});
if (!exceptions.isEmpty()) {
throw exceptions.get(0);
}
}
void insertNewAttachmentsOnTaskCreation(TaskImpl task)
throws InvalidArgumentException, AttachmentPersistenceException {
List<Attachment> attachments = task.getAttachments();
if (attachments != null) {
for (Attachment attachment : attachments) {
AttachmentImpl attachmentImpl = (AttachmentImpl) attachment;
initializeAndInsertAttachment(task, attachmentImpl);
}
}
}
void deleteRemovedAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl) {
private void deleteRemovedAttachmentsOnTaskUpdate(TaskImpl newTaskImpl, TaskImpl oldTaskImpl) {
final List<Attachment> newAttachments = newTaskImpl.getAttachments();
List<String> newAttachmentIds = new ArrayList<>();
@ -169,10 +186,9 @@ public class AttachmentHandler {
}
}
void insertNewAttachmentOnTaskUpdate(TaskImpl newTaskImpl, Attachment attachment)
private void insertNewAttachmentOnTaskUpdate(TaskImpl newTaskImpl, Attachment attachment)
throws AttachmentPersistenceException {
AttachmentImpl attachmentImpl = (AttachmentImpl) attachment;
initAttachment(attachmentImpl, newTaskImpl);
try {
attachmentMapper.insert(attachmentImpl);
@ -191,7 +207,7 @@ public class AttachmentHandler {
}
}
void initAttachment(AttachmentImpl attachment, Task newTask) {
private void initAttachment(AttachmentImpl attachment, Task newTask) {
if (attachment.getId() == null) {
attachment.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_ATTACHMENT));
}
@ -206,25 +222,22 @@ public class AttachmentHandler {
}
}
private void initializeAndInsertAttachment(TaskImpl task, AttachmentImpl attachmentImpl)
throws AttachmentPersistenceException, InvalidArgumentException {
initAttachment(attachmentImpl, task);
ObjectReference objRef = attachmentImpl.getObjectReference();
ObjectReference.validate(objRef, "ObjectReference", "Attachment");
try {
attachmentMapper.insert(attachmentImpl);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"TaskService.updateTask() for TaskId={} INSERTED an Attachment={}.",
task.getId(),
attachmentImpl);
}
} catch (PersistenceException e) {
throw new AttachmentPersistenceException(
String.format(
"Cannot insert the Attachement %s for Task %s because it already exists.",
attachmentImpl.getId(), task.getId()),
e.getCause());
private void verifyAttachment(AttachmentImpl attachment, String domain)
throws InvalidArgumentException, ClassificationNotFoundException {
ClassificationSummary classification = attachment.getClassificationSummary();
if (classification == null) {
throw new InvalidArgumentException("Classification of Attachment must not be null.");
}
if (classification.getKey() == null || classification.getKey().length() == 0) {
throw new InvalidArgumentException("ClassificationKey of Attachment must not be empty.");
}
ObjectReference.validate(attachment.getObjectReference(), "ObjectReference", "Attachment");
classification =
classificationService
.getClassification(attachment.getClassificationSummary().getKey(), domain)
.asSummary();
attachment.setClassificationSummary(classification);
}
}

View File

@ -158,7 +158,7 @@ public class TaskServiceImpl implements TaskService {
@Override
public Task createTask(Task taskToCreate)
throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException,
TaskAlreadyExistException, InvalidArgumentException {
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException {
if (CreateTaskPreprocessorManager.isCreateTaskPreprocessorEnabled()) {
taskToCreate = createTaskPreprocessorManager.processTaskBeforeCreation(taskToCreate);
@ -216,7 +216,7 @@ public class TaskServiceImpl implements TaskService {
this.classificationService.getClassification(classificationKey, workbasket.getDomain());
task.setClassificationSummary(classification.asSummary());
ObjectReference.validate(task.getPrimaryObjRef(), "primary ObjectReference", "Task");
standardSettings(task, classification);
standardSettingsOnTaskCreation(task, classification);
setCallbackStateOnTaskCreation(task);
try {
this.taskMapper.insert(task);
@ -1417,54 +1417,48 @@ public class TaskServiceImpl implements TaskService {
}
}
private void standardSettings(TaskImpl task, Classification classification)
throws InvalidArgumentException {
TaskImpl task1 = task;
private void standardSettingsOnTaskCreation(TaskImpl task, Classification classification)
throws InvalidArgumentException, ClassificationNotFoundException,
AttachmentPersistenceException {
final Instant now = Instant.now();
task1.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK));
if (task1.getExternalId() == null) {
task1.setExternalId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_EXT_TASK));
task.setId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK));
if (task.getExternalId() == null) {
task.setExternalId(IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_EXT_TASK));
}
task1.setState(TaskState.READY);
task1.setCreated(now);
task1.setModified(now);
task1.setRead(false);
task1.setTransferred(false);
task.setState(TaskState.READY);
task.setCreated(now);
task.setModified(now);
task.setRead(false);
task.setTransferred(false);
String creator = taskanaEngine.getEngine().getCurrentUserContext().getUserid();
if (taskanaEngine.getEngine().getConfiguration().isSecurityEnabled() && creator == null) {
throw new SystemException(
"TaskanaSecurity is enabled, but the current UserId is NULL while creating a Task.");
}
task1.setCreator(creator);
task.setCreator(creator);
// if no business process id is provided, a unique id is created.
if (task1.getBusinessProcessId() == null) {
task1.setBusinessProcessId(
if (task.getBusinessProcessId() == null) {
task.setBusinessProcessId(
IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_BUSINESS_PROCESS));
}
// null in case of manual tasks
if (task1.getPlanned() == null && (classification == null || task1.getDue() == null)) {
task1.setPlanned(now);
if (task.getPlanned() == null && (classification == null || task.getDue() == null)) {
task.setPlanned(now);
}
if (classification != null) {
task1 = serviceLevelHandler.updatePrioPlannedDueOfTask(task1, null, false);
if (task.getName() == null && classification != null) {
task.setName(classification.getName());
}
if (task.getDescription() == null && classification != null) {
task.setDescription(classification.getDescription());
}
if (task1.getName() == null && classification != null) {
task1.setName(classification.getName());
}
if (task1.getDescription() == null && classification != null) {
task1.setDescription(classification.getDescription());
}
try {
attachmentHandler.insertNewAttachmentsOnTaskCreation(task);
} catch (AttachmentPersistenceException e) {
throw new SystemException(
"Internal error when trying to insert new Attachments on Task Creation.", e);
}
attachmentHandler.insertNewAttachmentsOnTaskCreation(task);
// This has to be called after the AttachmentHandler because the AttachmentHandler fetches
// the Classifications of the Attachments.
// This is necessary to guarantee that the following calculation is correct.
serviceLevelHandler.updatePrioPlannedDueOfTask(task, null, false);
}
private void setCallbackStateOnTaskCreation(TaskImpl task) throws InvalidArgumentException {

View File

@ -288,7 +288,7 @@ class QueryClassificationAccTest extends AbstractAccTest {
void testQueryForServiceLevelIn() {
List<ClassificationSummary> results =
classificationService.createClassificationQuery().serviceLevelIn("P2D").list();
assertThat(results).hasSize(5);
assertThat(results).hasSize(6);
}
@Test

View File

@ -190,7 +190,6 @@ class UpdateClassificationAccTest extends AbstractAccTest {
"TKI:000000000000000000000000000000000054",
"TKI:000000000000000000000000000000000055",
"TKI:000000000000000000000000000000000000",
"TKI:000000000000000000000000000000000011",
"TKI:000000000000000000000000000000000053");
validateTaskPropertiesAfterClassificationChange(
before, tasksWithP1D, taskService, converter, 1, 1000);
@ -414,7 +413,7 @@ class UpdateClassificationAccTest extends AbstractAccTest {
Classification updatedClassification =
classificationService.getClassification("CLI:100000000000000000000000000000000003");
assertThat(updatedClassification).isNotNull();
assertThat(modifiedBefore.isAfter(updatedClassification.getModified())).isFalse();
assertThat(updatedClassification.getModified()).isAfter(modifiedBefore);
// TODO - resume old behaviour after attachment query is possible.
TaskService taskService = taskanaEngine.getTaskService();
List<String> tasksWithPD12 =
@ -465,7 +464,6 @@ class UpdateClassificationAccTest extends AbstractAccTest {
List<String> tasksWithPD1 =
List.of(
"TKI:000000000000000000000000000000000000",
"TKI:000000000000000000000000000000000011",
"TKI:000000000000000000000000000000000052",
"TKI:000000000000000000000000000000000053",
"TKI:000000000000000000000000000000000054",

View File

@ -17,6 +17,10 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
import pro.taskana.classification.api.models.ClassificationSummary;
import pro.taskana.classification.internal.models.ClassificationSummaryImpl;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.test.security.JaasExtension;
@ -40,6 +44,8 @@ import pro.taskana.workbasket.api.models.Workbasket;
class CreateTaskAccTest extends AbstractAccTest {
private final TaskService taskService = taskanaEngine.getTaskService();
private final ClassificationService classificationService =
taskanaEngine.getClassificationService();
@WithAccessId(user = "user-1-1")
@Test
@ -709,6 +715,91 @@ class CreateTaskAccTest extends AbstractAccTest {
.isInstanceOf(WorkbasketNotFoundException.class);
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_CreatingTaskWithAttachmentClassificationNull() {
TaskImpl task = (TaskImpl) makeNewTask(taskService);
Attachment attachment = taskService.newAttachment();
attachment.setObjectReference(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.createTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessage("Classification of Attachment must not be null.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_CreatingTaskWithAttachmentObjectReferenceNull() {
TaskImpl task = (TaskImpl) makeNewTask(taskService);
Attachment attachment = taskService.newAttachment();
attachment.setClassificationSummary(task.getClassificationSummary());
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.createTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessageContaining("ObjectReference of Attachment must not be null.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_CreatingTaskWithNotExistingAttachmentClassification() {
Attachment attachment = taskService.newAttachment();
attachment.setObjectReference(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
ClassificationSummary classification =
classificationService.newClassification("NOT_EXISTING", "DOMAIN_A", "").asSummary();
attachment.setClassificationSummary(classification);
TaskImpl task = (TaskImpl) makeNewTask(taskService);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.createTask(task))
.isInstanceOf(ClassificationNotFoundException.class);
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_CreatingTaskWithMissingAttachmentClassificationKey() {
Attachment attachment = taskService.newAttachment();
attachment.setObjectReference(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
ClassificationSummaryImpl classification = new ClassificationSummaryImpl();
attachment.setClassificationSummary(classification);
TaskImpl task = (TaskImpl) makeNewTask(taskService);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.createTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessageContaining("ClassificationKey of Attachment must not be empty.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_FetchAttachmentClassification_When_CreatingTaskWithAttachments()
throws Exception {
Attachment attachment = taskService.newAttachment();
attachment.setObjectReference(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
ClassificationSummary classification =
classificationService.newClassification("T2000", "DOMAIN_A", "").asSummary();
attachment.setClassificationSummary(classification);
TaskImpl task = (TaskImpl) makeNewTask(taskService);
task.addAttachment(attachment);
assertThat(classification.getServiceLevel()).isNull();
task = (TaskImpl) taskService.createTask(task);
classification = task.getAttachments().get(0).getClassificationSummary();
assertThat(classification.getId()).isNotNull();
assertThat(classification.getDomain()).isNotNull();
assertThat(classification.getServiceLevel()).isNotNull();
}
private Task setTaskProperties(Task task) {
task.setClassificationKey("L12010");
task.setPrimaryObjRef(
@ -721,7 +812,6 @@ class CreateTaskAccTest extends AbstractAccTest {
newTask.setClassificationKey("L12010");
newTask.setPrimaryObjRef(
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
newTask.setClassificationKey("L12010");
return newTask;
}
}

View File

@ -123,7 +123,7 @@ class QueryTasksAccTest extends AbstractAccTest {
.createTaskQuery()
.orderByAttachmentClassificationId(DESCENDING)
.listValues(A_CLASSIFICATION_ID, null);
assertThat(columnValueList).hasSize(12);
assertThat(columnValueList).hasSize(11);
columnValueList =
TASK_SERVICE
@ -529,13 +529,13 @@ class QueryTasksAccTest extends AbstractAccTest {
@WithAccessId(user = "admin")
@Test
void testQueryForAttachmentclassificationIdIn() {
void testQueryForAttachmentClassificationIdIn() {
List<TaskSummary> results =
TASK_SERVICE
.createTaskQuery()
.attachmentClassificationIdIn("CLI:000000000000000000000000000000000002")
.attachmentClassificationIdIn("CLI:100000000000000000000000000000000002")
.list();
assertThat(results).hasSize(1);
assertThat(results).hasSize(2);
assertThat(results.get(0).getId()).isEqualTo("TKI:000000000000000000000000000000000001");
}

View File

@ -268,8 +268,8 @@ class ServiceLevelPriorityAccTest extends AbstractAccTest {
// |TAI:000000000000000000000000000000000009 | CLI:100000000000000000000000000000000003 | P13D |
// +-----------------------------------------+------------------------------------------+------+
// |TKI:000000000000000000000000000000000001 | CLI:100000000000000000000000000000000005 | P15D |
// |TAI:000000000000000000000000000000000001 | CLI:000000000000000000000000000000000002 | P2D |
// |TAI:000000000000000000000000000000000002 | CLI:000000000000000000000000000000000003 | P3d |
// |TAI:000000000000000000000000000000000001 | CLI:100000000000000000000000000000000002 | P2D |
// |TAI:000000000000000000000000000000000002 | CLI:000000000000000000000000000000000003 | P3D |
// +-----------------------------------------+------------------------------------------+------+
// |TKI:000000000000000000000000000000000002 | CLI:100000000000000000000000000000000016 | P1D |
// |TAI:000000000000000000000000000000000003 | CLI:000000000000000000000000000000000004 | P4D |

View File

@ -13,8 +13,12 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.classification.api.exceptions.ClassificationNotFoundException;
import pro.taskana.classification.api.models.Classification;
import pro.taskana.classification.api.models.ClassificationSummary;
import pro.taskana.classification.internal.models.ClassificationSummaryImpl;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.test.security.JaasExtension;
import pro.taskana.common.test.security.WithAccessId;
import pro.taskana.task.api.TaskService;
@ -35,11 +39,13 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
private Task task;
private Attachment attachment;
private TaskService taskService;
private ClassificationService classificationService;
@BeforeEach
@WithAccessId(user = "admin")
void setUp() throws Exception {
taskService = taskanaEngine.getTaskService();
classificationService = taskanaEngine.getClassificationService();
task =
taskService.getTask(
"TKI:000000000000000000000000000000000000"); // class T2000, prio 1, SL P1D
@ -71,6 +77,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertThat(task.getAttachments())
.hasSize(attachmentCount + 1)
.contains(attachment)
@ -136,14 +143,14 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
Classification newClassification =
taskanaEngine
.getClassificationService()
.getClassification("CLI:000000000000000000000000000000000001"); // Prio 999, SL PT5H
.getClassification("CLI:100000000000000000000000000000000013"); // Prio 99, P2000D
updatedAttachment.setClassificationSummary(newClassification.asSummary());
task.addAttachment(updatedAttachment);
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertThat(task.getAttachments()).hasSize(attachmentCount2);
assertThat(task.getAttachments().get(0).getChannel()).isEqualTo(newChannel);
assertThat(task.getPriority()).isEqualTo(999);
assertThat(task.getPriority()).isEqualTo(99);
Instant expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expDue);
@ -261,13 +268,13 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
Classification newClassification =
taskanaEngine
.getClassificationService()
.getClassification("CLI:000000000000000000000000000000000001"); // Prio 999, SL PT5H
.getClassification("CLI:100000000000000000000000000000000013"); // Prio 99, P2000D
task.getAttachments().get(0).setClassificationSummary(newClassification.asSummary());
task = taskService.updateTask(task);
task = taskService.getTask(task.getId());
assertThat(task.getAttachments()).hasSize(attachmentCount);
assertThat(task.getAttachments().get(0).getChannel()).isEqualTo(newChannel);
assertThat(task.getPriority()).isEqualTo(999);
assertThat(task.getPriority()).isEqualTo(99);
Instant expDue = converter.addWorkingDaysToInstant(task.getPlanned(), Duration.ofDays(1));
assertThat(task.getDue()).isEqualTo(expDue);
@ -498,4 +505,103 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
assertThat(updatedTask.getModified()).isEqualTo(updatedAttachment.getModified());
assertThat(updatedAttachment.getCustomAttributeMap().get("TEST_KEY")).isEqualTo("TEST_VALUE");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_UpdatingTaskWithNewAttachmentClassificationNull() {
attachment.setClassificationSummary(null);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessage("Classification of Attachment must not be null.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_UpdatingTaskWithChangedAttachmentClassificationNull()
throws Exception {
task.addAttachment(attachment);
taskService.updateTask(task);
attachment.setClassificationSummary(null);
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessage("Classification of Attachment must not be null.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_UpdatingTaskWithNewAttachmentObjectReferenceNull()
throws Exception {
task.addAttachment(attachment);
taskService.updateTask(task);
task.removeAttachment(attachment.getId());
attachment.setObjectReference(null);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessage("ObjectReference of Attachment must not be null.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_UpdatingTaskWithChangedAttachmentObjectReferenceNull()
throws Exception {
task.addAttachment(attachment);
taskService.updateTask(task);
task.removeAttachment(attachment.getId());
attachment.setObjectReference(null);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessage("ObjectReference of Attachment must not be null.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_UpdatingTaskWithMissingAttachmentClassificationKey() {
ClassificationSummaryImpl classification = new ClassificationSummaryImpl();
attachment.setClassificationSummary(classification);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(InvalidArgumentException.class)
.hasMessageContaining("ClassificationKey of Attachment must not be empty.");
}
@WithAccessId(user = "user-1-1")
@Test
void should_ThrowException_When_UpdatingTaskWithNotExistingAttachmentClassification() {
Classification classification =
classificationService.newClassification("NOT_EXISTING", "DOMAIN_A", "");
attachment.setClassificationSummary(classification);
task.addAttachment(attachment);
assertThatThrownBy(() -> taskService.updateTask(task))
.isInstanceOf(ClassificationNotFoundException.class);
}
@WithAccessId(user = "user-1-1")
@Test
void should_FetchAttachmentClassification_When_UpdatingTaskWithAttachments()
throws Exception {
ClassificationSummary classification =
classificationService.newClassification("T2000", "DOMAIN_A", "").asSummary();
attachment.setClassificationSummary(classification);
task.addAttachment(attachment);
assertThat(classification.getServiceLevel()).isNull();
TaskImpl updatedTask = (TaskImpl) taskService.updateTask(task);
classification = updatedTask.getAttachments().get(0).getClassificationSummary();
assertThat(classification.getId()).isNotNull();
assertThat(classification.getDomain()).isNotNull();
assertThat(classification.getServiceLevel()).isNotNull();
}
}

View File

@ -13,6 +13,7 @@ import pro.taskana.common.api.exceptions.DomainNotFoundException;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.InvalidOwnerException;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskAlreadyExistException;
@ -40,7 +41,7 @@ public class ExampleBootstrap {
ClassificationNotFoundException, InvalidStateException, InvalidOwnerException,
TaskAlreadyExistException, InvalidArgumentException, DomainNotFoundException,
InvalidWorkbasketException, WorkbasketAlreadyExistException,
ClassificationAlreadyExistException {
ClassificationAlreadyExistException, AttachmentPersistenceException {
System.out.println("---------------------------> Start App");
Workbasket wb = taskanaEngine.getWorkbasketService().newWorkbasket("workbasket", "DOMAIN_A");

View File

@ -8,6 +8,7 @@ import pro.taskana.classification.api.exceptions.ClassificationNotFoundException
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.AttachmentPersistenceException;
import pro.taskana.task.api.exceptions.TaskAlreadyExistException;
import pro.taskana.task.api.models.ObjectReference;
import pro.taskana.task.api.models.Task;
@ -26,7 +27,7 @@ public class TaskanaComponent {
public void triggerRollback()
throws NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException,
TaskAlreadyExistException, InvalidArgumentException {
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException {
Task task = taskService.newTask("1");
task.setName("Unit Test Task");
ObjectReference objRef = new ObjectReference();

View File

@ -329,6 +329,8 @@ public class TaskController {
* referenced Workbasket
* @throws TaskAlreadyExistException if the requested Task already exists.
* @throws InvalidArgumentException if any input is semantically wrong.
* @throws AttachmentPersistenceException if an Attachment with ID will be added multiple times
* without using the task-methods
* @title Create a new Task
*/
@PostMapping(path = RestEndpoints.URL_TASKS)
@ -336,7 +338,7 @@ public class TaskController {
public ResponseEntity<TaskRepresentationModel> createTask(
@RequestBody TaskRepresentationModel taskRepresentationModel)
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
TaskAlreadyExistException, InvalidArgumentException {
TaskAlreadyExistException, InvalidArgumentException, AttachmentPersistenceException {
Task fromResource = taskRepresentationModelAssembler.toEntityModel(taskRepresentationModel);
Task createdTask = taskService.createTask(fromResource);