-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MERISK-1179: Add ability to reschedule tasks (#199)
Signed-off-by: Mariia Maksimova <[email protected]>
- Loading branch information
1 parent
9d3af41
commit 69aa3b8
Showing
8 changed files
with
295 additions
and
0 deletions.
There are no files selected for viewing
191 changes: 191 additions & 0 deletions
191
integration-tests/src/test/java/com/transferwise/tasks/testapp/TaskReschedulingIntTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
package com.transferwise.tasks.testapp; | ||
|
||
import static com.transferwise.tasks.domain.TaskStatus.WAITING; | ||
import static org.awaitility.Awaitility.await; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
import com.transferwise.common.baseutils.UuidUtils; | ||
import com.transferwise.tasks.BaseIntTest; | ||
import com.transferwise.tasks.ITaskDataSerializer; | ||
import com.transferwise.tasks.ITasksService; | ||
import com.transferwise.tasks.ITasksService.RescheduleTaskResponse.Result; | ||
import com.transferwise.tasks.dao.ITaskDao; | ||
import com.transferwise.tasks.domain.Task; | ||
import com.transferwise.tasks.domain.TaskStatus; | ||
import com.transferwise.tasks.management.ITasksManagementService; | ||
import com.transferwise.tasks.test.ITestTasksService; | ||
import io.micrometer.core.instrument.Counter; | ||
import java.time.ZonedDateTime; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.EnumSource; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
|
||
@Slf4j | ||
public class TaskReschedulingIntTest extends BaseIntTest { | ||
|
||
@Autowired | ||
private ITasksService tasksService; | ||
@Autowired | ||
private ITestTasksService testTasksService; | ||
@Autowired | ||
private ITaskDataSerializer taskDataSerializer; | ||
@Autowired | ||
private ITasksManagementService tasksManagementService; | ||
@Autowired | ||
private ITaskDao taskDao; | ||
|
||
@BeforeEach | ||
void setup() { | ||
transactionsHelper.withTransaction().asNew().call(() -> { | ||
testTasksService.reset(); | ||
return null; | ||
}); | ||
} | ||
|
||
@Test | ||
void taskCanBeSuccessfullyRescheduled() { | ||
testTaskHandlerAdapter.setProcessor(resultRegisteringSyncTaskProcessor); | ||
UUID taskId = UuidUtils.generatePrefixCombUuid(); | ||
|
||
transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.addTask(new ITasksService.AddTaskRequest() | ||
.setTaskId(taskId) | ||
.setData(taskDataSerializer.serialize("I want to be rescheduled")) | ||
.setType("test").setRunAfterTime(ZonedDateTime.now().plusHours(1))) | ||
); | ||
|
||
await().until(() -> !testTasksService.getWaitingTasks("test", null).isEmpty()); | ||
|
||
var task = tasksManagementService.getTasksById( | ||
new ITasksManagementService.GetTasksByIdRequest().setTaskIds(List.of(taskId)) | ||
).getTasks().stream().filter(t -> t.getTaskVersionId().getId().equals(taskId)).findFirst().orElseThrow(); | ||
|
||
assertTrue(transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.rescheduleTask( | ||
new ITasksService.RescheduleTaskRequest() | ||
.setTaskId(taskId) | ||
.setVersion(task.getTaskVersionId().getVersion()) | ||
.setRunAfterTime(ZonedDateTime.now().minusHours(1)) | ||
).getResult() == Result.OK | ||
)); | ||
|
||
await().until(() -> testTasksService.getTasks("test", null, WAITING).isEmpty()); | ||
await().until(() -> resultRegisteringSyncTaskProcessor.getTaskResults().get(taskId) != null); | ||
assertEquals(0, getFailedNextEventTimeChangeCount()); | ||
assertEquals(1, getTaskRescheduledCount()); | ||
} | ||
|
||
@Test | ||
void taskWillNotBeRescheduleIfVersionHasAlreadyChanged() { | ||
testTaskHandlerAdapter.setProcessor(resultRegisteringSyncTaskProcessor); | ||
final long initialFailedNextEventTimeChangeCount = getFailedNextEventTimeChangeCount(); | ||
final UUID taskId = UuidUtils.generatePrefixCombUuid(); | ||
|
||
transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.addTask(new ITasksService.AddTaskRequest() | ||
.setTaskId(taskId) | ||
.setData(taskDataSerializer.serialize("I want to be rescheduled too!")) | ||
.setType("test").setRunAfterTime(ZonedDateTime.now().plusHours(1))) | ||
); | ||
|
||
await().until(() -> !testTasksService.getWaitingTasks("test", null).isEmpty()); | ||
|
||
var task = tasksManagementService.getTasksById( | ||
new ITasksManagementService.GetTasksByIdRequest().setTaskIds(List.of(taskId)) | ||
).getTasks().stream().filter(t -> t.getTaskVersionId().getId().equals(taskId)).findFirst().orElseThrow(); | ||
|
||
assertFalse( | ||
transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.rescheduleTask( | ||
new ITasksService.RescheduleTaskRequest() | ||
.setTaskId(taskId) | ||
.setVersion(task.getTaskVersionId().getVersion() - 1) | ||
.setRunAfterTime(ZonedDateTime.now().plusHours(2)) | ||
).getResult() == Result.OK | ||
) | ||
); | ||
assertEquals(initialFailedNextEventTimeChangeCount + 1, getFailedNextEventTimeChangeCount()); | ||
assertEquals(0, getTaskRescheduledCount()); | ||
} | ||
|
||
@ParameterizedTest | ||
@EnumSource(value = TaskStatus.class, | ||
names = {"WAITING", "UNKNOWN"}, | ||
mode = EnumSource.Mode.EXCLUDE) | ||
void taskWillNotBeRescheduleIfNotWaiting(TaskStatus status) { | ||
testTaskHandlerAdapter.setProcessor(resultRegisteringSyncTaskProcessor); | ||
final long initialFailedNextEventTimeChangeCount = getFailedNextEventTimeChangeCount(); | ||
final UUID taskId = UuidUtils.generatePrefixCombUuid(); | ||
|
||
transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.addTask(new ITasksService.AddTaskRequest() | ||
.setTaskId(taskId) | ||
.setData(taskDataSerializer.serialize("I do not want to be rescheduled!")) | ||
.setType("test").setRunAfterTime(ZonedDateTime.now().plusHours(2))) | ||
); | ||
|
||
await().until(() -> !testTasksService.getWaitingTasks("test", null).isEmpty()); | ||
List<Task> tasks = testTasksService.getWaitingTasks("test", null); | ||
Task task = tasks.stream().filter(t -> t.getId().equals(taskId)).findFirst().orElseThrow(); | ||
|
||
transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.resumeTask(new ITasksService.ResumeTaskRequest().setTaskId(taskId).setVersion(task.getVersion())) | ||
); | ||
|
||
await().until(() -> testTasksService.getWaitingTasks("test", null).isEmpty()); | ||
|
||
var updateTask = tasksManagementService.getTasksById( | ||
new ITasksManagementService.GetTasksByIdRequest().setTaskIds(List.of(taskId)) | ||
).getTasks().stream().filter(t -> t.getTaskVersionId().getId().equals(taskId)).findFirst().orElseThrow(); | ||
|
||
taskDao.setStatus(taskId, status, updateTask.getTaskVersionId().getVersion()); | ||
|
||
var finalTask = tasksManagementService.getTasksById( | ||
new ITasksManagementService.GetTasksByIdRequest().setTaskIds(List.of(taskId)) | ||
).getTasks().stream().filter(t -> t.getTaskVersionId().getId().equals(taskId)).findFirst().orElseThrow(); | ||
|
||
assertFalse( | ||
transactionsHelper.withTransaction().asNew().call(() -> | ||
tasksService.rescheduleTask( | ||
new ITasksService.RescheduleTaskRequest() | ||
.setTaskId(taskId) | ||
.setVersion(finalTask.getTaskVersionId().getVersion()) | ||
.setRunAfterTime(ZonedDateTime.now().plusHours(2)) | ||
).getResult() == Result.OK | ||
) | ||
); | ||
assertEquals(initialFailedNextEventTimeChangeCount + 1, getFailedNextEventTimeChangeCount()); | ||
assertEquals(0, getTaskRescheduledCount()); | ||
} | ||
|
||
private long getFailedNextEventTimeChangeCount() { | ||
Counter counter = meterRegistry.find("twTasks.tasks.failedNextEventTimeChangeCount").tags( | ||
"taskType", "test" | ||
).counter(); | ||
|
||
if (counter == null) { | ||
return 0; | ||
} else { | ||
return (long) counter.count(); | ||
} | ||
} | ||
|
||
private long getTaskRescheduledCount() { | ||
Counter counter = meterRegistry.find("twTasks.tasks.rescheduledCount").tags( | ||
"taskType", "test" | ||
).counter(); | ||
|
||
if (counter == null) { | ||
return 0; | ||
} else { | ||
return (long) counter.count(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters