diff options
6 files changed, 42 insertions, 5 deletions
diff --git a/documentapi/src/main/java/com/yahoo/documentapi/Response.java b/documentapi/src/main/java/com/yahoo/documentapi/Response.java index 0a541a92c6a..cea9f247ade 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/Response.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/Response.java @@ -124,6 +124,9 @@ public class Response { /** The operation failed because its target document was not found. */ NOT_FOUND, + /** The operation failed because the cluster had insufficient storage to accept it. */ + INSUFFICIENT_STORAGE, + /** The operation failed for some unknown reason. */ ERROR diff --git a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java index 0a4ab66aea4..4d136dd743e 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java @@ -45,6 +45,7 @@ import java.util.logging.Logger; import static com.yahoo.documentapi.DocumentOperationParameters.parameters; import static com.yahoo.documentapi.Response.Outcome.CONDITION_FAILED; import static com.yahoo.documentapi.Response.Outcome.ERROR; +import static com.yahoo.documentapi.Response.Outcome.INSUFFICIENT_STORAGE; import static com.yahoo.documentapi.Response.Outcome.NOT_FOUND; import static com.yahoo.documentapi.Response.Outcome.SUCCESS; @@ -294,13 +295,21 @@ public class MessageBusAsyncSession implements MessageBusSession, AsyncSession { new Error(mbusResult.getError().getMessage() + " (" + mbusResult.getError().getCode() + ")")); } + private static Response.Outcome toOutcome(Reply reply) { + if ( reply instanceof UpdateDocumentReply && ! ((UpdateDocumentReply) reply).wasFound() + || reply instanceof RemoveDocumentReply && ! ((RemoveDocumentReply) reply).wasFound()) + return NOT_FOUND; + if (reply.getErrorCodes().contains(DocumentProtocol.ERROR_NO_SPACE)) + return INSUFFICIENT_STORAGE; + if (reply.getErrorCodes().contains(DocumentProtocol.ERROR_TEST_AND_SET_CONDITION_FAILED)) + return CONDITION_FAILED; + return ERROR; + } + private static Response toError(Reply reply, long reqId) { - boolean definitelyNotFound = reply instanceof UpdateDocumentReply && ! ((UpdateDocumentReply) reply).wasFound() - || reply instanceof RemoveDocumentReply && ! ((RemoveDocumentReply) reply).wasFound(); - boolean conditionFailed = reply.getErrorCodes().contains(DocumentProtocol.ERROR_TEST_AND_SET_CONDITION_FAILED); - Response.Outcome outcome = definitelyNotFound ? NOT_FOUND : conditionFailed ? CONDITION_FAILED : ERROR; Message msg = reply.getMessage(); String err = getErrorMessage(reply); + Response.Outcome outcome = toOutcome(reply); switch (msg.getType()) { case DocumentProtocol.MESSAGE_PUTDOCUMENT: return new DocumentResponse(reqId, ((PutDocumentMessage)msg).getDocumentPut().getDocument(), err, outcome, reply.getTrace()); diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutor.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutor.java index 8b0c966c46f..d56c8c1524e 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutor.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutor.java @@ -52,8 +52,9 @@ public interface DocumentOperationExecutor { NOT_FOUND, PRECONDITION_FAILED, BAD_REQUEST, + ERROR, TIMEOUT, - ERROR; + INSUFFICIENT_STORAGE; } diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java index 72e28d15e4b..7074d363316 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/DocumentOperationExecutorImpl.java @@ -55,6 +55,7 @@ import java.util.stream.Stream; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.BAD_REQUEST; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.ERROR; +import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.INSUFFICIENT_STORAGE; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.NOT_FOUND; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.OVERLOAD; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.PRECONDITION_FAILED; @@ -272,6 +273,8 @@ public class DocumentOperationExecutorImpl implements DocumentOperationExecutor return NOT_FOUND; case CONDITION_FAILED: return PRECONDITION_FAILED; + case INSUFFICIENT_STORAGE: + return INSUFFICIENT_STORAGE; default: log.log(WARNING, "Unexpected response outcome: " + outcome); case ERROR: // intentional fallthrough diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java index ea99c5bf762..2754d7ee627 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java @@ -350,6 +350,9 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler { case TIMEOUT: timeout(request, message, root, handler); break; + case INSUFFICIENT_STORAGE: + insufficientStorage(request, message, root, handler); + break; default: log.log(WARNING, "Unexpected error type '" + type + "'"); case ERROR: // intentional fallthrough @@ -441,6 +444,12 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler { return respond(Response.Status.GATEWAY_TIMEOUT, root, handler); } + private static ContentChannel insufficientStorage(HttpRequest request, String message, Cursor root, ResponseHandler handler) { + log.log(FINE, () -> "Insufficient storage for " + request.getMethod() + " " + request.getUri().getRawPath() + ": " + message); + root.setString("message", message); + return respond(Response.Status.INSUFFICIENT_STORAGE, root, handler); + } + private static ContentChannel respond(Inspector root, ResponseHandler handler) { return respond(200, root, handler); } diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java index 9554fa0a913..c6b611ed3c7 100644 --- a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java +++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java @@ -37,6 +37,7 @@ import java.util.Optional; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.BAD_REQUEST; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.ERROR; +import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.INSUFFICIENT_STORAGE; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.OVERLOAD; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.PRECONDITION_FAILED; import static com.yahoo.document.restapi.DocumentOperationExecutor.ErrorType.TIMEOUT; @@ -309,6 +310,17 @@ public class DocumentV1ApiTest { response.readAll()); assertEquals(504, response.getStatus()); + // INSUFFICIENT_STORAGE is a 504 + response = driver.sendRequest("http://localhost/document/v1/space/music/number/1/two"); + executor.lastOperationContext().error(INSUFFICIENT_STORAGE, "disk full"); + assertSameJson("{" + + " \"pathId\": \"/document/v1/space/music/number/1/two\"," + + " \"id\": \"id:space:music:n=1:two\"," + + " \"message\": \"disk full\"" + + "}", + response.readAll()); + assertEquals(507, response.getStatus()); + // OVERLOAD is a 429 response = driver.sendRequest("http://localhost/document/v1/space/music/number/1/two"); executor.lastOperationContext().error(OVERLOAD, "overload"); |