Skip to content

Commit

Permalink
add endpoint to get task types (#192)
Browse files Browse the repository at this point in the history
* add endpoint to get task types

* fix style

* accept collection of task types and subtypes
  • Loading branch information
gabrieltaets-tw authored Dec 13, 2023
1 parent 39fc84c commit 91d0660
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 33 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

#### 1.41.0 - 2023/11/16
### Added
- Added `taskType` and `taskSubType` parameters to management query endpoints.
- Added `/getTaskTypes` endpoint to retrieve list of registered task types and sub-types

## 1.40.6 - 2023/11/16
### Fixed

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=1.40.6
version=1.41.0
org.gradle.internal.http.socketTimeout=120000
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void gettingTasksInErrorStatusReturnsTasksInTheLimitOfMaxCount() {
randomProcessingTask().withSubType("3").save();
randomErrorTask().withSubType("4").save();

List<DaoTask1> tasks = managementTaskDao.getTasksInErrorStatus(2);
List<DaoTask1> tasks = managementTaskDao.getTasksInErrorStatus(2, null, null);

assertEquals(2, tasks.size());
for (DaoTask1 task : tasks) {
Expand All @@ -93,7 +93,7 @@ void gettingTasksInProcessingOrWaitingStatusReturnsTasksInTheLimitOfMaxCount() {
randomProcessingTask().withSubType("4").save();
randomWaitingTask().withSubType("5").save();

List<DaoTask3> tasks = managementTaskDao.getTasksInProcessingOrWaitingStatus(3);
List<DaoTask3> tasks = managementTaskDao.getTasksInProcessingOrWaitingStatus(3, null, null);

assertEquals(3, tasks.size());
assertEquals(3, tasks.stream().filter(t -> ImmutableSet.of("1", "3", "4", "5").contains(t.getSubType())).count());
Expand All @@ -114,7 +114,7 @@ void gettingStuckTasksReturnsTasksInTheLimitOfMaxCount() {
randomDoneTask().save();
randomWaitingTask().save();

List<DaoTask2> tasks = managementTaskDao.getStuckTasks(4, Duration.ofMillis(-2));
List<DaoTask2> tasks = managementTaskDao.getStuckTasks(4, null, null, Duration.ofMillis(-2));

assertEquals(4, tasks.size());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public ISyncTaskProcessor.ProcessResult process(ITask task) {
}

List<DaoTask1> error = transactionsHelper.withTransaction().asNew().call(() ->
managementTaskDao.getTasksInErrorStatus(10)
managementTaskDao.getTasksInErrorStatus(10, null, null)
);
boolean taskWasMarkedAsError = error.size() != 0 && error.get(0).getId().equals(taskRef.get().getTaskId());
if (taskWasMarkedAsError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
import com.transferwise.tasks.management.ITasksManagementPort;
import com.transferwise.tasks.management.ITasksManagementPort.GetTaskDataResponse;
import com.transferwise.tasks.management.ITasksManagementPort.GetTaskDataResponse.ResultCode;
import com.transferwise.tasks.management.ITasksManagementPort.GetTaskTypesResponse;
import com.transferwise.tasks.management.ITasksManagementPort.GetTaskWithoutDataResponse;
import com.transferwise.tasks.management.ITasksManagementPort.GetTasksInErrorResponse;
import com.transferwise.tasks.management.ITasksManagementPort.GetTasksInErrorResponse.TaskInError;
import com.transferwise.tasks.management.ITasksManagementPort.GetTasksInProcessingOrWaitingResponse;
import com.transferwise.tasks.management.ITasksManagementPort.GetTasksInProcessingOrWaitingResponse.TaskInProcessingOrWaiting;
import com.transferwise.tasks.management.ITasksManagementPort.GetTasksStuckResponse;
import com.transferwise.tasks.management.ITasksManagementPort.GetTasksStuckResponse.TaskStuck;
import java.time.ZonedDateTime;
Expand Down Expand Up @@ -354,6 +357,167 @@ void immediatelyResumingAllTasksWorks() {
assertFalse(task.getNextEventTime().isAfter(ZonedDateTime.now(TwContextClockHolder.getClock()).plusSeconds(1)));
}

@Test
void filtersErroredTasksByTypeAndSubType() {
final UUID taskId = transactionsHelper.withTransaction().asNew().call(() -> {
TaskTestBuilder.newTask().inStatus(TaskStatus.ERROR).withMaxStuckTime(ZonedDateTime.now().plusDays(2)).save();
TaskTestBuilder.newTask().inStatus(TaskStatus.ERROR).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("B")
.withSubType("SUB")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.ERROR).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.withSubType("BAD")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.ERROR).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withSubType("SUB")
.save();
return TaskTestBuilder.newTask().inStatus(TaskStatus.ERROR).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.withSubType("SUB")
.save()
.getTaskId();
});

ResponseEntity<GetTasksInErrorResponse> response = goodEngineerTemplate().postForEntity(
"/v1/twTasks/getTasksInError",
new ITasksManagementPort.GetTasksInErrorRequest().setMaxCount(10)
.setTaskTypes(List.of("A"))
.setTaskSubTypes(List.of("SUB")),
GetTasksInErrorResponse.class
);

assertEquals(200, response.getStatusCodeValue());
GetTasksInErrorResponse tasksInErrorResponse = response.getBody();
assertNotNull(tasksInErrorResponse);
List<TaskInError> tasksInError = tasksInErrorResponse.getTasksInError();
assertEquals(1, tasksInError.size());
assertEquals(taskId, tasksInError.get(0).getTaskVersionId().getId());
assertEquals("A", tasksInError.get(0).getType());
assertEquals("SUB", tasksInError.get(0).getSubType());
}

@Test
void filtersStuckTasksByTypeAndSubType() {
testTasksService.stopProcessing();

final UUID taskId = transactionsHelper.withTransaction().asNew().call(() -> {
TaskTestBuilder.newTask().inStatus(TaskStatus.PROCESSING).withMaxStuckTime(ZonedDateTime.now().minusDays(2)).save();
TaskTestBuilder.newTask().inStatus(TaskStatus.PROCESSING).withMaxStuckTime(ZonedDateTime.now().minusDays(2))
.withType("B")
.withSubType("SUB")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.PROCESSING).withMaxStuckTime(ZonedDateTime.now().minusDays(2))
.withType("A")
.withSubType("BAD")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.PROCESSING).withMaxStuckTime(ZonedDateTime.now().minusDays(2))
.withSubType("SUB")
.save();
return TaskTestBuilder.newTask().inStatus(TaskStatus.PROCESSING).withMaxStuckTime(ZonedDateTime.now().minusDays(2))
.withType("A")
.withSubType("SUB")
.save()
.getTaskId();
});

ResponseEntity<ITasksManagementPort.GetTasksStuckResponse> response = goodEngineerTemplate().postForEntity(
"/v1/twTasks/getTasksStuck",
new ITasksManagementPort.GetTasksStuckRequest().setMaxCount(10)
.setTaskTypes(List.of("A"))
.setTaskSubTypes(List.of("SUB")),
ITasksManagementPort.GetTasksStuckResponse.class
);

assertEquals(200, response.getStatusCodeValue());
GetTasksStuckResponse stuckTasksResponse = response.getBody();
assertNotNull(stuckTasksResponse);
List<TaskStuck> tasksStuck = stuckTasksResponse.getTasksStuck();
assertEquals(1, tasksStuck.size());
assertEquals(taskId, tasksStuck.get(0).getTaskVersionId().getId());
}

@Test
void filtersWaitingTasksByTypeAndSubType() {
final UUID taskId = transactionsHelper.withTransaction().asNew().call(() -> {
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2)).save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("B")
.withSubType("SUB")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.withSubType("BAD")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withSubType("SUB")
.save();
return TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.withSubType("SUB")
.save()
.getTaskId();
});

ResponseEntity<GetTasksInProcessingOrWaitingResponse> response = goodEngineerTemplate().postForEntity(
"/v1/twTasks/getTasksInProcessingOrWaiting",
new ITasksManagementPort.GetTasksInProcessingOrWaitingRequest().setMaxCount(10)
.setTaskTypes(List.of("A"))
.setTaskSubTypes(List.of("SUB")),
GetTasksInProcessingOrWaitingResponse.class
);

assertEquals(
200, response.getStatusCodeValue());
GetTasksInProcessingOrWaitingResponse waitingTasksResponse = response.getBody();
assertNotNull(waitingTasksResponse);
List<TaskInProcessingOrWaiting> tasksWaiting = waitingTasksResponse.getTasksInProcessingOrWaiting();
assertEquals(1, tasksWaiting.size());
assertEquals(taskId, tasksWaiting.get(0).getTaskVersionId().getId());
assertEquals("A", tasksWaiting.get(0).getType());
assertEquals("SUB", tasksWaiting.get(0).getSubType());
}

