From 03824050b9de32cc7c68c5a26179cc93a70bd82c Mon Sep 17 00:00:00 2001 From: Jon Marius Venstad Date: Fri, 18 Sep 2020 16:53:48 +0200 Subject: Get more juice out of Response --- .../com/yahoo/documentapi/DocumentIdResponse.java | 22 +++++-- .../com/yahoo/documentapi/DocumentResponse.java | 29 ++++++++- .../yahoo/documentapi/DocumentUpdateResponse.java | 32 ++++++++-- .../main/java/com/yahoo/documentapi/Response.java | 72 ++++++++++++++++------ .../yahoo/documentapi/local/LocalAsyncSession.java | 8 +-- .../messagebus/MessageBusAsyncSession.java | 18 ++++-- 6 files changed, 141 insertions(+), 40 deletions(-) (limited to 'documentapi') diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java index f0eaa344b35..34ab47571cf 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java @@ -16,8 +16,7 @@ public class DocumentIdResponse extends Response { /** Creates a successful response */ public DocumentIdResponse(long requestId) { - super(requestId); - documentId = null; + this(requestId, null); } /** @@ -36,9 +35,9 @@ public class DocumentIdResponse extends Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public DocumentIdResponse(long requestId, String textMessage, boolean success) { - super(requestId, textMessage, success); - documentId = null; + this(requestId, null, textMessage, success ? Outcome.SUCCESS : Outcome.ERROR); } /** @@ -48,8 +47,21 @@ public class DocumentIdResponse extends Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public DocumentIdResponse(long requestId, DocumentId documentId, String textMessage, boolean success) { - super(requestId, textMessage, success); + this(requestId, documentId, textMessage, success ? Outcome.SUCCESS : Outcome.ERROR); + } + + + /** + * Creates a response containing a textual message and/or a document id + * + * @param documentId the DocumentId to encapsulate in the Response + * @param textMessage the message to encapsulate in the Response + * @param outcome the outcome of the operation + */ + public DocumentIdResponse(long requestId, DocumentId documentId, String textMessage, Outcome outcome) { + super(requestId, textMessage, outcome); this.documentId = documentId; } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentResponse.java index 2f4c86688e2..172e5fd11c0 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentResponse.java @@ -16,8 +16,7 @@ public class DocumentResponse extends Response { /** Creates a successful response */ public DocumentResponse(long requestId) { - super(requestId); - document = null; + this(requestId, null); } /** @@ -36,11 +35,22 @@ public class DocumentResponse extends Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public DocumentResponse(long requestId, String textMessage, boolean success) { super(requestId, textMessage, success); document = null; } + /** + * Creates a response containing a textual message + * + * @param textMessage the message to encapsulate in the Response + * @param outcome the outcome of this operation + */ + public DocumentResponse(long requestId, String textMessage, Outcome outcome) { + this(requestId, null, textMessage, outcome); + } + /** * Creates a response containing a textual message and/or a document * @@ -48,8 +58,21 @@ public class DocumentResponse extends Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public DocumentResponse(long requestId, Document document, String textMessage, boolean success) { - super(requestId, textMessage, success); + this(requestId, document, textMessage, success ? Outcome.SUCCESS : Outcome.ERROR); + } + + + /** + * Creates a response containing a textual message and/or a document + * + * @param document the Document to encapsulate in the Response + * @param textMessage the message to encapsulate in the Response + * @param outcome the outcome of this operation + */ + public DocumentResponse(long requestId, Document document, String textMessage, Outcome outcome) { + super(requestId, textMessage, outcome); this.document = document; } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentUpdateResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentUpdateResponse.java index 2a273621acb..3294c216d96 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentUpdateResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentUpdateResponse.java @@ -12,11 +12,11 @@ import com.yahoo.document.DocumentUpdate; public class DocumentUpdateResponse extends Response { /** The document update of this response, if any */ - private DocumentUpdate documentUpdate = null; + private final DocumentUpdate documentUpdate; /** Creates a successful response */ public DocumentUpdateResponse(long requestId) { - super(requestId); + this(requestId, null); } /** @@ -35,8 +35,19 @@ public class DocumentUpdateResponse extends Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public DocumentUpdateResponse(long requestId, String textMessage, boolean success) { - super(requestId, textMessage, success); + this(requestId, null, textMessage, success ? Outcome.SUCCESS : Outcome.ERROR); + } + + /** + * Creates a response containing a textual message + * + * @param textMessage the message to encapsulate in the Response + * @param outcome the outcome of this operation + */ + public DocumentUpdateResponse(long requestId, String textMessage, Outcome outcome) { + this(requestId, null, textMessage, outcome); } /** @@ -46,8 +57,21 @@ public class DocumentUpdateResponse extends Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public DocumentUpdateResponse(long requestId, DocumentUpdate documentUpdate, String textMessage, boolean success) { - super(requestId, textMessage, success); + this(requestId, documentUpdate, textMessage, success ? Outcome.SUCCESS : Outcome.ERROR); + } + + + /** + * Creates a response containing a textual message and/or a document update + * + * @param documentUpdate the DocumentUpdate to encapsulate in the Response + * @param textMessage the message to encapsulate in the Response + * @param outcome the outcome of this operation + */ + public DocumentUpdateResponse(long requestId, DocumentUpdate documentUpdate, String textMessage, Outcome outcome) { + super(requestId, textMessage, outcome); this.documentUpdate = documentUpdate; } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/Response.java b/documentapi/src/main/java/com/yahoo/documentapi/Response.java index 4d8cb93d1d0..4c95a648949 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/Response.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/Response.java @@ -1,6 +1,11 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.documentapi; +import java.util.Objects; + +import static com.yahoo.documentapi.Response.Outcome.ERROR; +import static com.yahoo.documentapi.Response.Outcome.SUCCESS; + /** *

An asynchronous response from the document api. * Subclasses of this provide additional response information for particular operations.

@@ -13,11 +18,11 @@ public class Response { private final long requestId; private final String textMessage; - private final boolean success; + private final Outcome outcome; /** Creates a successful response containing no information */ public Response(long requestId) { - this(requestId, null, true); + this(requestId, null); } /** @@ -26,7 +31,7 @@ public class Response { * @param textMessage the message to encapsulate in the Response */ public Response(long requestId, String textMessage) { - this(requestId, textMessage, true); + this(requestId, textMessage, SUCCESS); } /** @@ -35,10 +40,21 @@ public class Response { * @param textMessage the message to encapsulate in the Response * @param success true if the response represents a successful call */ + @Deprecated(since = "7") // TODO: Remove on Vespa 8 public Response(long requestId, String textMessage, boolean success) { + this(requestId, textMessage, success ? SUCCESS : ERROR); + } + + /** + * Creates a response containing a textual message + * + * @param textMessage the message to encapsulate in the Response + * @param outcome the outcome of the operation + */ + public Response(long requestId, String textMessage, Outcome outcome) { this.requestId = requestId; this.textMessage = textMessage; - this.success = success; + this.outcome = outcome; } /** @@ -53,29 +69,47 @@ public class Response { * * @return true if success */ - public boolean isSuccess() { return success; } + public boolean isSuccess() { return outcome == SUCCESS; } + + /** Returns the outcome of this operation. */ + public Outcome outcome() { return outcome; } public long getRequestId() { return requestId; } - public int hashCode() { - return (Long.valueOf(requestId).hashCode()) + (textMessage == null ? 0 : textMessage.hashCode()) + - (success ? 1 : 0); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if ( ! (o instanceof Response)) return false; + Response response = (Response) o; + return requestId == response.requestId && + Objects.equals(textMessage, response.textMessage) && + outcome == response.outcome; } - public boolean equals(Object o) { - if (!(o instanceof Response)) { - return false; - } - Response other = (Response) o; - - return requestId == other.requestId && success == other.success && ( - textMessage == null && other.textMessage == null || - textMessage != null && other.textMessage != null && textMessage.equals(other.textMessage)); + @Override + public int hashCode() { + return Objects.hash(requestId, textMessage, outcome); } public String toString() { - return "Response " + requestId + (textMessage == null ? "" : textMessage) + - (success ? " SUCCESSFUL" : " UNSUCCESSFUL"); + return "Response " + requestId + (textMessage == null ? "" : textMessage) + " " + outcome; + } + + + public enum Outcome { + + /** The operation was a success. */ + SUCCESS, + + /** The operation failed due to an unmet test-and-set condition. */ + CONDITION_FAILED, + + /** The operation failed because its target document was not found. */ + NOT_FOUND, + + /** The operation failed for some unknown reason. */ + ERROR + } } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java index d0316b9fec8..398675e594e 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java @@ -63,7 +63,7 @@ public class LocalAsyncSession implements AsyncSession { syncSession.put(documentPut, pri); addResponse(new DocumentResponse(req)); } catch (Exception e) { - addResponse(new DocumentResponse(req, documentPut.getDocument(), e.getMessage(), false)); + addResponse(new DocumentResponse(req, documentPut.getDocument(), e.getMessage(), Response.Outcome.ERROR)); } return new Result(req); } @@ -85,7 +85,7 @@ public class LocalAsyncSession implements AsyncSession { try { addResponse(new DocumentResponse(req, syncSession.get(id))); } catch (Exception e) { - addResponse(new DocumentResponse(req, e.getMessage(), false)); + addResponse(new DocumentResponse(req, e.getMessage(), Response.Outcome.ERROR)); } return new Result(req); } @@ -101,7 +101,7 @@ public class LocalAsyncSession implements AsyncSession { if (syncSession.remove(new DocumentRemove(id), pri)) { addResponse(new RemoveResponse(req, true)); } else { - addResponse(new DocumentIdResponse(req, id, "Document not found.", false)); + addResponse(new DocumentIdResponse(req, id, "Document not found.", Response.Outcome.NOT_FOUND)); } return new Result(req); } @@ -117,7 +117,7 @@ public class LocalAsyncSession implements AsyncSession { if (syncSession.update(update, pri)) { addResponse(new UpdateResponse(req, true)); } else { - addResponse(new DocumentUpdateResponse(req, update, "Document not found.", false)); + addResponse(new DocumentUpdateResponse(req, update, "Document not found.", Response.Outcome.NOT_FOUND)); } return new Result(req); } 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 f505a0ef1cb..7471d285db1 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java @@ -41,6 +41,10 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Logger; +import static com.yahoo.documentapi.Response.Outcome.CONDITION_FAILED; +import static com.yahoo.documentapi.Response.Outcome.ERROR; +import static com.yahoo.documentapi.Response.Outcome.NOT_FOUND; + /** * An access session which wraps a messagebus source session sending document messages. * The sessions are multithread safe. @@ -257,19 +261,23 @@ public class MessageBusAsyncSession implements MessageBusSession, AsyncSession { } 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); switch (msg.getType()) { case DocumentProtocol.MESSAGE_PUTDOCUMENT: - return new DocumentResponse(reqId, ((PutDocumentMessage)msg).getDocumentPut().getDocument(), err, false); + return new DocumentResponse(reqId, ((PutDocumentMessage)msg).getDocumentPut().getDocument(), err, outcome); case DocumentProtocol.MESSAGE_UPDATEDOCUMENT: - return new DocumentUpdateResponse(reqId, ((UpdateDocumentMessage)msg).getDocumentUpdate(), err, false); + return new DocumentUpdateResponse(reqId, ((UpdateDocumentMessage)msg).getDocumentUpdate(), err, outcome); case DocumentProtocol.MESSAGE_REMOVEDOCUMENT: - return new DocumentIdResponse(reqId, ((RemoveDocumentMessage)msg).getDocumentId(), err, false); + return new DocumentIdResponse(reqId, ((RemoveDocumentMessage)msg).getDocumentId(), err, outcome); case DocumentProtocol.MESSAGE_GETDOCUMENT: - return new DocumentIdResponse(reqId, ((GetDocumentMessage)msg).getDocumentId(), err, false); + return new DocumentIdResponse(reqId, ((GetDocumentMessage)msg).getDocumentId(), err, outcome); default: - return new Response(reqId, err, false); + return new Response(reqId, err, outcome); } } -- cgit v1.2.3