This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 3b040cad230da8e3b4dbb260bfcdbed2a16992d2 Author: Benoit Tellier <[email protected]> AuthorDate: Thu May 23 18:10:15 2019 +0700 MAILBOX-351 WebAdmin route to allow me to reIndex previous tasks failures --- .../org/apache/james/webadmin/dto/TaskIdDto.java | 2 +- .../apache/james/webadmin/routes/TasksRoutes.java | 3 +- .../apache/james/webadmin/dto/TaskIdDtoTest.java | 4 +- .../james/webadmin/routes/TasksRoutesTest.java | 4 +- .../james/webadmin/routes/ReindexingRoutes.java | 76 ++++++- .../service/PreviousReIndexingService.java | 60 ++++++ .../webadmin/routes/ReindexingRoutesTest.java | 222 +++++++++++++++++++++ .../main/java/org/apache/james/task/TaskId.java | 17 +- .../java/org/apache/james/task/TaskManager.java | 22 +- 9 files changed, 389 insertions(+), 21 deletions(-) diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/dto/TaskIdDto.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/dto/TaskIdDto.java index 35f88e9..fbb74f0 100644 --- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/dto/TaskIdDto.java +++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/dto/TaskIdDto.java @@ -33,7 +33,7 @@ public class TaskIdDto { public static TaskIdDto respond(Response response, TaskId taskId) { response.status(HttpStatus.CREATED_201); - response.header(LOCATION.asString(), TasksRoutes.BASE + "/" + taskId.getValue()); + response.header(LOCATION.asString(), TasksRoutes.BASE + "/" + taskId.asString()); return TaskIdDto.from(taskId); } diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/TasksRoutes.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/TasksRoutes.java index 7dd1204..84f6eff 100644 --- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/TasksRoutes.java +++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/routes/TasksRoutes.java @@ -21,7 +21,6 @@ package org.apache.james.webadmin.routes; import java.util.List; import java.util.Optional; -import java.util.UUID; import java.util.function.Supplier; import javax.inject.Inject; @@ -172,7 +171,7 @@ public class TasksRoutes implements Routes { private TaskId getTaskId(Request req) { try { String id = req.params("id"); - return new TaskId(UUID.fromString(id)); + return TaskId.fromString(id); } catch (Exception e) { throw ErrorResponder.builder() .statusCode(HttpStatus.BAD_REQUEST_400) diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/dto/TaskIdDtoTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/dto/TaskIdDtoTest.java index 5f85a54..3a593eb 100644 --- a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/dto/TaskIdDtoTest.java +++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/dto/TaskIdDtoTest.java @@ -24,8 +24,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import java.util.UUID; - import org.apache.james.task.TaskId; import org.eclipse.jetty.http.HttpStatus; import org.junit.Test; @@ -38,7 +36,7 @@ public class TaskIdDtoTest { @Test public void respondShouldReturnCreatedWithTaskIdHeader() { Response response = mock(Response.class); - TaskId taskId = new TaskId(UUID.fromString(UID_VALUE)); + TaskId taskId = TaskId.fromString(UID_VALUE); TaskIdDto.respond(response, taskId); diff --git a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/routes/TasksRoutesTest.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/routes/TasksRoutesTest.java index 39947c0..1642068 100644 --- a/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/routes/TasksRoutesTest.java +++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/routes/TasksRoutesTest.java @@ -99,7 +99,7 @@ public class TasksRoutesTest { .statusCode(HttpStatus.OK_200) .body("", hasSize(1)) .body("[0].status", is(TaskManager.Status.IN_PROGRESS.getValue())) - .body("[0].taskId", is(taskId.getValue().toString())) + .body("[0].taskId", is(taskId.asString())) .body("[0].class", is(not(empty()))); } @@ -130,7 +130,7 @@ public class TasksRoutesTest { .statusCode(HttpStatus.OK_200) .body("", hasSize(1)) .body("[0].status", is(TaskManager.Status.IN_PROGRESS.getValue())) - .body("[0].taskId", is(taskId.getValue().toString())) + .body("[0].taskId", is(taskId.asString())) .body("[0].type", is(Task.UNKNOWN)); } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/ReindexingRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/ReindexingRoutes.java index 8c5a773..083579e 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/ReindexingRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/ReindexingRoutes.java @@ -28,13 +28,16 @@ import org.apache.james.core.User; import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.exception.MailboxNotFoundException; +import org.apache.james.mailbox.indexer.IndexingDetailInformation; import org.apache.james.mailbox.indexer.ReIndexer; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.task.Task; import org.apache.james.task.TaskId; import org.apache.james.task.TaskManager; +import org.apache.james.task.TaskNotFoundException; import org.apache.james.webadmin.Routes; import org.apache.james.webadmin.dto.TaskIdDto; +import org.apache.james.webadmin.service.PreviousReIndexingService; import org.apache.james.webadmin.utils.ErrorResponder; import org.apache.james.webadmin.utils.JsonTransformer; import org.eclipse.jetty.http.HttpStatus; @@ -62,19 +65,22 @@ public class ReindexingRoutes implements Routes { private static final String BASE_PATH = "/mailboxes"; private static final String USER_QUERY_PARAM = "user"; + private static final String RE_INDEX_FAILED_MESSAGES_QUERY_PARAM = "reIndexFailedMessagesOf"; private static final String MAILBOX_PARAM = ":mailbox"; private static final String UID_PARAM = ":uid"; private static final String MAILBOX_PATH = BASE_PATH + "/" + MAILBOX_PARAM; private static final String MESSAGE_PATH = MAILBOX_PATH + "/mails/" + UID_PARAM; private final TaskManager taskManager; + private final PreviousReIndexingService previousReIndexingService; private final MailboxId.Factory mailboxIdFactory; private final ReIndexer reIndexer; private final JsonTransformer jsonTransformer; @Inject - ReindexingRoutes(TaskManager taskManager, MailboxId.Factory mailboxIdFactory, ReIndexer reIndexer, JsonTransformer jsonTransformer) { + ReindexingRoutes(TaskManager taskManager, PreviousReIndexingService previousReIndexingService, MailboxId.Factory mailboxIdFactory, ReIndexer reIndexer, JsonTransformer jsonTransformer) { this.taskManager = taskManager; + this.previousReIndexingService = previousReIndexingService; this.mailboxIdFactory = mailboxIdFactory; this.reIndexer = reIndexer; this.jsonTransformer = jsonTransformer; @@ -110,7 +116,15 @@ public class ReindexingRoutes implements Routes { dataType = "String", defaultValue = "none", example = "?user=toto%40domain.tld", - value = "optional. If present, only mailboxes of that user will be reIndexed.") + value = "optional. If present, only mailboxes of that user will be reIndexed."), + @ApiImplicitParam( + name = "reIndexFailedMessagesOf", + paramType = "query parameter", + dataType = "String", + defaultValue = "none", + example = "?reIndexFailedMessagesOf=3294a976-ce63-491e-bd52-1b6f465ed7a2", + value = "optional. References a previously run reIndexing task. if present, the messages that this previous " + + "task failed to index will be reIndexed.") }) @ApiResponses(value = { @ApiResponse(code = HttpStatus.CREATED_201, message = "Task is created", response = TaskIdDto.class), @@ -118,10 +132,62 @@ public class ReindexingRoutes implements Routes { @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Bad request - details in the returned error message") }) private TaskIdDto reIndexAll(Request request, Response response) { - if (Strings.isNullOrEmpty(request.queryParams(USER_QUERY_PARAM))) { - return wrap(request, response, reIndexer::reIndex); + boolean userReIndexing = !Strings.isNullOrEmpty(request.queryParams(USER_QUERY_PARAM)); + boolean indexingCorrection = !Strings.isNullOrEmpty(request.queryParams(RE_INDEX_FAILED_MESSAGES_QUERY_PARAM)); + if (userReIndexing && indexingCorrection) { + return rejectInvalidQueryParameterCombination(); + } + if (userReIndexing) { + return wrap(request, response, () -> reIndexer.reIndex(extractUser(request))); + } + if (indexingCorrection) { + IndexingDetailInformation indexingDetailInformation = retrieveIndexingExecutionDetails(request); + return wrap(request, response, () -> reIndexer.reIndex(indexingDetailInformation.failures())); + } + return wrap(request, response, reIndexer::reIndex); + } + + private IndexingDetailInformation retrieveIndexingExecutionDetails(Request request) { + TaskId taskId = getTaskId(request); + try { + return previousReIndexingService.retrieveIndexingExecutionDetails(taskId); + } catch (PreviousReIndexingService.NotAnIndexingRetryiableTask | PreviousReIndexingService.TaskNotYetFinishedException e) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message("Invalid task id") + .cause(e) + .haltError(); + } catch (TaskNotFoundException e) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message("TaskId " + taskId.asString() + " does not exist") + .cause(e) + .haltError(); + } + } + + private TaskId getTaskId(Request request) { + try { + String id = request.queryParams(RE_INDEX_FAILED_MESSAGES_QUERY_PARAM); + return TaskId.fromString(id); + } catch (Exception e) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .cause(e) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message("Invalid task id") + .haltError(); } - return wrap(request, response, () -> reIndexer.reIndex(extractUser(request))); + } + + private TaskIdDto rejectInvalidQueryParameterCombination() { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message("Can not specify '" + USER_QUERY_PARAM + "' and '" + RE_INDEX_FAILED_MESSAGES_QUERY_PARAM + "' query parameters at the same time") + .haltError(); } @POST diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/PreviousReIndexingService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/PreviousReIndexingService.java new file mode 100644 index 0000000..2df5879 --- /dev/null +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/PreviousReIndexingService.java @@ -0,0 +1,60 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); 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.apache.james.webadmin.service; + +import javax.inject.Inject; + +import org.apache.james.mailbox.indexer.IndexingDetailInformation; +import org.apache.james.task.TaskExecutionDetails; +import org.apache.james.task.TaskId; +import org.apache.james.task.TaskManager; +import org.apache.james.task.TaskNotFoundException; + +public class PreviousReIndexingService { + public static class TaskNotYetFinishedException extends RuntimeException { + TaskNotYetFinishedException(TaskManager.Status currentStatus) { + super("Task is not yet finished. Current status is: " + currentStatus); + } + } + + public static class NotAnIndexingRetryiableTask extends RuntimeException { + NotAnIndexingRetryiableTask(String type) { + super("'" + type + "' is not a valid type of task for retrying a failed indexing"); + } + } + + private final TaskManager taskManager; + + @Inject + public PreviousReIndexingService(TaskManager taskManager) { + this.taskManager = taskManager; + } + + public IndexingDetailInformation retrieveIndexingExecutionDetails(TaskId taskId) throws NotAnIndexingRetryiableTask, TaskNotFoundException, TaskNotYetFinishedException { + TaskExecutionDetails executionDetails = taskManager.getExecutionDetails(taskId); + if (!executionDetails.getStatus().isFinished()) { + throw new TaskNotYetFinishedException(executionDetails.getStatus()); + } + return executionDetails.getAdditionalInformation() + .filter(additionalInformation -> additionalInformation instanceof IndexingDetailInformation) + .map(additionalInformation -> (IndexingDetailInformation) additionalInformation) + .orElseThrow(() -> new NotAnIndexingRetryiableTask(executionDetails.getType())); + } +} diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ReindexingRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ReindexingRoutesTest.java index e0af217..091ddb9 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ReindexingRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/ReindexingRoutesTest.java @@ -27,7 +27,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -48,6 +51,7 @@ import org.apache.james.metrics.logger.DefaultMetricFactory; import org.apache.james.task.MemoryTaskManager; import org.apache.james.webadmin.WebAdminServer; import org.apache.james.webadmin.WebAdminUtils; +import org.apache.james.webadmin.service.PreviousReIndexingService; import org.apache.james.webadmin.utils.ErrorResponder; import org.apache.james.webadmin.utils.JsonTransformer; import org.apache.mailbox.tools.indexer.FullReindexingTask; @@ -94,6 +98,7 @@ class ReindexingRoutesTest { new TasksRoutes(taskManager, jsonTransformer), new ReindexingRoutes( taskManager, + new PreviousReIndexingService(taskManager), mailboxIdFactory, reIndexer, jsonTransformer), @@ -828,4 +833,221 @@ class ReindexingRoutesTest { } } } + + @Nested + class FixingReIndexing { + @Nested + class Validation { + @Test + void fixingReIndexingShouldThrowOnMissingTaskQueryParameter() { + String taskId = with() + .post("/mailboxes?task=reIndex") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(taskId + "/await"); + + given() + .queryParam("reIndexFailedMessagesOf", taskId) + .when() + .post("/mailboxes") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .body("statusCode", is(400)) + .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType())) + .body("message", is("task query parameter is mandatory. The only supported value is `reIndex`")); + } + + @Test + void fixingReIndexingShouldThrowOnUserParameter() { + String taskId = with() + .post("/mailboxes?task=reIndex") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(taskId + "/await"); + + given() + .queryParam("reIndexFailedMessagesOf", taskId) + .queryParam("task", "reIndex") + .queryParam("user", "[email protected]") + .when() + .post("/mailboxes") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .body("statusCode", is(400)) + .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType())) + .body("message", is("Can not specify 'user' and 'reIndexFailedMessagesOf' query parameters at the same time")); + } + + @Test + void fixingReIndexingShouldFailWithBadTask() { + String taskId = with() + .post("/mailboxes?task=reIndex") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(taskId + "/await"); + + given() + .queryParam("reIndexFailedMessagesOf", taskId) + .when() + .post("/mailboxes?task=bad") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .body("statusCode", is(400)) + .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType())) + .body("message", is("task query parameter is mandatory. The only supported value is `reIndex`")); + } + + @Test + void fixingReIndexingShouldRejectNotExistingTask() { + String taskId = "bbdb69c9-082a-44b0-a85a-6e33e74287a5"; + + given() + .queryParam("reIndexFailedMessagesOf", taskId) + .when() + .post("/mailboxes?task=bad") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .body("statusCode", is(400)) + .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType())) + .body("message", is("TaskId bbdb69c9-082a-44b0-a85a-6e33e74287a5 does not exist")); + } + } + + @Nested + class TaskDetails { + @Test + void fixingReIndexingShouldNotFailWhenNoMail() { + String taskId = with() + .post("/mailboxes?task=reIndex") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(taskId + "/await"); + + String fixingTaskId = with() + .queryParam("reIndexFailedMessagesOf", taskId) + .queryParam("task", "reIndex") + .post("/mailboxes") + .jsonPath() + .get("taskId"); + + given() + .basePath(TasksRoutes.BASE) + .when() + .get(fixingTaskId + "/await") + .then() + .body("status", is("completed")) + .body("taskId", is(notNullValue())) + .body("type", is("ReIndexPreviousFailures")) + .body("additionalInformation.successfullyReprocessMailCount", is(0)) + .body("additionalInformation.failedReprocessedMailCount", is(0)) + .body("startedDate", is(notNullValue())) + .body("submitDate", is(notNullValue())) + .body("completedDate", is(notNullValue())); + } + + @Test + void fixingReIndexingShouldReturnTaskDetailsWhenMail() throws Exception { + MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); + mailboxManager.createMailbox(INBOX, systemSession).get(); + mailboxManager.getMailbox(INBOX, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"), + systemSession); + + doThrow(new RuntimeException()).when(searchIndex).add(any(MailboxSession.class), any(Mailbox.class), any(MailboxMessage.class)); + + String taskId = with() + .post("/mailboxes?task=reIndex") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(taskId + "/await"); + + doNothing().when(searchIndex).add(any(MailboxSession.class), any(Mailbox.class), any(MailboxMessage.class)); + + String fixingTaskId = with() + .queryParam("reIndexFailedMessagesOf", taskId) + .queryParam("task", "reIndex") + .post("/mailboxes") + .jsonPath() + .get("taskId"); + + given() + .basePath(TasksRoutes.BASE) + .when() + .get(fixingTaskId + "/await") + .then() + .body("status", is("completed")) + .body("taskId", is(notNullValue())) + .body("type", is("ReIndexPreviousFailures")) + .body("additionalInformation.successfullyReprocessMailCount", is(1)) + .body("additionalInformation.failedReprocessedMailCount", is(0)) + .body("startedDate", is(notNullValue())) + .body("submitDate", is(notNullValue())) + .body("completedDate", is(notNullValue())); + } + } + + @Nested + class SideEffects { + @Test + void fixingReprocessingShouldPerformReprocessingWhenMail() throws Exception { + MailboxSession systemSession = mailboxManager.createSystemSession(USERNAME); + MailboxId mailboxId = mailboxManager.createMailbox(INBOX, systemSession).get(); + ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession) + .appendMessage( + MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"), + systemSession); + + doThrow(new RuntimeException()).when(searchIndex).add(any(MailboxSession.class), any(Mailbox.class), any(MailboxMessage.class)); + + String taskId = with() + .post("/mailboxes?task=reIndex") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(taskId + "/await"); + + reset(searchIndex); + + String fixingTaskId = with() + .queryParam("reIndexFailedMessagesOf", taskId) + .queryParam("task", "reIndex") + .post("/mailboxes") + .jsonPath() + .get("taskId"); + + with() + .basePath(TasksRoutes.BASE) + .get(fixingTaskId + "/await") + .then() + .body("status", is("completed")); + + ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class); + ArgumentCaptor<Mailbox> mailboxCaptor = ArgumentCaptor.forClass(Mailbox.class); + verify(searchIndex).add(any(MailboxSession.class), mailboxCaptor.capture(), messageCaptor.capture()); + verifyNoMoreInteractions(searchIndex); + + assertThat(mailboxCaptor.getValue()).matches(mailbox -> mailbox.getMailboxId().equals(mailboxId)); + assertThat(messageCaptor.getValue()).matches(message -> message.getMailboxId().equals(mailboxId) + && message.getUid().equals(createdMessage.getUid())); + } + } + } } \ No newline at end of file diff --git a/server/task/src/main/java/org/apache/james/task/TaskId.java b/server/task/src/main/java/org/apache/james/task/TaskId.java index 4b66feb..3f30712 100644 --- a/server/task/src/main/java/org/apache/james/task/TaskId.java +++ b/server/task/src/main/java/org/apache/james/task/TaskId.java @@ -23,11 +23,22 @@ import java.util.Objects; import java.util.UUID; import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; public class TaskId { public static TaskId generateTaskId() { - return new TaskId(UUID.randomUUID()); + return fromUUID(UUID.randomUUID()); + } + + public static TaskId fromUUID(UUID uuid) { + Preconditions.checkNotNull(uuid, "'uuid' should not be null"); + return new TaskId(uuid); + } + + public static TaskId fromString(String uuid) { + Preconditions.checkNotNull(uuid, "'uuid' should not be null"); + return fromUUID(UUID.fromString(uuid)); } private final UUID value; @@ -40,6 +51,10 @@ public class TaskId { return value; } + public String asString() { + return value.toString(); + } + @Override public final boolean equals(Object o) { if (o instanceof TaskId) { diff --git a/server/task/src/main/java/org/apache/james/task/TaskManager.java b/server/task/src/main/java/org/apache/james/task/TaskManager.java index de3e16b..b04f2c2 100644 --- a/server/task/src/main/java/org/apache/james/task/TaskManager.java +++ b/server/task/src/main/java/org/apache/james/task/TaskManager.java @@ -23,13 +23,15 @@ import java.util.Arrays; import java.util.List; public interface TaskManager { + boolean FINISHED = true; + enum Status { - WAITING("waiting"), - IN_PROGRESS("inProgress"), - COMPLETED("completed"), - CANCEL_REQUESTED("canceledRequested"), - CANCELLED("canceled"), - FAILED("failed"); + WAITING("waiting", !FINISHED), + IN_PROGRESS("inProgress", !FINISHED), + CANCEL_REQUESTED("canceledRequested", !FINISHED), + COMPLETED("completed", FINISHED), + CANCELLED("canceled", FINISHED), + FAILED("failed", FINISHED); public static Status fromString(String value) { return Arrays.stream(values()) @@ -40,14 +42,20 @@ public interface TaskManager { } private final String value; + private final boolean finished; - Status(String value) { + Status(String value, boolean finished) { this.value = value; + this.finished = finished; } public String getValue() { return value; } + + public boolean isFinished() { + return finished; + } } TaskId submit(Task task); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