@Test
void getTaskTypesWillReturnCorrectly() {
transactionsHelper.withTransaction().asNew().run(() -> {
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.withSubType("SUB-2")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.withSubType("SUB-1")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("B")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("A")
.save();
TaskTestBuilder.newTask().inStatus(TaskStatus.WAITING).withMaxStuckTime(ZonedDateTime.now().plusDays(2))
.withType("B")
.save();
});

ResponseEntity<GetTaskTypesResponse> response = goodEngineerTemplate().getForEntity(
"/v1/twTasks/getTaskTypes",
GetTaskTypesResponse.class
);

assertEquals(200, response.getStatusCodeValue());
GetTaskTypesResponse typesResponse = response.getBody();
assertNotNull(typesResponse);
List<GetTaskTypesResponse.TaskType> types = typesResponse.getTypes();
assertEquals(2, types.size());
assertEquals("A", types.get(0).getType());
assertEquals("B", types.get(1).getType());
assertEquals(2, types.get(0).getSubTypes().size());
assertEquals("SUB-1", types.get(0).getSubTypes().get(0));
assertEquals("SUB-2", types.get(0).getSubTypes().get(1));
assertTrue(types.get(1).getSubTypes().isEmpty());
}

private TestRestTemplate goodEngineerTemplate() {
return testRestTemplate.withBasicAuth("goodEngineer", "q1w2e3r4");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ ResponseEntity<GetTasksInProcessingOrWaitingResponse> getTasksInProcessingOrWait
@ResponseBody
ResponseEntity<GetTasksByIdResponse> getTasksById(@RequestBody GetTasksByIdRequest request);

@GetMapping(value = "${tw-tasks.core.base-url:}/v1/twTasks/getTaskTypes", produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
ResponseEntity<GetTaskTypesResponse> getTaskTypes();


@Data
@Accessors(chain = true)
class GetTasksByIdRequest {
Expand Down Expand Up @@ -186,15 +191,18 @@ class GetTaskWithoutDataResponse {
@Data
@Accessors(chain = true)
class GetTasksInErrorRequest {

private int maxCount;
List<String> taskTypes;
List<String> taskSubTypes;
}

@Data
@Accessors(chain = true)
class GetTasksInProcessingOrWaitingRequest {

private int maxCount;
List<String> taskTypes;
List<String> taskSubTypes;
}

@Data
Expand Down Expand Up @@ -241,6 +249,8 @@ public static class TaskInError {
class GetTasksStuckRequest {

private int maxCount;
List<String> taskTypes;
List<String> taskSubTypes;
}

@Data
Expand All @@ -257,4 +267,17 @@ public static class TaskStuck {
private Instant stuckTime;
}
}

@Data
@Accessors(chain = true)
class GetTaskTypesResponse {
private List<TaskType> types;

@Data
@Accessors(chain = true)
public static class TaskType {
private String type;
private List<String> subTypes;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ public static class Result {
class GetTasksInErrorRequest {

private int maxCount;
private List<String> taskTypes;
private List<String> taskSubTypes;
}

@Data
Expand Down Expand Up @@ -137,6 +139,8 @@ class GetTasksStuckRequest {

private int maxCount;
private Duration delta;
private List<String> taskTypes;
private List<String> taskSubTypes;
}

@Data
Expand All @@ -161,6 +165,8 @@ public static class TaskStuck {
class GetTasksInProcessingOrWaitingRequest {

private int maxCount = 10;
private List<String> taskTypes;
private List<String> taskSubTypes;
}

@Data
Expand Down Expand Up @@ -207,4 +213,19 @@ public static class Task {
private Instant stateTime;
}
}

GetTaskTypesResponse getTaskTypes();

@Data
@Accessors(chain = true)
class GetTaskTypesResponse {
private List<TaskType> types;

@Data
@Accessors(chain = true)
public static class TaskType {
private String type;
private List<String> subTypes;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public final class ManagementEntryPointNames {
public static final String MARK_AS_FAILED = "markAsFailed";
public static final String GET_TASK_WITHOUT_DATA = "getTaskWithoutData";
public static final String GET_TASK_DATA = "getTaskData";
public static final String GET_TASKS_TYPES = "getTasksTypes";

private ManagementEntryPointNames() {
throw new AssertionError();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public ResponseEntity<GetTasksInErrorResponse> getTasksInError(@RequestBody(requ
return callWithAuthentication(() -> {
ITasksManagementService.GetTasksInErrorResponse serviceResponse = tasksManagementService
.getTasksInError(new ITasksManagementService.GetTasksInErrorRequest()
.setTaskTypes(request != null ? request.getTaskTypes() : null)
.setTaskSubTypes(request != null ? request.getTaskSubTypes() : null)
.setMaxCount(request != null ? request.getMaxCount() : DEFAULT_MAX_COUNT));

return ResponseEntity.ok(new GetTasksInErrorResponse().setTasksInError(serviceResponse.getTasksInError().stream().map(taskInError ->
Expand Down Expand Up @@ -140,6 +142,8 @@ public ResponseEntity<GetTasksInProcessingOrWaitingResponse> getTasksInProcessin
return callWithAuthentication(() -> {
ITasksManagementService.GetTasksInProcessingOrWaitingResponse serviceResponse = tasksManagementService
.getTasksInProcessingOrWaiting(new ITasksManagementService.GetTasksInProcessingOrWaitingRequest()
.setTaskTypes(request != null ? request.getTaskTypes() : null)
.setTaskSubTypes(request != null ? request.getTaskSubTypes() : null)
.setMaxCount(request != null ? request.getMaxCount() : DEFAULT_MAX_COUNT));

return ResponseEntity.ok(new GetTasksInProcessingOrWaitingResponse()
Expand Down Expand Up @@ -184,6 +188,8 @@ public ResponseEntity<GetTasksStuckResponse> getTasksStuck(@RequestBody(required
return callWithAuthentication(() -> {
ITasksManagementService.GetTasksStuckResponse serviceResponse = tasksManagementService
.getTasksStuck(new ITasksManagementService.GetTasksStuckRequest()
.setTaskTypes(request != null ? request.getTaskTypes() : null)
.setTaskSubTypes(request != null ? request.getTaskSubTypes() : null)
.setMaxCount(request != null ? request.getMaxCount() : DEFAULT_MAX_COUNT));

return ResponseEntity.ok(new GetTasksStuckResponse().setTasksStuck(serviceResponse.getTasksStuck().stream().map(taskStuck ->
Expand All @@ -192,6 +198,16 @@ public ResponseEntity<GetTasksStuckResponse> getTasksStuck(@RequestBody(required
});
}

@Override
public ResponseEntity<GetTaskTypesResponse> getTaskTypes() {
return callWithAuthentication(() -> {
ITasksManagementService.GetTaskTypesResponse serviceResponse = tasksManagementService.getTaskTypes();

return ResponseEntity.ok(new GetTaskTypesResponse().setTypes(serviceResponse.getTypes().stream().map(type ->
new GetTaskTypesResponse.TaskType().setType(type.getType()).setSubTypes(type.getSubTypes())).collect(Collectors.toList())));
});
}

protected <T> T callWithAuthentication(Supplier<T> supplier) {
return callWithAuthentication(tasksProperties.getTasksManagement().getRoles(), (auth) -> supplier.get());
}
Expand Down
Loading

0 comments on commit 91d0660

Please sign in to comment.