diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2020-09-18 23:45:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-18 23:45:54 +0200 |
commit | a8c10d0114c7157a34b82776d6c45aaf3e440147 (patch) | |
tree | 6fa9ec670ce1c99a5373c8013f9f2eb3a7cae986 | |
parent | 3a6bcde2ddcb322db6308e2817d1f3bdceded454 (diff) | |
parent | 060c1c8dc162ce9cf7e88b44f9fb986b511bf29b (diff) |
Merge pull request #14454 from vespa-engine/jonmv/async-document-v1
Jonmv/async document v1
18 files changed, 254 insertions, 74 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java index 3a99ee7d0c6..d729e2371c9 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java @@ -122,9 +122,9 @@ public abstract class ThreadedHttpRequestHandler extends ThreadedRequestHandler "IO error while responding to " + " [" + request.getUri() + "] " + "(total time " + time + " ms) ", e); - try { if (output != null) output.flush(); } catch (Exception ignored) { } // TODO: Shouldn't this be channel.close()? + try { output.flush(); } catch (Exception ignored) { } } finally { - if (channel != null && !(httpResponse instanceof AsyncHttpResponse)) { + if (channel != null && ! (httpResponse instanceof AsyncHttpResponse)) { channel.close(logOnCompletion); } } diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java index 34ba7676680..c198e0e8b32 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java @@ -15,6 +15,8 @@ import com.yahoo.jdisc.handler.OverloadException; import com.yahoo.jdisc.handler.ReadableContentChannel; import com.yahoo.jdisc.handler.ResponseDispatch; import com.yahoo.jdisc.handler.ResponseHandler; + +import java.util.Objects; import java.util.logging.Level; import java.net.URI; @@ -73,14 +75,13 @@ public abstract class ThreadedRequestHandler extends AbstractRequestHandler { */ @Inject protected ThreadedRequestHandler(Executor executor, Metric metric, boolean allowAsyncResponse) { - executor.getClass(); // throws NullPointerException - this.executor = executor; + this.executor = Objects.requireNonNull(executor); this.metric = (metric == null) ? new NullRequestMetric() : metric; this.allowAsyncResponse = allowAsyncResponse; } Metric.Context contextFor(Request request, Map<String, String> extraDimensions) { - BindingMatch match = request.getBindingMatch(); + BindingMatch<?> match = request.getBindingMatch(); if (match == null) return null; UriPattern matched = match.matched(); if (matched == null) return null; diff --git a/documentapi/abi-spec.json b/documentapi/abi-spec.json index bb4deed2914..a28ce1ee6db 100644 --- a/documentapi/abi-spec.json +++ b/documentapi/abi-spec.json @@ -38,6 +38,8 @@ "methods": [ "public abstract com.yahoo.documentapi.Result put(com.yahoo.document.Document)", "public com.yahoo.documentapi.Result put(com.yahoo.document.Document, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", + "public com.yahoo.documentapi.Result put(com.yahoo.document.DocumentPut)", + "public com.yahoo.documentapi.Result put(com.yahoo.document.DocumentPut, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", "public abstract com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId, boolean, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", @@ -126,6 +128,7 @@ "public void <init>(long, com.yahoo.document.DocumentId)", "public void <init>(long, java.lang.String, boolean)", "public void <init>(long, com.yahoo.document.DocumentId, java.lang.String, boolean)", + "public void <init>(long, com.yahoo.document.DocumentId, java.lang.String, com.yahoo.documentapi.Response$Outcome)", "public com.yahoo.document.DocumentId getDocumentId()", "public int hashCode()", "public boolean equals(java.lang.Object)", @@ -155,7 +158,9 @@ "public void <init>(long)", "public void <init>(long, com.yahoo.document.Document)", "public void <init>(long, java.lang.String, boolean)", + "public void <init>(long, java.lang.String, com.yahoo.documentapi.Response$Outcome)", "public void <init>(long, com.yahoo.document.Document, java.lang.String, boolean)", + "public void <init>(long, com.yahoo.document.Document, java.lang.String, com.yahoo.documentapi.Response$Outcome)", "public com.yahoo.document.Document getDocument()", "public int hashCode()", "public boolean equals(java.lang.Object)", @@ -173,7 +178,9 @@ "public void <init>(long)", "public void <init>(long, com.yahoo.document.DocumentUpdate)", "public void <init>(long, java.lang.String, boolean)", + "public void <init>(long, java.lang.String, com.yahoo.documentapi.Response$Outcome)", "public void <init>(long, com.yahoo.document.DocumentUpdate, java.lang.String, boolean)", + "public void <init>(long, com.yahoo.document.DocumentUpdate, java.lang.String, com.yahoo.documentapi.Response$Outcome)", "public com.yahoo.document.DocumentUpdate getDocumentUpdate()", "public int hashCode()", "public boolean equals(java.lang.Object)", @@ -353,6 +360,25 @@ ], "fields": [] }, + "com.yahoo.documentapi.Response$Outcome": { + "superClass": "java.lang.Enum", + "interfaces": [], + "attributes": [ + "public", + "final", + "enum" + ], + "methods": [ + "public static com.yahoo.documentapi.Response$Outcome[] values()", + "public static com.yahoo.documentapi.Response$Outcome valueOf(java.lang.String)" + ], + "fields": [ + "public static final enum com.yahoo.documentapi.Response$Outcome SUCCESS", + "public static final enum com.yahoo.documentapi.Response$Outcome CONDITION_FAILED", + "public static final enum com.yahoo.documentapi.Response$Outcome NOT_FOUND", + "public static final enum com.yahoo.documentapi.Response$Outcome ERROR" + ] + }, "com.yahoo.documentapi.Response": { "superClass": "java.lang.Object", "interfaces": [], @@ -363,11 +389,13 @@ "public void <init>(long)", "public void <init>(long, java.lang.String)", "public void <init>(long, java.lang.String, boolean)", + "public void <init>(long, java.lang.String, com.yahoo.documentapi.Response$Outcome)", "public java.lang.String getTextMessage()", "public boolean isSuccess()", + "public com.yahoo.documentapi.Response$Outcome outcome()", "public long getRequestId()", - "public int hashCode()", "public boolean equals(java.lang.Object)", + "public int hashCode()", "public java.lang.String toString()" ], "fields": [] @@ -902,7 +930,7 @@ "public void <init>(com.yahoo.documentapi.AsyncParameters, com.yahoo.documentapi.local.LocalDocumentAccess)", "public double getCurrentWindowSize()", "public com.yahoo.documentapi.Result put(com.yahoo.document.Document)", - "public com.yahoo.documentapi.Result put(com.yahoo.document.Document, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", + "public com.yahoo.documentapi.Result put(com.yahoo.document.DocumentPut, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId, boolean, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", @@ -990,7 +1018,7 @@ ], "methods": [ "public com.yahoo.documentapi.Result put(com.yahoo.document.Document)", - "public com.yahoo.documentapi.Result put(com.yahoo.document.Document, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", + "public com.yahoo.documentapi.Result put(com.yahoo.document.DocumentPut, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId, boolean, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", "public com.yahoo.documentapi.Result get(com.yahoo.document.DocumentId, com.yahoo.documentapi.messagebus.protocol.DocumentProtocol$Priority)", diff --git a/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java b/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java index c9db5223283..9f4ceaad37f 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java @@ -3,6 +3,7 @@ package com.yahoo.documentapi; import com.yahoo.document.Document; import com.yahoo.document.DocumentId; +import com.yahoo.document.DocumentPut; import com.yahoo.document.DocumentUpdate; import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol; @@ -44,7 +45,38 @@ public interface AsyncSession extends Session { * @return the synchronous result of this operation */ default Result put(Document document, DocumentProtocol.Priority priority) { - return put(document); + return put(new DocumentPut(document), priority); + } + + /** + * <p>Puts a document, with optional conditions on the operation. This method returns immediately.</p> + * + * <p>If this result is a success, this + * call will cause one or more {@link DocumentResponse} objects to appear within the timeout time of this session. + * The response returned later will either be a success, or contain the document submitted here. + * If it was not a success, this method has no further effects.</p> + * + * @param documentPut the DocumentPut to perform + * @return the synchronous result of this operation + */ + default Result put(DocumentPut documentPut) { + return put(documentPut, DocumentProtocol.Priority.NORMAL_3); + } + + /** + * <p>Puts a document, with optional conditions on the operation. This method returns immediately.</p> + * + * <p>If this result is a success, this + * call will cause one or more {@link DocumentResponse} objects to appear within the timeout time of this session. + * The response returned later will either be a success, or contain the document submitted here. + * If it was not a success, this method has no further effects.</p> + * + * @param documentPut the DocumentPut to perform + * @return the synchronous result of this operation + */ + // TODO Vespa 8: Make this the one to implement. + default Result put(DocumentPut documentPut, DocumentProtocol.Priority priority) { + return put(documentPut.getDocument()); } /** diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccess.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccess.java index d6c3d3ce92f..308eafcd596 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccess.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccess.java @@ -55,8 +55,11 @@ public abstract class DocumentAccess { * while attempting to create such an object, this method will throw an * exception. * + * @deprecated Inject a DocumentManagerConfig and create a MessageBusDocumentAccess from this instead. + * * @return a running document access object with all default configuration */ + @Deprecated(since = "7") public static DocumentAccess createDefault() { return new com.yahoo.documentapi.messagebus.MessageBusDocumentAccess(); } @@ -67,12 +70,11 @@ public abstract class DocumentAccess { * @param params the parameters to use for setup */ protected DocumentAccess(DocumentAccessParams params) { - super(); if (params.documentmanagerConfig().isPresent()) { // our config has been injected into the creator documentTypeManager = new DocumentTypeManager(params.documentmanagerConfig().get()); documentTypeConfigSubscriber = null; } - else { // fallback to old style subscription + else { // fallback to old style subscription — this should be avoided documentTypeManager = new DocumentTypeManager(); documentTypeConfigSubscriber = DocumentTypeManagerConfigurer.configure(documentTypeManager, params.getDocumentManagerConfigId()); } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccessException.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccessException.java index 207f2104bcd..0b33a0f8376 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccessException.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentAccessException.java @@ -9,7 +9,7 @@ import java.util.HashSet; /** * General exception thrown from various methods in the Vespa Document API. * - * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a> + * @author Einar M R Rosenvinge */ public class DocumentAccessException extends RuntimeException { diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java index 1f70cfdaaf0..34ab47571cf 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentIdResponse.java @@ -7,7 +7,7 @@ import com.yahoo.document.DocumentId; * The asynchronous response to a document remove operation. * This is a <i>value object</i>. * - * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a> + * @author Einar M R Rosenvinge */ public class DocumentIdResponse extends Response { @@ -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 983b4a0d5b2..172e5fd11c0 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentResponse.java @@ -7,7 +7,7 @@ import com.yahoo.document.Document; * The asynchronous response to a document put or get operation. * This is a <i>value object</i>. * - * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a> + * @author Einar M R Rosenvinge */ public class DocumentResponse extends Response { @@ -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,20 +35,44 @@ 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 * * @param document the Document to encapsulate in the 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 47b8737ee09..3294c216d96 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentUpdateResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentUpdateResponse.java @@ -7,16 +7,16 @@ import com.yahoo.document.DocumentUpdate; * The asynchronous response to a document update operation. * This is a <i>value object</i>. * - * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a> + * @author Einar M R Rosenvinge */ 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; + /** * <p>An asynchronous response from the document api. * Subclasses of this provide additional response information for particular operations.</p> @@ -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/Result.java b/documentapi/src/main/java/com/yahoo/documentapi/Result.java index 1242ccfe472..9b77090ea6d 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/Result.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/Result.java @@ -61,7 +61,7 @@ public class Result { * Returns the id of this operation. The asynchronous response to this operation * will contain the same id to allow clients who desire to, to match operations to responses. * - * @return the if of this operation + * @return the id of this operation */ public long getRequestId() { return requestId; } @@ -82,6 +82,7 @@ public class Result { /** The request failed, and retrying is pointless. */ FATAL_ERROR, /** Condition specified in operation not met error */ + @Deprecated(since = "7", forRemoval = true) // TODO: Remove on Vespa 8 — this is a Response outcome, not a Result outcome. CONDITION_NOT_MET_ERROR } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/VisitorResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/VisitorResponse.java index e73b0d59a12..6a10f0881c7 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/VisitorResponse.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/VisitorResponse.java @@ -2,10 +2,9 @@ package com.yahoo.documentapi; /** - * Common class for all visitor responses. All visitor responses have ack - * tokens that must be acked. + * Common class for all visitor responses. All visitor responses have ack tokens that must be ack'ed. * - * @author <a href="mailto:humbe@yahoo-inc.com">Håkon Humberset</a> + * @author Håkon Humberset */ public class VisitorResponse { private AckToken token; 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 00d6bb5ae33..398675e594e 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java @@ -53,17 +53,17 @@ public class LocalAsyncSession implements AsyncSession { @Override public Result put(Document document) { - return put(document, DocumentProtocol.Priority.NORMAL_3); + return put(new DocumentPut(document), DocumentProtocol.Priority.NORMAL_3); } @Override - public Result put(Document document, DocumentProtocol.Priority pri) { + public Result put(DocumentPut documentPut, DocumentProtocol.Priority pri) { long req = getNextRequestId(); try { - syncSession.put(new DocumentPut(document), pri); + syncSession.put(documentPut, pri); addResponse(new DocumentResponse(req)); } catch (Exception e) { - addResponse(new DocumentResponse(req, document, 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/local/LocalVisitorSession.java b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalVisitorSession.java index e107be94008..f087b646ca4 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalVisitorSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalVisitorSession.java @@ -1,11 +1,8 @@ package com.yahoo.documentapi.local; import com.yahoo.document.Document; -import com.yahoo.document.DocumentGet; import com.yahoo.document.DocumentId; import com.yahoo.document.DocumentPut; -import com.yahoo.document.Field; -import com.yahoo.document.fieldset.FieldCollection; import com.yahoo.document.fieldset.FieldSet; import com.yahoo.document.fieldset.FieldSetRepo; import com.yahoo.document.select.DocumentSelector; 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 ab39e4c30ff..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. @@ -92,12 +96,12 @@ public class MessageBusAsyncSession implements MessageBusSession, AsyncSession { @Override public Result put(Document document) { - return put(document, DocumentProtocol.Priority.NORMAL_3); + return put(new DocumentPut(document), DocumentProtocol.Priority.NORMAL_3); } @Override - public Result put(Document document, DocumentProtocol.Priority pri) { - PutDocumentMessage msg = new PutDocumentMessage(new DocumentPut(document)); + public Result put(DocumentPut documentPut, DocumentProtocol.Priority pri) { + PutDocumentMessage msg = new PutDocumentMessage(documentPut); msg.setPriority(pri); return send(msg); } @@ -238,7 +242,6 @@ public class MessageBusAsyncSession implements MessageBusSession, AsyncSession { private static Result.ResultType messageBusErrorToResultType(int messageBusError) { switch (messageBusError) { case ErrorCode.SEND_QUEUE_FULL: return Result.ResultType.TRANSIENT_ERROR; - case DocumentProtocol.ERROR_TEST_AND_SET_CONDITION_FAILED: return Result.ResultType.CONDITION_NOT_MET_ERROR; default: return Result.ResultType.FATAL_ERROR; } } @@ -258,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); } } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusSession.java b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusSession.java index 6022fbf6e39..fb6ed192cad 100755 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusSession.java @@ -13,26 +13,26 @@ public interface MessageBusSession { * * @return The route string. */ - public String getRoute(); + String getRoute(); /** * Sets the route to send all messages to when sending through this session. * * @param route The route string. */ - public void setRoute(String route); + void setRoute(String route); /** * Returns the trace level used when sending messages through this session. * * @return The trace level. */ - public int getTraceLevel(); + int getTraceLevel(); /** * Sets the trace level used when sending messages through this session. * * @param traceLevel The trace level to set. */ - public void setTraceLevel(int traceLevel); + void setTraceLevel(int traceLevel); } diff --git a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/ReplyMergerTestCase.java b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/ReplyMergerTestCase.java index 9172752760d..157b4a6585b 100644 --- a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/ReplyMergerTestCase.java +++ b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/ReplyMergerTestCase.java @@ -182,6 +182,26 @@ public class ReplyMergerTestCase { } @Test + // TODO: This seems wrong, and is probably a consequence of TAS being added later than this logic was written. + public void returnErrorDocumentReplyWhereDocWasFoundWhichIsProbablyWrong() { + Error e1 = new Error(DocumentProtocol.ERROR_TEST_AND_SET_CONDITION_FAILED, "fail"); + UpdateDocumentReply r1 = new UpdateDocumentReply(); + UpdateDocumentReply r2 = new UpdateDocumentReply(); + UpdateDocumentReply r3 = new UpdateDocumentReply(); + r1.addError(e1); // return error + r2.setWasFound(true); + r3.setWasFound(true); + + merger.merge(0, r1); + merger.merge(1, r2); + merger.merge(2, r3); + Tuple2<Integer, Reply> ret = merger.mergedReply(); + assertNull(ret.first); + assertNotSame(r1, ret.second); + assertThatErrorsMatch(new Error[] { e1 }, ret); + } + + @Test public void returnUpdateDocumentReplyWhereDocWasFound() { UpdateDocumentReply r1 = new UpdateDocumentReply(); UpdateDocumentReply r2 = new UpdateDocumentReply(); diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/HttpRequest.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/HttpRequest.java index 21e492fe57e..118c34245c0 100644 --- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/HttpRequest.java +++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/HttpRequest.java @@ -138,7 +138,7 @@ public class HttpRequest extends Request implements ServletOrJdiscHttpRequest { return version; } - /** Returns the remove address, or null if unresolved */ + /** Returns the remote address, or null if unresolved */ @Override public String getRemoteHostAddress() { if (remoteAddress instanceof InetSocketAddress) { |