From 4e0388ee6185e4a93299264a6d61756cd562a9f5 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Thu, 2 May 2024 08:46:00 -0600 Subject: [PATCH 01/10] feat(engine) Add update and delete Java/Rest APIs of task and processInstance DELETE /task/{taskId}/comment/{commentId} - deletes a comment of a given taskId and commentId DELETE /task/{taskId}/comment - deletes all comments of a given taskId PUT /task/comment - updates a comment DELETE /process-instance/{processInstanceId}/comment/{commentId} - deletes a comment of a given processInstanceId and commentId DELETE /process-instance/{processInstanceId}/comment. - deletes all comments of a given processInstanceId PUT /process-instance/comment - updates a comment related to: https://github.com/camunda/camunda-bpm-platform/issues/2551 --- .../org/camunda/bpm/engine/EntityTypes.java | 1 + .../org/camunda/bpm/engine/TaskService.java | 30 ++ .../engine/history/UserOperationLogEntry.java | 3 + .../bpm/engine/impl/TaskServiceImpl.java | 30 ++ .../bpm/engine/impl/cfg/CommandChecker.java | 5 + .../cfg/auth/AuthorizationCommandChecker.java | 56 ++- .../multitenancy/TenantCommandChecker.java | 17 +- .../bpm/engine/impl/cmd/AddCommentCmd.java | 12 +- .../cmd/DeleteProcessInstanceCommentCmd.java | 76 ++++ .../cmd/DeleteProcessInstanceCommentsCmd.java | 67 +++ .../engine/impl/cmd/DeleteTaskCommentCmd.java | 74 ++++ .../impl/cmd/DeleteTaskCommentsCmd.java | 64 +++ .../cmd/UpdateProcessInstanceCommentCmd.java | 90 ++++ .../engine/impl/cmd/UpdateTaskCommentCmd.java | 86 ++++ .../persistence/entity/CommentEntity.java | 8 + .../persistence/entity/CommentManager.java | 23 + .../entity/UserOperationLogManager.java | 28 ++ .../engine/impl/mapping/entity/Comment.xml | 61 ++- .../api/authorization/AuthorizationTest.java | 7 + ...ocessInstanceCommentAuthorizationTest.java | 168 +++++++ .../TaskCommentAuthorizationTest.java | 156 +++++++ .../ProcessEngineCharacterEncodingTest.java | 38 +- .../test/api/task/TaskLastUpdatedTest.java | 111 ++++- .../engine/test/api/task/TaskServiceTest.java | 415 +++++++++++++++++- 24 files changed, 1584 insertions(+), 42 deletions(-) create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java create mode 100644 engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java create mode 100644 engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java diff --git a/engine/src/main/java/org/camunda/bpm/engine/EntityTypes.java b/engine/src/main/java/org/camunda/bpm/engine/EntityTypes.java index 07850a5ec8f..967a087f4cf 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/EntityTypes.java +++ b/engine/src/main/java/org/camunda/bpm/engine/EntityTypes.java @@ -57,4 +57,5 @@ public class EntityTypes { public static final String OPERATION_LOG = "OperationLog"; public static final String INCIDENT = "Incident"; public static final String SYSTEM = "System"; + public static final String COMMENT = "Comment"; } diff --git a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java index 36ec40b3bbd..c0fa0f1d49a 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java +++ b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java @@ -1107,6 +1107,36 @@ public interface TaskService { /** Creates a comment to a task and/or process instance and returns the comment. */ Comment createComment(String taskId, String processInstanceId, String message); + /** + * Deletes a comment by a given taskId and comment ID + */ + void deleteTaskComment(String taskId, String commentId); + + /** + * Deletes a comment by a given processInstanceId and comment ID + */ + void deleteProcessInstanceComment(String processInstanceId, String commentId); + + /** + * Deletes comments by a given task ID + */ + void deleteTaskComments(String taskId); + + /** + * Deletes comments by a given processInstance ID + */ + void deleteProcessInstanceComments(String processInstanceId); + + /** + * Updates comment on a given task ID + */ + void updateTaskComment(String taskId, String commentId, String message); + + /** + * Updates comment on a given processInstance ID + */ + void updateProcessInstanceComment(String processInstanceId, String commentId, String message); + /** The comments related to the given task. */ List getTaskComments(String taskId); diff --git a/engine/src/main/java/org/camunda/bpm/engine/history/UserOperationLogEntry.java b/engine/src/main/java/org/camunda/bpm/engine/history/UserOperationLogEntry.java index 920c7227ad4..5f4f425ca5b 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/history/UserOperationLogEntry.java +++ b/engine/src/main/java/org/camunda/bpm/engine/history/UserOperationLogEntry.java @@ -122,6 +122,9 @@ public interface UserOperationLogEntry { String OPERATION_TYPE_SET_VARIABLE = "SetVariable"; String OPERATION_TYPE_SET_VARIABLES = "SetVariables"; + String OPERATION_TYPE_UPDATE_COMMENT = "UpdateComment"; + String OPERATION_TYPE_DELETE_COMMENT = "DeleteComment"; + String OPERATION_TYPE_REMOVE_VARIABLE = "RemoveVariable"; String OPERATION_TYPE_MODIFY_VARIABLE = "ModifyVariable"; diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java b/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java index 7a627ba6279..170bb135ca2 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java @@ -40,7 +40,11 @@ import org.camunda.bpm.engine.impl.cmd.DelegateTaskCmd; import org.camunda.bpm.engine.impl.cmd.DeleteAttachmentCmd; import org.camunda.bpm.engine.impl.cmd.DeleteGroupIdentityLinkCmd; +import org.camunda.bpm.engine.impl.cmd.DeleteProcessInstanceCommentCmd; +import org.camunda.bpm.engine.impl.cmd.DeleteProcessInstanceCommentsCmd; import org.camunda.bpm.engine.impl.cmd.DeleteTaskCmd; +import org.camunda.bpm.engine.impl.cmd.DeleteTaskCommentCmd; +import org.camunda.bpm.engine.impl.cmd.DeleteTaskCommentsCmd; import org.camunda.bpm.engine.impl.cmd.DeleteUserIdentityLinkCmd; import org.camunda.bpm.engine.impl.cmd.GetAttachmentCmd; import org.camunda.bpm.engine.impl.cmd.GetAttachmentContentCmd; @@ -71,6 +75,8 @@ import org.camunda.bpm.engine.impl.cmd.SetTaskOwnerCmd; import org.camunda.bpm.engine.impl.cmd.SetTaskPriorityCmd; import org.camunda.bpm.engine.impl.cmd.SetTaskVariablesCmd; +import org.camunda.bpm.engine.impl.cmd.UpdateProcessInstanceCommentCmd; +import org.camunda.bpm.engine.impl.cmd.UpdateTaskCommentCmd; import org.camunda.bpm.engine.impl.util.ExceptionUtil; import org.camunda.bpm.engine.task.Attachment; import org.camunda.bpm.engine.task.Comment; @@ -380,6 +386,30 @@ public Comment createComment(String taskId, String processInstance, String messa return commandExecutor.execute(new AddCommentCmd(taskId, processInstance, message)); } + public void deleteTaskComment(String taskId, String commentId) { + commandExecutor.execute(new DeleteTaskCommentCmd(taskId, commentId)); + } + + public void deleteProcessInstanceComment(String processInstanceId, String commentId) { + commandExecutor.execute(new DeleteProcessInstanceCommentCmd(processInstanceId, commentId)); + } + + public void deleteTaskComments(String taskId) { + commandExecutor.execute(new DeleteTaskCommentsCmd(taskId)); + } + + public void deleteProcessInstanceComments(String processInstanceId) { + commandExecutor.execute(new DeleteProcessInstanceCommentsCmd(processInstanceId)); + } + + public void updateTaskComment(String taskId, String commentId, String message) { + commandExecutor.execute(new UpdateTaskCommentCmd(taskId, commentId, message)); + } + + public void updateProcessInstanceComment(String processInstanceId, String commentId, String message) { + commandExecutor.execute(new UpdateProcessInstanceCommentCmd(processInstanceId, commentId, message)); + } + public List getTaskComments(String taskId) { return commandExecutor.execute(new GetTaskCommentsCmd(taskId)); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java index 8596ac73a6c..fd9cab75d38 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java @@ -271,6 +271,11 @@ public interface CommandChecker { */ void checkDeleteTask(TaskEntity task); + /** + * Check if it is allowed to update a task + */ + void checkUpdateTask(TaskEntity task); + /** * Checks if it is allowed to read the given decision definition. */ diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java index 0eb0e4c5714..abd204e0eed 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java @@ -16,6 +16,36 @@ */ package org.camunda.bpm.engine.impl.cfg.auth; +import static org.camunda.bpm.engine.authorization.Authorization.ANY; +import static org.camunda.bpm.engine.authorization.Permissions.CREATE; +import static org.camunda.bpm.engine.authorization.Permissions.CREATE_INSTANCE; +import static org.camunda.bpm.engine.authorization.Permissions.DELETE; +import static org.camunda.bpm.engine.authorization.Permissions.DELETE_HISTORY; +import static org.camunda.bpm.engine.authorization.Permissions.DELETE_INSTANCE; +import static org.camunda.bpm.engine.authorization.Permissions.READ; +import static org.camunda.bpm.engine.authorization.Permissions.READ_HISTORY; +import static org.camunda.bpm.engine.authorization.Permissions.READ_INSTANCE; +import static org.camunda.bpm.engine.authorization.Permissions.READ_TASK; +import static org.camunda.bpm.engine.authorization.Permissions.TASK_ASSIGN; +import static org.camunda.bpm.engine.authorization.Permissions.TASK_WORK; +import static org.camunda.bpm.engine.authorization.Permissions.UPDATE; +import static org.camunda.bpm.engine.authorization.Permissions.UPDATE_INSTANCE; +import static org.camunda.bpm.engine.authorization.Permissions.UPDATE_TASK; +import static org.camunda.bpm.engine.authorization.Resources.BATCH; +import static org.camunda.bpm.engine.authorization.Resources.DECISION_DEFINITION; +import static org.camunda.bpm.engine.authorization.Resources.DECISION_REQUIREMENTS_DEFINITION; +import static org.camunda.bpm.engine.authorization.Resources.DEPLOYMENT; +import static org.camunda.bpm.engine.authorization.Resources.PROCESS_DEFINITION; +import static org.camunda.bpm.engine.authorization.Resources.PROCESS_INSTANCE; +import static org.camunda.bpm.engine.authorization.Resources.TASK; + +import org.camunda.bpm.engine.authorization.Permission; +import org.camunda.bpm.engine.authorization.ProcessDefinitionPermissions; +import org.camunda.bpm.engine.authorization.ProcessInstancePermissions; +import org.camunda.bpm.engine.authorization.Resources; +import org.camunda.bpm.engine.authorization.SystemPermissions; +import org.camunda.bpm.engine.authorization.TaskPermissions; +import org.camunda.bpm.engine.authorization.UserOperationLogCategoryPermissions; import org.camunda.bpm.engine.history.HistoricCaseInstance; import org.camunda.bpm.engine.history.HistoricDecisionInstance; import org.camunda.bpm.engine.history.HistoricProcessInstance; @@ -29,24 +59,20 @@ import org.camunda.bpm.engine.impl.dmn.entity.repository.DecisionDefinitionEntity; import org.camunda.bpm.engine.impl.dmn.entity.repository.DecisionRequirementsDefinitionEntity; import org.camunda.bpm.engine.impl.history.event.HistoricExternalTaskLogEntity; -import org.camunda.bpm.engine.impl.persistence.entity.*; +import org.camunda.bpm.engine.impl.persistence.entity.AuthorizationManager; +import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricJobLogEventEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricTaskInstanceEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricVariableInstanceEntity; +import org.camunda.bpm.engine.impl.persistence.entity.JobEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; import org.camunda.bpm.engine.repository.CaseDefinition; import org.camunda.bpm.engine.repository.DecisionDefinition; import org.camunda.bpm.engine.repository.ProcessDefinition; import org.camunda.bpm.engine.runtime.CaseExecution; -import static org.camunda.bpm.engine.authorization.Authorization.ANY; -import static org.camunda.bpm.engine.authorization.Permissions.*; -import static org.camunda.bpm.engine.authorization.Resources.*; - -import org.camunda.bpm.engine.authorization.Permission; -import org.camunda.bpm.engine.authorization.ProcessDefinitionPermissions; -import org.camunda.bpm.engine.authorization.ProcessInstancePermissions; -import org.camunda.bpm.engine.authorization.Resources; -import org.camunda.bpm.engine.authorization.SystemPermissions; -import org.camunda.bpm.engine.authorization.TaskPermissions; -import org.camunda.bpm.engine.authorization.UserOperationLogCategoryPermissions; - /** * {@link CommandChecker} that uses the {@link AuthorizationManager} to perform * authorization checks. @@ -736,6 +762,10 @@ public void checkDeleteTask(TaskEntity task) { } } + public void checkUpdateTask(TaskEntity task) { + getAuthorizationManager().checkAuthorization(UPDATE, TASK, task.getId()); + } + public void checkUserOperationLog(UserOperationLogEntry entry, ProcessDefinitionPermissions processDefinitionPermission, UserOperationLogCategoryPermissions operationLogCategoryPermission) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java index b37fcb2a452..93c6d6e8965 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java @@ -30,7 +30,16 @@ import org.camunda.bpm.engine.impl.dmn.entity.repository.DecisionDefinitionEntity; import org.camunda.bpm.engine.impl.dmn.entity.repository.DecisionRequirementsDefinitionEntity; import org.camunda.bpm.engine.impl.history.event.HistoricExternalTaskLogEntity; -import org.camunda.bpm.engine.impl.persistence.entity.*; +import org.camunda.bpm.engine.impl.persistence.entity.DeploymentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricJobLogEventEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricTaskInstanceEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricVariableInstanceEntity; +import org.camunda.bpm.engine.impl.persistence.entity.JobEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; +import org.camunda.bpm.engine.impl.persistence.entity.TenantManager; import org.camunda.bpm.engine.repository.CaseDefinition; import org.camunda.bpm.engine.repository.DecisionDefinition; import org.camunda.bpm.engine.repository.ProcessDefinition; @@ -331,6 +340,12 @@ public void checkDeleteTask(TaskEntity task) { } } + public void checkUpdateTask(TaskEntity task) { + if (task != null && !getTenantManager().isAuthenticatedTenant(task.getTenantId())) { + throw LOG.exceptionCommandWithUnauthorizedTenant("update the task '" + task.getId() + "'"); + } + } + public void checkTaskAssign(TaskEntity task) { if (task != null && !getTenantManager().isAuthenticatedTenant(task.getTenantId())) { throw LOG.exceptionCommandWithUnauthorizedTenant("assign the task '"+ task.getId() + "'"); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/AddCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/AddCommentCmd.java index 31e4fc69174..1b2713c40d7 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/AddCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/AddCommentCmd.java @@ -16,9 +16,11 @@ */ package org.camunda.bpm.engine.impl.cmd; +import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_REMOVAL_TIME_STRATEGY_START; +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + import java.io.Serializable; import java.util.Date; - import org.camunda.bpm.engine.ProcessEngineException; import org.camunda.bpm.engine.impl.context.Context; import org.camunda.bpm.engine.impl.history.event.HistoricProcessInstanceEventEntity; @@ -31,9 +33,6 @@ import org.camunda.bpm.engine.task.Comment; import org.camunda.bpm.engine.task.Event; -import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_REMOVAL_TIME_STRATEGY_START; -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; - /** * @author Tom Baeyens @@ -78,10 +77,7 @@ public Comment execute(CommandContext commandContext) { provideRemovalTime(comment); } - String eventMessage = message.replaceAll("\\s+", " "); - if (eventMessage.length() > 163) { - eventMessage = eventMessage.substring(0, 160) + "..."; - } + String eventMessage = comment.toEventMessage(message); comment.setMessage(eventMessage); comment.setFullMessage(message); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java new file mode 100644 index 00000000000..00384d90f0a --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java @@ -0,0 +1,76 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; + +/** + * Command to delete a comment by a given commentId and processInstanceId. + */ +public class DeleteProcessInstanceCommentCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String commentId; + protected String processInstanceId; + + public DeleteProcessInstanceCommentCmd(String processInstanceId, String commentId) { + this.processInstanceId = processInstanceId; + this.commentId = commentId; + } + + public Object execute(CommandContext commandContext) { + ensureNotNull("commentId", commentId); + + CommentEntity comment = commandContext.getCommentManager() + .findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); + + if (comment != null) { + TaskEntity task = getTask(comment, commandContext); + checkUpdateProcessInstance(processInstanceId, commandContext); + commandContext.getDbEntityManager().delete(comment); + + PropertyChange propertyChange = new PropertyChange("comment", null, comment.getMessage()); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); + task.triggerUpdateEvent(); + } + + return null; + } + + private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) { + String taskId = comment.getTaskId(); + TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); + ensureNotNull("Task not found for taskId: " + taskId + " CommentId: " + commentId, "comment", comment); + return task; + } + + protected void checkUpdateProcessInstance(String processInstanceId, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateProcessInstanceById(processInstanceId); + } + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java new file mode 100644 index 00000000000..95a9043462e --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java @@ -0,0 +1,67 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.task.Comment; + +/** + * Command to delete comments by a given processInstance ID. + */ +public class DeleteProcessInstanceCommentsCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String processInstanceId; + + public DeleteProcessInstanceCommentsCmd(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public Object execute(CommandContext commandContext) { + ensureNotNull("processInstanceId", processInstanceId); + ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); + ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance: ", + processInstance); + + List comments = commandContext.getCommentManager().findCommentsByProcessInstanceId(processInstanceId); + if (!comments.isEmpty()) { + checkUpdateProcessInstance(processInstanceId, commandContext); + commandContext.getCommentManager() + .deleteCommentsByProcessInstanceIds(Collections.singletonList(processInstanceId)); + PropertyChange propertyChange = new PropertyChange("comment", null, null); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, processInstance, propertyChange); + } + return null; + } + + protected void checkUpdateProcessInstance(String processInstanceId, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateProcessInstanceById(processInstanceId); + } + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java new file mode 100644 index 00000000000..00ba640ac56 --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java @@ -0,0 +1,74 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; + +/** + * Command to delete a comment by a given commentId and taskId. + */ +public class DeleteTaskCommentCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String commentId; + protected String taskId; + + public DeleteTaskCommentCmd(String taskId, String commentId) { + this.taskId = taskId; + this.commentId = commentId; + } + + public Object execute(CommandContext commandContext) { + ensureNotNull("commentId", commentId); + + CommentEntity comment = commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); + if (comment != null) { + TaskEntity task = getTask(comment, commandContext); + + checkUpdateTask(task, commandContext); + commandContext.getDbEntityManager().delete(comment); + + PropertyChange propertyChange = new PropertyChange("comment", null, comment.getMessage()); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); + task.triggerUpdateEvent(); + } + return null; + } + + private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) { + String taskId = comment.getTaskId(); + TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); + ensureNotNull("Task not found for taskId: " + taskId + " CommentId: " + commentId, "comment", comment); + return task; + } + + protected void checkUpdateTask(TaskEntity task, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateTask(task); + } + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java new file mode 100644 index 00000000000..d6ea7857c06 --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java @@ -0,0 +1,64 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import java.util.List; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; +import org.camunda.bpm.engine.task.Comment; + +/** + * Command to delete comments by a given task ID. + */ +public class DeleteTaskCommentsCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String taskId; + + public DeleteTaskCommentsCmd(String taskId) { + this.taskId = taskId; + } + + public Void execute(CommandContext commandContext) { + ensureNotNull("taskId", taskId); + TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); + ensureNotNull("No task exists with taskId: " + taskId, "task", task); + List comments = commandContext.getCommentManager().findCommentsByTaskId(taskId); + if (!comments.isEmpty()) { + checkUpdateTask(task, commandContext); + commandContext.getCommentManager().deleteCommentsByTaskId(taskId); + PropertyChange propertyChange = new PropertyChange("comment", null, null); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); + task.triggerUpdateEvent(); + } + return null; + } + + protected void checkUpdateTask(TaskEntity task, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateTask(task); + } + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java new file mode 100644 index 00000000000..49cfb653817 --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java @@ -0,0 +1,90 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.impl.util.ClockUtil; + +/** + * Command to update a comment by a given processInstance ID. + */ +public class UpdateProcessInstanceCommentCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String commentId; + protected String message; + protected String processInstanceId; + + public UpdateProcessInstanceCommentCmd(String processInstanceId, String commentId, String message) { + this.processInstanceId = processInstanceId; + this.commentId = commentId; + this.message = message; + } + + public Object execute(CommandContext commandContext) { + ensureNotNull("commentId", commentId); + ensureNotNull("processInstanceId", processInstanceId); + ensureNotNull("message", message); + + CommentEntity comment = commandContext.getCommentManager() + .findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); + ensureNotNull("No comment exists with commentId: " + commentId + " and processInstanceId: " + processInstanceId, + "comment", comment); + + ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); + ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance", + processInstance); + + checkUpdateProcessInstance(processInstanceId, commandContext); + updateComment(commandContext, comment, message); + + PropertyChange propertyChange = new PropertyChange("comment", comment.getMessage(), message); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, processInstance, propertyChange); + + return null; + } + + protected void checkUpdateProcessInstance(String processInstanceId, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateProcessInstanceById(processInstanceId); + } + } + + private void updateComment(CommandContext commandContext, CommentEntity comment, String message) { + String eventMessage = comment.toEventMessage(message); + String userId = commandContext.getAuthenticatedUserId(); + + comment.setMessage(eventMessage); + comment.setFullMessage(message); + comment.setTime(ClockUtil.getCurrentTime()); + comment.setAction(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT); + comment.setUserId(userId); + + commandContext.getCommentManager().updateCommentMessage(comment); + } + +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java new file mode 100644 index 00000000000..4da47db8679 --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java @@ -0,0 +1,86 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; +import org.camunda.bpm.engine.impl.util.ClockUtil; + +/** + * Command to update a comment by a given task ID. + */ +public class UpdateTaskCommentCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String taskId; + protected String commentId; + protected String message; + + public UpdateTaskCommentCmd(String taskId, String commentId, String message) { + this.taskId = taskId; + this.commentId = commentId; + this.message = message; + } + + public Object execute(CommandContext commandContext) { + ensureNotNull("commentId", commentId); + ensureNotNull("taskId", taskId); + ensureNotNull("message", message); + + CommentEntity comment = commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); + ensureNotNull("No comment exists with commentId: " + commentId + " and taskId: " + taskId, "comment", comment); + TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); + ensureNotNull("No task exists with taskId: " + taskId, "task", task); + + checkUpdateTask(task, commandContext); + updateComment(commandContext, comment); + PropertyChange propertyChange = new PropertyChange("comment", comment.getMessage(), message); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, task, propertyChange); + task.triggerUpdateEvent(); + + return null; + } + + private void updateComment(CommandContext commandContext, CommentEntity comment) { + String eventMessage = comment.toEventMessage(message); + + String userId = commandContext.getAuthenticatedUserId(); + + comment.setMessage(eventMessage); + comment.setFullMessage(message); + comment.setTime(ClockUtil.getCurrentTime()); + comment.setAction(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT); + comment.setUserId(userId); + + commandContext.getCommentManager().updateCommentMessage(comment); + } + + protected void checkUpdateTask(TaskEntity task, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateTask(task); + } + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java index 776ff259403..a75d3d5249c 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java @@ -201,6 +201,14 @@ public void setRemovalTime(Date removalTime) { this.removalTime = removalTime; } + public String toEventMessage(String message) { + String eventMessage = message.replaceAll("\\s+", " "); + if (eventMessage.length() > 163) { + eventMessage = eventMessage.substring(0, 160) + "..."; + } + return eventMessage; + } + @Override public String toString() { return this.getClass().getSimpleName() diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java index 42e6fa8b27f..fc940a10fdb 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java @@ -108,6 +108,16 @@ public CommentEntity findCommentByTaskIdAndCommentId(String taskId, String comme return (CommentEntity) getDbEntityManager().selectOne("selectCommentByTaskIdAndCommentId", parameters); } + public CommentEntity findCommentByProcessInstanceIdAndCommentId(String processInstanceId, String commentId) { + checkHistoryEnabled(); + + Map parameters = new HashMap<>(); + parameters.put("processInstanceId", processInstanceId); + parameters.put("id", commentId); + + return (CommentEntity) getDbEntityManager().selectOne("selectCommentByProcessInstanceIdAndCommentId", parameters); + } + public DbOperation addRemovalTimeToCommentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); @@ -142,4 +152,17 @@ public DbOperation deleteCommentsByRemovalTime(Date removalTime, int minuteFrom, new ListQueryParameterObject(parameters, 0, batchSize)); } + public void updateCommentMessage(CommentEntity entity) { + checkHistoryEnabled(); + Map parameters = new HashMap<>(); + parameters.put("message", entity.getMessage()); + parameters.put("fullMessageBytes", entity.getFullMessageBytes()); + parameters.put("time", entity.getTime()); + parameters.put("action", entity.getAction()); + parameters.put("id", entity.getId()); + parameters.put("userId", entity.getUserId()); + + getDbEntityManager().update(CommentEntity.class, "updateComment", parameters); + } + } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java index 3d47d89b431..e7259ec0a45 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java @@ -493,6 +493,34 @@ public void logAttachmentOperation(String operation, ExecutionEntity processInst } } + public void logCommentOperation(String operation, TaskEntity task, PropertyChange propertyChange) { + if (isUserOperationLogEnabled()) { + UserOperationLogContext context = new UserOperationLogContext(); + + UserOperationLogContextEntryBuilder entryBuilder = UserOperationLogContextEntryBuilder.entry(operation, + EntityTypes.COMMENT) + .category(UserOperationLogEntry.CATEGORY_TASK_WORKER) + .inContextOf(task, Collections.singletonList(propertyChange)); + context.addEntry(entryBuilder.create()); + + fireUserOperationLog(context); + } + } + + public void logCommentOperation(String operation, ExecutionEntity processInstance, PropertyChange propertyChange) { + if (isUserOperationLogEnabled()) { + UserOperationLogContext context = new UserOperationLogContext(); + + UserOperationLogContextEntryBuilder entryBuilder = UserOperationLogContextEntryBuilder.entry(operation, + EntityTypes.COMMENT) + .category(UserOperationLogEntry.CATEGORY_TASK_WORKER) + .inContextOf(processInstance, Collections.singletonList(propertyChange)); + context.addEntry(entryBuilder.create()); + + fireUserOperationLog(context); + } + } + public void logVariableOperation(String operation, String executionId, String taskId, PropertyChange propertyChange) { if(isUserOperationLogEnabled()) { diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml index d24345f9219..19825d62a9a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml @@ -20,9 +20,9 @@ - + - + insert into ${prefix}ACT_HI_COMMENT (ID_, TYPE_, TIME_, USER_ID_, TASK_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, ACTION_, MESSAGE_, FULL_MSG_, TENANT_ID_, REMOVAL_TIME_) values ( @@ -60,6 +60,17 @@ + + update + ${prefix}ACT_HI_COMMENT + set MESSAGE_ = #{message ,jdbcType=VARCHAR}, + FULL_MSG_= #{fullMessageBytes ,jdbcType=BLOB}, + TIME_ = #{time ,jdbcType=TIMESTAMP}, + ACTION_ = #{action ,jdbcType=VARCHAR}, + USER_ID_ = #{userId ,jdbcType=VARCHAR} + where ID_ = #{id} + + update @@ -213,13 +224,19 @@ + + delete + from ${prefix}ACT_HI_COMMENT + where ID_ = #{id} + + - delete from ${prefix}ACT_HI_COMMENT where TASK_ID_ = #{taskId} + delete from ${prefix}ACT_HI_COMMENT where TASK_ID_ = #{taskId} delete from ${prefix}ACT_HI_COMMENT - where + where TASK_ID_ in ( select ID_ @@ -348,20 +365,25 @@ - + + - + @@ -427,29 +449,36 @@ + + diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/AuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/AuthorizationTest.java index b3c16f8bbde..7426c80036d 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/AuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/AuthorizationTest.java @@ -50,6 +50,7 @@ import org.camunda.bpm.engine.runtime.CaseInstance; import org.camunda.bpm.engine.runtime.Job; import org.camunda.bpm.engine.runtime.ProcessInstance; +import org.camunda.bpm.engine.task.Comment; import org.camunda.bpm.engine.task.Task; import org.camunda.bpm.engine.test.util.PluggableProcessEngineTest; import org.camunda.bpm.engine.variable.VariableMap; @@ -69,6 +70,8 @@ public abstract class AuthorizationTest extends PluggableProcessEngineTest { protected static final String VARIABLE_NAME = "aVariableName"; protected static final String VARIABLE_VALUE = "aVariableValue"; + protected static final String TASK_ID = "myTask"; + protected List deploymentIds = new ArrayList<>(); @Before @@ -287,6 +290,10 @@ protected void deleteTask(final String taskId, final boolean cascade) { }); } + protected Comment createComment(String taskId, String processInstanceId, String message) { + return runWithoutAuthorization(() -> taskService.createComment(taskId, processInstanceId, message)); + } + protected void addCandidateUser(final String taskId, final String user) { runWithoutAuthorization((Callable) () -> { taskService.addCandidateUser(taskId, user); diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java new file mode 100644 index 00000000000..1bf6033e0e4 --- /dev/null +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java @@ -0,0 +1,168 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.test.api.authorization; + +import static org.camunda.bpm.engine.authorization.Permissions.UPDATE; +import static org.camunda.bpm.engine.authorization.Resources.PROCESS_INSTANCE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import java.util.Collections; +import java.util.List; +import org.camunda.bpm.engine.AuthorizationException; +import org.camunda.bpm.engine.task.Comment; +import org.camunda.bpm.engine.test.Deployment; +import org.junit.Test; + +public class ProcessInstanceCommentAuthorizationTest extends AuthorizationTest { + protected static final String ONE_TASK_PROCESS_KEY = "oneTaskProcess"; + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceCommentWithoutAuthorization() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + createTask(TASK_ID); + + Comment createdComment = createComment(TASK_ID, processInstanceId, "aComment"); + + try { + // when + taskService.deleteProcessInstanceComment(processInstanceId, createdComment.getId()); + fail("Exception expected: It should not be possible to delete a task."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + e.getMessage()); + } + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceComment() { + // given + createTask(TASK_ID); + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + Comment createdComment = taskService.createComment(TASK_ID, processInstanceId, "aComment"); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + + // when + taskService.deleteProcessInstanceComment(processInstanceId, createdComment.getId()); + + // then + List deletedCommentLst = taskService.getProcessInstanceComments(processInstanceId); + assertEquals("The comments list should be empty", Collections.emptyList(), deletedCommentLst); + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceCommentsWithoutAuthorization() { + // given + createTask(TASK_ID); + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + createComment(TASK_ID, processInstanceId, "aComment"); + + try { + // when + taskService.deleteProcessInstanceComments(processInstanceId); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + e.getMessage()); + } + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceComments() { + // given + createTask(TASK_ID); + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + taskService.createComment(TASK_ID, processInstanceId, "aCommentOne"); + taskService.createComment(TASK_ID, processInstanceId, "aCommentTwo"); + + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + + // when + taskService.deleteProcessInstanceComments(processInstanceId); + + // then + List comments = taskService.getProcessInstanceComments(processInstanceId); + assertEquals("The comments list should be empty", Collections.emptyList(), comments); + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testUpdateProcessInstanceCommentWithoutAuthorization() { + // given + createTask(TASK_ID); + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + Comment createdComment = createComment(TASK_ID, processInstanceId, "originalComment"); + + try { + // when + taskService.updateProcessInstanceComment(processInstanceId, createdComment.getId(), "updateMessage"); + fail("Exception expected: It should not be possible to delete a task."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + e.getMessage()); + } + + deleteTask(TASK_ID, true); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testUpdateProcessInstanceComment() { + // given + String taskId = "myTask"; + createTask(taskId); + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + + String commentMessage = "OriginalCommentMessage"; + String updatedMessage = "UpdatedCommentMessage"; + Comment comment = taskService.createComment(taskId, processInstanceId, commentMessage); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + + // when + taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), updatedMessage); + + // then + List comments = taskService.getProcessInstanceComments(processInstanceId); + assertFalse("The comments list should not be empty", comments.isEmpty()); + assertEquals(updatedMessage, comments.get(0).getFullMessage()); + + // triggers a db clean up + deleteTask(taskId, true); + } + +} diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java new file mode 100644 index 00000000000..95e401ea401 --- /dev/null +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java @@ -0,0 +1,156 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.test.api.authorization; + +import static org.camunda.bpm.engine.authorization.Permissions.UPDATE; +import static org.camunda.bpm.engine.authorization.Resources.TASK; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.util.Collections; +import java.util.List; +import org.camunda.bpm.engine.AuthorizationException; +import org.camunda.bpm.engine.task.Comment; +import org.junit.Test; + +public class TaskCommentAuthorizationTest extends AuthorizationTest { + + @Test + public void testDeleteTaskCommentWithoutAuthorization() { + // given + createTask(TASK_ID); + Comment createdComment = createComment(TASK_ID, null, "aComment"); + + try { + // when + taskService.deleteTaskComment(TASK_ID, createdComment.getId()); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent( + "The user with id 'test' does not have 'UPDATE' permission on resource 'myTask' of type 'Task'", + e.getMessage()); + } + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Test + public void testDeleteTaskComment() { + // given + createTask(TASK_ID); + Comment createdComment = taskService.createComment(TASK_ID, null, "aComment"); + createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); + + // when + taskService.deleteTaskComment(TASK_ID, createdComment.getId()); + + // then + Comment shouldBeDeleletedComment = taskService.getTaskComment(TASK_ID, createdComment.getId()); + assertNull(shouldBeDeleletedComment); + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Test + public void testDeleteTaskCommentsWithoutAuthorization() { + // given + createTask(TASK_ID); + createComment(TASK_ID, null, "aComment"); + + try { + // when + taskService.deleteTaskComments(TASK_ID); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent( + "The user with id 'test' does not have 'UPDATE' permission on resource 'myTask' of type 'Task'", + e.getMessage()); + } + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Test + public void testDeleteTaskComments() { + // given + createTask(TASK_ID); + taskService.createComment(TASK_ID, null, "aCommentOne"); + taskService.createComment(TASK_ID, null, "aCommentTwo"); + + createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); + + // when + taskService.deleteTaskComments(TASK_ID); + + // then + List comments = taskService.getTaskComments(TASK_ID); + assertEquals("The comments list should be empty", Collections.emptyList(), comments); + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Test + public void testUpdateTaskCommentWithoutAuthorization() { + // given + createTask(TASK_ID); + Comment createdComment = createComment(TASK_ID, null, "originalComment"); + + try { + // when + taskService.updateTaskComment(TASK_ID, createdComment.getId(), "updateMessage"); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent( + "The user with id 'test' does not have 'UPDATE' permission on resource 'myTask' of type 'Task'", + e.getMessage()); + } + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + + @Test + public void testUpdateTaskComment() { + // given + createTask(TASK_ID); + String commentMessage = "OriginalCommentMessage"; + String updatedMessage = "UpdatedCommentMessage"; + Comment comment = taskService.createComment(TASK_ID, null, commentMessage); + createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); + + // when + taskService.updateTaskComment(TASK_ID, comment.getId(), updatedMessage); + + // then + List comments = taskService.getTaskComments(TASK_ID); + assertFalse("The comments list should not be empty", comments.isEmpty()); + assertEquals(updatedMessage, comments.get(0).getFullMessage()); + + // triggers a db clean up + deleteTask(TASK_ID, true); + } + +} diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/encoding/ProcessEngineCharacterEncodingTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/encoding/ProcessEngineCharacterEncodingTest.java index bd25ac5ddf1..95d61e7c1b0 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/encoding/ProcessEngineCharacterEncodingTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/encoding/ProcessEngineCharacterEncodingTest.java @@ -24,7 +24,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; - import org.camunda.bpm.engine.TaskService; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.engine.task.Comment; @@ -90,6 +89,10 @@ protected Task newTaskWithComment(String message) { return task; } + protected Comment createNewComment(String taskId, String message) { + return taskService.createComment(taskId, null, message); + } + @Test public void shouldPreserveArabicTaskCommentMessageWithCharset() { // given @@ -118,4 +121,37 @@ public void shouldPreserveLatinTaskCommentMessageWithCharset() { assertThat(taskComments.get(0).getFullMessage()).isEqualTo(message); } + @Test + public void shouldPreserveArabicTaskUpdateCommentMessageWithCharset() { + // given + String taskId = newTask().getId(); + Comment comment = createNewComment(taskId, "OriginalMessage"); + + // when + String updatedMessage = "این نمونه است"; + taskService.updateTaskComment(taskId, comment.getId(), updatedMessage); + + Comment updatedComment = taskService.getTaskComment(taskId, comment.getId()); + + // then + assertThat(updatedComment).isNotNull(); + assertThat(updatedComment.getFullMessage()).isEqualTo(updatedMessage); + } + + @Test + public void shouldPreserveLatinTaskUpdateCommentMessageWithCharset() { + // given + String taskId = newTask().getId(); + Comment comment = createNewComment(taskId, "OriginalMessage"); + + // when + String updatedMessage = "This is an example"; + taskService.updateTaskComment(taskId, comment.getId(), updatedMessage); + + Comment updatedComment = taskService.getTaskComment(taskId, comment.getId()); + + // then + assertThat(updatedComment).isNotNull(); + assertThat(updatedComment.getFullMessage()).isEqualTo(updatedMessage); + } } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskLastUpdatedTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskLastUpdatedTest.java index 915c7fb7f4a..33a8000f924 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskLastUpdatedTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskLastUpdatedTest.java @@ -20,7 +20,6 @@ import java.util.Date; import java.util.List; - import org.assertj.core.api.Assertions; import org.camunda.bpm.engine.OptimisticLockingException; import org.camunda.bpm.engine.RuntimeService; @@ -30,6 +29,7 @@ import org.camunda.bpm.engine.impl.util.ClockUtil; import org.camunda.bpm.engine.runtime.ProcessInstance; import org.camunda.bpm.engine.task.Attachment; +import org.camunda.bpm.engine.task.Comment; import org.camunda.bpm.engine.task.IdentityLinkType; import org.camunda.bpm.engine.task.Task; import org.camunda.bpm.engine.test.Deployment; @@ -414,4 +414,113 @@ public void shouldNotSaveTaskConcurrentlyUpdatedByDependentEntity() { Assertions.assertThatThrownBy(() -> taskService.saveTask(task)) .isInstanceOf(OptimisticLockingException.class); } + + @Test + public void shouldSetLastUpdatedOnTaskDeleteComment() { + // given + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + Comment comment = taskService.createComment(task.getId(), processInstance.getId(), "message"); + + Date beforeUpdate = getBeforeCurrentTime(); + + // when + taskService.deleteTaskComment(task.getId(), comment.getId()); + + // then + Task taskResult = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertThat(taskResult).isNotNull(); + assertThat(taskResult.getLastUpdated()).isAfter(beforeUpdate); + } + + @Test + public void shouldSetLastUpdatedOnTaskDeleteComments() { + // given + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + taskService.createComment(task.getId(), processInstance.getId(), "message"); + + Date beforeUpdate = getBeforeCurrentTime(); + + // when + taskService.deleteTaskComments(task.getId()); + + // then + Task taskResult = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertThat(taskResult).isNotNull(); + assertThat(taskResult.getLastUpdated()).isAfter(beforeUpdate); + } + + @Test + public void shouldSetLastUpdatedOnTaskCommentUpdate() { + // given + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + Comment comment = taskService.createComment(task.getId(), processInstance.getId(), "aMessage"); + + Date beforeUpdate = getBeforeCurrentTime(); + + // when + taskService.updateTaskComment(task.getId(), comment.getId(), "updatedMessage"); + + // then + Task taskResult = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertThat(taskResult).isNotNull(); + assertThat(taskResult.getLastUpdated()).isAfter(beforeUpdate); + } + + @Test + public void shouldSetLastUpdatedOnProcessInstanceDeleteComment() { + // given + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + Comment comment = taskService.createComment(task.getId(), processInstance.getId(), "message"); + + Date beforeUpdate = getBeforeCurrentTime(); + + // when + taskService.deleteProcessInstanceComment(processInstance.getId(), comment.getId()); + + // then + Task taskResult = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertThat(taskResult).isNotNull(); + assertThat(taskResult.getLastUpdated()).isAfter(beforeUpdate); + } + + @Test + public void shouldSetLastUpdatedOnProcessInstanceDeleteComments() { + // given + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + taskService.createComment(task.getId(), processInstance.getId(), "message"); + + Date beforeUpdate = getBeforeCurrentTime(); + + // when + taskService.deleteProcessInstanceComments(processInstance.getId()); + + // then + Task taskResult = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertThat(taskResult).isNotNull(); + assertThat(taskResult.getLastUpdated()).isAfter(beforeUpdate); + } + + @Test + public void shouldSetLastUpdatedOnProcessInstanceCommentUpdate() { + // given + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + Comment comment = taskService.createComment(task.getId(), processInstance.getId(), "aMessage"); + + Date beforeUpdate = getBeforeCurrentTime(); + + // when + taskService.updateProcessInstanceComment(processInstance.getId(), comment.getId(), "updatedMessage"); + + // then + Task taskResult = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertThat(taskResult).isNotNull(); + assertThat(taskResult.getLastUpdated()).isAfter(beforeUpdate); + } + } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java index 62dc62060dd..c577269d7c5 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java @@ -37,7 +37,6 @@ import java.util.List; import java.util.Map; import java.util.Set; - import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.CaseService; import org.camunda.bpm.engine.HistoryService; @@ -80,7 +79,6 @@ import org.camunda.bpm.engine.test.util.ProcessEngineBootstrapRule; import org.camunda.bpm.engine.test.util.ProcessEngineTestRule; import org.camunda.bpm.engine.test.util.ProvidedProcessEngineRule; -import org.camunda.bpm.engine.test.util.RemoveAfter; import org.camunda.bpm.engine.variable.VariableMap; import org.camunda.bpm.engine.variable.Variables; import org.camunda.bpm.engine.variable.type.ValueType; @@ -282,6 +280,419 @@ public void testTaskOwner() { taskService.deleteTask(task.getId(), true); } + @Test + public void testDeleteTaskCommentNullCommentId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + try { + taskService.deleteTaskComment(taskId, null); + + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("commentId is null", ae.getMessage()); + } finally { + taskService.deleteTask(task.getId(), true); + } + } + + @Test + public void testDeleteTaskCommentNullTaskIdAndCommentId() { + try { + taskService.deleteTaskComment(null, null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("commentId is null", ae.getMessage()); + } + } + + @Test + public void testDeleteTaskCommentNotExistingCommentId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + // Deleting non-existing comment should be silently ignored + taskService.deleteTaskComment(taskId, "notExistingCommentId"); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Test + public void testDeleteTaskComment() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + //create a task comment + Comment comment = taskService.createComment(taskId, "pid", "aMessage"); + String commentId = comment.getId(); + + //delete a comment + taskService.deleteTaskComment(taskId, commentId); + + //make sure the comment is not there. + Comment shouldBeDeleted = taskService.getTaskComment(taskId, commentId); + assertNull(shouldBeDeleted); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Test + public void testDeleteTaskCommentsNullTaskId() { + try { + taskService.deleteTaskComments(null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("taskId is null", ae.getMessage()); + } + } + + @Test + public void testDeleteTaskCommentsNonExistingTaskId() { + try { + taskService.deleteTaskComments("nonExistingTaskId"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("No task exists with taskId:", ae.getMessage()); + } + } + + @Test + public void testDeleteTaskCommentsNoComments() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + // Deleting comments of a task that doesnt have any comments should silently ignored + taskService.deleteTaskComments(taskId); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Test + public void testDeleteTaskComments() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + //create a task comment + Comment comment = taskService.createComment(taskId, "pid", "aMessage"); + + //delete a comment + taskService.deleteTaskComments(taskId); + + //make sure the comment is not there. + Comment shouldBeDeleted = taskService.getTaskComment(taskId, comment.getId()); + assertNull(shouldBeDeleted); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Test + public void testUpdateTaskCommentNullCommentId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + try { + taskService.updateTaskComment(taskId, null, "aMessage"); + + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("commentId is null", ae.getMessage()); + } finally { + taskService.deleteTask(task.getId(), true); + } + } + + @Test + public void testUpdateTaskCommentNullTaskId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + Comment comment = taskService.createComment(taskId, null, "originalMessage"); + + try { + taskService.updateTaskComment(null, comment.getId(), "updatedMessage"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("taskId is null", ae.getMessage()); + } finally { + taskService.deleteTask(taskId, true); + } + } + + @Test + public void testUpdateTaskCommentNullMessage() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + Comment comment = taskService.createComment(taskId, null, "originalMessage"); + + try { + taskService.updateTaskComment(taskId, comment.getId(), null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("message is null", ae.getMessage()); + } finally { + taskService.deleteTask(task.getId(), true); + } + } + + @Test + public void testUpdateTaskCommentNotExistingCommentId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + taskService.createComment(taskId, null, "originalMessage"); + String nonExistingCommentId = "notExistingCommentId"; + + try { + taskService.updateTaskComment(taskId, nonExistingCommentId, "updatedMessage"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("No comment exists with commentId: " + nonExistingCommentId + " and taskId: " + taskId, + ae.getMessage()); + } finally { + taskService.deleteTask(task.getId(), true); + } + } + + @Test + public void testUpdateTaskComment() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + Comment comment = taskService.createComment(taskId, null, "originalMessage"); + String updatedMessage = "updatedMessage"; + + taskService.updateTaskComment(taskId, comment.getId(), updatedMessage); + + Comment actual = taskService.getTaskComment(taskId, comment.getId()); + + assertThat(actual).isNotNull(); + assertEquals(updatedMessage, actual.getFullMessage()); + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Test + public void testDeleteProcessInstanceCommentNullCommentId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + try { + taskService.deleteProcessInstanceComment(taskId, null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("commentId is null", ae.getMessage()); + } finally { + taskService.deleteTask(taskId, true); + } + } + + @Test + public void testDeleteProcessInstanceCommentNullTaskIdAndCommentId() { + try { + taskService.deleteProcessInstanceComment(null, null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("commentId is null", ae.getMessage()); + } + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceCommentNotExistingCommentId() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + + // Deleting non-existing comment should be silently ignored + taskService.deleteProcessInstanceComment(processInstance.getId(), "notExistingCommentId"); + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceComment() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + + //create a task comment + Comment comment = taskService.createComment(taskId, processInstanceId, "aMessage"); + + //delete a comment + taskService.deleteProcessInstanceComment(processInstanceId, comment.getId()); + + //make sure the comment is not there. + List shouldBeDeletedLst = taskService.getProcessInstanceComments(processInstanceId); + assertThat(shouldBeDeletedLst).isEmpty(); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Test + public void testDeleteProcessInstanceCommentsNullTaskId() { + try { + taskService.deleteProcessInstanceComments(null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("processInstanceId is null", ae.getMessage()); + } + } + + @Test + public void testDeleteProcessInstanceCommentsNonExistingTaskId() { + try { + taskService.deleteProcessInstanceComments("nonExistingTaskId"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("No processInstance exists with processInstanceId:", ae.getMessage()); + } + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceCommentsNoComments() { + + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + + // Deleting comments of a task that doesn't have any comments should silently ignored + taskService.deleteProcessInstanceComments(processInstance.getId()); + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceComments() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + + //create a task comment + taskService.createComment(taskId, processInstanceId, "messageOne"); + taskService.createComment(taskId, processInstanceId, "messageTwo"); + + //delete a comment + taskService.deleteProcessInstanceComments(processInstanceId); + + //make sure the comment is not there. + List shouldBeDeletedLst = taskService.getProcessInstanceComments(processInstanceId); + assertThat(shouldBeDeletedLst).isEmpty(); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessInstanceCommentNullCommentId() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + try { + taskService.updateProcessInstanceComment(processInstance.getId(), null, "aMessage"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("commentId is null", ae.getMessage()); + } + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessInstanceCommentNullProcessInstanceId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Comment comment = taskService.createComment(task.getId(), processInstance.getId(), "originalMessage"); + + try { + taskService.updateProcessInstanceComment(null, comment.getId(), "updatedMessage"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("processInstanceId is null", ae.getMessage()); + } finally { + taskService.deleteTask(task.getId(), true); + } + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessInstanceCommentNullMessage() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Comment comment = taskService.createComment(taskId, processInstance.getId(), "originalMessage"); + + try { + taskService.updateProcessInstanceComment(processInstance.getId(), comment.getId(), null); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent("message is null", ae.getMessage()); + } finally { + taskService.deleteTask(task.getId(), true); + } + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessInstanceCommentNotExistingCommentId() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + taskService.createComment(taskId, processInstanceId, "originalMessage"); + + String nonExistingCommentId = "notExistingCommentId"; + try { + taskService.updateProcessInstanceComment(processInstanceId, nonExistingCommentId, "updatedMessage"); + fail("ProcessEngineException expected"); + } catch (ProcessEngineException ae) { + testRule.assertTextPresent( + "No comment exists with commentId: " + nonExistingCommentId + " and processInstanceId: " + processInstanceId, + ae.getMessage()); + } finally { + taskService.deleteTask(taskId, true); + } + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessInstanceComment() { + Task task = taskService.newTask(); + taskService.saveTask(task); + String taskId = task.getId(); + + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + + Comment comment = taskService.createComment(taskId, processInstanceId, "originalMessage"); + String updatedMessage = "updatedMessage"; + + taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), updatedMessage); + + List updateCommentLst = taskService.getProcessInstanceComments(processInstanceId); + + assertThat(updateCommentLst).isNotEmpty(); + assertThat(updateCommentLst).hasSize(1); + + Comment actual = updateCommentLst.get(0); + assertEquals(updatedMessage, actual.getFullMessage()); + + // Finally, delete task + taskService.deleteTask(taskId, true); + } + @Test public void testTaskComments() { int historyLevel = processEngineConfiguration.getHistoryLevel().getId(); From 228e66a4abe6283db6956ec110ddc5b977987eaa Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Thu, 2 May 2024 08:46:40 -0600 Subject: [PATCH 02/10] feat(engine-rest-core) Add update and delete Java/Rest APIs of task and processInstance DELETE /task/{taskId}/comment/{commentId} - deletes a comment of a given taskId and commentId DELETE /task/{taskId}/comment - deletes all comments of a given taskId PUT /task/comment - updates a comment DELETE /process-instance/{processInstanceId}/comment/{commentId} - deletes a comment of a given processInstanceId and commentId DELETE /process-instance/{processInstanceId}/comment. - deletes all comments of a given processInstanceId PUT /process-instance/comment - updates a comment related to: https://github.com/camunda/camunda-bpm-platform/issues/2551 --- .../ProcessInstanceCommentResource.java | 18 +- .../ProcessInstanceCommentResourceImpl.java | 71 +++- .../rest/sub/task/TaskCommentResource.java | 26 +- .../task/impl/TaskCommentResourceImpl.java | 52 ++- ...essInstanceRestServiceInteractionTest.java | 341 ++++++++++++++++++ .../rest/TaskRestServiceInteractionTest.java | 319 +++++++++++++++- .../bpm/engine/rest/helper/MockProvider.java | 5 + 7 files changed, 816 insertions(+), 16 deletions(-) diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/ProcessInstanceCommentResource.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/ProcessInstanceCommentResource.java index 50cb90b189d..e1a3fa2d88f 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/ProcessInstanceCommentResource.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/ProcessInstanceCommentResource.java @@ -17,11 +17,14 @@ package org.camunda.bpm.engine.rest.sub.runtime; import java.util.List; - +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; - import org.camunda.bpm.engine.rest.dto.task.CommentDto; public interface ProcessInstanceCommentResource { @@ -30,4 +33,15 @@ public interface ProcessInstanceCommentResource { @Produces(MediaType.APPLICATION_JSON) List getComments(); + @DELETE + @Path("/{commentId}") + @Produces(MediaType.APPLICATION_JSON) + void deleteComment(@PathParam("commentId") String commentId); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateComment(CommentDto comment); + + @DELETE + void deleteComments(); } diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java index aec71d23e23..f84bda46861 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java @@ -19,11 +19,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; - import javax.ws.rs.core.Response.Status; - +import org.camunda.bpm.engine.AuthorizationException; import org.camunda.bpm.engine.IdentityService; import org.camunda.bpm.engine.ProcessEngine; +import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.TaskService; +import org.camunda.bpm.engine.exception.NotValidException; +import org.camunda.bpm.engine.exception.NullValueException; import org.camunda.bpm.engine.history.HistoricProcessInstance; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.engine.impl.identity.Authentication; @@ -59,6 +62,70 @@ public List getComments() { return comments; } + /** + * Deletes a comment by a given commentId + */ + @Override + public void deleteComment(String commentId) { + ensureHistoryEnabled(Status.FORBIDDEN); + ensureProcessInstanceExists(Status.NOT_FOUND); + + TaskService taskService = engine.getTaskService(); + try { + taskService.deleteProcessInstanceComment(processInstanceId, commentId); + } catch (NotValidException e) { + throw new InvalidRequestException(Status.NOT_FOUND, + "Deletion is not possible. No comment exists for processInstanceId '" + processInstanceId + + "' and comment id '" + commentId + "'."); + } + } + + /** + * Updates message for a given processInstance ID and commentId + */ + public void updateComment(CommentDto comment) { + ensureHistoryEnabled(Status.FORBIDDEN); + ensureProcessInstanceExists(Status.NOT_FOUND); + + TaskService taskService = engine.getTaskService(); + try { + taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), comment.getMessage()); + } catch (NotValidException e) { + throw new InvalidRequestException(Status.NOT_FOUND, + "Update is not possible. No comment exists for process instance id '" + processInstanceId + + "' and comment id '" + comment.getId() + "'."); + } catch (AuthorizationException e) { + throw e; + } catch (NullValueException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); + } catch (ProcessEngineException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e, "Not enough parameters submitted"); + } + } + + /** + * Deletes all comments by a given processInstanceId + */ + @Override + public void deleteComments() { + ensureHistoryEnabled(Status.FORBIDDEN); + ensureProcessInstanceExists(Status.NOT_FOUND); + TaskService taskService = engine.getTaskService(); + + try { + taskService.deleteProcessInstanceComments(processInstanceId); + } catch (NotValidException e) { + throw new InvalidRequestException(Status.NOT_FOUND, + "Deletion of comments not possible for processInstance id '" + processInstanceId + "'."); + } + } + + private void ensureHistoryEnabled(Status status) { + if (!isHistoryEnabled()) { + throw new InvalidRequestException(status, "History is not enabled"); + } + } + private boolean isHistoryEnabled() { IdentityService identityService = engine.getIdentityService(); Authentication currentAuthentication = identityService.getCurrentAuthentication(); diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/TaskCommentResource.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/TaskCommentResource.java index 4815f70ed85..261c6ef077d 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/TaskCommentResource.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/TaskCommentResource.java @@ -16,13 +16,19 @@ */ package org.camunda.bpm.engine.rest.sub.task; -import org.camunda.bpm.engine.rest.dto.task.CommentDto; - -import javax.ws.rs.*; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import java.util.List; +import org.camunda.bpm.engine.rest.dto.task.CommentDto; public interface TaskCommentResource { @@ -41,4 +47,16 @@ public interface TaskCommentResource { @Produces(MediaType.APPLICATION_JSON) CommentDto createComment(@Context UriInfo uriInfo, CommentDto comment); + @DELETE + @Path("/{commentId}") + @Produces(MediaType.APPLICATION_JSON) + void deleteComment(@PathParam("commentId") String commentId); + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + void updateComment(CommentDto comment); + + @DELETE + void deleteComments(); + } diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java index 23d4aecfd3b..91c97e2f986 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java @@ -20,14 +20,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; - import javax.ws.rs.HttpMethod; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; - +import org.camunda.bpm.engine.AuthorizationException; import org.camunda.bpm.engine.IdentityService; import org.camunda.bpm.engine.ProcessEngine; import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.TaskService; +import org.camunda.bpm.engine.exception.NotValidException; +import org.camunda.bpm.engine.exception.NullValueException; import org.camunda.bpm.engine.history.HistoricTaskInstance; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.engine.impl.identity.Authentication; @@ -77,6 +79,52 @@ public CommentDto getComment(String commentId) { return CommentDto.fromComment(comment); } + public void deleteComment(String commentId) { + ensureHistoryEnabled(Status.FORBIDDEN); + ensureTaskExists(Status.NOT_FOUND); + + TaskService taskService = engine.getTaskService(); + try { + taskService.deleteTaskComment(taskId, commentId); + } catch (NotValidException e) { + throw new InvalidRequestException(Status.NOT_FOUND, + "Deletion is not possible. No comment exists for task id '" + taskId + "' and comment id '" + commentId + + "'."); + } + } + + public void updateComment(CommentDto comment) { + ensureHistoryEnabled(Status.FORBIDDEN); + ensureTaskExists(Status.NOT_FOUND); + + try { + engine.getTaskService().updateTaskComment(taskId, comment.getId(), comment.getMessage()); + } catch (NotValidException e) { + throw new InvalidRequestException(Status.NOT_FOUND, + "Update is not possible. No comment exists for task id '" + taskId + "' and comment id '" + comment.getId() + + "'."); + } catch (AuthorizationException e) { + throw e; + } catch (NullValueException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); + } catch (ProcessEngineException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e, "Not enough parameters submitted"); + } + } + + public void deleteComments() { + ensureHistoryEnabled(Status.FORBIDDEN); + ensureTaskExists(Status.NOT_FOUND); + TaskService taskService = engine.getTaskService(); + + try { + taskService.deleteTaskComments(taskId); + } catch (NotValidException e) { + throw new InvalidRequestException(Status.NOT_FOUND, + "Deletion of comments not possible for task id '" + taskId + "'."); + } + } + public CommentDto createComment(UriInfo uriInfo, CommentDto commentDto) { ensureHistoryEnabled(Status.FORBIDDEN); ensureTaskExists(Status.BAD_REQUEST); diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java index 345be01068e..c7c132dd0f7 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java @@ -17,11 +17,16 @@ package org.camunda.bpm.engine.rest; import static io.restassured.RestAssured.given; +import static org.camunda.bpm.engine.rest.helper.MockProvider.EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE; +import static org.camunda.bpm.engine.rest.helper.MockProvider.EXAMPLE_PROCESS_INSTANCE_COMMENT_ID; import static org.camunda.bpm.engine.rest.helper.MockProvider.EXAMPLE_TASK_ID; +import static org.camunda.bpm.engine.rest.helper.MockProvider.NON_EXISTING_ID; import static org.camunda.bpm.engine.rest.helper.MockProvider.createMockBatch; import static org.camunda.bpm.engine.rest.helper.MockProvider.createMockHistoricProcessInstance; import static org.camunda.bpm.engine.rest.util.DateTimeUtils.DATE_FORMAT_WITH_TIMEZONE; +import static org.camunda.bpm.engine.rest.util.DateTimeUtils.withTimezone; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -62,6 +67,7 @@ import org.camunda.bpm.engine.TaskService; import org.camunda.bpm.engine.batch.Batch; import org.camunda.bpm.engine.exception.NotFoundException; +import org.camunda.bpm.engine.exception.NotValidException; import org.camunda.bpm.engine.exception.NullValueException; import org.camunda.bpm.engine.history.HistoricProcessInstance; import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery; @@ -141,6 +147,8 @@ public class ProcessInstanceRestServiceInteractionTest extends AbstractRestServi protected static final String SINGLE_PROCESS_INSTANCE_URL = PROCESS_INSTANCE_URL + "/{id}"; protected static final String PROCESS_INSTANCE_VARIABLES_URL = SINGLE_PROCESS_INSTANCE_URL + "/variables"; protected static final String PROCESS_INSTANCE_COMMENTS_URL = SINGLE_PROCESS_INSTANCE_URL + "/comment"; + protected static final String SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL = + PROCESS_INSTANCE_COMMENTS_URL + "/{commentId}"; protected static final String DELETE_PROCESS_INSTANCES_ASYNC_URL = PROCESS_INSTANCE_URL + "/delete"; protected static final String DELETE_PROCESS_INSTANCES_ASYNC_HIST_QUERY_URL = PROCESS_INSTANCE_URL + "/delete-historic-query-based"; protected static final String SET_JOB_RETRIES_ASYNC_URL = PROCESS_INSTANCE_URL + "/job-retries"; @@ -838,6 +846,339 @@ public void testGetProcessInstanceCommentsWithHistoryDisabled() { .get(PROCESS_INSTANCE_COMMENTS_URL); } + @Test + public void testDeleteInstanceCommentThrowsAuthorizationException() { + String message = "expected exception"; + doThrow(new AuthorizationException(message)).when(taskServiceMock) + .deleteProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, EXAMPLE_PROCESS_INSTANCE_COMMENT_ID); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .pathParam("commentId", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteInstanceComment() { + mockHistoryFull(); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .pathParam("commentId", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteInstanceCommentWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .pathParam("commentId", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteInstanceCommentForNonExistingCommentId() { + mockHistoryFull(); + doThrow(new NotValidException()).when(taskServiceMock) + .deleteProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, NON_EXISTING_ID); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .pathParam("commentId", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .contentType(ContentType.JSON) + .body(containsString( + "Deletion is not possible. No comment exists for processInstanceId '" + EXAMPLE_PROCESS_INSTANCE_ID + + "' and comment id '" + NON_EXISTING_ID + "'.")) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteInstanceCommentForNonExistingCommentIdWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .pathParam("commentId", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteInstanceCommentForNonExistingProcessInstance() { + mockHistoryFull(); + historicProcessInstanceQueryMock = mock(HistoricProcessInstanceQuery.class); + when(historyServiceMock.createHistoricProcessInstanceQuery()).thenReturn(historicProcessInstanceQueryMock); + when(historicProcessInstanceQueryMock.processInstanceId(eq(NON_EXISTING_ID))).thenReturn( + historicProcessInstanceQueryMock); + when(historicProcessInstanceQueryMock.singleResult()).thenReturn(null); + + given().pathParam("id", NON_EXISTING_ID) + .pathParam("commentId", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .body(containsString("No process instance found for id " + NON_EXISTING_ID)) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteInstanceCommentForNonExistingTaskWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", NON_EXISTING_ID) + .pathParam("commentId", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteProcessInstanceCommentsThrowsAuthorizationException() { + String message = "expected exception"; + doThrow(new AuthorizationException(message)).when(taskServiceMock) + .deleteProcessInstanceComments(MockProvider.EXAMPLE_TASK_ID); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .when() + .delete(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testDeleteProcessInstanceComments() { + mockHistoryFull(); + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .delete(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testDeleteProcessInstanceCommentsWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testDeleteProcessInstanceCommentsForNonExistingTask() { + mockHistoryFull(); + historicProcessInstanceQueryMock = mock(HistoricProcessInstanceQuery.class); + when(historyServiceMock.createHistoricProcessInstanceQuery()).thenReturn(historicProcessInstanceQueryMock); + when(historicProcessInstanceQueryMock.processInstanceId(eq(NON_EXISTING_ID))).thenReturn( + historicProcessInstanceQueryMock); + when(historicProcessInstanceQueryMock.singleResult()).thenReturn(null); + + given().pathParam("id", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .body(containsString("No process instance found for id " + NON_EXISTING_ID)) + .when() + .delete(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testDeleteProcessInstanceCommentsForNonExistingTaskWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testUpdateProcessInstanceCommentCommentIdNull() { + mockHistoryFull(); + + String message = "expected exception"; + doThrow(new NullValueException(message)).when(taskServiceMock) + .updateProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, null, EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + + Map json = new HashMap<>(); + + json.put("id", null); + json.put("message", EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.BAD_REQUEST.getStatusCode()) + .when() + .put(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testUpdateProcessInstanceCommentMessageIsNull() { + mockHistoryFull(); + + String message = "expected exception"; + doThrow(new NullValueException(message)).when(taskServiceMock) + .updateProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, EXAMPLE_PROCESS_INSTANCE_COMMENT_ID, null); + + Map json = new HashMap<>(); + + json.put("id", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID); + json.put("message", null); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.BAD_REQUEST.getStatusCode()) + .when() + .put(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testUpdateProcessInstanceComment() { + mockHistoryFull(); + Map json = new HashMap<>(); + + json.put("id", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID); + json.put("message", EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .put(PROCESS_INSTANCE_COMMENTS_URL); + + verify(taskServiceMock).updateProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, + EXAMPLE_PROCESS_INSTANCE_COMMENT_ID, EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + } + + @Test + public void testUpdateProcessInstanceCommentExtraProperties() { + mockHistoryFull(); + + Map json = new HashMap<>(); + //Only id and message are used + json.put("id", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID); + json.put("userId", "anyUserId"); + json.put("time", withTimezone("2014-01-01T00:00:00")); + json.put("message", EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + json.put("removalTime", withTimezone("2014-05-01T00:00:00")); + json.put("processInstanceId", MockProvider.EXAMPLE_PROCESS_INSTANCE_ID); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .put(PROCESS_INSTANCE_COMMENTS_URL); + + verify(taskServiceMock).updateProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, + EXAMPLE_PROCESS_INSTANCE_COMMENT_ID, EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + } + + @Test + public void testUpdateProcessInstanceCommentProcessInstanceIdNotFound() { + mockHistoryFull(); + historicProcessInstanceQueryMock = mock(HistoricProcessInstanceQuery.class); + when(historyServiceMock.createHistoricProcessInstanceQuery()).thenReturn(historicProcessInstanceQueryMock); + when(historicProcessInstanceQueryMock.processInstanceId(eq(NON_EXISTING_ID))).thenReturn( + historicProcessInstanceQueryMock); + when(historicProcessInstanceQueryMock.singleResult()).thenReturn(null); + + Map json = new HashMap<>(); + + json.put("id", EXAMPLE_PROCESS_INSTANCE_ID); + json.put("message", EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + + given().pathParam("id", NON_EXISTING_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .contentType(ContentType.JSON) + .body("type", equalTo(InvalidRequestException.class.getSimpleName())) + .body(containsString("No process instance found for id " + NON_EXISTING_ID)) + .when() + .put(PROCESS_INSTANCE_COMMENTS_URL); + } + + @Test + public void testUpdateProcessInstanceCommentThrowsAuthorizationException() { + mockHistoryFull(); + String message = "expected exception"; + doThrow(new AuthorizationException(message)).when(taskServiceMock) + .updateProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, EXAMPLE_PROCESS_INSTANCE_COMMENT_ID, + EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + + Map json = new HashMap<>(); + json.put("id", EXAMPLE_PROCESS_INSTANCE_COMMENT_ID); + json.put("message", EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE); + + given().pathParam("id", EXAMPLE_PROCESS_INSTANCE_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .contentType(ContentType.JSON) + .when() + .put(PROCESS_INSTANCE_COMMENTS_URL); + + } + @Test public void testGetFileVariable() { String variableKey = "aVariableKey"; diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java index 8234416f821..d21fb63dafc 100755 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java @@ -65,6 +65,9 @@ import static org.mockito.Mockito.when; import static org.mockito.hamcrest.MockitoHamcrest.argThat; +import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; +import io.restassured.response.Response; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -76,11 +79,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; - import javax.ws.rs.HttpMethod; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; - import org.assertj.core.api.Assertions; import org.camunda.bpm.ProcessApplicationService; import org.camunda.bpm.application.ProcessApplicationInfo; @@ -95,6 +96,7 @@ import org.camunda.bpm.engine.TaskService; import org.camunda.bpm.engine.exception.NotFoundException; import org.camunda.bpm.engine.exception.NotValidException; +import org.camunda.bpm.engine.exception.NullValueException; import org.camunda.bpm.engine.form.TaskFormData; import org.camunda.bpm.engine.history.HistoricTaskInstance; import org.camunda.bpm.engine.history.HistoricTaskInstanceQuery; @@ -143,10 +145,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import io.restassured.http.ContentType; -import io.restassured.path.json.JsonPath; -import io.restassured.response.Response; - public class TaskRestServiceInteractionTest extends AbstractRestServiceTest { @@ -3726,6 +3724,315 @@ public void testHandleBpmnEscalationMissingEscalationCode() { .post(HANDLE_BPMN_ESCALATION_URL); } + @Test + public void testDeleteTaskCommentThrowsAuthorizationException() { + String message = "expected exception"; + doThrow(new AuthorizationException(message)).when(taskServiceMock) + .deleteTaskComment(MockProvider.EXAMPLE_TASK_ID, EXAMPLE_TASK_COMMENT_ID); + + given().pathParam("id", MockProvider.EXAMPLE_TASK_ID) + .pathParam("commentId", EXAMPLE_TASK_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskComment() { + given().pathParam("id", MockProvider.EXAMPLE_TASK_ID) + .pathParam("commentId", EXAMPLE_TASK_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskCommentWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", MockProvider.EXAMPLE_TASK_ID) + .pathParam("commentId", EXAMPLE_TASK_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskCommentForNonExistingCommentId() { + doThrow(new NotValidException()).when(taskServiceMock).deleteTaskComment(EXAMPLE_TASK_ID, NON_EXISTING_ID); + + given().pathParam("id", EXAMPLE_TASK_ID) + .pathParam("commentId", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .contentType(ContentType.JSON) + .body(containsString( + "Deletion is not possible. No comment exists for task id '" + EXAMPLE_TASK_ID + "' and comment id '" + + NON_EXISTING_ID + "'.")) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskCommentForNonExistingCommentIdWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", EXAMPLE_TASK_ID) + .pathParam("commentId", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskCommentForNonExistingTask() { + when(historicTaskInstanceQueryMock.taskId(NON_EXISTING_ID)).thenReturn(historicTaskInstanceQueryMock); + when(historicTaskInstanceQueryMock.singleResult()).thenReturn(null); + + given().pathParam("id", NON_EXISTING_ID) + .pathParam("commentId", EXAMPLE_TASK_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .body(containsString("No task found for task id " + NON_EXISTING_ID)) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskCommentForNonExistingTaskWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", NON_EXISTING_ID) + .pathParam("commentId", EXAMPLE_TASK_COMMENT_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + } + + @Test + public void testDeleteTaskCommentsThrowsAuthorizationException() { + String message = "expected exception"; + doThrow(new AuthorizationException(message)).when(taskServiceMock).deleteTaskComments(MockProvider.EXAMPLE_TASK_ID); + + given().pathParam("id", MockProvider.EXAMPLE_TASK_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .when() + .delete(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testDeleteTaskComments() { + given().pathParam("id", MockProvider.EXAMPLE_TASK_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .delete(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testDeleteTaskCommentsWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", MockProvider.EXAMPLE_TASK_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testDeleteTaskCommentsForNonExistingTask() { + when(historicTaskInstanceQueryMock.taskId(NON_EXISTING_ID)).thenReturn(historicTaskInstanceQueryMock); + when(historicTaskInstanceQueryMock.singleResult()).thenReturn(null); + + given().pathParam("id", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .body(containsString("No task found for task id " + NON_EXISTING_ID)) + .when() + .delete(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testDeleteTaskCommentsForNonExistingTaskWithHistoryDisabled() { + mockHistoryDisabled(); + + given().pathParam("id", NON_EXISTING_ID) + .header("accept", MediaType.APPLICATION_JSON) + .then() + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .body(containsString("History is not enabled")) + .when() + .delete(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testUpdateTaskComment() { + Map json = new HashMap<>(); + + json.put("id", EXAMPLE_TASK_COMMENT_ID); + json.put("message", EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + + given().pathParam("id", EXAMPLE_TASK_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .put(SINGLE_TASK_COMMENTS_URL); + + verify(taskServiceMock).updateTaskComment(EXAMPLE_TASK_ID, EXAMPLE_TASK_COMMENT_ID, + EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + } + + @Test + public void testUpdateTaskCommentCommentIdNull() { + String message = "expected exception"; + doThrow(new NullValueException(message)).when(taskServiceMock) + .updateTaskComment(EXAMPLE_TASK_ID, null, EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + + Map json = new HashMap<>(); + + json.put("id", null); + json.put("message", EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + + given().pathParam("id", EXAMPLE_TASK_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.BAD_REQUEST.getStatusCode()) + .when() + .put(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testUpdateTaskCommentMessageIdNull() { + String message = "expected exception"; + doThrow(new NullValueException(message)).when(taskServiceMock) + .updateTaskComment(EXAMPLE_TASK_ID, EXAMPLE_TASK_COMMENT_ID, null); + + Map json = new HashMap<>(); + + json.put("id", EXAMPLE_TASK_COMMENT_ID); + json.put("message", null); + + given().pathParam("id", EXAMPLE_TASK_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.BAD_REQUEST.getStatusCode()) + .when() + .put(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testUpdateTaskCommentExtraProperties() { + Map json = new HashMap<>(); + + //Only id and message are used + json.put("id", EXAMPLE_TASK_COMMENT_ID); + json.put("userId", "anyUserId"); + json.put("time", withTimezone("2014-01-01T00:00:00")); + json.put("message", EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + json.put("removalTime", withTimezone("2014-05-01T00:00:00")); + json.put("rootProcessInstanceId", EXAMPLE_TASK_COMMENT_ROOT_PROCESS_INSTANCE_ID); + json.put("processInstanceId", MockProvider.EXAMPLE_PROCESS_INSTANCE_ID); + + given().pathParam("id", EXAMPLE_TASK_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.NO_CONTENT.getStatusCode()) + .when() + .put(SINGLE_TASK_COMMENTS_URL); + + verify(taskServiceMock).updateTaskComment(EXAMPLE_TASK_ID, EXAMPLE_TASK_COMMENT_ID, + EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + } + + @Test + public void testUpdateTaskCommentTaskIdNotFound() { + when(historicTaskInstanceQueryMock.taskId(NON_EXISTING_ID)).thenReturn(historicTaskInstanceQueryMock); + when(historicTaskInstanceQueryMock.singleResult()).thenReturn(null); + + Map json = new HashMap<>(); + + json.put("id", EXAMPLE_TASK_COMMENT_ID); + json.put("message", EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + + given().pathParam("id", NON_EXISTING_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.NOT_FOUND.getStatusCode()) + .contentType(ContentType.JSON) + .body("type", equalTo(InvalidRequestException.class.getSimpleName())) + .body(containsString("No task found for task id " + NON_EXISTING_ID)) + .when() + .put(SINGLE_TASK_COMMENTS_URL); + } + + @Test + public void testUpdateTaskCommentThrowsAuthorizationException() { + String message = "expected exception"; + doThrow(new AuthorizationException(message)).when(taskServiceMock) + .updateTaskComment(EXAMPLE_TASK_ID, EXAMPLE_TASK_COMMENT_ID, EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + when(historicTaskInstanceQueryMock.taskId(EXAMPLE_TASK_ID)).thenReturn(historicTaskInstanceQueryMock); + + Map json = new HashMap<>(); + json.put("id", EXAMPLE_TASK_COMMENT_ID); + json.put("message", EXAMPLE_TASK_COMMENT_FULL_MESSAGE); + + given().pathParam("id", EXAMPLE_TASK_ID) + .body(json) + .contentType(ContentType.JSON) + .header("accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(Status.FORBIDDEN.getStatusCode()) + .contentType(ContentType.JSON) + .when() + .put(SINGLE_TASK_COMMENTS_URL); + + } + @SuppressWarnings({ "rawtypes", "unchecked" }) private void verifyTaskComments(List mockTaskComments, Response response) { List list = response.as(List.class); diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java index 4a4a312996e..b48c11170d5 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java @@ -201,6 +201,11 @@ public abstract class MockProvider { public static final String EXAMPLE_TASK_COMMENT_TIME = withTimezone("2014-04-24T14:10:44"); public static final String EXAMPLE_TASK_COMMENT_ROOT_PROCESS_INSTANCE_ID = "aRootProcInstId"; + //process instance comment + public static final String EXAMPLE_PROCESS_INSTANCE_COMMENT_ID = "aProcessInstanceCommentId"; + public static final String EXAMPLE_PROCESS_INSTANCE_COMMENT_FULL_MESSAGE = "aProcessInstanceCommentFullMessage"; + + // task attachment public static final String EXAMPLE_TASK_ATTACHMENT_ID = "aTaskAttachmentId"; public static final String EXAMPLE_TASK_ATTACHMENT_NAME = "aTaskAttachmentName"; From 8a1f5da80a3e204147dd356bdd70620ba4431c39 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Thu, 2 May 2024 08:48:09 -0600 Subject: [PATCH 03/10] feat(engine-rest-openapi) Add update and delete Java/Rest APIs of task and processInstance DELETE /task/{taskId}/comment/{commentId} - deletes a comment of a given taskId and commentId DELETE /task/{taskId}/comment - deletes all comments of a given taskId PUT /task/comment - updates a comment DELETE /process-instance/{processInstanceId}/comment/{commentId} - deletes a comment of a given processInstanceId and commentId DELETE /process-instance/{processInstanceId}/comment. - deletes all comments of a given processInstanceId PUT /process-instance/comment - updates a comment related to: https://github.com/camunda/camunda-bpm-platform/issues/2551 --- .../process-instance/{id}/comment/delete.ftl | 49 +++++++++++++ .../process-instance/{id}/comment/put.ftl | 73 +++++++++++++++++++ .../{id}/comment/{commentId}/delete.ftl | 59 +++++++++++++++ .../paths/task/{id}/comment/delete.ftl | 49 +++++++++++++ .../templates/paths/task/{id}/comment/put.ftl | 64 ++++++++++++++++ .../task/{id}/comment/{commentId}/delete.ftl | 59 +++++++++++++++ 6 files changed, 353 insertions(+) create mode 100644 engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl create mode 100644 engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl create mode 100644 engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl create mode 100644 engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl create mode 100644 engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl create mode 100644 engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl new file mode 100644 index 00000000000..1e69efbe1fe --- /dev/null +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl @@ -0,0 +1,49 @@ +<#macro endpoint_macro docsUrl=""> + { + <@lib.endpointInfo + id = "deleteProcessInstanceComments" + tag = "Process Instance Comment" + summary = "Delete ProcessInstance Comments" + desc = "Deletes all comments of a processIntance by processInstance id." /> + + "parameters": [ + + <@lib.parameter + name = "id" + location = "path" + type = "string" + required = true + last = true + desc = "The id of the process instance for which all comments are to be deleted."/> + + ], + "responses": { + + <@lib.response + code = "204" + desc = "Request successful." /> + + <@lib.response + code = "401" + dto = "ExceptionDto" + desc = "The authenticated user is unauthorized to delete this resource. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format."/> + + <@lib.response + code = "403" + dto = "AuthorizationExceptionDto" + desc = "The history of the engine is disabled. See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "500" + dto = "ExceptionDto" + last = true + desc = "Comments of a process instance could not be deleted successfully. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + } + } + \ No newline at end of file diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl new file mode 100644 index 00000000000..241dd541207 --- /dev/null +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl @@ -0,0 +1,73 @@ +<#macro endpoint_macro docsUrl=""> + { + + <@lib.endpointInfo + id = "updateProcessInstanceComment" + tag = "Process Instance Comment" + summary = "Update" + desc = "Updates a Comment." /> + + "parameters" : [ + + <@lib.parameter + name = "id" + location = "path" + type = "string" + required = true + last = true + desc = "The id associated of a process instance of a comment to be updated."/> + + ], + + <@lib.requestBody + mediaType = "application/json" + dto = "CommentDto" + requestDesc = "**Note:** Only the `id` and `message` properties will be used. Every other + property passed to this endpoint will be ignored." + examples = ['"example-1": { + "summary": "PUT /process-instance/aProcessInstanceId/comment", + "value": { + "id": "75bc161a-12da-11e4-7d3a-f4ccdc10a445", + "message": "a process instance comment" + } + }'] /> + + "responses" : { + + <@lib.response + code = "204" + desc = "Request successful." /> + + <@lib.response + code = "400" + dto = "ExceptionDto" + desc = "Returned if some of the query parameters are invalid, for example if + the value of `commentId` parameter is supplied as null. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "401" + dto = "ExceptionDto" + desc = "The authenticated user is unauthorized to update this resource. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "403" + dto = "AuthorizationExceptionDto" + desc = "The history of the engine is disabled. See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "500" + dto = "ExceptionDto" + last = true + desc = "The comment of a process instance could not be updated successfully. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + } + } + + \ No newline at end of file diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl new file mode 100644 index 00000000000..24dffb571bd --- /dev/null +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl @@ -0,0 +1,59 @@ +<#macro endpoint_macro docsUrl=""> + { + + <@lib.endpointInfo + id = "deleteProcessInstanceComment" + tag = "Process Instance Comment" + summary = "Delete" + desc = "Removes a comment from a process instance by id." /> + + "parameters" : [ + + <@lib.parameter + name = "id" + location = "path" + type = "string" + required = true + desc = "The id of the processInstance." /> + + <@lib.parameter + name = "commentId" + location = "path" + type = "string" + required = true + last = true + desc = "The id of the comment to be removed." /> + + ], + + "responses" : { + + <@lib.response + code = "204" + desc = "Request successful." /> + + <@lib.response + code = "401" + dto = "ExceptionDto" + desc = "The authenticated user is unauthorized to delete this resource. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "403" + dto = "AuthorizationExceptionDto" + desc = "The history of the engine is disabled. See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "500" + dto = "ExceptionDto" + last = true + desc = "The comment of a process instance could not be deleted successfully. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + } + } + + \ No newline at end of file diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl new file mode 100644 index 00000000000..959596b0d7d --- /dev/null +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl @@ -0,0 +1,49 @@ +<#macro endpoint_macro docsUrl=""> + { + <@lib.endpointInfo + id = "deleteTaskComments" + tag = "Task Comment" + summary = "Delete Task Comments" + desc = "Deletes all comments of a task by task id." /> + + "parameters": [ + + <@lib.parameter + name = "id" + location = "path" + type = "string" + required = true + last = true + desc = "The id of the task for which all comments are to be deleted."/> + + ], + "responses": { + + <@lib.response + code = "204" + desc = "Request successful." /> + + <@lib.response + code = "401" + dto = "ExceptionDto" + desc = "The authenticated user is unauthorized to delete this resource. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." + /> + + <@lib.response + code = "403" + dto = "AuthorizationExceptionDto" + desc = "The history of the engine is disabled. See the [Introduction](/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "500" + dto = "ExceptionDto" + last = true + desc = "Comments of a task could not be deleted successfully. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + } + } + \ No newline at end of file diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl new file mode 100644 index 00000000000..f995c70b04c --- /dev/null +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl @@ -0,0 +1,64 @@ +<#macro endpoint_macro docsUrl=""> + { + + <@lib.endpointInfo + id = "updateTaskComment" + tag = "Task Comment" + summary = "Update" + desc = "Updates a Comment." /> + + "parameters" : [ + + <@lib.parameter + name = "id" + location = "path" + type = "string" + required = true + last = true + desc = "The id associated of a task of a comment to be updated."/> + + ], + + <@lib.requestBody + mediaType = "application/json" + dto = "CommentDto" + requestDesc = "**Note:** Only the `id` and `message` properties will be used. Every other + property passed to this endpoint will be ignored." + examples = ['"example-1": { + "summary": "PUT /task/aTaskId/comment", + "value": { + "id": "86cd272a-23ea-22e5-8e4a-e5bded20a556", + "message": "a task comment" + } + }'] /> + + "responses" : { + + <@lib.response + code = "204" + desc = "Request successful." /> + + <@lib.response + code = "401" + dto = "ExceptionDto" + desc = "The authenticated user is unauthorized to update this resource. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format."/> + + <@lib.response + code = "403" + dto = "AuthorizationExceptionDto" + desc = "The history of the engine is disabled. See the [Introduction](/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "500" + dto = "ExceptionDto" + last = true + desc = "The comment of a task could not be updated successfully. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + } + } + + \ No newline at end of file diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl new file mode 100644 index 00000000000..e7758150bf2 --- /dev/null +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl @@ -0,0 +1,59 @@ +<#macro endpoint_macro docsUrl=""> + { + + <@lib.endpointInfo + id = "deleteTaskComment" + tag = "Task Comment" + summary = "Delete" + desc = "Removes a comment from a task by id." /> + + "parameters" : [ + + <@lib.parameter + name = "id" + location = "path" + type = "string" + required = true + desc = "The id of the task." /> + + <@lib.parameter + name = "commentId" + location = "path" + type = "string" + required = true + last = true + desc = "The id of the comment to be removed." /> + + ], + + "responses" : { + + <@lib.response + code = "204" + desc = "Request successful." /> + + <@lib.response + code = "401" + dto = "ExceptionDto" + desc = "The authenticated user is unauthorized to delete this resource. See the + [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format."/> + + <@lib.response + code = "403" + dto = "AuthorizationExceptionDto" + desc = "The history of the engine is disabled. See the [Introduction](/reference/rest/overview/#error-handling) + for the error response format." /> + + <@lib.response + code = "500" + dto = "ExceptionDto" + last = true + desc = "The comment of a task could not be deleted successfully. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) + for the error response format." /> + + } + } + + \ No newline at end of file From c307a42aedaf627cd6ece79e8dc837343e0d59e3 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Thu, 9 May 2024 15:37:12 -0600 Subject: [PATCH 04/10] chore(engine) added git issue number in newly created files. --- .../bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java | 2 ++ .../bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java | 2 ++ .../org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java | 2 ++ .../org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java | 2 ++ .../bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java | 2 ++ .../org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java | 2 ++ 6 files changed, 12 insertions(+) diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java index 00384d90f0a..14c3d4a9f90 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java @@ -28,6 +28,8 @@ import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; /** + * see https://github.com/camunda/camunda-bpm-platform/issues/2551 + * * Command to delete a comment by a given commentId and processInstanceId. */ public class DeleteProcessInstanceCommentCmd implements Command, Serializable { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java index 95a9043462e..193f7cadb06 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java @@ -30,6 +30,8 @@ import org.camunda.bpm.engine.task.Comment; /** + * see https://github.com/camunda/camunda-bpm-platform/issues/2551 + * * Command to delete comments by a given processInstance ID. */ public class DeleteProcessInstanceCommentsCmd implements Command, Serializable { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java index 00ba640ac56..3df8e277978 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java @@ -28,6 +28,8 @@ import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; /** + * see https://github.com/camunda/camunda-bpm-platform/issues/2551 + * * Command to delete a comment by a given commentId and taskId. */ public class DeleteTaskCommentCmd implements Command, Serializable { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java index d6ea7857c06..afdd22b35a8 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java @@ -29,6 +29,8 @@ import org.camunda.bpm.engine.task.Comment; /** + * see https://github.com/camunda/camunda-bpm-platform/issues/2551 + * * Command to delete comments by a given task ID. */ public class DeleteTaskCommentsCmd implements Command, Serializable { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java index 49cfb653817..e0d78e0f5db 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java @@ -29,6 +29,8 @@ import org.camunda.bpm.engine.impl.util.ClockUtil; /** + * see https://github.com/camunda/camunda-bpm-platform/issues/2551 + * * Command to update a comment by a given processInstance ID. */ public class UpdateProcessInstanceCommentCmd implements Command, Serializable { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java index 4da47db8679..09062cba42c 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java @@ -29,6 +29,8 @@ import org.camunda.bpm.engine.impl.util.ClockUtil; /** + * see https://github.com/camunda/camunda-bpm-platform/issues/2551 + * * Command to update a comment by a given task ID. */ public class UpdateTaskCommentCmd implements Command, Serializable { From b7d5510979abee5da87b8991af2cb347654b5b39 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Wed, 26 Jun 2024 14:20:49 -0600 Subject: [PATCH 05/10] feat(engine) - add revision to comments - change authorization to task_assign from task_update - refactor code - add more java docs --- .../org/camunda/bpm/engine/TaskService.java | 57 ++++++++- .../bpm/engine/impl/TaskServiceImpl.java | 13 +- .../bpm/engine/impl/cfg/CommandChecker.java | 5 - .../cfg/auth/AuthorizationCommandChecker.java | 4 - .../multitenancy/TenantCommandChecker.java | 6 - .../cmd/DeleteProcessInstanceCommentCmd.java | 72 ++++++++--- .../cmd/DeleteProcessInstanceCommentsCmd.java | 69 ---------- .../engine/impl/cmd/DeleteTaskCommentCmd.java | 55 ++++++-- .../impl/cmd/DeleteTaskCommentsCmd.java | 66 ---------- .../bpm/engine/impl/cmd/UpdateCommentCmd.java | 119 ++++++++++++++++++ .../cmd/UpdateProcessInstanceCommentCmd.java | 92 -------------- .../engine/impl/cmd/UpdateTaskCommentCmd.java | 88 ------------- .../impl/db/sql/DbSqlSessionFactory.java | 1 + .../persistence/entity/CommentEntity.java | 20 ++- .../persistence/entity/CommentManager.java | 2 + .../activiti.cockroachdb.create.history.sql | 1 + .../db/create/activiti.db2.create.history.sql | 1 + .../db/create/activiti.h2.create.history.sql | 1 + .../activiti.mariadb.create.history.sql | 1 + .../create/activiti.mssql.create.history.sql | 1 + .../create/activiti.mysql.create.history.sql | 1 + .../create/activiti.oracle.create.history.sql | 1 + .../activiti.postgres.create.history.sql | 1 + .../cockroachdb_engine_7.21_to_7.22.sql | 9 ++ .../db/upgrade/db2_engine_7.21_to_7.22.sql | 9 ++ .../db/upgrade/h2_engine_7.21_to_7.22.sql | 9 ++ .../upgrade/mariadb_engine_7.21_to_7.22.sql | 9 ++ .../db/upgrade/mssql_engine_7.21_to_7.22.sql | 9 ++ .../db/upgrade/mysql_engine_7.21_to_7.22.sql | 9 ++ .../db/upgrade/oracle_engine_7.21_to_7.22.sql | 9 ++ .../upgrade/postgres_engine_7.21_to_7.22.sql | 9 ++ .../engine/impl/mapping/entity/Comment.xml | 28 +++-- ...ocessInstanceCommentAuthorizationTest.java | 14 +-- .../TaskCommentAuthorizationTest.java | 6 +- .../engine/test/api/task/TaskServiceTest.java | 43 +------ 35 files changed, 413 insertions(+), 427 deletions(-) delete mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java delete mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java create mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java delete mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java delete mode 100644 engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java diff --git a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java index c0fa0f1d49a..93f46d61926 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java +++ b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java @@ -1108,32 +1108,81 @@ public interface TaskService { Comment createComment(String taskId, String processInstanceId, String message); /** - * Deletes a comment by a given taskId and comment ID + * Deletes a comment of a given taskId and commentId + * + * @param taskId id of a task of a comment that is intended to be deleted + * @param commentId id of a comment that is intended to be deleted + * @throws NotFoundException if no task with the given id exists + * @throws BadUserRequestException if task id or error code were null or empty + * @throws ProcessEngineException when task and comment don't exist with the given taskId and commentId + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void deleteTaskComment(String taskId, String commentId); /** * Deletes a comment by a given processInstanceId and comment ID + * + * @param processInstanceId id of a processInstance of a comment that is intended to be deleted + * @param commentId id of a comment that is intended to be deleted + * @throws NotFoundException if no task with the given process instance id exists + * @throws ProcessEngineException when given process instance id and comment id are passed as null + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void deleteProcessInstanceComment(String processInstanceId, String commentId); /** - * Deletes comments by a given task ID + * Deletes all comments by a given task ID + * + * @param taskId id of a task of all comments that are intended to be deleted + * @throws NotFoundException when the task doesn't exist with a given task id + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void deleteTaskComments(String taskId); /** - * Deletes comments by a given processInstance ID + * Deletes all comments by a given processInstance ID + * + * @param processInstanceId id of a process instance of comments that are intended to be deleted + * @throws NotFoundException when the process instance doesn't exist with a given process instance id + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void deleteProcessInstanceComments(String processInstanceId); /** - * Updates comment on a given task ID + * Updates a comment on a given task ID + * + * @param taskId id of a task of a comment that is intended to be updated + * @param commentId id of a comment that is intended to be updated + * @param message new message that needs to be updated + * @throws NotFoundException if no task with the given taskId id exists + * @throws NotFoundException if no comment found to be updated for a given comment id + * @throws ProcessEngineException when given task id and comment id are passed as null + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void updateTaskComment(String taskId, String commentId, String message); /** * Updates comment on a given processInstance ID + * + * @param processInstanceId id of a process instance of a comment that is intended to be updated + * @param commentId id of a comment that is intended to be updated + * @param message new message that needs to be updated + * @throws NotFoundException if no process instance with the given processInstanceId id exists + * @throws NotFoundException if no comment found to be updated for a given comment id + * @throws ProcessEngineException when given process instance id and comment id are passed as null + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void updateProcessInstanceComment(String processInstanceId, String commentId, String message); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java b/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java index 170bb135ca2..a4f7a929829 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/TaskServiceImpl.java @@ -41,10 +41,8 @@ import org.camunda.bpm.engine.impl.cmd.DeleteAttachmentCmd; import org.camunda.bpm.engine.impl.cmd.DeleteGroupIdentityLinkCmd; import org.camunda.bpm.engine.impl.cmd.DeleteProcessInstanceCommentCmd; -import org.camunda.bpm.engine.impl.cmd.DeleteProcessInstanceCommentsCmd; import org.camunda.bpm.engine.impl.cmd.DeleteTaskCmd; import org.camunda.bpm.engine.impl.cmd.DeleteTaskCommentCmd; -import org.camunda.bpm.engine.impl.cmd.DeleteTaskCommentsCmd; import org.camunda.bpm.engine.impl.cmd.DeleteUserIdentityLinkCmd; import org.camunda.bpm.engine.impl.cmd.GetAttachmentCmd; import org.camunda.bpm.engine.impl.cmd.GetAttachmentContentCmd; @@ -75,8 +73,7 @@ import org.camunda.bpm.engine.impl.cmd.SetTaskOwnerCmd; import org.camunda.bpm.engine.impl.cmd.SetTaskPriorityCmd; import org.camunda.bpm.engine.impl.cmd.SetTaskVariablesCmd; -import org.camunda.bpm.engine.impl.cmd.UpdateProcessInstanceCommentCmd; -import org.camunda.bpm.engine.impl.cmd.UpdateTaskCommentCmd; +import org.camunda.bpm.engine.impl.cmd.UpdateCommentCmd; import org.camunda.bpm.engine.impl.util.ExceptionUtil; import org.camunda.bpm.engine.task.Attachment; import org.camunda.bpm.engine.task.Comment; @@ -395,19 +392,19 @@ public void deleteProcessInstanceComment(String processInstanceId, String commen } public void deleteTaskComments(String taskId) { - commandExecutor.execute(new DeleteTaskCommentsCmd(taskId)); + commandExecutor.execute(new DeleteTaskCommentCmd(taskId)); } public void deleteProcessInstanceComments(String processInstanceId) { - commandExecutor.execute(new DeleteProcessInstanceCommentsCmd(processInstanceId)); + commandExecutor.execute(new DeleteProcessInstanceCommentCmd(processInstanceId)); } public void updateTaskComment(String taskId, String commentId, String message) { - commandExecutor.execute(new UpdateTaskCommentCmd(taskId, commentId, message)); + commandExecutor.execute(new UpdateCommentCmd(taskId, null, commentId, message)); } public void updateProcessInstanceComment(String processInstanceId, String commentId, String message) { - commandExecutor.execute(new UpdateProcessInstanceCommentCmd(processInstanceId, commentId, message)); + commandExecutor.execute(new UpdateCommentCmd(null, processInstanceId, commentId, message)); } public List getTaskComments(String taskId) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java index fd9cab75d38..8596ac73a6c 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/CommandChecker.java @@ -271,11 +271,6 @@ public interface CommandChecker { */ void checkDeleteTask(TaskEntity task); - /** - * Check if it is allowed to update a task - */ - void checkUpdateTask(TaskEntity task); - /** * Checks if it is allowed to read the given decision definition. */ diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java index abd204e0eed..aabfc943176 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/auth/AuthorizationCommandChecker.java @@ -762,10 +762,6 @@ public void checkDeleteTask(TaskEntity task) { } } - public void checkUpdateTask(TaskEntity task) { - getAuthorizationManager().checkAuthorization(UPDATE, TASK, task.getId()); - } - public void checkUserOperationLog(UserOperationLogEntry entry, ProcessDefinitionPermissions processDefinitionPermission, UserOperationLogCategoryPermissions operationLogCategoryPermission) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java index 93c6d6e8965..bf682125670 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/multitenancy/TenantCommandChecker.java @@ -340,12 +340,6 @@ public void checkDeleteTask(TaskEntity task) { } } - public void checkUpdateTask(TaskEntity task) { - if (task != null && !getTenantManager().isAuthenticatedTenant(task.getTenantId())) { - throw LOG.exceptionCommandWithUnauthorizedTenant("update the task '" + task.getId() + "'"); - } - } - public void checkTaskAssign(TaskEntity task) { if (task != null && !getTenantManager().isAuthenticatedTenant(task.getTenantId())) { throw LOG.exceptionCommandWithUnauthorizedTenant("assign the task '"+ task.getId() + "'"); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java index 14c3d4a9f90..fd720f03663 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java @@ -19,19 +19,24 @@ import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; import java.io.Serializable; +import java.util.Collections; +import java.util.List; +import org.camunda.bpm.engine.ProcessEngineException; import org.camunda.bpm.engine.history.UserOperationLogEntry; import org.camunda.bpm.engine.impl.cfg.CommandChecker; import org.camunda.bpm.engine.impl.interceptor.Command; import org.camunda.bpm.engine.impl.interceptor.CommandContext; import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; +import org.camunda.bpm.engine.task.Comment; /** - * see https://github.com/camunda/camunda-bpm-platform/issues/2551 - * - * Command to delete a comment by a given commentId and processInstanceId. + * Command to delete a comment by a given commentId and processInstanceId or to delete all comments + * of a given processInstanceId */ + public class DeleteProcessInstanceCommentCmd implements Command, Serializable { private static final long serialVersionUID = 1L; @@ -43,24 +48,59 @@ public DeleteProcessInstanceCommentCmd(String processInstanceId, String commentI this.commentId = commentId; } + public DeleteProcessInstanceCommentCmd(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + public Object execute(CommandContext commandContext) { - ensureNotNull("commentId", commentId); + if (processInstanceId == null && commentId == null) { + throw new ProcessEngineException("Both process instance and comment ids are null"); + } + + ensureNotNull("processInstanceId", processInstanceId); + + if (commentId != null && processInstanceId != null) { + CommentEntity comment = commandContext.getCommentManager() + .findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); + if (comment != null) { - CommentEntity comment = commandContext.getCommentManager() - .findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); + TaskEntity task = getTask(comment, commandContext); - if (comment != null) { - TaskEntity task = getTask(comment, commandContext); - checkUpdateProcessInstance(processInstanceId, commandContext); - commandContext.getDbEntityManager().delete(comment); + checkTaskAssign(task, commandContext); + commandContext.getDbEntityManager().delete(comment); + logOperation(comment, task, null, commandContext); + task.triggerUpdateEvent(); + } + } else { + ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); + ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance: ", + processInstance); - PropertyChange propertyChange = new PropertyChange("comment", null, comment.getMessage()); + List comments = commandContext.getCommentManager().findCommentsByProcessInstanceId(processInstanceId); + if (!comments.isEmpty()) { + TaskEntity task = commandContext.getTaskManager().findTaskById(comments.get(0).getTaskId()); + checkTaskAssign(task, commandContext); + commandContext.getCommentManager() + .deleteCommentsByProcessInstanceIds(Collections.singletonList(processInstanceId)); + logOperation(null, null, processInstance, commandContext); + } + } + return null; + } + + private void logOperation(CommentEntity comment, + TaskEntity task, + ExecutionEntity processInstance, + CommandContext commandContext) { + PropertyChange propertyChange = new PropertyChange("comment", null, + (comment != null) ? comment.getMessage() : null); + if (task != null) { commandContext.getOperationLogManager() .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); - task.triggerUpdateEvent(); + } else { + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, processInstance, propertyChange); } - - return null; } private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) { @@ -70,9 +110,9 @@ private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) return task; } - protected void checkUpdateProcessInstance(String processInstanceId, CommandContext commandContext) { + protected void checkTaskAssign(TaskEntity task, CommandContext commandContext) { for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkUpdateProcessInstanceById(processInstanceId); + checker.checkTaskAssign(task); } } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java deleted file mode 100644 index 193f7cadb06..00000000000 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentsCmd.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. Camunda licenses this file to you under the Apache License, - * Version 2.0; you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.camunda.bpm.engine.impl.cmd; - -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; - -import java.io.Serializable; -import java.util.Collections; -import java.util.List; -import org.camunda.bpm.engine.history.UserOperationLogEntry; -import org.camunda.bpm.engine.impl.cfg.CommandChecker; -import org.camunda.bpm.engine.impl.interceptor.Command; -import org.camunda.bpm.engine.impl.interceptor.CommandContext; -import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; -import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; -import org.camunda.bpm.engine.task.Comment; - -/** - * see https://github.com/camunda/camunda-bpm-platform/issues/2551 - * - * Command to delete comments by a given processInstance ID. - */ -public class DeleteProcessInstanceCommentsCmd implements Command, Serializable { - - private static final long serialVersionUID = 1L; - protected String processInstanceId; - - public DeleteProcessInstanceCommentsCmd(String processInstanceId) { - this.processInstanceId = processInstanceId; - } - - public Object execute(CommandContext commandContext) { - ensureNotNull("processInstanceId", processInstanceId); - ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); - ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance: ", - processInstance); - - List comments = commandContext.getCommentManager().findCommentsByProcessInstanceId(processInstanceId); - if (!comments.isEmpty()) { - checkUpdateProcessInstance(processInstanceId, commandContext); - commandContext.getCommentManager() - .deleteCommentsByProcessInstanceIds(Collections.singletonList(processInstanceId)); - PropertyChange propertyChange = new PropertyChange("comment", null, null); - commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, processInstance, propertyChange); - } - return null; - } - - protected void checkUpdateProcessInstance(String processInstanceId, CommandContext commandContext) { - for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkUpdateProcessInstanceById(processInstanceId); - } - } -} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java index 3df8e277978..93bd88d6e3f 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java @@ -19,6 +19,8 @@ import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; import java.io.Serializable; +import java.util.List; +import org.camunda.bpm.engine.ProcessEngineException; import org.camunda.bpm.engine.history.UserOperationLogEntry; import org.camunda.bpm.engine.impl.cfg.CommandChecker; import org.camunda.bpm.engine.impl.interceptor.Command; @@ -26,12 +28,13 @@ import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; +import org.camunda.bpm.engine.task.Comment; /** - * see https://github.com/camunda/camunda-bpm-platform/issues/2551 - * - * Command to delete a comment by a given commentId and taskId. + * Command to delete a comment by a given commentId and taskId or to delete all comments + * of a given task Id */ + public class DeleteTaskCommentCmd implements Command, Serializable { private static final long serialVersionUID = 1L; @@ -43,24 +46,50 @@ public DeleteTaskCommentCmd(String taskId, String commentId) { this.commentId = commentId; } + public DeleteTaskCommentCmd(String taskId) { + this.taskId = taskId; + } + public Object execute(CommandContext commandContext) { - ensureNotNull("commentId", commentId); + if (commentId == null && taskId == null) { + throw new ProcessEngineException("Both task and comment ids are null"); + } - CommentEntity comment = commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); - if (comment != null) { - TaskEntity task = getTask(comment, commandContext); + ensureNotNull("taskId", taskId); - checkUpdateTask(task, commandContext); - commandContext.getDbEntityManager().delete(comment); + TaskEntity task = null; + CommentEntity comment = null; + if (commentId != null && taskId != null) { + comment = commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); + if (comment != null) { + task = getTask(comment, commandContext); + checkTaskAssign(task, commandContext); + commandContext.getDbEntityManager().delete(comment); + } + } else { + task = commandContext.getTaskManager().findTaskById(taskId); + ensureNotNull("No task exists with taskId: " + taskId, "task", task); + List comments = commandContext.getCommentManager().findCommentsByTaskId(taskId); + if (!comments.isEmpty()) { + checkTaskAssign(task, commandContext); + commandContext.getCommentManager().deleteCommentsByTaskId(taskId); + } + } - PropertyChange propertyChange = new PropertyChange("comment", null, comment.getMessage()); + if (task != null) { commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, + getCommentPropertyChange(comment != null ? comment.getMessage() : null)); task.triggerUpdateEvent(); } + return null; } + private PropertyChange getCommentPropertyChange(String message) { + return new PropertyChange("comment", null, message); + } + private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) { String taskId = comment.getTaskId(); TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); @@ -68,9 +97,9 @@ private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) return task; } - protected void checkUpdateTask(TaskEntity task, CommandContext commandContext) { + protected void checkTaskAssign(TaskEntity task, CommandContext commandContext) { for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkUpdateTask(task); + checker.checkTaskAssign(task); } } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java deleted file mode 100644 index afdd22b35a8..00000000000 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentsCmd.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. Camunda licenses this file to you under the Apache License, - * Version 2.0; you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.camunda.bpm.engine.impl.cmd; - -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; - -import java.io.Serializable; -import java.util.List; -import org.camunda.bpm.engine.history.UserOperationLogEntry; -import org.camunda.bpm.engine.impl.cfg.CommandChecker; -import org.camunda.bpm.engine.impl.interceptor.Command; -import org.camunda.bpm.engine.impl.interceptor.CommandContext; -import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; -import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; -import org.camunda.bpm.engine.task.Comment; - -/** - * see https://github.com/camunda/camunda-bpm-platform/issues/2551 - * - * Command to delete comments by a given task ID. - */ -public class DeleteTaskCommentsCmd implements Command, Serializable { - - private static final long serialVersionUID = 1L; - protected String taskId; - - public DeleteTaskCommentsCmd(String taskId) { - this.taskId = taskId; - } - - public Void execute(CommandContext commandContext) { - ensureNotNull("taskId", taskId); - TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); - ensureNotNull("No task exists with taskId: " + taskId, "task", task); - List comments = commandContext.getCommentManager().findCommentsByTaskId(taskId); - if (!comments.isEmpty()) { - checkUpdateTask(task, commandContext); - commandContext.getCommentManager().deleteCommentsByTaskId(taskId); - PropertyChange propertyChange = new PropertyChange("comment", null, null); - commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); - task.triggerUpdateEvent(); - } - return null; - } - - protected void checkUpdateTask(TaskEntity task, CommandContext commandContext) { - for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkUpdateTask(task); - } - } -} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java new file mode 100644 index 00000000000..26e68c8966b --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java @@ -0,0 +1,119 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.impl.cmd; + +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.io.Serializable; +import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.cfg.CommandChecker; +import org.camunda.bpm.engine.impl.interceptor.Command; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; +import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; +import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; +import org.camunda.bpm.engine.impl.util.ClockUtil; + +/** + * Command to update a comment by a given task ID or a process Instance ID + */ +public class UpdateCommentCmd implements Command, Serializable { + + private static final long serialVersionUID = 1L; + protected String taskId; + protected String commentId; + protected String processInstanceId; + protected String message; + + public UpdateCommentCmd(String taskId, String processInstanceId, String commentId, String message) { + this.taskId = taskId; + this.processInstanceId = processInstanceId; + this.commentId = commentId; + this.message = message; + } + + public Object execute(CommandContext commandContext) { + if (processInstanceId == null && taskId == null) { + throw new ProcessEngineException("Both process instance and task ids are null"); + } + + ensureNotNull("commentId", commentId); + ensureNotNull("message", message); + + if(null == processInstanceId) { + ensureNotNull("taskId", taskId); + CommentEntity comment = getComment(commandContext); + ensureNotNull("No comment exists with commentId: " + commentId + " and taskId: " + taskId, "comment", comment); + TaskEntity task = updateComment(taskId, commandContext, comment); + commandContext.getOperationLogManager().logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, task, getPropertyChange(comment)); + task.triggerUpdateEvent(); + } + else { + ensureNotNull("processInstanceId", processInstanceId); + CommentEntity comment = getComment(commandContext); + ensureNotNull("No comment exists with commentId: " + commentId + " and processInstanceId: " + processInstanceId, "comment", comment); + ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); + ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance", processInstance); + updateComment(comment.getTaskId(), commandContext, comment); + commandContext.getOperationLogManager().logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, processInstance, getPropertyChange(comment)); + } + + return null; + } + + private TaskEntity updateComment(String taskId, CommandContext commandContext, CommentEntity comment) { + TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); + ensureNotNull("No task exists with taskId: " + taskId, "task", task); + + checkTaskAssign(task, commandContext); + updateComment(commandContext, comment); + return task; + } + + private CommentEntity getComment(CommandContext commandContext) { + if(taskId !=null) { + return commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); + } + return commandContext.getCommentManager().findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); + } + + private PropertyChange getPropertyChange(CommentEntity comment) { + return new PropertyChange("comment", comment.getMessage(), message); + } + + protected void checkTaskAssign(TaskEntity task, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkTaskAssign(task); + } + } + + private void updateComment(CommandContext commandContext, CommentEntity comment) { + String eventMessage = comment.toEventMessage(message); + + String userId = commandContext.getAuthenticatedUserId(); + + comment.setMessage(eventMessage); + comment.setFullMessage(message); + comment.setTime(ClockUtil.getCurrentTime()); + comment.setAction(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT); + comment.setUserId(userId); + + commandContext.getDbEntityManager().update(CommentEntity.class, "updateComment", comment); + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java deleted file mode 100644 index e0d78e0f5db..00000000000 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateProcessInstanceCommentCmd.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. Camunda licenses this file to you under the Apache License, - * Version 2.0; you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.camunda.bpm.engine.impl.cmd; - -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; - -import java.io.Serializable; -import org.camunda.bpm.engine.history.UserOperationLogEntry; -import org.camunda.bpm.engine.impl.cfg.CommandChecker; -import org.camunda.bpm.engine.impl.interceptor.Command; -import org.camunda.bpm.engine.impl.interceptor.CommandContext; -import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; -import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; -import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; -import org.camunda.bpm.engine.impl.util.ClockUtil; - -/** - * see https://github.com/camunda/camunda-bpm-platform/issues/2551 - * - * Command to update a comment by a given processInstance ID. - */ -public class UpdateProcessInstanceCommentCmd implements Command, Serializable { - - private static final long serialVersionUID = 1L; - protected String commentId; - protected String message; - protected String processInstanceId; - - public UpdateProcessInstanceCommentCmd(String processInstanceId, String commentId, String message) { - this.processInstanceId = processInstanceId; - this.commentId = commentId; - this.message = message; - } - - public Object execute(CommandContext commandContext) { - ensureNotNull("commentId", commentId); - ensureNotNull("processInstanceId", processInstanceId); - ensureNotNull("message", message); - - CommentEntity comment = commandContext.getCommentManager() - .findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); - ensureNotNull("No comment exists with commentId: " + commentId + " and processInstanceId: " + processInstanceId, - "comment", comment); - - ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); - ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance", - processInstance); - - checkUpdateProcessInstance(processInstanceId, commandContext); - updateComment(commandContext, comment, message); - - PropertyChange propertyChange = new PropertyChange("comment", comment.getMessage(), message); - commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, processInstance, propertyChange); - - return null; - } - - protected void checkUpdateProcessInstance(String processInstanceId, CommandContext commandContext) { - for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkUpdateProcessInstanceById(processInstanceId); - } - } - - private void updateComment(CommandContext commandContext, CommentEntity comment, String message) { - String eventMessage = comment.toEventMessage(message); - String userId = commandContext.getAuthenticatedUserId(); - - comment.setMessage(eventMessage); - comment.setFullMessage(message); - comment.setTime(ClockUtil.getCurrentTime()); - comment.setAction(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT); - comment.setUserId(userId); - - commandContext.getCommentManager().updateCommentMessage(comment); - } - -} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java deleted file mode 100644 index 09062cba42c..00000000000 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateTaskCommentCmd.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. Camunda licenses this file to you under the Apache License, - * Version 2.0; you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.camunda.bpm.engine.impl.cmd; - -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; - -import java.io.Serializable; -import org.camunda.bpm.engine.history.UserOperationLogEntry; -import org.camunda.bpm.engine.impl.cfg.CommandChecker; -import org.camunda.bpm.engine.impl.interceptor.Command; -import org.camunda.bpm.engine.impl.interceptor.CommandContext; -import org.camunda.bpm.engine.impl.persistence.entity.CommentEntity; -import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; -import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; -import org.camunda.bpm.engine.impl.util.ClockUtil; - -/** - * see https://github.com/camunda/camunda-bpm-platform/issues/2551 - * - * Command to update a comment by a given task ID. - */ -public class UpdateTaskCommentCmd implements Command, Serializable { - - private static final long serialVersionUID = 1L; - protected String taskId; - protected String commentId; - protected String message; - - public UpdateTaskCommentCmd(String taskId, String commentId, String message) { - this.taskId = taskId; - this.commentId = commentId; - this.message = message; - } - - public Object execute(CommandContext commandContext) { - ensureNotNull("commentId", commentId); - ensureNotNull("taskId", taskId); - ensureNotNull("message", message); - - CommentEntity comment = commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); - ensureNotNull("No comment exists with commentId: " + commentId + " and taskId: " + taskId, "comment", comment); - TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); - ensureNotNull("No task exists with taskId: " + taskId, "task", task); - - checkUpdateTask(task, commandContext); - updateComment(commandContext, comment); - PropertyChange propertyChange = new PropertyChange("comment", comment.getMessage(), message); - commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, task, propertyChange); - task.triggerUpdateEvent(); - - return null; - } - - private void updateComment(CommandContext commandContext, CommentEntity comment) { - String eventMessage = comment.toEventMessage(message); - - String userId = commandContext.getAuthenticatedUserId(); - - comment.setMessage(eventMessage); - comment.setFullMessage(message); - comment.setTime(ClockUtil.getCurrentTime()); - comment.setAction(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT); - comment.setUserId(userId); - - commandContext.getCommentManager().updateCommentMessage(comment); - } - - protected void checkUpdateTask(TaskEntity task, CommandContext commandContext) { - for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkUpdateTask(task); - } - } -} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java b/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java index aa79cc50aca..25bcd377096 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java @@ -411,6 +411,7 @@ public class DbSqlSessionFactory implements SessionFactory { addDatabaseSpecificStatement(postgresLikeDatabase, "selectCommentsByTaskId", "selectCommentsByTaskId_postgres"); addDatabaseSpecificStatement(postgresLikeDatabase, "selectCommentsByProcessInstanceId", "selectCommentsByProcessInstanceId_postgres"); addDatabaseSpecificStatement(postgresLikeDatabase, "selectCommentByTaskIdAndCommentId", "selectCommentByTaskIdAndCommentId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "selectCommentByProcessInstanceIdAndCommentId", "selectCommentByProcessInstanceIdAndCommentId_postgres"); addDatabaseSpecificStatement(postgresLikeDatabase, "selectEventsByTaskId", "selectEventsByTaskId_postgres"); addDatabaseSpecificStatement(postgresLikeDatabase, "selectFilterByQueryCriteria", "selectFilterByQueryCriteria_postgres"); addDatabaseSpecificStatement(postgresLikeDatabase, "selectFilter", "selectFilter_postgres"); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java index a75d3d5249c..30dd0bff6e0 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java @@ -23,6 +23,7 @@ import java.util.StringTokenizer; import org.camunda.bpm.engine.impl.db.DbEntity; +import org.camunda.bpm.engine.impl.db.HasDbRevision; import org.camunda.bpm.engine.impl.db.HistoricEntity; import org.camunda.bpm.engine.impl.util.StringUtil; import org.camunda.bpm.engine.task.Comment; @@ -32,7 +33,7 @@ /** * @author Tom Baeyens */ -public class CommentEntity implements Comment, Event, DbEntity, HistoricEntity, Serializable { +public class CommentEntity implements Comment, Event, HasDbRevision, DbEntity, HistoricEntity, Serializable { private static final long serialVersionUID = 1L; @@ -54,6 +55,7 @@ public class CommentEntity implements Comment, Event, DbEntity, HistoricEntity, protected String tenantId; protected String rootProcessInstanceId; protected Date removalTime; + protected int revision; public Object getPersistentState() { return CommentEntity.class; @@ -219,6 +221,7 @@ public String toString() { + ", taskId=" + taskId + ", processInstanceId=" + processInstanceId + ", rootProcessInstanceId=" + rootProcessInstanceId + + ", revision= "+ revision + ", removalTime=" + removalTime + ", action=" + action + ", message=" + message @@ -226,4 +229,19 @@ public String toString() { + ", tenantId=" + tenantId + "]"; } + + @Override + public void setRevision(int revision) { + this.revision = revision; + } + + @Override + public int getRevision() { + return revision; + } + + @Override + public int getRevisionNext() { + return revision + 1; + } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java index fc940a10fdb..5dfc0ca0f28 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java @@ -161,6 +161,8 @@ public void updateCommentMessage(CommentEntity entity) { parameters.put("action", entity.getAction()); parameters.put("id", entity.getId()); parameters.put("userId", entity.getUserId()); + parameters.put("revision", entity.getRevision()); + parameters.put("revisionNext", entity.getRevisionNext()); getDbEntityManager().update(CommentEntity.class, "updateComment", parameters); } diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql index 3724a8a2105..a85ce058a58 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql @@ -184,6 +184,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ bytea, TENANT_ID_ varchar(64), REMOVAL_TIME_ timestamp, + REV_ integer, primary key (ID_) ); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.db2.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.db2.create.history.sql index 630b111ec86..7d80451ee01 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.db2.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.db2.create.history.sql @@ -185,6 +185,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ BLOB, TENANT_ID_ varchar(64), REMOVAL_TIME_ timestamp, + REV_ integer, primary key (ID_) ); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.h2.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.h2.create.history.sql index eb908ea74e3..65b3e581a1c 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.h2.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.h2.create.history.sql @@ -184,6 +184,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ longvarbinary, TENANT_ID_ varchar(64), REMOVAL_TIME_ timestamp, + REV_ integer, primary key (ID_) ); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mariadb.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mariadb.create.history.sql index bdd20b2aa40..fed19d4b51b 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mariadb.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mariadb.create.history.sql @@ -184,6 +184,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ LONGBLOB, TENANT_ID_ varchar(64), REMOVAL_TIME_ datetime(3), + REV_ integer, primary key (ID_) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mssql.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mssql.create.history.sql index 16d040264f4..b5857eb06fc 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mssql.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mssql.create.history.sql @@ -183,6 +183,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ image, TENANT_ID_ nvarchar(64), REMOVAL_TIME_ datetime2, + REV_ integer, primary key (ID_) ); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mysql.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mysql.create.history.sql index bd11b0450c1..a460b3f9937 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mysql.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.mysql.create.history.sql @@ -184,6 +184,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ LONGBLOB, TENANT_ID_ varchar(64), REMOVAL_TIME_ datetime, + REV_ integer, primary key (ID_) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.oracle.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.oracle.create.history.sql index c9eec91daec..b6ebfd5c3af 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.oracle.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.oracle.create.history.sql @@ -184,6 +184,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ BLOB, TENANT_ID_ NVARCHAR2(64), REMOVAL_TIME_ TIMESTAMP(6), + REV_ integer, primary key (ID_) ); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.postgres.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.postgres.create.history.sql index 3724a8a2105..a85ce058a58 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.postgres.create.history.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.postgres.create.history.sql @@ -184,6 +184,7 @@ create table ACT_HI_COMMENT ( FULL_MSG_ bytea, TENANT_ID_ varchar(64), REMOVAL_TIME_ timestamp, + REV_ integer, primary key (ID_) ); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql index ab7cd1a4591..a7e516c1631 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql @@ -19,3 +19,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql index 972d54a543e..d0ad039ac0a 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql @@ -17,3 +17,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); + +alter table ACT_HI_COMMENT + add column REV_ integer; + +--Set revision number to already existing comments +-- if any for backward compatibility +update ACT_HI_COMMENT +set REV_ = 1 +where REV_ is null; \ No newline at end of file diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml index 19825d62a9a..3e7338b13d8 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml @@ -24,7 +24,7 @@ - insert into ${prefix}ACT_HI_COMMENT (ID_, TYPE_, TIME_, USER_ID_, TASK_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, ACTION_, MESSAGE_, FULL_MSG_, TENANT_ID_, REMOVAL_TIME_) + insert into ${prefix}ACT_HI_COMMENT (ID_, TYPE_, TIME_, USER_ID_, TASK_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_,ACTION_, MESSAGE_, FULL_MSG_, TENANT_ID_, REMOVAL_TIME_, REV_) values ( #{id ,jdbcType=VARCHAR}, #{type ,jdbcType=VARCHAR}, @@ -37,12 +37,13 @@ #{message ,jdbcType=VARCHAR}, #{fullMessageBytes ,jdbcType=BLOB}, #{tenantId ,jdbcType=VARCHAR}, - #{removalTime, jdbcType=TIMESTAMP} + #{removalTime, jdbcType=TIMESTAMP}, + 1 ) - insert into ${prefix}ACT_HI_COMMENT (ID_, TYPE_, TIME_, USER_ID_, TASK_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, ACTION_, MESSAGE_, FULL_MSG_, TENANT_ID_, REMOVAL_TIME_) + insert into ${prefix}ACT_HI_COMMENT (ID_, TYPE_, TIME_, USER_ID_, TASK_ID_, ROOT_PROC_INST_ID_, PROC_INST_ID_, ACTION_, MESSAGE_, FULL_MSG_, TENANT_ID_, REMOVAL_TIME_, REV_) values ( #{id ,jdbcType=VARCHAR}, #{type ,jdbcType=VARCHAR}, @@ -55,20 +56,22 @@ #{message ,jdbcType=VARCHAR}, #{fullMessageBytes ,jdbcType=BINARY}, #{tenantId ,jdbcType=VARCHAR}, - #{removalTime, jdbcType=TIMESTAMP} + #{removalTime, jdbcType=TIMESTAMP}, + 1 ) - + update ${prefix}ACT_HI_COMMENT set MESSAGE_ = #{message ,jdbcType=VARCHAR}, FULL_MSG_= #{fullMessageBytes ,jdbcType=BLOB}, TIME_ = #{time ,jdbcType=TIMESTAMP}, ACTION_ = #{action ,jdbcType=VARCHAR}, - USER_ID_ = #{userId ,jdbcType=VARCHAR} - where ID_ = #{id} + USER_ID_ = #{userId ,jdbcType=VARCHAR}, + REV_ = #{revisionNext, jdbcType=INTEGER} + where ID_ = #{id} and REV_ = #{revision, jdbcType=INTEGER} delete from ${prefix}ACT_HI_COMMENT - where ID_ = #{id} + where ID_ = #{id} and REV_ = #{revision} @@ -349,6 +352,7 @@ + @@ -364,6 +368,7 @@ + @@ -481,4 +486,11 @@ and ID_ = #{id,jdbcType=VARCHAR} + + diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java index 1bf6033e0e4..cc027ab79d3 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java @@ -17,7 +17,7 @@ package org.camunda.bpm.engine.test.api.authorization; import static org.camunda.bpm.engine.authorization.Permissions.UPDATE; -import static org.camunda.bpm.engine.authorization.Resources.PROCESS_INSTANCE; +import static org.camunda.bpm.engine.authorization.Resources.TASK; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; @@ -47,7 +47,7 @@ public void testDeleteProcessInstanceCommentWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a task."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -62,7 +62,7 @@ public void testDeleteProcessInstanceComment() { createTask(TASK_ID); String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); Comment createdComment = taskService.createComment(TASK_ID, processInstanceId, "aComment"); - createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); // when taskService.deleteProcessInstanceComment(processInstanceId, createdComment.getId()); @@ -89,7 +89,7 @@ public void testDeleteProcessInstanceCommentsWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a comment."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -106,7 +106,7 @@ public void testDeleteProcessInstanceComments() { taskService.createComment(TASK_ID, processInstanceId, "aCommentOne"); taskService.createComment(TASK_ID, processInstanceId, "aCommentTwo"); - createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); // when taskService.deleteProcessInstanceComments(processInstanceId); @@ -133,7 +133,7 @@ public void testUpdateProcessInstanceCommentWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a task."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -151,7 +151,7 @@ public void testUpdateProcessInstanceComment() { String commentMessage = "OriginalCommentMessage"; String updatedMessage = "UpdatedCommentMessage"; Comment comment = taskService.createComment(taskId, processInstanceId, commentMessage); - createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); // when taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), updatedMessage); diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java index 95e401ea401..33676e2c1bb 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java @@ -44,7 +44,7 @@ public void testDeleteTaskCommentWithoutAuthorization() { } catch (AuthorizationException e) { // then testRule.assertTextPresent( - "The user with id 'test' does not have 'UPDATE' permission on resource 'myTask' of type 'Task'", + "The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -83,7 +83,7 @@ public void testDeleteTaskCommentsWithoutAuthorization() { } catch (AuthorizationException e) { // then testRule.assertTextPresent( - "The user with id 'test' does not have 'UPDATE' permission on resource 'myTask' of type 'Task'", + "The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -124,7 +124,7 @@ public void testUpdateTaskCommentWithoutAuthorization() { } catch (AuthorizationException e) { // then testRule.assertTextPresent( - "The user with id 'test' does not have 'UPDATE' permission on resource 'myTask' of type 'Task'", + "The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java index c577269d7c5..fdfd0473886 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java @@ -280,29 +280,13 @@ public void testTaskOwner() { taskService.deleteTask(task.getId(), true); } - @Test - public void testDeleteTaskCommentNullCommentId() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); - try { - taskService.deleteTaskComment(taskId, null); - - fail("ProcessEngineException expected"); - } catch (ProcessEngineException ae) { - testRule.assertTextPresent("commentId is null", ae.getMessage()); - } finally { - taskService.deleteTask(task.getId(), true); - } - } - @Test public void testDeleteTaskCommentNullTaskIdAndCommentId() { try { taskService.deleteTaskComment(null, null); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { - testRule.assertTextPresent("commentId is null", ae.getMessage()); + testRule.assertTextPresent("Both task and comment ids are null", ae.getMessage()); } } @@ -346,7 +330,7 @@ public void testDeleteTaskCommentsNullTaskId() { taskService.deleteTaskComments(null); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { - testRule.assertTextPresent("taskId is null", ae.getMessage()); + testRule.assertTextPresent("Both task and comment ids are null", ae.getMessage()); } } @@ -420,7 +404,7 @@ public void testUpdateTaskCommentNullTaskId() { taskService.updateTaskComment(null, comment.getId(), "updatedMessage"); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { - testRule.assertTextPresent("taskId is null", ae.getMessage()); + testRule.assertTextPresent("Both process instance and task ids are null", ae.getMessage()); } finally { taskService.deleteTask(taskId, true); } @@ -480,28 +464,13 @@ public void testUpdateTaskComment() { taskService.deleteTask(taskId, true); } - @Test - public void testDeleteProcessInstanceCommentNullCommentId() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); - try { - taskService.deleteProcessInstanceComment(taskId, null); - fail("ProcessEngineException expected"); - } catch (ProcessEngineException ae) { - testRule.assertTextPresent("commentId is null", ae.getMessage()); - } finally { - taskService.deleteTask(taskId, true); - } - } - @Test public void testDeleteProcessInstanceCommentNullTaskIdAndCommentId() { try { taskService.deleteProcessInstanceComment(null, null); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { - testRule.assertTextPresent("commentId is null", ae.getMessage()); + testRule.assertTextPresent("Both process instance and comment ids are null", ae.getMessage()); } } @@ -544,7 +513,7 @@ public void testDeleteProcessInstanceCommentsNullTaskId() { taskService.deleteProcessInstanceComments(null); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { - testRule.assertTextPresent("processInstanceId is null", ae.getMessage()); + testRule.assertTextPresent("Both process instance and comment ids are null", ae.getMessage()); } } @@ -617,7 +586,7 @@ public void testUpdateProcessInstanceCommentNullProcessInstanceId() { taskService.updateProcessInstanceComment(null, comment.getId(), "updatedMessage"); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { - testRule.assertTextPresent("processInstanceId is null", ae.getMessage()); + testRule.assertTextPresent("Both process instance and task ids are null", ae.getMessage()); } finally { taskService.deleteTask(task.getId(), true); } From 92eb6b03b1521bf2d71865ecdcbd888b01ef5d5a Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Thu, 27 Jun 2024 11:32:30 -0600 Subject: [PATCH 06/10] feat(engine) update task_assign authorization to task_work for delete/update comments --- .../org/camunda/bpm/engine/TaskService.java | 24 +++++++++---------- .../cmd/DeleteProcessInstanceCommentCmd.java | 8 +++---- .../engine/impl/cmd/DeleteTaskCommentCmd.java | 8 +++---- .../bpm/engine/impl/cmd/UpdateCommentCmd.java | 6 ++--- ...ocessInstanceCommentAuthorizationTest.java | 6 ++--- .../TaskCommentAuthorizationTest.java | 6 ++--- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java index 93f46d61926..08159f18128 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java +++ b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java @@ -1115,8 +1115,8 @@ public interface TaskService { * @throws NotFoundException if no task with the given id exists * @throws BadUserRequestException if task id or error code were null or empty * @throws ProcessEngineException when task and comment don't exist with the given taskId and commentId - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} * (if the task is part of a running process instance). */ void deleteTaskComment(String taskId, String commentId); @@ -1128,8 +1128,8 @@ public interface TaskService { * @param commentId id of a comment that is intended to be deleted * @throws NotFoundException if no task with the given process instance id exists * @throws ProcessEngineException when given process instance id and comment id are passed as null - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} * (if the task is part of a running process instance). */ void deleteProcessInstanceComment(String processInstanceId, String commentId); @@ -1139,8 +1139,8 @@ public interface TaskService { * * @param taskId id of a task of all comments that are intended to be deleted * @throws NotFoundException when the task doesn't exist with a given task id - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} * (if the task is part of a running process instance). */ void deleteTaskComments(String taskId); @@ -1150,8 +1150,8 @@ public interface TaskService { * * @param processInstanceId id of a process instance of comments that are intended to be deleted * @throws NotFoundException when the process instance doesn't exist with a given process instance id - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} * (if the task is part of a running process instance). */ void deleteProcessInstanceComments(String processInstanceId); @@ -1165,8 +1165,8 @@ public interface TaskService { * @throws NotFoundException if no task with the given taskId id exists * @throws NotFoundException if no comment found to be updated for a given comment id * @throws ProcessEngineException when given task id and comment id are passed as null - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} * (if the task is part of a running process instance). */ void updateTaskComment(String taskId, String commentId, String message); @@ -1180,8 +1180,8 @@ public interface TaskService { * @throws NotFoundException if no process instance with the given processInstanceId id exists * @throws NotFoundException if no comment found to be updated for a given comment id * @throws ProcessEngineException when given process instance id and comment id are passed as null - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_ASSIGN} permissions on {@link Resources#PROCESS_DEFINITION} + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} * (if the task is part of a running process instance). */ void updateProcessInstanceComment(String processInstanceId, String commentId, String message); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java index fd720f03663..b112e081697 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java @@ -66,7 +66,7 @@ public Object execute(CommandContext commandContext) { TaskEntity task = getTask(comment, commandContext); - checkTaskAssign(task, commandContext); + checkTaskWork(task, commandContext); commandContext.getDbEntityManager().delete(comment); logOperation(comment, task, null, commandContext); task.triggerUpdateEvent(); @@ -79,7 +79,7 @@ public Object execute(CommandContext commandContext) { List comments = commandContext.getCommentManager().findCommentsByProcessInstanceId(processInstanceId); if (!comments.isEmpty()) { TaskEntity task = commandContext.getTaskManager().findTaskById(comments.get(0).getTaskId()); - checkTaskAssign(task, commandContext); + checkTaskWork(task, commandContext); commandContext.getCommentManager() .deleteCommentsByProcessInstanceIds(Collections.singletonList(processInstanceId)); logOperation(null, null, processInstance, commandContext); @@ -110,9 +110,9 @@ private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) return task; } - protected void checkTaskAssign(TaskEntity task, CommandContext commandContext) { + protected void checkTaskWork(TaskEntity task, CommandContext commandContext) { for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkTaskAssign(task); + checker.checkTaskWork(task); } } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java index 93bd88d6e3f..fe08f702191 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java @@ -63,7 +63,7 @@ public Object execute(CommandContext commandContext) { comment = commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); if (comment != null) { task = getTask(comment, commandContext); - checkTaskAssign(task, commandContext); + checkTaskWork(task, commandContext); commandContext.getDbEntityManager().delete(comment); } } else { @@ -71,7 +71,7 @@ public Object execute(CommandContext commandContext) { ensureNotNull("No task exists with taskId: " + taskId, "task", task); List comments = commandContext.getCommentManager().findCommentsByTaskId(taskId); if (!comments.isEmpty()) { - checkTaskAssign(task, commandContext); + checkTaskWork(task, commandContext); commandContext.getCommentManager().deleteCommentsByTaskId(taskId); } } @@ -97,9 +97,9 @@ private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) return task; } - protected void checkTaskAssign(TaskEntity task, CommandContext commandContext) { + protected void checkTaskWork(TaskEntity task, CommandContext commandContext) { for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkTaskAssign(task); + checker.checkTaskWork(task); } } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java index 26e68c8966b..ec335df214b 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java @@ -81,7 +81,7 @@ private TaskEntity updateComment(String taskId, CommandContext commandContext, C TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); ensureNotNull("No task exists with taskId: " + taskId, "task", task); - checkTaskAssign(task, commandContext); + checkTaskWork(task, commandContext); updateComment(commandContext, comment); return task; } @@ -97,9 +97,9 @@ private PropertyChange getPropertyChange(CommentEntity comment) { return new PropertyChange("comment", comment.getMessage(), message); } - protected void checkTaskAssign(TaskEntity task, CommandContext commandContext) { + protected void checkTaskWork(TaskEntity task, CommandContext commandContext) { for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { - checker.checkTaskAssign(task); + checker.checkTaskWork(task); } } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java index cc027ab79d3..616156de0f7 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java @@ -47,7 +47,7 @@ public void testDeleteProcessInstanceCommentWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a task."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -89,7 +89,7 @@ public void testDeleteProcessInstanceCommentsWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a comment."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -133,7 +133,7 @@ public void testUpdateProcessInstanceCommentWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a task."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java index 33676e2c1bb..4397296035c 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java @@ -44,7 +44,7 @@ public void testDeleteTaskCommentWithoutAuthorization() { } catch (AuthorizationException e) { // then testRule.assertTextPresent( - "The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + "The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -83,7 +83,7 @@ public void testDeleteTaskCommentsWithoutAuthorization() { } catch (AuthorizationException e) { // then testRule.assertTextPresent( - "The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + "The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } @@ -124,7 +124,7 @@ public void testUpdateTaskCommentWithoutAuthorization() { } catch (AuthorizationException e) { // then testRule.assertTextPresent( - "The user with id 'test' does not have one of the following permissions: 'TASK_ASSIGN' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + "The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", e.getMessage()); } From 89004edbfb7d655c5896a02fc840f35eb8dc3532 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Sun, 4 Aug 2024 20:13:34 -0600 Subject: [PATCH 07/10] delete cockroachdb files --- .../activiti.cockroachdb.create.history.sql | 447 ------------------ .../cockroachdb_engine_7.21_to_7.22.sql | 36 -- 2 files changed, 483 deletions(-) delete mode 100644 engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql delete mode 100644 engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql deleted file mode 100644 index 5d8f90e2c08..00000000000 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.cockroachdb.create.history.sql +++ /dev/null @@ -1,447 +0,0 @@ --- --- Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH --- under one or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information regarding copyright --- ownership. Camunda licenses this file to you under the Apache License, --- Version 2.0; you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- - -create table ACT_HI_PROCINST ( - ID_ varchar(64) not null, - PROC_INST_ID_ varchar(64) not null, - BUSINESS_KEY_ varchar(255), - PROC_DEF_KEY_ varchar(255), - PROC_DEF_ID_ varchar(64) not null, - START_TIME_ timestamp not null, - END_TIME_ timestamp, - REMOVAL_TIME_ timestamp, - DURATION_ bigint, - START_USER_ID_ varchar(255), - START_ACT_ID_ varchar(255), - END_ACT_ID_ varchar(255), - SUPER_PROCESS_INSTANCE_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - SUPER_CASE_INSTANCE_ID_ varchar(64), - CASE_INST_ID_ varchar(64), - DELETE_REASON_ varchar(4000), - TENANT_ID_ varchar(64), - STATE_ varchar(255), - primary key (ID_), - unique (PROC_INST_ID_) -); - -create table ACT_HI_ACTINST ( - ID_ varchar(64) not null, - PARENT_ACT_INST_ID_ varchar(64), - PROC_DEF_KEY_ varchar(255), - PROC_DEF_ID_ varchar(64) not null, - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64) not null, - EXECUTION_ID_ varchar(64) not null, - ACT_ID_ varchar(255) not null, - TASK_ID_ varchar(64), - CALL_PROC_INST_ID_ varchar(64), - CALL_CASE_INST_ID_ varchar(64), - ACT_NAME_ varchar(255), - ACT_TYPE_ varchar(255) not null, - ASSIGNEE_ varchar(255), - START_TIME_ timestamp not null, - END_TIME_ timestamp, - DURATION_ bigint, - ACT_INST_STATE_ integer, - SEQUENCE_COUNTER_ bigint, - TENANT_ID_ varchar(64), - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_TASKINST ( - ID_ varchar(64) not null, - TASK_DEF_KEY_ varchar(255), - PROC_DEF_KEY_ varchar(255), - PROC_DEF_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - EXECUTION_ID_ varchar(64), - CASE_DEF_KEY_ varchar(255), - CASE_DEF_ID_ varchar(64), - CASE_INST_ID_ varchar(64), - CASE_EXECUTION_ID_ varchar(64), - ACT_INST_ID_ varchar(64), - NAME_ varchar(255), - PARENT_TASK_ID_ varchar(64), - DESCRIPTION_ varchar(4000), - OWNER_ varchar(255), - ASSIGNEE_ varchar(255), - START_TIME_ timestamp not null, - END_TIME_ timestamp, - DURATION_ bigint, - DELETE_REASON_ varchar(4000), - PRIORITY_ integer, - DUE_DATE_ timestamp, - FOLLOW_UP_DATE_ timestamp, - TENANT_ID_ varchar(64), - REMOVAL_TIME_ timestamp, - TASK_STATE_ varchar(64), - primary key (ID_) -); - -create table ACT_HI_VARINST ( - ID_ varchar(64) not null, - PROC_DEF_KEY_ varchar(255), - PROC_DEF_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - EXECUTION_ID_ varchar(64), - ACT_INST_ID_ varchar(64), - CASE_DEF_KEY_ varchar(255), - CASE_DEF_ID_ varchar(64), - CASE_INST_ID_ varchar(64), - CASE_EXECUTION_ID_ varchar(64), - TASK_ID_ varchar(64), - NAME_ varchar(255) not null, - VAR_TYPE_ varchar(100), - CREATE_TIME_ timestamp, - REV_ integer, - BYTEARRAY_ID_ varchar(64), - DOUBLE_ double precision, - LONG_ bigint, - TEXT_ varchar(4000), - TEXT2_ varchar(4000), - TENANT_ID_ varchar(64), - STATE_ varchar(20), - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_DETAIL ( - ID_ varchar(64) not null, - TYPE_ varchar(255) not null, - PROC_DEF_KEY_ varchar(255), - PROC_DEF_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - EXECUTION_ID_ varchar(64), - CASE_DEF_KEY_ varchar(255), - CASE_DEF_ID_ varchar(64), - CASE_INST_ID_ varchar(64), - CASE_EXECUTION_ID_ varchar(64), - TASK_ID_ varchar(64), - ACT_INST_ID_ varchar(64), - VAR_INST_ID_ varchar(64), - NAME_ varchar(255) not null, - VAR_TYPE_ varchar(64), - REV_ integer, - TIME_ timestamp not null, - BYTEARRAY_ID_ varchar(64), - DOUBLE_ double precision, - LONG_ bigint, - TEXT_ varchar(4000), - TEXT2_ varchar(4000), - SEQUENCE_COUNTER_ bigint, - TENANT_ID_ varchar(64), - OPERATION_ID_ varchar(64), - REMOVAL_TIME_ timestamp, - INITIAL_ boolean, - primary key (ID_) -); - -create table ACT_HI_IDENTITYLINK ( - ID_ varchar(64) not null, - TIMESTAMP_ timestamp not null, - TYPE_ varchar(255), - USER_ID_ varchar(255), - GROUP_ID_ varchar(255), - TASK_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_DEF_ID_ varchar(64), - OPERATION_TYPE_ varchar(64), - ASSIGNER_ID_ varchar(64), - PROC_DEF_KEY_ varchar(255), - TENANT_ID_ varchar(64), - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_COMMENT ( - ID_ varchar(64) not null, - TYPE_ varchar(255), - TIME_ timestamp not null, - USER_ID_ varchar(255), - TASK_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - ACTION_ varchar(255), - MESSAGE_ varchar(4000), - FULL_MSG_ bytea, - TENANT_ID_ varchar(64), - REMOVAL_TIME_ timestamp, - REV_ integer, - primary key (ID_) -); - -create table ACT_HI_ATTACHMENT ( - ID_ varchar(64) not null, - REV_ integer, - USER_ID_ varchar(255), - NAME_ varchar(255), - DESCRIPTION_ varchar(4000), - TYPE_ varchar(255), - TASK_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - URL_ varchar(4000), - CONTENT_ID_ varchar(64), - TENANT_ID_ varchar(64), - CREATE_TIME_ timestamp, - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_OP_LOG ( - ID_ varchar(64) not null, - DEPLOYMENT_ID_ varchar(64), - PROC_DEF_ID_ varchar(64), - PROC_DEF_KEY_ varchar(255), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - EXECUTION_ID_ varchar(64), - CASE_DEF_ID_ varchar(64), - CASE_INST_ID_ varchar(64), - CASE_EXECUTION_ID_ varchar(64), - TASK_ID_ varchar(64), - JOB_ID_ varchar(64), - JOB_DEF_ID_ varchar(64), - BATCH_ID_ varchar(64), - USER_ID_ varchar(255), - TIMESTAMP_ timestamp not null, - OPERATION_TYPE_ varchar(64), - OPERATION_ID_ varchar(64), - ENTITY_TYPE_ varchar(30), - PROPERTY_ varchar(64), - ORG_VALUE_ varchar(4000), - NEW_VALUE_ varchar(4000), - TENANT_ID_ varchar(64), - REMOVAL_TIME_ timestamp, - CATEGORY_ varchar(64), - EXTERNAL_TASK_ID_ varchar(64), - ANNOTATION_ varchar(4000), - primary key (ID_) -); - -create table ACT_HI_INCIDENT ( - ID_ varchar(64) not null, - PROC_DEF_KEY_ varchar(255), - PROC_DEF_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - EXECUTION_ID_ varchar(64), - CREATE_TIME_ timestamp not null, - END_TIME_ timestamp, - INCIDENT_MSG_ varchar(4000), - INCIDENT_TYPE_ varchar(255) not null, - ACTIVITY_ID_ varchar(255), - FAILED_ACTIVITY_ID_ varchar(255), - CAUSE_INCIDENT_ID_ varchar(64), - ROOT_CAUSE_INCIDENT_ID_ varchar(64), - CONFIGURATION_ varchar(255), - HISTORY_CONFIGURATION_ varchar(255), - INCIDENT_STATE_ integer, - TENANT_ID_ varchar(64), - JOB_DEF_ID_ varchar(64), - ANNOTATION_ varchar(4000), - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_JOB_LOG ( - ID_ varchar(64) not null, - TIMESTAMP_ timestamp not null, - JOB_ID_ varchar(64) not null, - JOB_DUEDATE_ timestamp, - JOB_RETRIES_ integer, - JOB_PRIORITY_ bigint NOT NULL DEFAULT 0, - JOB_EXCEPTION_MSG_ varchar(4000), - JOB_EXCEPTION_STACK_ID_ varchar(64), - JOB_STATE_ integer, - JOB_DEF_ID_ varchar(64), - JOB_DEF_TYPE_ varchar(255), - JOB_DEF_CONFIGURATION_ varchar(255), - ACT_ID_ varchar(255), - FAILED_ACT_ID_ varchar(255), - EXECUTION_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROCESS_INSTANCE_ID_ varchar(64), - PROCESS_DEF_ID_ varchar(64), - PROCESS_DEF_KEY_ varchar(255), - DEPLOYMENT_ID_ varchar(64), - SEQUENCE_COUNTER_ bigint, - TENANT_ID_ varchar(64), - HOSTNAME_ varchar(255), - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_BATCH ( - ID_ varchar(64) not null, - TYPE_ varchar(255), - TOTAL_JOBS_ integer, - JOBS_PER_SEED_ integer, - INVOCATIONS_PER_JOB_ integer, - SEED_JOB_DEF_ID_ varchar(64), - MONITOR_JOB_DEF_ID_ varchar(64), - BATCH_JOB_DEF_ID_ varchar(64), - TENANT_ID_ varchar(64), - CREATE_USER_ID_ varchar(255), - START_TIME_ timestamp not null, - END_TIME_ timestamp, - REMOVAL_TIME_ timestamp, - EXEC_START_TIME_ timestamp, - primary key (ID_) -); - -create table ACT_HI_EXT_TASK_LOG ( - ID_ varchar(64) not null, - TIMESTAMP_ timestamp not null, - EXT_TASK_ID_ varchar(64) not null, - RETRIES_ integer, - TOPIC_NAME_ varchar(255), - WORKER_ID_ varchar(255), - PRIORITY_ bigint not null default 0, - ERROR_MSG_ varchar(4000), - ERROR_DETAILS_ID_ varchar(64), - ACT_ID_ varchar(255), - ACT_INST_ID_ varchar(64), - EXECUTION_ID_ varchar(64), - PROC_INST_ID_ varchar(64), - ROOT_PROC_INST_ID_ varchar(64), - PROC_DEF_ID_ varchar(64), - PROC_DEF_KEY_ varchar(255), - TENANT_ID_ varchar(64), - STATE_ integer, - REMOVAL_TIME_ timestamp, - primary key (ID_) -); - -create index ACT_IDX_HI_PRO_INST_END on ACT_HI_PROCINST(END_TIME_); -create index ACT_IDX_HI_PRO_I_BUSKEY on ACT_HI_PROCINST(BUSINESS_KEY_); -create index ACT_IDX_HI_PRO_INST_TENANT_ID on ACT_HI_PROCINST(TENANT_ID_); -create index ACT_IDX_HI_PRO_INST_PROC_DEF_KEY on ACT_HI_PROCINST(PROC_DEF_KEY_); -create index ACT_IDX_HI_PRO_INST_PROC_TIME on ACT_HI_PROCINST(START_TIME_, END_TIME_); -create index ACT_IDX_HI_PI_PDEFID_END_TIME on ACT_HI_PROCINST(PROC_DEF_ID_, END_TIME_); -create index ACT_IDX_HI_PRO_INST_ROOT_PI on ACT_HI_PROCINST(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_PRO_INST_RM_TIME on ACT_HI_PROCINST(REMOVAL_TIME_); - -create index ACT_IDX_HI_ACTINST_ROOT_PI on ACT_HI_ACTINST(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_ACT_INST_START_END on ACT_HI_ACTINST(START_TIME_, END_TIME_); -create index ACT_IDX_HI_ACT_INST_END on ACT_HI_ACTINST(END_TIME_); -create index ACT_IDX_HI_ACT_INST_PROCINST on ACT_HI_ACTINST(PROC_INST_ID_, ACT_ID_); -create index ACT_IDX_HI_ACT_INST_COMP on ACT_HI_ACTINST(EXECUTION_ID_, ACT_ID_, END_TIME_, ID_); -create index ACT_IDX_HI_ACT_INST_STATS on ACT_HI_ACTINST(PROC_DEF_ID_, PROC_INST_ID_, ACT_ID_, END_TIME_, ACT_INST_STATE_); -create index ACT_IDX_HI_ACT_INST_TENANT_ID on ACT_HI_ACTINST(TENANT_ID_); -create index ACT_IDX_HI_ACT_INST_PROC_DEF_KEY on ACT_HI_ACTINST(PROC_DEF_KEY_); -create index ACT_IDX_HI_AI_PDEFID_END_TIME on ACT_HI_ACTINST(PROC_DEF_ID_, END_TIME_); -create index ACT_IDX_HI_ACT_INST_RM_TIME on ACT_HI_ACTINST(REMOVAL_TIME_); - -create index ACT_IDX_HI_TASKINST_ROOT_PI on ACT_HI_TASKINST(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_TASK_INST_TENANT_ID on ACT_HI_TASKINST(TENANT_ID_); -create index ACT_IDX_HI_TASK_INST_PROC_DEF_KEY on ACT_HI_TASKINST(PROC_DEF_KEY_); -create index ACT_IDX_HI_TASKINST_PROCINST on ACT_HI_TASKINST(PROC_INST_ID_); -create index ACT_IDX_HI_TASKINSTID_PROCINST on ACT_HI_TASKINST(ID_,PROC_INST_ID_); -create index ACT_IDX_HI_TASK_INST_RM_TIME on ACT_HI_TASKINST(REMOVAL_TIME_); -create index ACT_IDX_HI_TASK_INST_START on ACT_HI_TASKINST(START_TIME_); -create index ACT_IDX_HI_TASK_INST_END on ACT_HI_TASKINST(END_TIME_); - -create index ACT_IDX_HI_DETAIL_ROOT_PI on ACT_HI_DETAIL(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_DETAIL_PROC_INST on ACT_HI_DETAIL(PROC_INST_ID_); -create index ACT_IDX_HI_DETAIL_ACT_INST on ACT_HI_DETAIL(ACT_INST_ID_); -create index ACT_IDX_HI_DETAIL_CASE_INST on ACT_HI_DETAIL(CASE_INST_ID_); -create index ACT_IDX_HI_DETAIL_CASE_EXEC on ACT_HI_DETAIL(CASE_EXECUTION_ID_); -create index ACT_IDX_HI_DETAIL_TIME on ACT_HI_DETAIL(TIME_); -create index ACT_IDX_HI_DETAIL_NAME on ACT_HI_DETAIL(NAME_); -create index ACT_IDX_HI_DETAIL_TASK_ID on ACT_HI_DETAIL(TASK_ID_); -create index ACT_IDX_HI_DETAIL_TENANT_ID on ACT_HI_DETAIL(TENANT_ID_); -create index ACT_IDX_HI_DETAIL_PROC_DEF_KEY on ACT_HI_DETAIL(PROC_DEF_KEY_); -create index ACT_IDX_HI_DETAIL_BYTEAR on ACT_HI_DETAIL(BYTEARRAY_ID_); -create index ACT_IDX_HI_DETAIL_RM_TIME on ACT_HI_DETAIL(REMOVAL_TIME_); -create index ACT_IDX_HI_DETAIL_TASK_BYTEAR on ACT_HI_DETAIL(BYTEARRAY_ID_, TASK_ID_); -create index ACT_IDX_HI_DETAIL_VAR_INST_ID on ACT_HI_DETAIL(VAR_INST_ID_); - -create index ACT_IDX_HI_IDENT_LNK_ROOT_PI on ACT_HI_IDENTITYLINK(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_IDENT_LNK_USER on ACT_HI_IDENTITYLINK(USER_ID_); -create index ACT_IDX_HI_IDENT_LNK_GROUP on ACT_HI_IDENTITYLINK(GROUP_ID_); -create index ACT_IDX_HI_IDENT_LNK_TENANT_ID on ACT_HI_IDENTITYLINK(TENANT_ID_); -create index ACT_IDX_HI_IDENT_LNK_PROC_DEF_KEY on ACT_HI_IDENTITYLINK(PROC_DEF_KEY_); -create index ACT_IDX_HI_IDENT_LINK_TASK on ACT_HI_IDENTITYLINK(TASK_ID_); -create index ACT_IDX_HI_IDENT_LINK_RM_TIME on ACT_HI_IDENTITYLINK(REMOVAL_TIME_); -create index ACT_IDX_HI_IDENT_LNK_TIMESTAMP on ACT_HI_IDENTITYLINK(TIMESTAMP_); - -create index ACT_IDX_HI_VARINST_ROOT_PI on ACT_HI_VARINST(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_PROCVAR_PROC_INST on ACT_HI_VARINST(PROC_INST_ID_); -create index ACT_IDX_HI_PROCVAR_NAME_TYPE on ACT_HI_VARINST(NAME_, VAR_TYPE_); -create index ACT_IDX_HI_CASEVAR_CASE_INST on ACT_HI_VARINST(CASE_INST_ID_); -create index ACT_IDX_HI_VAR_INST_TENANT_ID on ACT_HI_VARINST(TENANT_ID_); -create index ACT_IDX_HI_VAR_INST_PROC_DEF_KEY on ACT_HI_VARINST(PROC_DEF_KEY_); -create index ACT_IDX_HI_VARINST_BYTEAR on ACT_HI_VARINST(BYTEARRAY_ID_); -create index ACT_IDX_HI_VARINST_RM_TIME on ACT_HI_VARINST(REMOVAL_TIME_); -create index ACT_IDX_HI_VAR_PI_NAME_TYPE on ACT_HI_VARINST(PROC_INST_ID_, NAME_, VAR_TYPE_); -create index ACT_IDX_HI_VARINST_NAME on ACT_HI_VARINST(NAME_); -create index ACT_IDX_HI_VARINST_ACT_INST_ID on ACT_HI_VARINST(ACT_INST_ID_); - -create index ACT_IDX_HI_INCIDENT_TENANT_ID on ACT_HI_INCIDENT(TENANT_ID_); -create index ACT_IDX_HI_INCIDENT_PROC_DEF_KEY on ACT_HI_INCIDENT(PROC_DEF_KEY_); -create index ACT_IDX_HI_INCIDENT_ROOT_PI on ACT_HI_INCIDENT(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_INCIDENT_PROCINST on ACT_HI_INCIDENT(PROC_INST_ID_); -create index ACT_IDX_HI_INCIDENT_RM_TIME on ACT_HI_INCIDENT(REMOVAL_TIME_); -create index ACT_IDX_HI_INCIDENT_CREATE_TIME on ACT_HI_INCIDENT(CREATE_TIME_); -create index ACT_IDX_HI_INCIDENT_END_TIME on ACT_HI_INCIDENT(END_TIME_); - -create index ACT_IDX_HI_JOB_LOG_ROOT_PI on ACT_HI_JOB_LOG(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_JOB_LOG_PROCINST on ACT_HI_JOB_LOG(PROCESS_INSTANCE_ID_); -create index ACT_IDX_HI_JOB_LOG_PROCDEF on ACT_HI_JOB_LOG(PROCESS_DEF_ID_); -create index ACT_IDX_HI_JOB_LOG_TENANT_ID on ACT_HI_JOB_LOG(TENANT_ID_); -create index ACT_IDX_HI_JOB_LOG_JOB_DEF_ID on ACT_HI_JOB_LOG(JOB_DEF_ID_); -create index ACT_IDX_HI_JOB_LOG_PROC_DEF_KEY on ACT_HI_JOB_LOG(PROCESS_DEF_KEY_); -create index ACT_IDX_HI_JOB_LOG_EX_STACK on ACT_HI_JOB_LOG(JOB_EXCEPTION_STACK_ID_); -create index ACT_IDX_HI_JOB_LOG_RM_TIME on ACT_HI_JOB_LOG(REMOVAL_TIME_); -create index ACT_IDX_HI_JOB_LOG_JOB_CONF on ACT_HI_JOB_LOG(JOB_DEF_CONFIGURATION_); - -create index ACT_HI_BAT_RM_TIME on ACT_HI_BATCH(REMOVAL_TIME_); - -create index ACT_HI_EXT_TASK_LOG_ROOT_PI on ACT_HI_EXT_TASK_LOG(ROOT_PROC_INST_ID_); -create index ACT_HI_EXT_TASK_LOG_PROCINST on ACT_HI_EXT_TASK_LOG(PROC_INST_ID_); -create index ACT_HI_EXT_TASK_LOG_PROCDEF on ACT_HI_EXT_TASK_LOG(PROC_DEF_ID_); -create index ACT_HI_EXT_TASK_LOG_PROC_DEF_KEY on ACT_HI_EXT_TASK_LOG(PROC_DEF_KEY_); -create index ACT_HI_EXT_TASK_LOG_TENANT_ID on ACT_HI_EXT_TASK_LOG(TENANT_ID_); -create index ACT_IDX_HI_EXTTASKLOG_ERRORDET on ACT_HI_EXT_TASK_LOG(ERROR_DETAILS_ID_); -create index ACT_HI_EXT_TASK_LOG_RM_TIME on ACT_HI_EXT_TASK_LOG(REMOVAL_TIME_); - -create index ACT_IDX_HI_OP_LOG_ROOT_PI on ACT_HI_OP_LOG(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_OP_LOG_PROCINST on ACT_HI_OP_LOG(PROC_INST_ID_); -create index ACT_IDX_HI_OP_LOG_PROCDEF on ACT_HI_OP_LOG(PROC_DEF_ID_); -create index ACT_IDX_HI_OP_LOG_TASK on ACT_HI_OP_LOG(TASK_ID_); -create index ACT_IDX_HI_OP_LOG_RM_TIME on ACT_HI_OP_LOG(REMOVAL_TIME_); -create index ACT_IDX_HI_OP_LOG_TIMESTAMP on ACT_HI_OP_LOG(TIMESTAMP_); -create index ACT_IDX_HI_OP_LOG_USER_ID on ACT_HI_OP_LOG(USER_ID_); -create index ACT_IDX_HI_OP_LOG_OP_TYPE on ACT_HI_OP_LOG(OPERATION_TYPE_); -create index ACT_IDX_HI_OP_LOG_ENTITY_TYPE on ACT_HI_OP_LOG(ENTITY_TYPE_); - -create index ACT_IDX_HI_ATTACHMENT_CONTENT on ACT_HI_ATTACHMENT(CONTENT_ID_); -create index ACT_IDX_HI_ATTACHMENT_ROOT_PI on ACT_HI_ATTACHMENT(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_ATTACHMENT_PROCINST on ACT_HI_ATTACHMENT(PROC_INST_ID_); -create index ACT_IDX_HI_ATTACHMENT_TASK on ACT_HI_ATTACHMENT(TASK_ID_); -create index ACT_IDX_HI_ATTACHMENT_RM_TIME on ACT_HI_ATTACHMENT(REMOVAL_TIME_); - -create index ACT_IDX_HI_COMMENT_TASK on ACT_HI_COMMENT(TASK_ID_); -create index ACT_IDX_HI_COMMENT_ROOT_PI on ACT_HI_COMMENT(ROOT_PROC_INST_ID_); -create index ACT_IDX_HI_COMMENT_PROCINST on ACT_HI_COMMENT(PROC_INST_ID_); -create index ACT_IDX_HI_COMMENT_RM_TIME on ACT_HI_COMMENT(REMOVAL_TIME_); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql deleted file mode 100644 index 3cfd1c1b2a6..00000000000 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/cockroachdb_engine_7.21_to_7.22.sql +++ /dev/null @@ -1,36 +0,0 @@ --- --- Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH --- under one or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information regarding copyright --- ownership. Camunda licenses this file to you under the Apache License, --- Version 2.0; you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- - --- table writes should ideally come after schema changes, see https://github.com/cockroachdb/cockroach/pull/58182 - -insert into ACT_GE_SCHEMA_LOG -values ('1100', CURRENT_TIMESTAMP, '7.22.0'); - -alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); - -alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); - -alter table ACT_HI_COMMENT - add column REV_ integer; - ---Set revision number to already existing comments --- if any for backward compatibility -update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; - - From ac5f84b0ab9fab45f0aa7beae8aef573d3e2c7a2 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Wed, 11 Sep 2024 00:25:03 -0600 Subject: [PATCH 08/10] Feedback Adjustments - fix verbiage in ftl files - add standalone tests for delete comment(s) by process instance id and task id - fix/rewrite sql statement - write additional process instance tests - few minor changes --- .../process-instance/{id}/comment/delete.ftl | 9 +- .../process-instance/{id}/comment/get.ftl | 2 +- .../process-instance/{id}/comment/put.ftl | 6 +- .../{id}/comment/{commentId}/delete.ftl | 9 +- .../paths/task/{id}/comment/delete.ftl | 7 + .../templates/paths/task/{id}/comment/put.ftl | 7 + .../task/{id}/comment/{commentId}/delete.ftl | 7 + .../ProcessInstanceCommentResourceImpl.java | 23 +-- .../task/impl/TaskCommentResourceImpl.java | 22 +-- ...essInstanceRestServiceInteractionTest.java | 4 + .../rest/TaskRestServiceInteractionTest.java | 2 + .../org/camunda/bpm/engine/TaskService.java | 13 +- .../cmd/DeleteProcessInstanceCommentCmd.java | 55 ++---- .../engine/impl/cmd/DeleteTaskCommentCmd.java | 12 +- .../bpm/engine/impl/cmd/UpdateCommentCmd.java | 45 +++-- .../persistence/entity/CommentEntity.java | 6 +- .../persistence/entity/CommentManager.java | 16 -- .../db/upgrade/db2_engine_7.21_to_7.22.sql | 3 +- .../db/upgrade/h2_engine_7.21_to_7.22.sql | 3 +- .../upgrade/mariadb_engine_7.21_to_7.22.sql | 5 +- .../db/upgrade/mssql_engine_7.21_to_7.22.sql | 7 +- .../db/upgrade/mysql_engine_7.21_to_7.22.sql | 3 +- .../db/upgrade/oracle_engine_7.21_to_7.22.sql | 3 +- .../upgrade/postgres_engine_7.21_to_7.22.sql | 3 +- ...ocessInstanceCommentAuthorizationTest.java | 135 ++++++++++++-- .../TaskCommentAuthorizationTest.java | 125 +++++++++++++ .../engine/test/api/task/TaskServiceTest.java | 174 +++++++++++++----- 27 files changed, 518 insertions(+), 188 deletions(-) diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl index 1e69efbe1fe..5b3bea61268 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/delete.ftl @@ -4,7 +4,7 @@ id = "deleteProcessInstanceComments" tag = "Process Instance Comment" summary = "Delete ProcessInstance Comments" - desc = "Deletes all comments of a processIntance by processInstance id." /> + desc = "Deletes all comments of a process instance by id." /> "parameters": [ @@ -23,6 +23,13 @@ code = "204" desc = "Request successful." /> + <@lib.response + code = "400" + dto = "ExceptionDto" + last = true + desc = "Returned if a given process instance id is invalid. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) for the error response format."/> + <@lib.response code = "401" dto = "ExceptionDto" diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/get.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/get.ftl index 58f20a2616b..44dc2e3e357 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/get.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/get.ftl @@ -3,7 +3,7 @@ <@lib.endpointInfo id = "getProcessInstanceComments" - tag = "Process Instance" + tag = "Process Instance comment" summary = "Get Process Instance Comments" desc = "Gets the comments for a process instance by id." /> diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl index 241dd541207..775f0cbf071 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/put.ftl @@ -41,10 +41,8 @@ <@lib.response code = "400" dto = "ExceptionDto" - desc = "Returned if some of the query parameters are invalid, for example if - the value of `commentId` parameter is supplied as null. See the - [Introduction](${docsUrl}/reference/rest/overview/#error-handling) - for the error response format." /> + desc = "Returned if a given process instance id or comment id is invalid. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) for the error response format."/> <@lib.response code = "401" diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl index 24dffb571bd..44e9ba937c8 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/process-instance/{id}/comment/{commentId}/delete.ftl @@ -14,7 +14,7 @@ location = "path" type = "string" required = true - desc = "The id of the processInstance." /> + desc = "The id of the process instance." /> <@lib.parameter name = "commentId" @@ -32,6 +32,13 @@ code = "204" desc = "Request successful." /> + <@lib.response + code = "400" + dto = "ExceptionDto" + last = true + desc = "Returned if a given process instance id or comment id is invalid. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) for the error response format."/> + <@lib.response code = "401" dto = "ExceptionDto" diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl index 959596b0d7d..f7c49ac882a 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/delete.ftl @@ -23,6 +23,13 @@ code = "204" desc = "Request successful." /> + <@lib.response + code = "400" + dto = "ExceptionDto" + last = true + desc = "Returned if a given task id is invalid. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) for the error response format."/> + <@lib.response code = "401" dto = "ExceptionDto" diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl index f995c70b04c..240c62f500f 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/put.ftl @@ -38,6 +38,13 @@ code = "204" desc = "Request successful." /> + <@lib.response + code = "400" + dto = "ExceptionDto" + last = true + desc = "Returned if a given task id or comment id is invalid. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) for the error response format."/> + <@lib.response code = "401" dto = "ExceptionDto" diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl index e7758150bf2..4c2675edd09 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/task/{id}/comment/{commentId}/delete.ftl @@ -32,6 +32,13 @@ code = "204" desc = "Request successful." /> + <@lib.response + code = "400" + dto = "ExceptionDto" + last = true + desc = "Returned if a given task id or comment id is invalid. + See the [Introduction](${docsUrl}/reference/rest/overview/#error-handling) for the error response format."/> + <@lib.response code = "401" dto = "ExceptionDto" diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java index f84bda46861..1b67404fbd2 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/runtime/impl/ProcessInstanceCommentResourceImpl.java @@ -23,9 +23,7 @@ import org.camunda.bpm.engine.AuthorizationException; import org.camunda.bpm.engine.IdentityService; import org.camunda.bpm.engine.ProcessEngine; -import org.camunda.bpm.engine.ProcessEngineException; import org.camunda.bpm.engine.TaskService; -import org.camunda.bpm.engine.exception.NotValidException; import org.camunda.bpm.engine.exception.NullValueException; import org.camunda.bpm.engine.history.HistoricProcessInstance; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; @@ -73,10 +71,10 @@ public void deleteComment(String commentId) { TaskService taskService = engine.getTaskService(); try { taskService.deleteProcessInstanceComment(processInstanceId, commentId); - } catch (NotValidException e) { - throw new InvalidRequestException(Status.NOT_FOUND, - "Deletion is not possible. No comment exists for processInstanceId '" + processInstanceId - + "' and comment id '" + commentId + "'."); + } catch (AuthorizationException e) { + throw e; + } catch (NullValueException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); } } @@ -90,16 +88,10 @@ public void updateComment(CommentDto comment) { TaskService taskService = engine.getTaskService(); try { taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), comment.getMessage()); - } catch (NotValidException e) { - throw new InvalidRequestException(Status.NOT_FOUND, - "Update is not possible. No comment exists for process instance id '" + processInstanceId - + "' and comment id '" + comment.getId() + "'."); } catch (AuthorizationException e) { throw e; } catch (NullValueException e) { throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); - } catch (ProcessEngineException e) { - throw new InvalidRequestException(Status.BAD_REQUEST, e, "Not enough parameters submitted"); } } @@ -114,9 +106,10 @@ public void deleteComments() { try { taskService.deleteProcessInstanceComments(processInstanceId); - } catch (NotValidException e) { - throw new InvalidRequestException(Status.NOT_FOUND, - "Deletion of comments not possible for processInstance id '" + processInstanceId + "'."); + } catch (AuthorizationException e) { + throw e; + } catch (NullValueException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); } } diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java index 91c97e2f986..8a24336172c 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/sub/task/impl/TaskCommentResourceImpl.java @@ -28,7 +28,6 @@ import org.camunda.bpm.engine.ProcessEngine; import org.camunda.bpm.engine.ProcessEngineException; import org.camunda.bpm.engine.TaskService; -import org.camunda.bpm.engine.exception.NotValidException; import org.camunda.bpm.engine.exception.NullValueException; import org.camunda.bpm.engine.history.HistoricTaskInstance; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; @@ -86,10 +85,10 @@ public void deleteComment(String commentId) { TaskService taskService = engine.getTaskService(); try { taskService.deleteTaskComment(taskId, commentId); - } catch (NotValidException e) { - throw new InvalidRequestException(Status.NOT_FOUND, - "Deletion is not possible. No comment exists for task id '" + taskId + "' and comment id '" + commentId - + "'."); + } catch (AuthorizationException e) { + throw e; + } catch (NullValueException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); } } @@ -99,16 +98,10 @@ public void updateComment(CommentDto comment) { try { engine.getTaskService().updateTaskComment(taskId, comment.getId(), comment.getMessage()); - } catch (NotValidException e) { - throw new InvalidRequestException(Status.NOT_FOUND, - "Update is not possible. No comment exists for task id '" + taskId + "' and comment id '" + comment.getId() - + "'."); } catch (AuthorizationException e) { throw e; } catch (NullValueException e) { throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); - } catch (ProcessEngineException e) { - throw new InvalidRequestException(Status.BAD_REQUEST, e, "Not enough parameters submitted"); } } @@ -119,9 +112,10 @@ public void deleteComments() { try { taskService.deleteTaskComments(taskId); - } catch (NotValidException e) { - throw new InvalidRequestException(Status.NOT_FOUND, - "Deletion of comments not possible for task id '" + taskId + "'."); + } catch (AuthorizationException e) { + throw e; + } catch (NullValueException e) { + throw new InvalidRequestException(Status.BAD_REQUEST, e.getMessage()); } } diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java index c7c132dd0f7..dc86a9293a2 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java @@ -874,6 +874,8 @@ public void testDeleteInstanceComment() { .statusCode(Status.NO_CONTENT.getStatusCode()) .when() .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); + + verify(taskServiceMock).deleteProcessInstanceComment(EXAMPLE_PROCESS_INSTANCE_ID, EXAMPLE_PROCESS_INSTANCE_COMMENT_ID); } @Test @@ -986,6 +988,8 @@ public void testDeleteProcessInstanceComments() { .statusCode(Status.NO_CONTENT.getStatusCode()) .when() .delete(PROCESS_INSTANCE_COMMENTS_URL); + + verify(taskServiceMock).deleteProcessInstanceComments(EXAMPLE_PROCESS_INSTANCE_ID); } @Test diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java index 2d9f9c48312..a541e377025 100755 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java @@ -3751,6 +3751,7 @@ public void testDeleteTaskComment() { .statusCode(Status.NO_CONTENT.getStatusCode()) .when() .delete(SINGLE_TASK_SINGLE_COMMENT_URL); + verify(taskServiceMock).deleteTaskComment(EXAMPLE_TASK_ID, EXAMPLE_TASK_COMMENT_ID ); } @Test @@ -3855,6 +3856,7 @@ public void testDeleteTaskComments() { .statusCode(Status.NO_CONTENT.getStatusCode()) .when() .delete(SINGLE_TASK_COMMENTS_URL); + verify(taskServiceMock).deleteTaskComments(EXAMPLE_TASK_ID); } @Test diff --git a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java index 08159f18128..d618c154977 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/TaskService.java +++ b/engine/src/main/java/org/camunda/bpm/engine/TaskService.java @@ -1114,6 +1114,7 @@ public interface TaskService { * @param commentId id of a comment that is intended to be deleted * @throws NotFoundException if no task with the given id exists * @throws BadUserRequestException if task id or error code were null or empty + * @throws BadUserRequestException when given both task and comment ids are null * @throws ProcessEngineException when task and comment don't exist with the given taskId and commentId * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} @@ -1177,12 +1178,12 @@ public interface TaskService { * @param processInstanceId id of a process instance of a comment that is intended to be updated * @param commentId id of a comment that is intended to be updated * @param message new message that needs to be updated - * @throws NotFoundException if no process instance with the given processInstanceId id exists - * @throws NotFoundException if no comment found to be updated for a given comment id - * @throws ProcessEngineException when given process instance id and comment id are passed as null - * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} - * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} - * (if the task is part of a running process instance). + * @throws NotFoundException if no process instance with the given processInstanceId id exists + * @throws NotFoundException if no comment found to be updated for a given comment id + * @throws BadUserRequestException when given both process instance id and comment id are passed as null + * @throws AuthorizationException If the user hasn't any of {@link Permissions#UPDATE}, {@link Permissions#TASK_WORK} permissions on {@link Resources#TASK} + * or no {@link Permissions#UPDATE_TASK}, {@link Permissions#TASK_WORK} permissions on {@link Resources#PROCESS_DEFINITION} + * (if the task is part of a running process instance). */ void updateProcessInstanceComment(String processInstanceId, String commentId, String message); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java index b112e081697..7bdf7e49aaf 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteProcessInstanceCommentCmd.java @@ -21,7 +21,7 @@ import java.io.Serializable; import java.util.Collections; import java.util.List; -import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.history.UserOperationLogEntry; import org.camunda.bpm.engine.impl.cfg.CommandChecker; import org.camunda.bpm.engine.impl.interceptor.Command; @@ -54,60 +54,38 @@ public DeleteProcessInstanceCommentCmd(String processInstanceId) { public Object execute(CommandContext commandContext) { if (processInstanceId == null && commentId == null) { - throw new ProcessEngineException("Both process instance and comment ids are null"); + throw new BadUserRequestException("Both process instance and comment ids are null"); } ensureNotNull("processInstanceId", processInstanceId); + ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); + ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance", + processInstance); if (commentId != null && processInstanceId != null) { CommentEntity comment = commandContext.getCommentManager() .findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); - if (comment != null) { - - TaskEntity task = getTask(comment, commandContext); - checkTaskWork(task, commandContext); + if (comment != null) { + checkUpdateProcessInstanceById(processInstanceId, commandContext); commandContext.getDbEntityManager().delete(comment); - logOperation(comment, task, null, commandContext); - task.triggerUpdateEvent(); } } else { - ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); - ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance: ", - processInstance); - List comments = commandContext.getCommentManager().findCommentsByProcessInstanceId(processInstanceId); if (!comments.isEmpty()) { - TaskEntity task = commandContext.getTaskManager().findTaskById(comments.get(0).getTaskId()); - checkTaskWork(task, commandContext); + checkUpdateProcessInstanceById(processInstanceId, commandContext); commandContext.getCommentManager() .deleteCommentsByProcessInstanceIds(Collections.singletonList(processInstanceId)); - logOperation(null, null, processInstance, commandContext); } } + logOperation(processInstance, commandContext); return null; } - private void logOperation(CommentEntity comment, - TaskEntity task, - ExecutionEntity processInstance, - CommandContext commandContext) { - PropertyChange propertyChange = new PropertyChange("comment", null, - (comment != null) ? comment.getMessage() : null); - if (task != null) { - commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, propertyChange); - } else { - commandContext.getOperationLogManager() - .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, processInstance, propertyChange); - } - } - - private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) { - String taskId = comment.getTaskId(); - TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); - ensureNotNull("Task not found for taskId: " + taskId + " CommentId: " + commentId, "comment", comment); - return task; + private void logOperation(ExecutionEntity processInstance, CommandContext commandContext) { + PropertyChange propertyChange = new PropertyChange("comment", null, null); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, processInstance, propertyChange); } protected void checkTaskWork(TaskEntity task, CommandContext commandContext) { @@ -115,4 +93,11 @@ protected void checkTaskWork(TaskEntity task, CommandContext commandContext) { checker.checkTaskWork(task); } } + + protected void checkUpdateProcessInstanceById(String processInstanceId, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateProcessInstanceById(processInstanceId); + } + } + } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java index fe08f702191..83c6bebc044 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/DeleteTaskCommentCmd.java @@ -20,7 +20,7 @@ import java.io.Serializable; import java.util.List; -import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.history.UserOperationLogEntry; import org.camunda.bpm.engine.impl.cfg.CommandChecker; import org.camunda.bpm.engine.impl.interceptor.Command; @@ -52,7 +52,7 @@ public DeleteTaskCommentCmd(String taskId) { public Object execute(CommandContext commandContext) { if (commentId == null && taskId == null) { - throw new ProcessEngineException("Both task and comment ids are null"); + throw new BadUserRequestException("Both task and comment ids are null"); } ensureNotNull("taskId", taskId); @@ -70,8 +70,8 @@ public Object execute(CommandContext commandContext) { task = commandContext.getTaskManager().findTaskById(taskId); ensureNotNull("No task exists with taskId: " + taskId, "task", task); List comments = commandContext.getCommentManager().findCommentsByTaskId(taskId); + checkTaskWork(task, commandContext); if (!comments.isEmpty()) { - checkTaskWork(task, commandContext); commandContext.getCommentManager().deleteCommentsByTaskId(taskId); } } @@ -79,17 +79,13 @@ public Object execute(CommandContext commandContext) { if (task != null) { commandContext.getOperationLogManager() .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_DELETE_COMMENT, task, - getCommentPropertyChange(comment != null ? comment.getMessage() : null)); + new PropertyChange("comment", null, null)); task.triggerUpdateEvent(); } return null; } - private PropertyChange getCommentPropertyChange(String message) { - return new PropertyChange("comment", null, message); - } - private TaskEntity getTask(CommentEntity comment, CommandContext commandContext) { String taskId = comment.getTaskId(); TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java index ec335df214b..10de71534f2 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/UpdateCommentCmd.java @@ -19,7 +19,7 @@ import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; import java.io.Serializable; -import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.history.UserOperationLogEntry; import org.camunda.bpm.engine.impl.cfg.CommandChecker; import org.camunda.bpm.engine.impl.interceptor.Command; @@ -50,44 +50,55 @@ public UpdateCommentCmd(String taskId, String processInstanceId, String commentI public Object execute(CommandContext commandContext) { if (processInstanceId == null && taskId == null) { - throw new ProcessEngineException("Both process instance and task ids are null"); + throw new BadUserRequestException("Both process instance and task ids are null"); } ensureNotNull("commentId", commentId); ensureNotNull("message", message); - if(null == processInstanceId) { + if (null == processInstanceId) { ensureNotNull("taskId", taskId); CommentEntity comment = getComment(commandContext); ensureNotNull("No comment exists with commentId: " + commentId + " and taskId: " + taskId, "comment", comment); - TaskEntity task = updateComment(taskId, commandContext, comment); - commandContext.getOperationLogManager().logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, task, getPropertyChange(comment)); + TaskEntity task = updateTaskComment(taskId, commandContext, comment); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, task, getPropertyChange(comment)); task.triggerUpdateEvent(); - } - else { + } else { ensureNotNull("processInstanceId", processInstanceId); CommentEntity comment = getComment(commandContext); - ensureNotNull("No comment exists with commentId: " + commentId + " and processInstanceId: " + processInstanceId, "comment", comment); + ensureNotNull("No comment exists with commentId: " + commentId + " and processInstanceId: " + processInstanceId, + "comment", comment); ExecutionEntity processInstance = commandContext.getExecutionManager().findExecutionById(processInstanceId); - ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance", processInstance); - updateComment(comment.getTaskId(), commandContext, comment); - commandContext.getOperationLogManager().logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, processInstance, getPropertyChange(comment)); + ensureNotNull("No processInstance exists with processInstanceId: " + processInstanceId, "processInstance", + processInstance); + updateProcessInstanceComment(processInstanceId, commandContext, comment); + commandContext.getOperationLogManager() + .logCommentOperation(UserOperationLogEntry.OPERATION_TYPE_UPDATE_COMMENT, processInstance, + getPropertyChange(comment)); } return null; } - private TaskEntity updateComment(String taskId, CommandContext commandContext, CommentEntity comment) { + private TaskEntity updateTaskComment(String taskId, CommandContext commandContext, CommentEntity comment) { TaskEntity task = commandContext.getTaskManager().findTaskById(taskId); ensureNotNull("No task exists with taskId: " + taskId, "task", task); checkTaskWork(task, commandContext); updateComment(commandContext, comment); - return task; + return task; + } + + private void updateProcessInstanceComment(String processInstanceId, + CommandContext commandContext, + CommentEntity comment) { + checkUpdateProcessInstanceById(processInstanceId, commandContext); + updateComment(commandContext, comment); } private CommentEntity getComment(CommandContext commandContext) { - if(taskId !=null) { + if (taskId != null) { return commandContext.getCommentManager().findCommentByTaskIdAndCommentId(taskId, commentId); } return commandContext.getCommentManager().findCommentByProcessInstanceIdAndCommentId(processInstanceId, commentId); @@ -103,6 +114,12 @@ protected void checkTaskWork(TaskEntity task, CommandContext commandContext) { } } + protected void checkUpdateProcessInstanceById(String processInstanceId, CommandContext commandContext) { + for (CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) { + checker.checkUpdateProcessInstanceById(processInstanceId); + } + } + private void updateComment(CommandContext commandContext, CommentEntity comment) { String eventMessage = comment.toEventMessage(message); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java index 30dd0bff6e0..730bd163ff1 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentEntity.java @@ -19,7 +19,9 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.StringTokenizer; import org.camunda.bpm.engine.impl.db.DbEntity; @@ -58,7 +60,9 @@ public class CommentEntity implements Comment, Event, HasDbRevision, DbEntity, H protected int revision; public Object getPersistentState() { - return CommentEntity.class; + Map persistentState = new HashMap<>(); + persistentState.put("message", message); + return persistentState; } public byte[] getFullMessageBytes() { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java index 5dfc0ca0f28..57fa8a219ce 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java @@ -151,20 +151,4 @@ public DbOperation deleteCommentsByRemovalTime(Date removalTime, int minuteFrom, .deletePreserveOrder(CommentEntity.class, "deleteCommentsByRemovalTime", new ListQueryParameterObject(parameters, 0, batchSize)); } - - public void updateCommentMessage(CommentEntity entity) { - checkHistoryEnabled(); - Map parameters = new HashMap<>(); - parameters.put("message", entity.getMessage()); - parameters.put("fullMessageBytes", entity.getFullMessageBytes()); - parameters.put("time", entity.getTime()); - parameters.put("action", entity.getAction()); - parameters.put("id", entity.getId()); - parameters.put("userId", entity.getUserId()); - parameters.put("revision", entity.getRevision()); - parameters.put("revisionNext", entity.getRevisionNext()); - - getDbEntityManager().update(CommentEntity.class, "updateComment", parameters); - } - } diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql index 912056b111e..4451dc5e2b1 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql @@ -28,5 +28,4 @@ alter table ACT_HI_COMMENT --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql index 912056b111e..4451dc5e2b1 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql @@ -28,5 +28,4 @@ alter table ACT_HI_COMMENT --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql index 912056b111e..b03c300ac4e 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql @@ -23,10 +23,9 @@ alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); alter table ACT_HI_COMMENT - add column REV_ integer; + add column REV_ int; --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql index 912056b111e..f63fb2c3060 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql @@ -18,9 +18,9 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); -alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); +alter table ACT_RU_TASK add TASK_STATE_ nvarchar(64); -alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); +alter table ACT_HI_TASKINST add TASK_STATE_ nvarchar(64); alter table ACT_HI_COMMENT add column REV_ integer; @@ -28,5 +28,4 @@ alter table ACT_HI_COMMENT --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql index 912056b111e..4451dc5e2b1 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql @@ -28,5 +28,4 @@ alter table ACT_HI_COMMENT --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql index 912056b111e..4451dc5e2b1 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql @@ -28,5 +28,4 @@ alter table ACT_HI_COMMENT --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql index 912056b111e..4451dc5e2b1 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql @@ -28,5 +28,4 @@ alter table ACT_HI_COMMENT --Set revision number to already existing comments -- if any for backward compatibility update ACT_HI_COMMENT -set REV_ = 1 -where REV_ is null; +set REV_ = 1; diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java index 616156de0f7..b8d659b4297 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/ProcessInstanceCommentAuthorizationTest.java @@ -17,7 +17,7 @@ package org.camunda.bpm.engine.test.api.authorization; import static org.camunda.bpm.engine.authorization.Permissions.UPDATE; -import static org.camunda.bpm.engine.authorization.Resources.TASK; +import static org.camunda.bpm.engine.authorization.Resources.PROCESS_INSTANCE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; @@ -34,7 +34,7 @@ public class ProcessInstanceCommentAuthorizationTest extends AuthorizationTest { @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") @Test - public void testDeleteProcessInstanceCommentWithoutAuthorization() { + public void testDeleteProcessInstanceTaskCommentWithoutAuthorization() { // given String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); createTask(TASK_ID); @@ -47,7 +47,7 @@ public void testDeleteProcessInstanceCommentWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a task."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", e.getMessage()); } @@ -57,12 +57,12 @@ public void testDeleteProcessInstanceCommentWithoutAuthorization() { @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") @Test - public void testDeleteProcessInstanceComment() { + public void testDeleteProcessInstanceTaskComment() { // given createTask(TASK_ID); String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); Comment createdComment = taskService.createComment(TASK_ID, processInstanceId, "aComment"); - createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); // when taskService.deleteProcessInstanceComment(processInstanceId, createdComment.getId()); @@ -77,7 +77,7 @@ public void testDeleteProcessInstanceComment() { @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") @Test - public void testDeleteProcessInstanceCommentsWithoutAuthorization() { + public void testDeleteProcessInstanceTaskCommentsWithoutAuthorization() { // given createTask(TASK_ID); String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); @@ -89,7 +89,7 @@ public void testDeleteProcessInstanceCommentsWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a comment."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", e.getMessage()); } @@ -99,14 +99,14 @@ public void testDeleteProcessInstanceCommentsWithoutAuthorization() { @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") @Test - public void testDeleteProcessInstanceComments() { + public void testDeleteProcessInstanceTaskComments() { // given createTask(TASK_ID); String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); taskService.createComment(TASK_ID, processInstanceId, "aCommentOne"); taskService.createComment(TASK_ID, processInstanceId, "aCommentTwo"); - createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); // when taskService.deleteProcessInstanceComments(processInstanceId); @@ -121,7 +121,7 @@ public void testDeleteProcessInstanceComments() { @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") @Test - public void testUpdateProcessInstanceCommentWithoutAuthorization() { + public void testUpdateProcessInstanceTaskCommentWithoutAuthorization() { // given createTask(TASK_ID); String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); @@ -133,7 +133,7 @@ public void testUpdateProcessInstanceCommentWithoutAuthorization() { fail("Exception expected: It should not be possible to delete a task."); } catch (AuthorizationException e) { // then - testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource 'myTask' of type 'Task' or 'UPDATE' permission on resource 'myTask' of type 'Task'", + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", e.getMessage()); } @@ -142,7 +142,7 @@ public void testUpdateProcessInstanceCommentWithoutAuthorization() { @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") @Test - public void testUpdateProcessInstanceComment() { + public void testUpdateProcessInstanceTaskComment() { // given String taskId = "myTask"; createTask(taskId); @@ -151,7 +151,7 @@ public void testUpdateProcessInstanceComment() { String commentMessage = "OriginalCommentMessage"; String updatedMessage = "UpdatedCommentMessage"; Comment comment = taskService.createComment(taskId, processInstanceId, commentMessage); - createGrantAuthorization(TASK, TASK_ID, userId, UPDATE); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); // when taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), updatedMessage); @@ -165,4 +165,113 @@ public void testUpdateProcessInstanceComment() { deleteTask(taskId, true); } + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceCommentWithoutAuthorization() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + + Comment createdComment = createComment(null, processInstanceId, "aComment"); + + try { + // when + taskService.deleteProcessInstanceComment(processInstanceId, createdComment.getId()); + fail("Exception expected: It should not be possible to delete a task."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + e.getMessage()); + } + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceComment() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + Comment createdComment = taskService.createComment(null, processInstanceId, "aComment"); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + + // when + taskService.deleteProcessInstanceComment(processInstanceId, createdComment.getId()); + + // then + List deletedCommentLst = taskService.getProcessInstanceComments(processInstanceId); + assertEquals("The comments list should be empty", Collections.emptyList(), deletedCommentLst); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceCommentsWithoutAuthorization() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + createComment(null, processInstanceId, "aComment"); + + try { + // when + taskService.deleteProcessInstanceComments(processInstanceId); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + e.getMessage()); + } + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testDeleteProcessInstanceComments() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + taskService.createComment(null, processInstanceId, "aCommentOne"); + taskService.createComment(null, processInstanceId, "aCommentTwo"); + + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + + // when + taskService.deleteProcessInstanceComments(processInstanceId); + + // then + List comments = taskService.getProcessInstanceComments(processInstanceId); + assertEquals("The comments list should be empty", Collections.emptyList(), comments); + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testUpdateProcessInstanceCommentWithoutAuthorization() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + Comment createdComment = createComment(null, processInstanceId, "originalComment"); + + try { + // when + taskService.updateProcessInstanceComment(processInstanceId, createdComment.getId(), "updateMessage"); + fail("Exception expected: It should not be possible to delete a task."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent("The user with id 'test' does not have one of the following permissions: 'UPDATE'", + e.getMessage()); + } + } + + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + @Test + public void testUpdateProcessInstanceComment() { + // given + String processInstanceId = startProcessInstanceByKey(ONE_TASK_PROCESS_KEY).getId(); + + String commentMessage = "OriginalCommentMessage"; + String updatedMessage = "UpdatedCommentMessage"; + Comment comment = taskService.createComment(null, processInstanceId, commentMessage); + createGrantAuthorization(PROCESS_INSTANCE, processInstanceId, userId, UPDATE); + + // when + taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), updatedMessage); + + // then + List comments = taskService.getProcessInstanceComments(processInstanceId); + assertFalse("The comments list should not be empty", comments.isEmpty()); + assertEquals(updatedMessage, comments.get(0).getFullMessage()); + } + } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java index 4397296035c..073bbe99a60 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/authorization/TaskCommentAuthorizationTest.java @@ -26,11 +26,16 @@ import java.util.Collections; import java.util.List; import org.camunda.bpm.engine.AuthorizationException; +import org.camunda.bpm.engine.runtime.ProcessInstance; import org.camunda.bpm.engine.task.Comment; +import org.camunda.bpm.engine.task.Task; +import org.camunda.bpm.engine.test.Deployment; import org.junit.Test; public class TaskCommentAuthorizationTest extends AuthorizationTest { + protected static final String PROCESS_KEY = "oneTaskProcess"; + @Test public void testDeleteTaskCommentWithoutAuthorization() { // given @@ -153,4 +158,124 @@ public void testUpdateTaskComment() { deleteTask(TASK_ID, true); } + @Test + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + public void testDeleteProcessTaskCommentWithoutAuthorization() { + // given + ProcessInstance processInstance = startProcessInstanceByKey(PROCESS_KEY); + Task task = selectSingleTask(); + Comment createdComment = createComment(task.getId(), processInstance.getId(), "aComment"); + + try { + // when + taskService.deleteTaskComment(task.getId(), createdComment.getId()); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent( + "The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource", + e.getMessage()); + } + } + + @Test + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + public void testDeleteProcessTaskComment() { + // given + ProcessInstance processInstance = startProcessInstanceByKey(PROCESS_KEY); + Task task = selectSingleTask(); + task.setAssignee("demo"); + Comment createdComment = taskService.createComment(task.getId(), processInstance.getId(), "aComment"); + createGrantAuthorization(TASK, task.getId(), userId, UPDATE); + + // when + taskService.deleteTaskComment(task.getId(), createdComment.getId()); + + // then + Comment shouldBeDeleletedComment = taskService.getTaskComment(task.getId(), createdComment.getId()); + assertNull(shouldBeDeleletedComment); + } + + @Test + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + public void testDeleteProcessTaskCommentsWithoutAuthorization() { + // given + ProcessInstance processInstance = startProcessInstanceByKey(PROCESS_KEY); + Task task = selectSingleTask(); + createComment(task.getId(), processInstance.getId(), "aComment"); + + try { + // when + taskService.deleteTaskComments(task.getId()); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent( + "The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource", + e.getMessage()); + } + } + + @Test + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + public void testDeleteProcessTaskComments() { + // given + ProcessInstance processInstance = startProcessInstanceByKey(PROCESS_KEY); + Task task = selectSingleTask(); + taskService.createComment(task.getId(), processInstance.getId(), "aCommentOne"); + taskService.createComment(task.getId(), processInstance.getId(), "aCommentTwo"); + + createGrantAuthorization(TASK, task.getId(), userId, UPDATE); + + // when + taskService.deleteTaskComments(task.getId()); + + // then + List comments = taskService.getTaskComments(task.getId()); + assertEquals("The comments list should be empty", Collections.emptyList(), comments); + } + + @Test + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + public void testUpdateProcessTaskCommentWithoutAuthorization() { + // given + ProcessInstance processInstance = startProcessInstanceByKey(PROCESS_KEY); + Task task = selectSingleTask(); + + Comment createdComment = createComment(task.getId(), processInstance.getId(), "originalComment"); + + try { + // when + taskService.updateTaskComment(task.getId(), createdComment.getId(), "updateMessage"); + fail("Exception expected: It should not be possible to delete a comment."); + } catch (AuthorizationException e) { + // then + testRule.assertTextPresent( + "The user with id 'test' does not have one of the following permissions: 'TASK_WORK' permission on resource", + e.getMessage()); + } + } + + @Test + @Deployment(resources = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml") + public void testUpdateProcessTaskComment() { + // given + ProcessInstance processInstance = startProcessInstanceByKey(PROCESS_KEY); + Task task = selectSingleTask(); + task.setAssignee("demo"); + + String commentMessage = "OriginalCommentMessage"; + String updatedMessage = "UpdatedCommentMessage"; + Comment comment = taskService.createComment(task.getId(), processInstance.getId(), commentMessage); + createGrantAuthorization(TASK, task.getId(), userId, UPDATE); + + // when + taskService.updateTaskComment(task.getId(), comment.getId(), updatedMessage); + + // then + List comments = taskService.getTaskComments(task.getId()); + assertFalse("The comments list should not be empty", comments.isEmpty()); + assertEquals(updatedMessage, comments.get(0).getFullMessage()); + } + } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java index acaedc55c19..7b383f59b07 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/task/TaskServiceTest.java @@ -306,13 +306,13 @@ public void testDeleteTaskCommentNotExistingCommentId() { } @Test - public void testDeleteTaskComment() { + public void testDeleteTaskCommentWithoutProcessInstance() { Task task = taskService.newTask(); taskService.saveTask(task); String taskId = task.getId(); //create a task comment - Comment comment = taskService.createComment(taskId, "pid", "aMessage"); + Comment comment = taskService.createComment(taskId, null, "aMessage"); String commentId = comment.getId(); //delete a comment @@ -326,6 +326,25 @@ public void testDeleteTaskComment() { taskService.deleteTask(taskId, true); } + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteTaskCommentWithProcessInstance() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); + + //create a task comment + Comment comment = taskService.createComment(taskId, processInstance.getId(), "aMessage"); + String commentId = comment.getId(); + + //delete a comment + taskService.deleteTaskComment(taskId, commentId); + + //make sure the comment is not there. + Comment shouldBeDeleted = taskService.getTaskComment(taskId, commentId); + assertNull(shouldBeDeleted); + } + @Test public void testDeleteTaskCommentsNullTaskId() { try { @@ -366,7 +385,7 @@ public void testDeleteTaskComments() { String taskId = task.getId(); //create a task comment - Comment comment = taskService.createComment(taskId, "pid", "aMessage"); + Comment comment = taskService.createComment(taskId, null, "aMessage"); //delete a comment taskService.deleteTaskComments(taskId); @@ -379,6 +398,24 @@ public void testDeleteTaskComments() { taskService.deleteTask(taskId, true); } + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceTaskComments() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); + + //create a task comment + Comment comment = taskService.createComment(taskId, processInstance.getId(), "aMessage"); + + //delete a comment + taskService.deleteTaskComments(taskId); + + //make sure the comment is not there. + Comment shouldBeDeleted = taskService.getTaskComment(taskId, comment.getId()); + assertNull(shouldBeDeleted); + } + @Test public void testUpdateTaskCommentNullCommentId() { Task task = taskService.newTask(); @@ -466,6 +503,24 @@ public void testUpdateTaskComment() { taskService.deleteTask(taskId, true); } + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessTaskComment() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); + + Comment comment = taskService.createComment(taskId, processInstance.getId(), "originalMessage"); + String updatedMessage = "updatedMessage"; + + taskService.updateTaskComment(taskId, comment.getId(), updatedMessage); + + Comment actual = taskService.getTaskComment(taskId, comment.getId()); + + assertThat(actual).isNotNull(); + assertEquals(updatedMessage, actual.getFullMessage()); + } + @Test public void testDeleteProcessInstanceCommentNullTaskIdAndCommentId() { try { @@ -487,12 +542,10 @@ public void testDeleteProcessInstanceCommentNotExistingCommentId() { @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @Test - public void testDeleteProcessInstanceComment() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); - + public void testDeleteTaskProcessInstanceComment() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); String processInstanceId = processInstance.getId(); //create a task comment @@ -504,9 +557,23 @@ public void testDeleteProcessInstanceComment() { //make sure the comment is not there. List shouldBeDeletedLst = taskService.getProcessInstanceComments(processInstanceId); assertThat(shouldBeDeletedLst).isEmpty(); + } - // Finally, delete task - taskService.deleteTask(taskId, true); + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceComment() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + + //create a task comment + Comment comment = taskService.createComment(null, processInstanceId, "aMessage"); + + //delete a comment + taskService.deleteProcessInstanceComment(processInstanceId, comment.getId()); + + //make sure the comment is not there. + List shouldBeDeletedLst = taskService.getProcessInstanceComments(processInstanceId); + assertThat(shouldBeDeletedLst).isEmpty(); } @Test @@ -541,12 +608,28 @@ public void testDeleteProcessInstanceCommentsNoComments() { @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @Test - public void testDeleteProcessInstanceComments() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); + public void testDeleteProcessInstanceCommentsWithoutTaskComments() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + + //create a task comment + taskService.createComment(null, processInstanceId, "messageOne"); + taskService.createComment(null, processInstanceId, "messageTwo"); + //delete a comment + taskService.deleteProcessInstanceComments(processInstanceId); + + //make sure the comment is not there. + List shouldBeDeletedLst = taskService.getProcessInstanceComments(processInstanceId); + assertThat(shouldBeDeletedLst).isEmpty(); + } + + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testDeleteProcessInstanceCommentsWithTask() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); String processInstanceId = processInstance.getId(); //create a task comment @@ -559,9 +642,6 @@ public void testDeleteProcessInstanceComments() { //make sure the comment is not there. List shouldBeDeletedLst = taskService.getProcessInstanceComments(processInstanceId); assertThat(shouldBeDeletedLst).isEmpty(); - - // Finally, delete task - taskService.deleteTask(taskId, true); } @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @@ -579,49 +659,46 @@ public void testUpdateProcessInstanceCommentNullCommentId() { @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @Test public void testUpdateProcessInstanceCommentNullProcessInstanceId() { - Task task = taskService.newTask(); - taskService.saveTask(task); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); - Comment comment = taskService.createComment(task.getId(), processInstance.getId(), "originalMessage"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); + + Comment comment = taskService.createComment(taskId, processInstance.getId(), "originalMessage"); try { taskService.updateProcessInstanceComment(null, comment.getId(), "updatedMessage"); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { testRule.assertTextPresent("Both process instance and task ids are null", ae.getMessage()); - } finally { - taskService.deleteTask(task.getId(), true); } } @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @Test public void testUpdateProcessInstanceCommentNullMessage() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); - Comment comment = taskService.createComment(taskId, processInstance.getId(), "originalMessage"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); + String processInstanceId = processInstance.getId(); + + Comment comment = taskService.createComment(taskId, processInstanceId, "originalMessage"); try { - taskService.updateProcessInstanceComment(processInstance.getId(), comment.getId(), null); + taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), null); fail("ProcessEngineException expected"); } catch (ProcessEngineException ae) { testRule.assertTextPresent("message is null", ae.getMessage()); - } finally { - taskService.deleteTask(task.getId(), true); } } @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @Test public void testUpdateProcessInstanceCommentNotExistingCommentId() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); - ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); String processInstanceId = processInstance.getId(); + taskService.createComment(taskId, processInstanceId, "originalMessage"); String nonExistingCommentId = "notExistingCommentId"; @@ -632,19 +709,15 @@ public void testUpdateProcessInstanceCommentNotExistingCommentId() { testRule.assertTextPresent( "No comment exists with commentId: " + nonExistingCommentId + " and processInstanceId: " + processInstanceId, ae.getMessage()); - } finally { - taskService.deleteTask(taskId, true); } } @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) @Test - public void testUpdateProcessInstanceComment() { - Task task = taskService.newTask(); - taskService.saveTask(task); - String taskId = task.getId(); - + public void testUpdateProcessInstanceCommentWithTask() { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + String taskId = task.getId(); String processInstanceId = processInstance.getId(); Comment comment = taskService.createComment(taskId, processInstanceId, "originalMessage"); @@ -659,9 +732,26 @@ public void testUpdateProcessInstanceComment() { Comment actual = updateCommentLst.get(0); assertEquals(updatedMessage, actual.getFullMessage()); + } - // Finally, delete task - taskService.deleteTask(taskId, true); + @Deployment(resources = { "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml" }) + @Test + public void testUpdateProcessInstanceCommentWithoutTask() { + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess"); + String processInstanceId = processInstance.getId(); + + Comment comment = taskService.createComment(null, processInstanceId, "originalMessage"); + String updatedMessage = "updatedMessage"; + + taskService.updateProcessInstanceComment(processInstanceId, comment.getId(), updatedMessage); + + List updateCommentLst = taskService.getProcessInstanceComments(processInstanceId); + + assertThat(updateCommentLst).isNotEmpty(); + assertThat(updateCommentLst).hasSize(1); + + Comment actual = updateCommentLst.get(0); + assertEquals(updatedMessage, actual.getFullMessage()); } @Test From 970ec8dd9d81a06d2fde5da3db634d8ea02920e6 Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Wed, 11 Sep 2024 10:40:44 -0600 Subject: [PATCH 09/10] Fix engine-rest tests --- .../rest/ProcessInstanceRestServiceInteractionTest.java | 5 +---- .../bpm/engine/rest/TaskRestServiceInteractionTest.java | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java index dc86a9293a2..ad522eea1f4 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/ProcessInstanceRestServiceInteractionTest.java @@ -904,11 +904,8 @@ public void testDeleteInstanceCommentForNonExistingCommentId() { .header("accept", MediaType.APPLICATION_JSON) .then() .expect() - .statusCode(Status.NOT_FOUND.getStatusCode()) + .statusCode(Status.BAD_REQUEST.getStatusCode()) .contentType(ContentType.JSON) - .body(containsString( - "Deletion is not possible. No comment exists for processInstanceId '" + EXAMPLE_PROCESS_INSTANCE_ID - + "' and comment id '" + NON_EXISTING_ID + "'.")) .when() .delete(SINGLE_PROCESS_INSTANCE_SINGLE_COMMENT_URL); } diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java index a541e377025..96767c68632 100755 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java @@ -3778,11 +3778,8 @@ public void testDeleteTaskCommentForNonExistingCommentId() { .header("accept", MediaType.APPLICATION_JSON) .then() .expect() - .statusCode(Status.NOT_FOUND.getStatusCode()) + .statusCode(Status.BAD_REQUEST.getStatusCode()) .contentType(ContentType.JSON) - .body(containsString( - "Deletion is not possible. No comment exists for task id '" + EXAMPLE_TASK_ID + "' and comment id '" - + NON_EXISTING_ID + "'.")) .when() .delete(SINGLE_TASK_SINGLE_COMMENT_URL); } From 2d65b7ff1d289a13a75c8bbb6596192a1ee2bd2d Mon Sep 17 00:00:00 2001 From: Prajwol Bhandari Date: Fri, 20 Sep 2024 10:22:33 -0600 Subject: [PATCH 10/10] Fix merge conflicts with master --- .../bpm/engine/rest/TaskRestServiceInteractionTest.java | 9 ++++++--- .../bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql | 4 ++++ .../bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql | 3 +++ .../engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql | 3 +++ .../bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql | 3 +++ .../bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql | 3 +++ .../bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql | 7 +++++-- .../engine/db/upgrade/postgres_engine_7.21_to_7.22.sql | 3 +++ 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java index 96767c68632..9c5e142b6b4 100755 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/TaskRestServiceInteractionTest.java @@ -65,9 +65,6 @@ import static org.mockito.Mockito.when; import static org.mockito.hamcrest.MockitoHamcrest.argThat; -import io.restassured.http.ContentType; -import io.restassured.path.json.JsonPath; -import io.restassured.response.Response; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -79,9 +76,11 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; + import javax.ws.rs.HttpMethod; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; + import org.assertj.core.api.Assertions; import org.camunda.bpm.ProcessApplicationService; import org.camunda.bpm.application.ProcessApplicationInfo; @@ -145,6 +144,10 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; +import io.restassured.response.Response; + public class TaskRestServiceInteractionTest extends AbstractRestServiceTest { diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql index 4451dc5e2b1..d85626e9e75 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/db2_engine_7.21_to_7.22.sql @@ -22,6 +22,10 @@ alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); + +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ varchar(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); + alter table ACT_HI_COMMENT add column REV_ integer; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql index 4451dc5e2b1..57f7a508346 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/h2_engine_7.21_to_7.22.sql @@ -22,6 +22,9 @@ alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ varchar(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); + alter table ACT_HI_COMMENT add column REV_ integer; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql index b03c300ac4e..100940729ac 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mariadb_engine_7.21_to_7.22.sql @@ -22,6 +22,9 @@ alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ varchar(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); + alter table ACT_HI_COMMENT add column REV_ int; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql index f63fb2c3060..12d0aff0d86 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mssql_engine_7.21_to_7.22.sql @@ -22,6 +22,9 @@ alter table ACT_RU_TASK add TASK_STATE_ nvarchar(64); alter table ACT_HI_TASKINST add TASK_STATE_ nvarchar(64); +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ nvarchar(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); + alter table ACT_HI_COMMENT add column REV_ integer; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql index 4451dc5e2b1..57f7a508346 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/mysql_engine_7.21_to_7.22.sql @@ -22,6 +22,9 @@ alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ varchar(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); + alter table ACT_HI_COMMENT add column REV_ integer; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql index 4451dc5e2b1..cfdc0854ad0 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/oracle_engine_7.21_to_7.22.sql @@ -18,9 +18,12 @@ insert into ACT_GE_SCHEMA_LOG values ('1100', CURRENT_TIMESTAMP, '7.22.0'); -alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); +alter table ACT_RU_TASK add TASK_STATE_ NVARCHAR2(64); -alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); +alter table ACT_HI_TASKINST add TASK_STATE_ NVARCHAR2(64); + +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ NVARCHAR2(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); alter table ACT_HI_COMMENT add column REV_ integer; diff --git a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql index 4451dc5e2b1..57f7a508346 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql +++ b/engine/src/main/resources/org/camunda/bpm/engine/db/upgrade/postgres_engine_7.21_to_7.22.sql @@ -22,6 +22,9 @@ alter table ACT_RU_TASK add column TASK_STATE_ varchar(64); alter table ACT_HI_TASKINST add column TASK_STATE_ varchar(64); +alter table ACT_HI_PROCINST add RESTARTED_PROC_INST_ID_ varchar(64); +create index ACT_IDX_HI_PRO_RST_PRO_INST_ID on ACT_HI_PROCINST(RESTARTED_PROC_INST_ID_); + alter table ACT_HI_COMMENT add column REV_ integer;