Skip to content

Commit

Permalink
feature: move assign task to miranum platform (#373)
Browse files Browse the repository at this point in the history
Move assign task use case to miranum platform
  • Loading branch information
lmoesle authored May 29, 2024
1 parent 132afea commit dc7d868
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 70 deletions.
26 changes: 26 additions & 0 deletions .run/MiranumProcessIntegrationExample.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="MiranumProcessIntegrationExample" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
<module name="miranum-process-integration-example" />
<option name="SPRING_BOOT_MAIN_CLASS" value="io.miragon.miranum.platform.MiranumProcessIntegrationExample" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="io.miragon.miranum.platform.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<extension name="net.ashald.envfile">
<option name="IS_ENABLED" value="true" />
<option name="IS_SUBST" value="false" />
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
<option name="IS_IGNORE_MISSING_FILES" value="false" />
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
<ENTRIES>
<ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
<ENTRY IS_ENABLED="true" PARSER="env" IS_EXECUTABLE="false" PATH="connect/examples/process-integration-example/local.env" />
</ENTRIES>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.miragon.miranum.platform.adapter.in.task;

import io.miragon.miranum.platform.adapter.in.task.dto.AssignTaskDto;
import io.miragon.miranum.platform.adapter.in.task.dto.CompleteTaskDto;
import io.miragon.miranum.platform.application.port.in.WorkOnUserTaskInPort;
import io.miragon.miranum.platform.security.authentication.UserAuthenticationProvider;
Expand Down Expand Up @@ -28,19 +27,4 @@ public void completeTask(
this.workOnUserTaskInPort.completeUserTask(authenticationProvider.getLoggedInUser(), taskId, completeTaskDto.getPayload());
}

@PostMapping("/{taskId}/assign")
public void assignTask(
@Parameter(name = "taskId", description = "A task id string used during search with the task string.", in = ParameterIn.PATH) @Valid @PathVariable(value = "taskId", required = false) String taskId,
@Valid @RequestBody AssignTaskDto assignTaskDto
) {
this.workOnUserTaskInPort.assignUserTask(authenticationProvider.getLoggedInUser(), taskId, assignTaskDto.getAssignee());
}

@PostMapping("/{taskId}/unassign")
public void unassignTask(
@Parameter(name = "taskId", description = "A task id string used during search with the task string.", in = ParameterIn.PATH) @Valid @PathVariable(value = "taskId", required = false) String taskId
) {
this.workOnUserTaskInPort.unassignUserTask(authenticationProvider.getLoggedInUser(), taskId);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package io.miragon.miranum.platform.adapter.out.miranum;

import io.miragon.miranum.connect.task.api.TaskApi;
import io.miragon.miranum.connect.task.api.command.AssignUserTaskCommand;
import io.miragon.miranum.connect.task.api.command.CompleteTaskCommand;
import io.miragon.miranum.connect.task.api.exception.TaskAccessDeniedException;
import io.miragon.miranum.platform.application.port.out.WorkOnUserTaskOutPort;
import io.miragon.miranum.platform.security.authentication.UserAuthenticationProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

Expand All @@ -16,7 +14,6 @@
public class MiranumTaskAdapter implements WorkOnUserTaskOutPort {

private final TaskApi taskApi;
private final UserAuthenticationProvider authenticationProvider;

@Override
public void completeUserTask(String user, String taskId, Map<String, Object> payload) throws TaskAccessDeniedException {
Expand All @@ -25,17 +22,4 @@ public void completeUserTask(String user, String taskId, Map<String, Object> pay
.variables(payload)
.build(), user);
}

@Override
public void assignUserTask(String user, String taskId, String assignee) throws TaskAccessDeniedException {
taskApi.assignUserTask(AssignUserTaskCommand.builder()
.taskId(taskId)
.assignee(assignee)
.build(), user, authenticationProvider.getLoggedInUserRoles());
}

@Override
public void unassignUserTask(String user, String taskId) throws TaskAccessDeniedException {
taskApi.unassignUserTask(taskId, user, authenticationProvider.getLoggedInUserRoles());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,4 @@ public void completeUserTask(String user, String taskId, Map<String, Object> pay
taskOutPort.completeUserTask(user, taskId, payload);
}

@Override
public void assignUserTask(String user, String taskId, String assignee) throws TaskAccessDeniedException {
taskOutPort.assignUserTask(user, taskId, assignee);
}

@Override
public void unassignUserTask(String user, String taskId) throws TaskAccessDeniedException {
taskOutPort.unassignUserTask(user, taskId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@ public interface WorkOnUserTaskInPort {

void completeUserTask(String user, String taskId, Map<String, Object> payload) throws TaskAccessDeniedException;

void assignUserTask(String user, String taskId, String assignee) throws TaskAccessDeniedException;

void unassignUserTask(String user, String taskId) throws TaskAccessDeniedException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@ public interface WorkOnUserTaskOutPort {

void completeUserTask(String user, String taskId, Map<String, Object> payload) throws TaskAccessDeniedException;

void assignUserTask(String user, String taskId, String assignee) throws TaskAccessDeniedException;

void unassignUserTask(String user, String taskId) throws TaskAccessDeniedException;

}
7 changes: 7 additions & 0 deletions platform/engine/task/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
<scope>provided</scope>
</dependency>

<!-- miranum connect -->
<dependency>
<groupId>io.miragon.miranum.connect</groupId>
<artifactId>connect-task-api</artifactId>
<version>0.7.0-SNAPSHOT</version>
</dependency>

<!-- Feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.miragon.miranum.platform.tasklist.adapter.in.task;

import io.miragon.miranum.platform.security.authentication.UserAuthenticationProvider;
import io.miragon.miranum.platform.tasklist.adapter.in.task.dto.AssignTaskDto;
import io.miragon.miranum.platform.tasklist.application.port.in.UserTaskQuery;
import io.miragon.miranum.platform.tasklist.application.port.in.WorkOnTaskUseCase;
import io.miragon.miranum.platform.tasklist.domain.Task;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
Expand All @@ -10,10 +12,7 @@
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;

Expand All @@ -25,6 +24,7 @@
public class TaskController {

private final UserTaskQuery userTaskQuery;
private final WorkOnTaskUseCase workOnTaskUseCase;
private final UserAuthenticationProvider authenticationProvider;

@GetMapping("/user")
Expand All @@ -46,4 +46,19 @@ public Task getTask(
return userTaskQuery.getTask(taskId, authenticationProvider.getLoggedInUser());
}

@PostMapping("/{taskId}/assign")
public void assignTask(
@Parameter(name = "taskId", description = "A task id string used during search with the task string.", in = ParameterIn.PATH) @Valid @PathVariable(value = "taskId", required = false) String taskId,
@Valid @RequestBody AssignTaskDto assignTaskDto
) {
this.workOnTaskUseCase.assignUserTask(authenticationProvider.getLoggedInUser(), taskId, assignTaskDto.getAssignee());
}

@PostMapping("/{taskId}/unassign")
public void unassignTask(
@Parameter(name = "taskId", description = "A task id string used during search with the task string.", in = ParameterIn.PATH) @Valid @PathVariable(value = "taskId", required = false) String taskId
) {
this.workOnTaskUseCase.unassignUserTask(authenticationProvider.getLoggedInUser(), taskId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.miragon.miranum.platform.tasklist.adapter.out.task.miranum;

import io.miragon.miranum.connect.task.api.command.AssignUserTaskCommand;
import io.miragon.miranum.connect.task.api.command.CompleteTaskCommand;
import io.miragon.miranum.connect.task.api.exception.TaskOperationFailedException;
import io.miragon.miranum.connect.task.impl.TaskOutPort;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.NotImplementedException;
import org.camunda.bpm.engine.TaskService;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class MiranumTaskAdapter implements TaskOutPort {

private final TaskService taskService;

@Override
public void completeTask(CompleteTaskCommand command) throws TaskOperationFailedException {
throw new NotImplementedException("Not implemented");
}

@Override
public void assignUserTask(AssignUserTaskCommand command) throws TaskOperationFailedException {
try {
taskService.claim(command.getTaskId(), command.getAssignee());
} catch (final RuntimeException e) {
throw new TaskOperationFailedException(e.getMessage());
}
}

@Override
public void cancelUserTask(String taskId) throws TaskOperationFailedException {
throw new NotImplementedException("Not implemented");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.miragon.miranum.platform.tasklist.application.port.in;

import io.miragon.miranum.platform.tasklist.exception.TaskAccessDeniedException;

public interface WorkOnTaskUseCase {


void assignUserTask(String user, String taskId, String assignee) throws TaskAccessDeniedException;

void unassignUserTask(String user, String taskId) throws TaskAccessDeniedException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.miragon.miranum.platform.tasklist.application.service;

import io.miragon.miranum.connect.task.api.TaskApi;
import io.miragon.miranum.connect.task.api.command.AssignUserTaskCommand;
import io.miragon.miranum.platform.security.authentication.UserAuthenticationProvider;
import io.miragon.miranum.platform.tasklist.application.port.in.WorkOnTaskUseCase;
import io.miragon.miranum.platform.tasklist.exception.TaskAccessDeniedException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class AssignTaskService implements WorkOnTaskUseCase {

private final TaskApi connectTaskApi;
private final UserAuthenticationProvider userAuthenticationProvider;

@Override
public void assignUserTask(String user, String taskId, String assignee) throws TaskAccessDeniedException {
final AssignUserTaskCommand command = AssignUserTaskCommand.builder()
.taskId(taskId)
.assignee(assignee)
.build();
connectTaskApi.assignUserTask(command, assignee, userAuthenticationProvider.getLoggedInUserRoles());
}

@Override
public void unassignUserTask(String user, String taskId) throws TaskAccessDeniedException {
connectTaskApi.unassignUserTask(taskId, null, userAuthenticationProvider.getLoggedInUserRoles());
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package io.miragon.miranum.platform.tasklist.adapter.in.task;

import io.miragon.miranum.platform.security.authentication.UserAuthenticationProvider;
import io.miragon.miranum.platform.tasklist.adapter.in.task.dto.AssignTaskDto;
import io.miragon.miranum.platform.tasklist.application.port.in.UserTaskQuery;
import io.miragon.miranum.platform.tasklist.application.port.in.WorkOnTaskUseCase;
import io.miragon.miranum.platform.tasklist.domain.Task;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;

class TaskControllerTest {

private final UserTaskQuery userTaskQuery = mock(UserTaskQuery.class);
private final UserAuthenticationProvider authenticationProvider = mock(UserAuthenticationProvider.class);
private final TaskController taskController = new TaskController(userTaskQuery, authenticationProvider);
private final WorkOnTaskUseCase workOnTaskUseCase = mock(WorkOnTaskUseCase.class);
private final TaskController taskController = new TaskController(userTaskQuery, workOnTaskUseCase, authenticationProvider);

private final String loggedInUser = "testUser";
private final List<Task> exampleTasks = List.of(
Expand Down Expand Up @@ -105,4 +107,20 @@ void test_get_task_by_id() {

assertThat(result).isEqualTo(expectedTask);
}

@Test
void test_assign_task() {
final String taskId = "1";
final String assignee = "testAssignee";
final AssignTaskDto assignTaskDto = new AssignTaskDto(assignee);
taskController.assignTask(taskId, assignTaskDto);
verify(workOnTaskUseCase).assignUserTask(loggedInUser, taskId, assignee);
}

@Test
void test_unasign_task() {
final String taskId = "1";
taskController.unassignTask(taskId);
verify(workOnTaskUseCase).unassignUserTask(loggedInUser, taskId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.miragon.miranum.platform.tasklist.adapter.out.miranum;

import io.miragon.miranum.connect.task.api.command.AssignUserTaskCommand;
import io.miragon.miranum.connect.task.api.exception.TaskOperationFailedException;
import io.miragon.miranum.connect.task.impl.TaskOutPort;
import io.miragon.miranum.platform.tasklist.adapter.out.task.miranum.MiranumTaskAdapter;
import org.apache.commons.lang3.NotImplementedException;
import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.TaskService;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;

class MiranumTaskAdapterTest {

private final TaskService taskService = mock(TaskService.class);
private final TaskOutPort miranumTaskAdapter = new MiranumTaskAdapter(taskService);

@Test
void testAssignUserTask() {
final AssignUserTaskCommand command = AssignUserTaskCommand.builder()
.taskId("1")
.assignee("testUser")
.build();
miranumTaskAdapter.assignUserTask(command);

final ArgumentCaptor<String> taskIdCaptor = ArgumentCaptor.forClass(String.class);
final ArgumentCaptor<String> userCaptor = ArgumentCaptor.forClass(String.class);
verify(taskService).claim(taskIdCaptor.capture(), userCaptor.capture());

assertThat(taskIdCaptor.getValue()).isEqualTo("1");
assertThat(userCaptor.getValue()).isEqualTo("testUser");
}

@Test
void testAssignUserTask_ThrowsTaskOperationFailedException() {
doThrow(new ProcessEngineException("Error")).when(taskService).claim(anyString(), anyString());
assertThrows(TaskOperationFailedException.class, () -> {
final AssignUserTaskCommand command = AssignUserTaskCommand.builder()
.taskId("1")
.assignee("testUser")
.build();
miranumTaskAdapter.assignUserTask(command);
});
}

@Test
void testCompleteTask() {
assertThrows(NotImplementedException.class, () -> miranumTaskAdapter.completeTask(null));
}

@Test
void testCancelUserTask() {
assertThrows(NotImplementedException.class, () -> miranumTaskAdapter.cancelUserTask(null));
}

}
Loading

0 comments on commit dc7d868

Please sign in to comment.