You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/03/12 03:19:51 UTC
[james-project] 13/15: JAMES-2663 Adding action parameter to
restoring API path
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 8ccfd9c1f0c8bb839785d2885d1586d8f5d4377f
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue Mar 5 15:15:03 2019 +0700
JAMES-2663 Adding action parameter to restoring API path
---
.../vault/routes/DeletedMessagesVaultRoutes.java | 92 ++++++++++++++++++----
.../routes/DeletedMessagesVaultRoutesTest.java | 78 +++++++++++++++++-
src/site/markdown/server/manage-webadmin.md | 13 ++-
3 files changed, 160 insertions(+), 23 deletions(-)
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutes.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutes.java
index 3fc748a..edca31a 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutes.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutes.java
@@ -21,22 +21,31 @@ package org.apache.james.webadmin.vault.routes;
import static org.apache.james.webadmin.Constants.SEPARATOR;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+
import javax.inject.Inject;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.commons.lang3.StringUtils;
import org.apache.james.core.User;
+import org.apache.james.task.Task;
import org.apache.james.task.TaskId;
import org.apache.james.task.TaskManager;
import org.apache.james.webadmin.Constants;
import org.apache.james.webadmin.Routes;
import org.apache.james.webadmin.dto.TaskIdDto;
-import org.apache.james.webadmin.utils.ErrorResponder;
import org.apache.james.webadmin.utils.JsonTransformer;
import org.eclipse.jetty.http.HttpStatus;
+import com.github.steveash.guavate.Guavate;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -53,9 +62,39 @@ import spark.Service;
@Produces(Constants.JSON_CONTENT_TYPE)
public class DeletedMessagesVaultRoutes implements Routes {
+ enum UserVaultAction {
+ RESTORE("restore");
+
+ static Optional<UserVaultAction> getAction(String value) {
+ Preconditions.checkNotNull(value, "action cannot be null");
+ Preconditions.checkArgument(StringUtils.isNotBlank(value), "action cannot be empty or blank");
+
+ return Stream.of(values())
+ .filter(action -> action.value.equals(value))
+ .findFirst();
+ }
+
+ private static List<String> plainValues() {
+ return Stream.of(values())
+ .map(UserVaultAction::getValue)
+ .collect(Guavate.toImmutableList());
+ }
+
+ private final String value;
+
+ UserVaultAction(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ }
+
public static final String ROOT_PATH = "deletedMessages/user";
private static final String USER_PATH_PARAM = "user";
private static final String RESTORE_PATH = ROOT_PATH + SEPARATOR + ":" + USER_PATH_PARAM;
+ private static final String ACTION_QUERY_PARAM = "action";
private final RestoreService vaultRestore;
private final JsonTransformer jsonTransformer;
@@ -77,7 +116,7 @@ public class DeletedMessagesVaultRoutes implements Routes {
@Override
public void define(Service service) {
- service.post(RESTORE_PATH, this::restore, jsonTransformer);
+ service.post(RESTORE_PATH, this::userActions, jsonTransformer);
}
@POST
@@ -91,28 +130,51 @@ public class DeletedMessagesVaultRoutes implements Routes {
dataType = "String",
defaultValue = "none",
example = "user@james.org",
- value = "Compulsory. Needs to be a valid username represent for an user had requested to restore deleted emails")
+ value = "Compulsory. Needs to be a valid username represent for an user had requested to restore deleted emails"),
+ @ApiImplicitParam(
+ required = true,
+ dataType = "String",
+ name = "action",
+ paramType = "query",
+ example = "?action=restore",
+ value = "Compulsory. Needs to be a valid action represent for an operation to perform on the Deleted Message Vault, " +
+ "valid action should be in the list (restore)")
})
@ApiResponses(value = {
@ApiResponse(code = HttpStatus.CREATED_201, message = "Task is created", response = TaskIdDto.class),
@ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Bad request - user param is invalid"),
@ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Internal server error - Something went bad on the server side.")
})
- private TaskIdDto restore(Request request, Response response) {
- User userToRestore = extractUser(request);
- TaskId taskId = taskManager.submit(new DeletedMessagesVaultRestoreTask(userToRestore, vaultRestore));
+ private TaskIdDto userActions(Request request, Response response) {
+ UserVaultAction requestedAction = extractUserVaultAction(request);
+
+ Task requestedTask = generateTask(requestedAction, request);
+ TaskId taskId = taskManager.submit(requestedTask);
return TaskIdDto.respond(response, taskId);
}
- private User extractUser(Request request) {
- try {
- return User.fromUsername(request.params(USER_PATH_PARAM));
- } catch (IllegalArgumentException e) {
- throw ErrorResponder.builder()
- .statusCode(HttpStatus.BAD_REQUEST_400)
- .type(ErrorResponder.ErrorType.INVALID_ARGUMENT)
- .message(e.getMessage())
- .haltError();
+ private Task generateTask(UserVaultAction requestedAction, Request request) {
+ User userToRestore = User.fromUsername(request.params(USER_PATH_PARAM));
+
+ switch (requestedAction) {
+ case RESTORE:
+ return new DeletedMessagesVaultRestoreTask(userToRestore, vaultRestore);
+ default:
+ throw new NotImplementedException(requestedAction + " is not yet handled.");
}
}
+
+ private UserVaultAction extractUserVaultAction(Request request) {
+ String actionParam = request.queryParams(ACTION_QUERY_PARAM);
+ return Optional.ofNullable(actionParam)
+ .map(this::getUserVaultAction)
+ .orElseThrow(() -> new IllegalArgumentException("action parameter is missing"));
+ }
+
+ private UserVaultAction getUserVaultAction(String actionString) {
+ return UserVaultAction.getAction(actionString)
+ .orElseThrow(() -> new IllegalArgumentException(String.format("'%s' is not a valid action. Supported values are: (%s)",
+ actionString,
+ Joiner.on(",").join(UserVaultAction.plainValues()))));
+ }
}
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java
index 7349d5a..460e3c2 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java
@@ -116,19 +116,78 @@ class DeletedMessagesVaultRoutesTest {
class ValidationTest {
@Test
- void restoreShouldReturnInvalidWhenUserIsInvalid() {
+ void restoreShouldReturnInvalidWhenActionIsMissing() {
when()
+ .post(USER.asString())
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is(notNullValue()))
+ .body("details", is(notNullValue()));
+ }
+
+ @Test
+ void restoreShouldReturnInvalidWhenPassingEmptyAction() {
+ given()
+ .queryParam("action", "")
+ .when()
+ .post(USER.asString())
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is(notNullValue()))
+ .body("details", is(notNullValue()));
+ }
+
+ @Test
+ void restoreShouldReturnInvalidWhenActionIsInValid() {
+ given()
+ .queryParam("action", "invalid action")
+ .when()
+ .post(USER.asString())
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is(notNullValue()))
+ .body("details", is(notNullValue()));
+ }
+
+ @Test
+ void restoreShouldReturnInvalidWhenPassingCaseInsensitiveAction() {
+ given()
+ .queryParam("action", "RESTORE")
+ .when()
+ .post(USER.asString())
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is(notNullValue()))
+ .body("details", is(notNullValue()));
+ }
+
+ @Test
+ void restoreShouldReturnInvalidWhenUserIsInvalid() {
+ given()
+ .queryParam("action", "restore")
+ .when()
.post("not@valid@user.com")
.then()
.statusCode(HttpStatus.BAD_REQUEST_400)
.body("statusCode", is(400))
.body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
- .body("message", is("The username should not contain multiple domain delimiter."));
+ .body("message", is(notNullValue()))
+ .body("details", is(notNullValue()));
}
@Test
void postShouldReturnNotFoundWhenNoUserPathParameter() {
- when()
+ given()
+ .queryParam("action", "restore")
+ .when()
.post()
.then()
.statusCode(HttpStatus.NOT_FOUND_404)
@@ -151,11 +210,13 @@ class DeletedMessagesVaultRoutesTest {
.search(any(), any());
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
given()
+ .queryParam("action", "restore")
.basePath(TasksRoutes.BASE)
.when()
.get(taskId + "/await")
@@ -185,6 +246,7 @@ class DeletedMessagesVaultRoutesTest {
.appendMessage(any(), any());
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
@@ -214,6 +276,7 @@ class DeletedMessagesVaultRoutesTest {
.createMailbox(any(MailboxPath.class), any(MailboxSession.class));
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
@@ -236,7 +299,9 @@ class DeletedMessagesVaultRoutesTest {
@Test
void restoreShouldReturnATaskCreated() {
- when()
+ given()
+ .queryParam("action", "restore")
+ .when()
.post(USER.asString())
.then()
.statusCode(HttpStatus.CREATED_201)
@@ -249,6 +314,7 @@ class DeletedMessagesVaultRoutesTest {
vault.append(USER, DELETED_MESSAGE_2, new ByteArrayInputStream(CONTENT)).block();
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
@@ -275,6 +341,7 @@ class DeletedMessagesVaultRoutesTest {
vault.append(USER, DELETED_MESSAGE_2, new ByteArrayInputStream(CONTENT)).block();
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
@@ -304,6 +371,7 @@ class DeletedMessagesVaultRoutesTest {
vault.append(USER, DELETED_MESSAGE_2, new ByteArrayInputStream(CONTENT)).block();
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
@@ -325,6 +393,7 @@ class DeletedMessagesVaultRoutesTest {
vault.append(USER, DELETED_MESSAGE_2, new ByteArrayInputStream(CONTENT)).block();
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
@@ -348,6 +417,7 @@ class DeletedMessagesVaultRoutesTest {
vault.append(USER, DELETED_MESSAGE_2, new ByteArrayInputStream(CONTENT)).block();
String taskId = with()
+ .queryParam("action", "restore")
.post(USER.asString())
.jsonPath()
.get("taskId");
diff --git a/src/site/markdown/server/manage-webadmin.md b/src/site/markdown/server/manage-webadmin.md
index b00a62f..a660766 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -2560,17 +2560,22 @@ Here are the following actions available on the 'Deleted Messages Vault'
Deleted messages of a specific user can be restored by calling the following endpoint:
```
-curl -XPOST http://ip:port/deletedMessages/user/userToRestore@domain.ext
+curl -XPOST http://ip:port/deletedMessages/user/userToRestore@domain.ext?action=restore
```
**All** messages in the Deleted Messages Vault of an specified user will be appended to his 'Restored-Messages' mailbox, which will be created if needed.
-**Note**: Restoring matched messages by queries is not supported yet
-
+**Note**:
+ - Restoring matched messages by queries is not supported yet
+ - Query parameter `action` is required and should have value `restore` to represent for restoring feature. Otherwise, a bad request response will be returned
+ - Query parameter `action` is case sensitive
Response code:
- 201: Task for restoring deleted has been created
- - 400: Bad request, user parameter is invalid
+ - 400: Bad request:
+ - action query param is not present
+ - action query param is not a valid action
+ - user parameter is invalid
The scheduled task will have the following type `deletedMessages/restore` and the following `additionalInformation`:
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org