diff options
Diffstat (limited to 'documentapi/src')
38 files changed, 4306 insertions, 4933 deletions
diff --git a/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java b/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java index 2e78a023910..c9db5223283 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/AsyncSession.java @@ -43,7 +43,9 @@ public interface AsyncSession extends Session { * @param document the Document to put * @return the synchronous result of this operation */ - Result put(Document document, DocumentProtocol.Priority priority); + default Result put(Document document, DocumentProtocol.Priority priority) { + return put(document); + } /** * <p>Gets a document. This method returns immediately.</p> @@ -71,8 +73,30 @@ public interface AsyncSession extends Session { * @param priority The priority with which to perform this operation. * @return the synchronous result of this operation * @throws UnsupportedOperationException if this access implementation does not support retrieving + * @deprecated the 'headersonly' flag has no effect */ - Result get(DocumentId id, boolean headersOnly, DocumentProtocol.Priority priority); + @Deprecated // TODO: Remove on Vespa 8 + default Result get(DocumentId id, boolean headersOnly, DocumentProtocol.Priority priority) { + return get(id); + } + + /** + * <p>Gets a document. 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 contain the requested document if it is a success. + * If it was not a success, this method has no further effects.</p> + * + * @param id the id of the document to get + * @param priority The priority with which to perform this operation. + * @return the synchronous result of this operation + * @throws UnsupportedOperationException if this access implementation does not support retrieving + */ + default Result get(DocumentId id, DocumentProtocol.Priority priority) { + return get(id); + } + /** * <p>Removes a document if it is present. This method returns immediately.</p> @@ -101,7 +125,9 @@ public interface AsyncSession extends Session { * @return the synchronous result of this operation * @throws UnsupportedOperationException if this access implementation does not support removal */ - Result remove(DocumentId id, DocumentProtocol.Priority priority); + default Result remove(DocumentId id, DocumentProtocol.Priority priority) { + return remove(id); + } /** * <p>Updates a document. This method returns immediately.</p> @@ -130,7 +156,9 @@ public interface AsyncSession extends Session { * @return the synchronous result of this operation * @throws UnsupportedOperationException if this access implementation does not support update */ - Result update(DocumentUpdate update, DocumentProtocol.Priority priority); + default Result update(DocumentUpdate update, DocumentProtocol.Priority priority) { + return update(update); + } /** * Returns the current send window size of the session. diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentListVisitorResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentListVisitorResponse.java deleted file mode 100644 index 3acbf70a21e..00000000000 --- a/documentapi/src/main/java/com/yahoo/documentapi/DocumentListVisitorResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -// 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 com.yahoo.vdslib.DocumentList; - -/** - * Visitor response containing a document list. All visitor responses have ack - * tokens that must be acked. - * - * @author <a href="mailto:humbe@yahoo-inc.com">Håkon Humberset</a> - */ -public class DocumentListVisitorResponse extends VisitorResponse { - private DocumentList documents; - - /** - * Creates visitor response containing a document list and an ack token. - * - * @param docs the document list - * @param ack the ack token - */ - public DocumentListVisitorResponse(DocumentList docs, AckToken ack) { - super(ack); - documents = docs; - } - - /** @return the document list */ - public DocumentList getDocumentList() { return documents; } -} diff --git a/documentapi/src/main/java/com/yahoo/documentapi/DocumentOpVisitorResponse.java b/documentapi/src/main/java/com/yahoo/documentapi/DocumentOpVisitorResponse.java new file mode 100644 index 00000000000..f5641b915f4 --- /dev/null +++ b/documentapi/src/main/java/com/yahoo/documentapi/DocumentOpVisitorResponse.java @@ -0,0 +1,28 @@ +// 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 com.yahoo.document.DocumentOperation; + +/** + * Visitor response containing a document operation. All visitor responses have ack + * tokens that must be acked. + * + * @author Arne H Juul + */ +public class DocumentOpVisitorResponse extends VisitorResponse { + private DocumentOperation op; + + /** + * Creates visitor response containing a document operation and an ack token. + * + * @param op the document operation + * @param ack the ack token + */ + public DocumentOpVisitorResponse(DocumentOperation op, AckToken ack) { + super(ack); + this.op = op; + } + + /** @return the document operation */ + public DocumentOperation getDocumentOperation() { return op; } +} diff --git a/documentapi/src/main/java/com/yahoo/documentapi/ProgressToken.java b/documentapi/src/main/java/com/yahoo/documentapi/ProgressToken.java index f5701802a84..9a6c2ea3bd3 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/ProgressToken.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/ProgressToken.java @@ -7,11 +7,10 @@ import java.util.Map; import java.util.TreeMap; import java.util.logging.Logger; -import com.yahoo.document.*; -import com.yahoo.document.serialization.*; +import com.yahoo.document.BucketId; import com.yahoo.io.GrowableByteBuffer; import com.yahoo.log.LogLevel; -import com.yahoo.vespa.objects.Serializer; +import com.yahoo.vespa.objects.BufferSerializer; /** * Token to use to keep track of progress for visiting. Can be used to resume @@ -213,7 +212,7 @@ public class ProgressToken { } public ProgressToken(byte[] serialized) { - DocumentDeserializer in = DocumentDeserializerFactory.create42(null, GrowableByteBuffer.wrap(serialized)); + BufferSerializer in = new BufferSerializer(GrowableByteBuffer.wrap(serialized)); distributionBits = in.getInt(null); bucketCursor = in.getLong(null); finishedBucketCount = in.getLong(null); @@ -228,7 +227,7 @@ public class ProgressToken { } public byte[] serialize() { - DocumentSerializer out = DocumentSerializerFactory.create42(new GrowableByteBuffer()); + BufferSerializer out = new BufferSerializer(new GrowableByteBuffer()); out.putInt(null, distributionBits); out.putLong(null, bucketCursor); out.putLong(null, finishedBucketCount); diff --git a/documentapi/src/main/java/com/yahoo/documentapi/Result.java b/documentapi/src/main/java/com/yahoo/documentapi/Result.java index c905fa24cb1..1242ccfe472 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/Result.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/Result.java @@ -66,20 +66,6 @@ public class Result { public long getRequestId() { return requestId; } /** - * @deprecated use type() instead. - * Returns the type of result. - * - * @return the type of result, typically if this is an error or a success, and what kind of error. - * Does not return CONDITION_NOT_MET_ERROR for backward compatibility. - * @see com.yahoo.documentapi.Result.ResultType - */ - @Deprecated - public ResultType getType() { return - type == ResultType.CONDITION_NOT_MET_ERROR - ? ResultType.FATAL_ERROR - : type;} - - /** * Returns the type of result. * * @return the type of result, typically if this is an error or a success, and what kind of error. diff --git a/documentapi/src/main/java/com/yahoo/documentapi/SimpleVisitorDocumentQueue.java b/documentapi/src/main/java/com/yahoo/documentapi/SimpleVisitorDocumentQueue.java index 102f17a64b1..e1dbe615f7d 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/SimpleVisitorDocumentQueue.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/SimpleVisitorDocumentQueue.java @@ -3,7 +3,6 @@ package com.yahoo.documentapi; import com.yahoo.document.Document; import com.yahoo.document.DocumentId; -import com.yahoo.vdslib.DocumentList; import java.util.LinkedList; import java.util.List; diff --git a/documentapi/src/main/java/com/yahoo/documentapi/SyncParameters.java b/documentapi/src/main/java/com/yahoo/documentapi/SyncParameters.java index b1986680532..acf027dd0aa 100755 --- a/documentapi/src/main/java/com/yahoo/documentapi/SyncParameters.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/SyncParameters.java @@ -13,12 +13,7 @@ import java.util.Optional; public class SyncParameters extends Parameters { private final Duration defaultTimeout; - /** - * @deprecated Use {@link Builder} instead. - */ - @Deprecated - // TODO Vespa 7: Make private - public SyncParameters() { + private SyncParameters() { this(null); } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/SyncSession.java b/documentapi/src/main/java/com/yahoo/documentapi/SyncSession.java index 0ce0ccc2377..c254df3ba02 100755 --- a/documentapi/src/main/java/com/yahoo/documentapi/SyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/SyncSession.java @@ -34,7 +34,9 @@ public interface SyncSession extends Session { * @param documentPut The DocumentPut operation * @param priority The priority with which to perform this operation. */ - void put(DocumentPut documentPut, DocumentProtocol.Priority priority); + default void put(DocumentPut documentPut, DocumentProtocol.Priority priority) { + put(documentPut); + } /** * <p>Gets a document.</p> @@ -45,10 +47,10 @@ public interface SyncSession extends Session { * @throws UnsupportedOperationException Thrown if this access does not * support retrieving. */ - Document get(DocumentId id); + default Document get(DocumentId id) { return get(id, null); } /** - * <p>Gets a document.</p> + * Gets a document with an unspecified timeout * * @param id The id of the document to get. * @param fieldSet A comma-separated list of fields to retrieve @@ -58,7 +60,9 @@ public interface SyncSession extends Session { * @throws UnsupportedOperationException Thrown if this access does not * support retrieving. */ - Document get(DocumentId id, String fieldSet, DocumentProtocol.Priority priority); + default Document get(DocumentId id, String fieldSet, DocumentProtocol.Priority priority) { + return get(id, fieldSet, priority, null); + } /** * <p>Gets a document with timeout.</p> @@ -70,10 +74,7 @@ public interface SyncSession extends Session { * @throws UnsupportedOperationException Thrown if this access does not support retrieving. * @throws DocumentAccessException on any messagebus error, including timeout ({@link com.yahoo.messagebus.ErrorCode#TIMEOUT}). */ - // TODO Vespa 7: Remove default implementation. Consider removing get() overloads without timeout. - default Document get(DocumentId id, Duration timeout) { - return get(id); - } + Document get(DocumentId id, Duration timeout); /** * <p>Gets a document with timeout. </p> @@ -87,10 +88,7 @@ public interface SyncSession extends Session { * @throws UnsupportedOperationException Thrown if this access does not support retrieving. * @throws DocumentAccessException on any messagebus error, including timeout ({@link com.yahoo.messagebus.ErrorCode#TIMEOUT}). */ - // TODO Vespa 7: Remove default implementation. Consider removing get() overloads without timeout. - default Document get(DocumentId id, String fieldSet, DocumentProtocol.Priority priority, Duration timeout) { - return get(id, fieldSet, priority); - } + Document get(DocumentId id, String fieldSet, DocumentProtocol.Priority priority, Duration timeout); /** * <p>Removes a document if it is present and condition is fulfilled.</p> diff --git a/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataHandler.java b/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataHandler.java index fc27af2c306..57d4c78d9be 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataHandler.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataHandler.java @@ -5,8 +5,6 @@ import com.yahoo.document.Document; import com.yahoo.document.DocumentId; import com.yahoo.documentapi.messagebus.protocol.*; import com.yahoo.messagebus.Message; -import com.yahoo.vdslib.DocumentList; -import com.yahoo.vdslib.Entry; import com.yahoo.vdslib.SearchResult; import com.yahoo.vdslib.DocumentSummary; import com.yahoo.document.BucketId; diff --git a/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataQueue.java b/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataQueue.java index a6648a6c89b..5c4e6c625a9 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataQueue.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/VisitorDataQueue.java @@ -4,9 +4,8 @@ package com.yahoo.documentapi; import com.yahoo.document.DocumentOperation; import com.yahoo.documentapi.messagebus.protocol.PutDocumentMessage; import com.yahoo.documentapi.messagebus.protocol.RemoveDocumentMessage; +import com.yahoo.documentapi.messagebus.protocol.UpdateDocumentMessage; import com.yahoo.messagebus.Message; -import com.yahoo.vdslib.DocumentList; -import com.yahoo.vdslib.Entry; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -18,7 +17,7 @@ import java.util.concurrent.TimeUnit; * implements the <code>getNext</code> methods, thus implementing the polling * API defined in VisitorDataHandler. * <p> - * Visitor responses containing document lists should be polled for with the + * Visitor responses should be polled for with the * <code>getNext</code> methods and need to be acked when processed for * visiting not to halt. The class is thread safe. * @@ -41,8 +40,7 @@ public class VisitorDataQueue extends VisitorDataHandler { } private void appendSingleOpToPendingList(final DocumentOperation op, final AckToken token) { - final DocumentList docList = DocumentList.create(Entry.create(op)); - final DocumentListVisitorResponse response = new DocumentListVisitorResponse(docList, token); + final DocumentOpVisitorResponse response = new DocumentOpVisitorResponse(op, token); pendingResponses.add(response); } @@ -59,14 +57,6 @@ public class VisitorDataQueue extends VisitorDataHandler { } } - /** - * @deprecated This method is no longer called by the visitor subsystem. See onMessage instead. - */ - @Deprecated - public void onDocuments(DocumentList docs, AckToken token) { - pendingResponses.add(new DocumentListVisitorResponse(docs, token)); - } - // Inherit doc from VisitorDataHandler @Override public VisitorResponse getNext() { diff --git a/documentapi/src/main/java/com/yahoo/documentapi/VisitorParameters.java b/documentapi/src/main/java/com/yahoo/documentapi/VisitorParameters.java index 0cf8e05c8ed..64854373e05 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/VisitorParameters.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/VisitorParameters.java @@ -140,7 +140,7 @@ public class VisitorParameters extends Parameters { public boolean getVisitRemoves() { return visitRemoves; } - public boolean getVisitHeadersOnly() { return "[header]".equals(fieldSet); } + public boolean getVisitHeadersOnly() { return false; } /** @return The field set to use. */ public String fieldSet() { return fieldSet; } @@ -231,7 +231,9 @@ public class VisitorParameters extends Parameters { public void setVisitRemoves(boolean visitRemoves) { this.visitRemoves = visitRemoves; } - public void setVisitHeadersOnly(boolean headersOnly) { this.fieldSet = headersOnly ? "[header]" : "[all]"; } + /** @deprecated this option is ignored */ + @Deprecated // TODO: Remove on Vespa 8 + public void setVisitHeadersOnly(boolean headersOnly) { } /** Set field set to use. */ public void fieldSet(String fieldSet) { this.fieldSet = fieldSet; } 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 4e331071be7..00d6bb5ae33 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalAsyncSession.java @@ -74,7 +74,13 @@ public class LocalAsyncSession implements AsyncSession { } @Override + @Deprecated // TODO: Remove on Vespa 8 public Result get(DocumentId id, boolean headersOnly, DocumentProtocol.Priority pri) { + return get(id, pri); + } + + @Override + public Result get(DocumentId id, DocumentProtocol.Priority pri) { long req = getNextRequestId(); try { addResponse(new DocumentResponse(req, syncSession.get(id))); diff --git a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalSyncSession.java b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalSyncSession.java index 45df2015da4..ea0ee2eaee1 100755 --- a/documentapi/src/main/java/com/yahoo/documentapi/local/LocalSyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/local/LocalSyncSession.java @@ -10,6 +10,8 @@ import com.yahoo.documentapi.Response; import com.yahoo.documentapi.SyncSession; import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol; +import java.time.Duration; + /** * @author bratseth */ @@ -36,15 +38,12 @@ public class LocalSyncSession implements SyncSession { } @Override - public Document get(DocumentId id) { + public Document get(DocumentId id, Duration timeout) { return access.documents.get(id); } @Override - public Document get(DocumentId id, String fieldSet, DocumentProtocol.Priority pri) { - // FIXME: More than half the get() methods are deprecated, but they all - // call exactly the same method, including this one, throwing away most - // of the parameters + public Document get(DocumentId id, String fieldSet, DocumentProtocol.Priority priority, Duration timeout) { return access.documents.get(id); } 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 8a6fa85c68b..67b9444e73f 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/MessageBusAsyncSession.java @@ -86,8 +86,14 @@ public class MessageBusAsyncSession implements MessageBusSession, AsyncSession { } @Override + @Deprecated // TODO: Remove on Vespa 8 public Result get(DocumentId id, boolean headersOnly, DocumentProtocol.Priority pri) { - GetDocumentMessage msg = new GetDocumentMessage(id, headersOnly ? "[header]" : "[all]"); + return get(id, pri); + } + + @Override + public Result get(DocumentId id, DocumentProtocol.Priority pri) { + GetDocumentMessage msg = new GetDocumentMessage(id, "[all]"); msg.setPriority(pri); return send(msg); } diff --git a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java index 10a316f7751..e627316de30 100755 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/DocumentProtocol.java @@ -301,55 +301,48 @@ public class DocumentProtocol implements Protocol { putRoutingPolicyFactory("SubsetService", new RoutingPolicyFactories.SubsetServicePolicyFactory()); // Prepare version specifications to use when adding routable factories. - VersionSpecification version52 = new VersionSpecification(5, 115); VersionSpecification version6 = new VersionSpecification(6, 221); - List<VersionSpecification> from52 = Arrays.asList(version52, version6); - List<VersionSpecification> from6 = Collections.singletonList(version6); // TODO decide minor version... - - // 5.2 serialization (keep alphabetized please) - putRoutableFactory(MESSAGE_CREATEVISITOR, new RoutableFactories52.CreateVisitorMessageFactory(), from52); - putRoutableFactory(MESSAGE_DESTROYVISITOR, new RoutableFactories52.DestroyVisitorMessageFactory(), from52); - putRoutableFactory(MESSAGE_DOCUMENTLIST, new RoutableFactories52.DocumentListMessageFactory(), from52); - putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, new RoutableFactories52.DocumentSummaryMessageFactory(), from52); - putRoutableFactory(MESSAGE_EMPTYBUCKETS, new RoutableFactories52.EmptyBucketsMessageFactory(), from52); - putRoutableFactory(MESSAGE_GETBUCKETLIST, new RoutableFactories52.GetBucketListMessageFactory(), from52); - putRoutableFactory(MESSAGE_GETBUCKETSTATE, new RoutableFactories52.GetBucketStateMessageFactory(), from52); - putRoutableFactory(MESSAGE_GETDOCUMENT, new RoutableFactories52.GetDocumentMessageFactory(), from52); - putRoutableFactory(MESSAGE_MAPVISITOR, new RoutableFactories52.MapVisitorMessageFactory(), from52); - putRoutableFactory(MESSAGE_PUTDOCUMENT, new RoutableFactories52.PutDocumentMessageFactory(), from52); - putRoutableFactory(MESSAGE_QUERYRESULT, new RoutableFactories52.QueryResultMessageFactory(), from52); - putRoutableFactory(MESSAGE_REMOVEDOCUMENT, new RoutableFactories52.RemoveDocumentMessageFactory(), from52); - putRoutableFactory(MESSAGE_REMOVELOCATION, new RoutableFactories52.RemoveLocationMessageFactory(), from52); - putRoutableFactory(MESSAGE_SEARCHRESULT, new RoutableFactories52.SearchResultMessageFactory(), from52); - putRoutableFactory(MESSAGE_STATBUCKET, new RoutableFactories52.StatBucketMessageFactory(), from52); - putRoutableFactory(MESSAGE_UPDATEDOCUMENT, new RoutableFactories52.UpdateDocumentMessageFactory(), from52); - putRoutableFactory(MESSAGE_VISITORINFO, new RoutableFactories52.VisitorInfoMessageFactory(), from52); - putRoutableFactory(REPLY_CREATEVISITOR, new RoutableFactories52.CreateVisitorReplyFactory(), from52); - putRoutableFactory(REPLY_DESTROYVISITOR, new RoutableFactories52.DestroyVisitorReplyFactory(), from52); - putRoutableFactory(REPLY_DOCUMENTIGNORED, new RoutableFactories52.DocumentIgnoredReplyFactory(), from52); - putRoutableFactory(REPLY_DOCUMENTLIST, new RoutableFactories52.DocumentListReplyFactory(), from52); - putRoutableFactory(REPLY_DOCUMENTSUMMARY, new RoutableFactories52.DocumentSummaryReplyFactory(), from52); - putRoutableFactory(REPLY_EMPTYBUCKETS, new RoutableFactories52.EmptyBucketsReplyFactory(), from52); - putRoutableFactory(REPLY_GETBUCKETLIST, new RoutableFactories52.GetBucketListReplyFactory(), from52); - putRoutableFactory(REPLY_GETBUCKETSTATE, new RoutableFactories52.GetBucketStateReplyFactory(), from52); - putRoutableFactory(REPLY_GETDOCUMENT, new RoutableFactories52.GetDocumentReplyFactory(), from52); - putRoutableFactory(REPLY_MAPVISITOR, new RoutableFactories52.MapVisitorReplyFactory(), from52); - putRoutableFactory(REPLY_PUTDOCUMENT, new RoutableFactories52.PutDocumentReplyFactory(), from52); - putRoutableFactory(REPLY_QUERYRESULT, new RoutableFactories52.QueryResultReplyFactory(), from52); - putRoutableFactory(REPLY_REMOVEDOCUMENT, new RoutableFactories52.RemoveDocumentReplyFactory(), from52); - putRoutableFactory(REPLY_REMOVELOCATION, new RoutableFactories52.RemoveLocationReplyFactory(), from52); - putRoutableFactory(REPLY_SEARCHRESULT, new RoutableFactories52.SearchResultReplyFactory(), from52); - putRoutableFactory(REPLY_STATBUCKET, new RoutableFactories52.StatBucketReplyFactory(), from52); - putRoutableFactory(REPLY_UPDATEDOCUMENT, new RoutableFactories52.UpdateDocumentReplyFactory(), from52); - putRoutableFactory(REPLY_UPDATEDOCUMENT, new RoutableFactories52.UpdateDocumentReplyFactory(), from52); - putRoutableFactory(REPLY_VISITORINFO, new RoutableFactories52.VisitorInfoReplyFactory(), from52); - putRoutableFactory(REPLY_WRONGDISTRIBUTION, new RoutableFactories52.WrongDistributionReplyFactory(), from52); - - // 6.x serialization + List<VersionSpecification> from6 = Collections.singletonList(version6); + + // 6.x serialization (keep alphabetized please) putRoutableFactory(MESSAGE_CREATEVISITOR, new RoutableFactories60.CreateVisitorMessageFactory(), from6); - putRoutableFactory(MESSAGE_STATBUCKET, new RoutableFactories60.StatBucketMessageFactory(), from6); + putRoutableFactory(MESSAGE_DESTROYVISITOR, new RoutableFactories60.DestroyVisitorMessageFactory(), from6); + putRoutableFactory(MESSAGE_DOCUMENTLIST, new RoutableFactories60.DocumentListMessageFactory(), from6); + putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, new RoutableFactories60.DocumentSummaryMessageFactory(), from6); + putRoutableFactory(MESSAGE_EMPTYBUCKETS, new RoutableFactories60.EmptyBucketsMessageFactory(), from6); putRoutableFactory(MESSAGE_GETBUCKETLIST, new RoutableFactories60.GetBucketListMessageFactory(), from6); + putRoutableFactory(MESSAGE_GETBUCKETSTATE, new RoutableFactories60.GetBucketStateMessageFactory(), from6); + putRoutableFactory(MESSAGE_GETDOCUMENT, new RoutableFactories60.GetDocumentMessageFactory(), from6); + putRoutableFactory(MESSAGE_MAPVISITOR, new RoutableFactories60.MapVisitorMessageFactory(), from6); + putRoutableFactory(MESSAGE_PUTDOCUMENT, new RoutableFactories60.PutDocumentMessageFactory(), from6); + putRoutableFactory(MESSAGE_QUERYRESULT, new RoutableFactories60.QueryResultMessageFactory(), from6); + putRoutableFactory(MESSAGE_REMOVEDOCUMENT, new RoutableFactories60.RemoveDocumentMessageFactory(), from6); + putRoutableFactory(MESSAGE_REMOVELOCATION, new RoutableFactories60.RemoveLocationMessageFactory(), from6); + putRoutableFactory(MESSAGE_SEARCHRESULT, new RoutableFactories60.SearchResultMessageFactory(), from6); + putRoutableFactory(MESSAGE_STATBUCKET, new RoutableFactories60.StatBucketMessageFactory(), from6); + putRoutableFactory(MESSAGE_UPDATEDOCUMENT, new RoutableFactories60.UpdateDocumentMessageFactory(), from6); + putRoutableFactory(MESSAGE_VISITORINFO, new RoutableFactories60.VisitorInfoMessageFactory(), from6); + putRoutableFactory(REPLY_CREATEVISITOR, new RoutableFactories60.CreateVisitorReplyFactory(), from6); + putRoutableFactory(REPLY_DESTROYVISITOR, new RoutableFactories60.DestroyVisitorReplyFactory(), from6); + putRoutableFactory(REPLY_DOCUMENTIGNORED, new RoutableFactories60.DocumentIgnoredReplyFactory(), from6); + putRoutableFactory(REPLY_DOCUMENTLIST, new RoutableFactories60.DocumentListReplyFactory(), from6); + putRoutableFactory(REPLY_DOCUMENTSUMMARY, new RoutableFactories60.DocumentSummaryReplyFactory(), from6); + putRoutableFactory(REPLY_EMPTYBUCKETS, new RoutableFactories60.EmptyBucketsReplyFactory(), from6); + putRoutableFactory(REPLY_GETBUCKETLIST, new RoutableFactories60.GetBucketListReplyFactory(), from6); + putRoutableFactory(REPLY_GETBUCKETSTATE, new RoutableFactories60.GetBucketStateReplyFactory(), from6); + putRoutableFactory(REPLY_GETDOCUMENT, new RoutableFactories60.GetDocumentReplyFactory(), from6); + putRoutableFactory(REPLY_MAPVISITOR, new RoutableFactories60.MapVisitorReplyFactory(), from6); + putRoutableFactory(REPLY_PUTDOCUMENT, new RoutableFactories60.PutDocumentReplyFactory(), from6); + putRoutableFactory(REPLY_QUERYRESULT, new RoutableFactories60.QueryResultReplyFactory(), from6); + putRoutableFactory(REPLY_REMOVEDOCUMENT, new RoutableFactories60.RemoveDocumentReplyFactory(), from6); + putRoutableFactory(REPLY_REMOVELOCATION, new RoutableFactories60.RemoveLocationReplyFactory(), from6); + putRoutableFactory(REPLY_SEARCHRESULT, new RoutableFactories60.SearchResultReplyFactory(), from6); + putRoutableFactory(REPLY_STATBUCKET, new RoutableFactories60.StatBucketReplyFactory(), from6); + putRoutableFactory(REPLY_UPDATEDOCUMENT, new RoutableFactories60.UpdateDocumentReplyFactory(), from6); + putRoutableFactory(REPLY_UPDATEDOCUMENT, new RoutableFactories60.UpdateDocumentReplyFactory(), from6); + putRoutableFactory(REPLY_VISITORINFO, new RoutableFactories60.VisitorInfoReplyFactory(), from6); + putRoutableFactory(REPLY_WRONGDISTRIBUTION, new RoutableFactories60.WrongDistributionReplyFactory(), from6); } /** diff --git a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories52.java b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories52.java deleted file mode 100644 index 89a0aa22bb3..00000000000 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories52.java +++ /dev/null @@ -1,953 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.documentapi.messagebus.protocol; - -import com.yahoo.document.BucketId; -import com.yahoo.document.Document; -import com.yahoo.document.DocumentId; -import com.yahoo.document.DocumentPut; -import com.yahoo.document.DocumentUpdate; -import com.yahoo.document.FixedBucketSpaces; -import com.yahoo.document.TestAndSetCondition; -import com.yahoo.document.serialization.DocumentDeserializer; -import com.yahoo.document.serialization.DocumentSerializer; -import com.yahoo.document.serialization.DocumentSerializerFactory; -import com.yahoo.documentapi.messagebus.loadtypes.LoadTypeSet; -import com.yahoo.log.LogLevel; -import com.yahoo.messagebus.Routable; -import com.yahoo.vdslib.DocumentList; -import com.yahoo.vdslib.DocumentSummary; -import com.yahoo.vdslib.SearchResult; -import com.yahoo.vdslib.VisitorStatistics; -import com.yahoo.vespa.objects.Deserializer; -import com.yahoo.vespa.objects.Serializer; - -import java.util.Map; -import java.util.logging.Logger; - -import static com.yahoo.documentapi.messagebus.protocol.AbstractRoutableFactory.decodeString; -import static com.yahoo.documentapi.messagebus.protocol.AbstractRoutableFactory.encodeString; - - -/** - * @author Vegard Sjonfjell - * This class encapsulates all the {@link RoutableFactory} classes needed to implement serialization for the document - * protocol. When adding new factories to this class, please KEEP THE THEM ORDERED alphabetically like they are now. - */ -public abstract class RoutableFactories52 { - - /** - * Implements the shared factory logic required for {@link DocumentMessage} objects, and it offers a more convenient - * interface for implementing {@link RoutableFactory}. - * - * @author Simon Thoresen Hult - */ - public static abstract class DocumentMessageFactory extends AbstractRoutableFactory { - - /** - * This method encodes the given message using the given serializer. You are guaranteed to only receive messages - * of the type that this factory was registered for. - * <p> - * This method is NOT exception safe. Return false to - * signal failure. - * - * @param msg The message to encode. - * @param serializer The serializer to use for encoding. - * @return True if the message was encoded. - */ - protected abstract boolean doEncode(DocumentMessage msg, DocumentSerializer serializer); - - /** - * This method decodes a message from the given deserializer. You are guaranteed to only receive byte buffers - * generated by a previous call to {@link #doEncode(DocumentMessage, DocumentSerializer)}. - * <p> - * This method is NOT exception safe. Return null to signal failure. - * - * @param deserializer The deserializer to use for decoding. - * @return The decoded message. - */ - protected abstract DocumentMessage doDecode(DocumentDeserializer deserializer); - - public boolean encode(Routable obj, DocumentSerializer out) { - if (!(obj instanceof DocumentMessage)) { - throw new AssertionError( - "Document message factory (" + getClass().getName() + ") registered for incompatible " + - "routable type " + obj.getType() + "(" + obj.getClass().getName() + ")."); - } - DocumentMessage msg = (DocumentMessage)obj; - out.putByte(null, (byte)(msg.getPriority().getValue())); - out.putInt(null, msg.getLoadType().getId()); - return doEncode(msg, out); - } - - public Routable decode(DocumentDeserializer in, LoadTypeSet loadTypes) { - byte pri = in.getByte(null); - int loadType = in.getInt(null); - DocumentMessage msg = doDecode(in); - if (msg != null) { - msg.setPriority(DocumentProtocol.getPriority(pri)); - msg.setLoadType(loadTypes.getIdMap().get(loadType)); - } - return msg; - } - } - - /** - * Implements the shared factory logic required for {@link DocumentReply} objects, and it offers a more convenient - * interface for implementing {@link RoutableFactory}. - * - * @author Simon Thoresen Hult - */ - public static abstract class DocumentReplyFactory extends AbstractRoutableFactory { - - /** - * This method encodes the given reply into the given byte buffer. You are guaranteed to only receive replies of - * the type that this factory was registered for. - * <p> - * This method is NOT exception safe. Return false to signal - * failure. - * - * @param reply The reply to encode. - * @param buf The byte buffer to write to. - * @return True if the message was encoded. - */ - protected abstract boolean doEncode(DocumentReply reply, DocumentSerializer buf); - - /** - * This method decodes a reply from the given byte buffer. You are guaranteed to only receive byte buffers - * generated by a previous call to {@link #doEncode(DocumentReply, com.yahoo.document.serialization.DocumentSerializer)}. - * - * <p> - * This method is NOT exception safe. Return null to signal failure. - * - * @param buf The byte buffer to read from. - * @return The decoded reply. - */ - protected abstract DocumentReply doDecode(DocumentDeserializer buf); - - public boolean encode(Routable obj, DocumentSerializer out) { - if (!(obj instanceof DocumentReply)) { - throw new AssertionError( - "Document reply factory (" + getClass().getName() + ") registered for incompatible " + - "routable type " + obj.getType() + "(" + obj.getClass().getName() + ")."); - } - DocumentReply reply = (DocumentReply)obj; - out.putByte(null, (byte)(reply.getPriority().getValue())); - return doEncode(reply, out); - } - - public Routable decode(DocumentDeserializer in, LoadTypeSet loadTypes) { - byte pri = in.getByte(null); - DocumentReply reply = doDecode(in); - if (reply != null) { - reply.setPriority(DocumentProtocol.getPriority(pri)); - } - return reply; - } - } - - public static class CreateVisitorMessageFactory extends DocumentMessageFactory { - - protected String decodeBucketSpace(Deserializer deserializer) { - return FixedBucketSpaces.defaultSpace(); - } - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - CreateVisitorMessage msg = new CreateVisitorMessage(); - msg.setLibraryName(decodeString(buf)); - msg.setInstanceId(decodeString(buf)); - msg.setControlDestination(decodeString(buf)); - msg.setDataDestination(decodeString(buf)); - msg.setDocumentSelection(decodeString(buf)); - msg.setMaxPendingReplyCount(buf.getInt(null)); - - int size = buf.getInt(null); - for (int i = 0; i < size; i++) { - long reversed = buf.getLong(null); - long rawid = ((reversed >>> 56) & 0x00000000000000FFl) | ((reversed >>> 40) & 0x000000000000FF00l) | - ((reversed >>> 24) & 0x0000000000FF0000l) | ((reversed >>> 8) & 0x00000000FF000000l) | - ((reversed << 8) & 0x000000FF00000000l) | ((reversed << 24) & 0x0000FF0000000000l) | - ((reversed << 40) & 0x00FF000000000000l) | ((reversed << 56) & 0xFF00000000000000l); - msg.getBuckets().add(new BucketId(rawid)); - } - - msg.setFromTimestamp(buf.getLong(null)); - msg.setToTimestamp(buf.getLong(null)); - msg.setVisitRemoves(buf.getByte(null) == (byte)1); - msg.setFieldSet(decodeString(buf)); - msg.setVisitInconsistentBuckets(buf.getByte(null) == (byte)1); - - size = buf.getInt(null); - for (int i = 0; i < size; i++) { - String key = decodeString(buf); - int sz = buf.getInt(null); - msg.getParameters().put(key, buf.getBytes(null, sz)); - } - - msg.setVisitorOrdering(buf.getInt(null)); - msg.setMaxBucketsPerVisitor(buf.getInt(null)); - msg.setVisitorDispatcherVersion(50); - msg.setBucketSpace(decodeBucketSpace(buf)); - return msg; - } - - protected boolean encodeBucketSpace(String bucketSpace, DocumentSerializer buf) { - return FixedBucketSpaces.defaultSpace().equals(bucketSpace); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - CreateVisitorMessage msg = (CreateVisitorMessage)obj; - encodeString(msg.getLibraryName(), buf); - encodeString(msg.getInstanceId(), buf); - encodeString(msg.getControlDestination(), buf); - encodeString(msg.getDataDestination(), buf); - encodeString(msg.getDocumentSelection(), buf); - buf.putInt(null, msg.getMaxPendingReplyCount()); - - buf.putInt(null, msg.getBuckets().size()); - for (BucketId id : msg.getBuckets()) { - long rawid = id.getRawId(); - long reversed = ((rawid >>> 56) & 0x00000000000000FFl) | ((rawid >>> 40) & 0x000000000000FF00l) | - ((rawid >>> 24) & 0x0000000000FF0000l) | ((rawid >>> 8) & 0x00000000FF000000l) | - ((rawid << 8) & 0x000000FF00000000l) | ((rawid << 24) & 0x0000FF0000000000l) | - ((rawid << 40) & 0x00FF000000000000l) | ((rawid << 56) & 0xFF00000000000000l); - buf.putLong(null, reversed); - } - - buf.putLong(null, msg.getFromTimestamp()); - buf.putLong(null, msg.getToTimestamp()); - buf.putByte(null, msg.getVisitRemoves() ? (byte)1 : (byte)0); - encodeString(msg.getFieldSet(), buf); - buf.putByte(null, msg.getVisitInconsistentBuckets() ? (byte)1 : (byte)0); - - buf.putInt(null, msg.getParameters().size()); - for (Map.Entry<String, byte[]> pairs : msg.getParameters().entrySet()) { - encodeString(pairs.getKey(), buf); - byte[] b = pairs.getValue(); - buf.putInt(null, b.length); - buf.put(null, b); - } - - buf.putInt(null, msg.getVisitorOrdering()); - buf.putInt(null, msg.getMaxBucketsPerVisitor()); - return encodeBucketSpace(msg.getBucketSpace(), buf); - } - } - - public static class CreateVisitorReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - CreateVisitorReply reply = new CreateVisitorReply(DocumentProtocol.REPLY_CREATEVISITOR); - reply.setLastBucket(new BucketId(buf.getLong(null))); - - VisitorStatistics vs = new VisitorStatistics(); - vs.setBucketsVisited(buf.getInt(null)); - vs.setDocumentsVisited(buf.getLong(null)); - vs.setBytesVisited(buf.getLong(null)); - vs.setDocumentsReturned(buf.getLong(null)); - vs.setBytesReturned(buf.getLong(null)); - vs.setSecondPassDocumentsReturned(buf.getLong(null)); - vs.setSecondPassBytesReturned(buf.getLong(null)); - reply.setVisitorStatistics(vs); - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - CreateVisitorReply reply = (CreateVisitorReply)obj; - buf.putLong(null, reply.getLastBucket().getRawId()); - buf.putInt(null, reply.getVisitorStatistics().getBucketsVisited()); - buf.putLong(null, reply.getVisitorStatistics().getDocumentsVisited()); - buf.putLong(null, reply.getVisitorStatistics().getBytesVisited()); - buf.putLong(null, reply.getVisitorStatistics().getDocumentsReturned()); - buf.putLong(null, reply.getVisitorStatistics().getBytesReturned()); - buf.putLong(null, reply.getVisitorStatistics().getSecondPassDocumentsReturned()); - buf.putLong(null, reply.getVisitorStatistics().getSecondPassBytesReturned()); - return true; - } - } - - public static class DestroyVisitorMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - DestroyVisitorMessage msg = new DestroyVisitorMessage(); - msg.setInstanceId(decodeString(buf)); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - DestroyVisitorMessage msg = (DestroyVisitorMessage)obj; - encodeString(msg.getInstanceId(), buf); - return true; - } - } - - public static class DestroyVisitorReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_DESTROYVISITOR); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class DocumentIgnoredReplyFactory extends DocumentReplyFactory { - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new DocumentIgnoredReply(); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class DocumentListMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - DocumentListMessage msg = new DocumentListMessage(); - msg.setBucketId(new BucketId(buf.getLong(null))); - int len = buf.getInt(null); - for (int i = 0; i < len; i++) { - msg.getDocuments().add(new DocumentListEntry(buf)); - } - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - DocumentListMessage msg = (DocumentListMessage)obj; - buf.putLong(null, msg.getBucketId().getRawId()); - buf.putInt(null, msg.getDocuments().size()); - - for (int i = 0; i < msg.getDocuments().size(); i++) { - msg.getDocuments().get(i).serialize(buf); - } - return true; - } - } - - public static class DocumentListReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_DOCUMENTLIST); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class DocumentSummaryMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - DocumentSummaryMessage msg = new DocumentSummaryMessage(); - msg.setDocumentSummary(new DocumentSummary(buf)); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - return false; // not supported - } - } - - public static class DocumentSummaryReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_DOCUMENTSUMMARY); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class EmptyBucketsMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - EmptyBucketsMessage msg = new EmptyBucketsMessage(); - int size = buf.getInt(null); - for (int i = 0; i < size; ++i) { - msg.getBucketIds().add(new BucketId(buf.getLong(null))); - } - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - EmptyBucketsMessage msg = (EmptyBucketsMessage)obj; - buf.putInt(null, msg.getBucketIds().size()); - for (BucketId bid : msg.getBucketIds()) { - buf.putLong(null, bid.getRawId()); - } - return true; - } - } - - public static class EmptyBucketsReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_EMPTYBUCKETS); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class GetBucketListMessageFactory extends DocumentMessageFactory { - - protected String decodeBucketSpace(Deserializer deserializer) { - return FixedBucketSpaces.defaultSpace(); - } - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - GetBucketListMessage msg = new GetBucketListMessage(); - msg.setBucketId(new BucketId(buf.getLong(null))); - msg.setBucketSpace(decodeBucketSpace(buf)); - return msg; - } - - protected boolean encodeBucketSpace(String bucketSpace, DocumentSerializer buf) { - return FixedBucketSpaces.defaultSpace().equals(bucketSpace); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - GetBucketListMessage msg = (GetBucketListMessage)obj; - buf.putLong(null, msg.getBucketId().getRawId()); - return encodeBucketSpace(msg.getBucketSpace(), buf); - } - } - - public static class GetBucketListReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - GetBucketListReply reply = new GetBucketListReply(); - int len = buf.getInt(null); - for (int i = 0; i < len; i++) { - GetBucketListReply.BucketInfo info = new GetBucketListReply.BucketInfo(); - info.bucket = new BucketId(buf.getLong(null)); - info.bucketInformation = decodeString(buf); - reply.getBuckets().add(info); - } - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - GetBucketListReply reply = (GetBucketListReply)obj; - buf.putInt(null, reply.getBuckets().size()); - for (GetBucketListReply.BucketInfo info : reply.getBuckets()) { - buf.putLong(null, info.bucket.getRawId()); - encodeString(info.bucketInformation, buf); - } - return true; - } - } - - public static class GetBucketStateMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - GetBucketStateMessage msg = new GetBucketStateMessage(); - msg.setBucketId(new BucketId(buf.getLong(null))); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - GetBucketStateMessage msg = (GetBucketStateMessage)obj; - buf.putLong(null, msg.getBucketId().getRawId()); - return true; - } - } - - public static class GetBucketStateReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - GetBucketStateReply reply = new GetBucketStateReply(); - int size = buf.getInt(null); - for (int i = 0; i < size; i++) { - reply.getBucketState().add(new DocumentState(buf)); - } - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - GetBucketStateReply reply = (GetBucketStateReply)obj; - buf.putInt(null, reply.getBucketState().size()); - for (DocumentState stat : reply.getBucketState()) { - stat.serialize(buf); - } - return true; - } - } - - public static class GetDocumentMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - return new GetDocumentMessage(new DocumentId(buf), decodeString(buf)); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - GetDocumentMessage msg = (GetDocumentMessage)obj; - msg.getDocumentId().serialize(buf); - encodeString(msg.getFieldSet(), buf); - return true; - } - } - - public static class GetDocumentReplyFactory extends DocumentReplyFactory { - - private final LazyDecoder decoder = new LazyDecoder() { - - public void decode(Routable obj, DocumentDeserializer buf) { - GetDocumentReply reply = (GetDocumentReply)obj; - - Document doc = null; - byte flag = buf.getByte(null); - if (flag != 0) { - doc = Document.createDocument(buf); - reply.setDocument(doc); - } - long lastModified = buf.getLong(null); - reply.setLastModified(lastModified); - if (doc != null) { - doc.setLastModified(lastModified); - } - } - }; - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - GetDocumentReply reply = new GetDocumentReply(decoder, buf); - - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - GetDocumentReply reply = (GetDocumentReply)obj; - if (reply.getSerializedBuffer() != null) { - buf.put(null, reply.getSerializedBuffer()); - } else { - Document document = reply.getDocument(); - buf.putByte(null, (byte)(document == null ? 0 : 1)); - if (document != null) { - document.serialize(buf); - } - buf.putLong(null, reply.getLastModified()); - } - return true; - } - } - - public static class MapVisitorMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - MapVisitorMessage msg = new MapVisitorMessage(); - int size = buf.getInt(null); - for (int i = 0; i < size; i++) { - String key = decodeString(buf); - String value = decodeString(buf); - msg.getData().put(key, value); - } - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - MapVisitorMessage msg = (MapVisitorMessage)obj; - buf.putInt(null, msg.getData().size()); - for (Map.Entry<String, String> pairs : msg.getData().entrySet()) { - encodeString(pairs.getKey(), buf); - encodeString(pairs.getValue(), buf); - } - return true; - } - } - - public static class MapVisitorReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_MAPVISITOR); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class PutDocumentMessageFactory extends DocumentMessageFactory { - protected void decodeInto(PutDocumentMessage msg, DocumentDeserializer buf) { - msg.setDocumentPut(new DocumentPut(Document.createDocument(buf))); - msg.setTimestamp(buf.getLong(null)); - decodeTasCondition(msg, buf); - } - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buffer) { - final LazyDecoder decoder = (obj, buf) -> { - decodeInto((PutDocumentMessage) obj, buf); - }; - - return new PutDocumentMessage(decoder, buffer); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - PutDocumentMessage msg = (PutDocumentMessage)obj; - if (msg.getSerializedBuffer() != null) { - buf.put(null, msg.getSerializedBuffer()); - } else { - msg.getDocumentPut().getDocument().serialize(buf); - buf.putLong(null, msg.getTimestamp()); - encodeTasCondition(buf, (TestAndSetMessage) obj); - } - return true; - } - } - - public static class PutDocumentReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - WriteDocumentReply rep = new WriteDocumentReply(DocumentProtocol.REPLY_PUTDOCUMENT); - rep.setHighestModificationTimestamp(buf.getLong(null)); - return rep; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - WriteDocumentReply rep = (WriteDocumentReply)obj; - buf.putLong(null, rep.getHighestModificationTimestamp()); - return true; - } - } - - public static class RemoveDocumentMessageFactory extends DocumentMessageFactory { - protected void decodeInto(RemoveDocumentMessage msg, DocumentDeserializer buf) { - msg.setDocumentId(new DocumentId(buf)); - decodeTasCondition(msg, buf); - } - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - RemoveDocumentMessage msg = new RemoveDocumentMessage(); - decodeInto(msg, buf); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - RemoveDocumentMessage msg = (RemoveDocumentMessage)obj; - msg.getDocumentId().serialize(buf); - encodeTasCondition(buf, (TestAndSetMessage) obj); - return true; - } - } - - public static class RemoveDocumentReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - RemoveDocumentReply reply = new RemoveDocumentReply(); - byte flag = buf.getByte(null); - reply.setWasFound(flag != 0); - reply.setHighestModificationTimestamp(buf.getLong(null)); - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - RemoveDocumentReply reply = (RemoveDocumentReply)obj; - buf.putByte(null, (byte)(reply.wasFound() ? 1 : 0)); - buf.putLong(null, reply.getHighestModificationTimestamp()); - return true; - } - } - - public static class RemoveLocationMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - return new RemoveLocationMessage(decodeString(buf)); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - RemoveLocationMessage msg = (RemoveLocationMessage)obj; - encodeString(msg.getDocumentSelection(), buf); - return true; - } - } - - public static class RemoveLocationReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new DocumentReply(DocumentProtocol.REPLY_REMOVELOCATION); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class SearchResultMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - SearchResultMessage msg = new SearchResultMessage(); - msg.setSearchResult(new SearchResult(buf)); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - return false; // not supported - } - } - - public static class QueryResultMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - QueryResultMessage msg = new QueryResultMessage(); - msg.setSearchResult(new SearchResult(buf)); - msg.setSummary(new DocumentSummary(buf)); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - return false; // not supported - } - } - - public static class SearchResultReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_SEARCHRESULT); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class QueryResultReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_QUERYRESULT); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class StatBucketMessageFactory extends DocumentMessageFactory { - - protected String decodeBucketSpace(Deserializer deserializer) { - return FixedBucketSpaces.defaultSpace(); - } - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - StatBucketMessage msg = new StatBucketMessage(); - msg.setBucketId(new BucketId(buf.getLong(null))); - msg.setDocumentSelection(decodeString(buf)); - msg.setBucketSpace(decodeBucketSpace(buf)); - return msg; - } - - protected boolean encodeBucketSpace(String bucketSpace, DocumentSerializer buf) { - return FixedBucketSpaces.defaultSpace().equals(bucketSpace); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - StatBucketMessage msg = (StatBucketMessage)obj; - buf.putLong(null, msg.getBucketId().getRawId()); - encodeString(msg.getDocumentSelection(), buf); - return encodeBucketSpace(msg.getBucketSpace(), buf); - } - } - - public static class StatBucketReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - StatBucketReply reply = new StatBucketReply(); - reply.setResults(decodeString(buf)); - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - StatBucketReply reply = (StatBucketReply)obj; - encodeString(reply.getResults(), buf); - return true; - } - } - - public static class UpdateDocumentMessageFactory extends DocumentMessageFactory { - protected void decodeInto(UpdateDocumentMessage msg, DocumentDeserializer buf) { - msg.setDocumentUpdate(new DocumentUpdate(buf)); - msg.setOldTimestamp(buf.getLong(null)); - msg.setNewTimestamp(buf.getLong(null)); - decodeTasCondition(msg, buf); - } - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buffer) { - final LazyDecoder decoder = (obj, buf) -> { - decodeInto((UpdateDocumentMessage) obj, buf); - }; - - return new UpdateDocumentMessage(decoder, buffer); - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - UpdateDocumentMessage msg = (UpdateDocumentMessage)obj; - if (msg.getSerializedBuffer() != null) { - buf.put(null, msg.getSerializedBuffer()); - } else { - msg.getDocumentUpdate().serialize(buf); - buf.putLong(null, msg.getOldTimestamp()); - buf.putLong(null, msg.getNewTimestamp()); - encodeTasCondition(buf, (TestAndSetMessage) obj); - } - return true; - } - } - - public static class UpdateDocumentReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - UpdateDocumentReply rep = new UpdateDocumentReply(); - byte flag = buf.getByte(null); - rep.setWasFound(flag != 0); - rep.setHighestModificationTimestamp(buf.getLong(null)); - return rep; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - UpdateDocumentReply rep = (UpdateDocumentReply)obj; - buf.putByte(null, (byte)(rep.wasFound() ? 1 : 0)); - buf.putLong(null, rep.getHighestModificationTimestamp()); - return true; - } - } - - public static class VisitorInfoMessageFactory extends DocumentMessageFactory { - - @Override - protected DocumentMessage doDecode(DocumentDeserializer buf) { - VisitorInfoMessage msg = new VisitorInfoMessage(); - int size = buf.getInt(null); - for (int i = 0; i < size; i++) { - long reversed = buf.getLong(null); - long rawid = ((reversed >>> 56) & 0x00000000000000FFl) | ((reversed >>> 40) & 0x000000000000FF00l) | - ((reversed >>> 24) & 0x0000000000FF0000l) | ((reversed >>> 8) & 0x00000000FF000000l) | - ((reversed << 8) & 0x000000FF00000000l) | ((reversed << 24) & 0x0000FF0000000000l) | - ((reversed << 40) & 0x00FF000000000000l) | ((reversed << 56) & 0xFF00000000000000l); - msg.getFinishedBuckets().add(new BucketId(rawid)); - } - - msg.setErrorMessage(decodeString(buf)); - return msg; - } - - @Override - protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { - VisitorInfoMessage msg = (VisitorInfoMessage)obj; - buf.putInt(null, msg.getFinishedBuckets().size()); - for (BucketId id : msg.getFinishedBuckets()) { - long rawid = id.getRawId(); - long reversed = ((rawid >>> 56) & 0x00000000000000FFl) | ((rawid >>> 40) & 0x000000000000FF00l) | - ((rawid >>> 24) & 0x0000000000FF0000l) | ((rawid >>> 8) & 0x00000000FF000000l) | - ((rawid << 8) & 0x000000FF00000000l) | ((rawid << 24) & 0x0000FF0000000000l) | - ((rawid << 40) & 0x00FF000000000000l) | ((rawid << 56) & 0xFF00000000000000l); - buf.putLong(null, reversed); - } - encodeString(msg.getErrorMessage(), buf); - return true; - } - } - - public static class VisitorInfoReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - return new VisitorReply(DocumentProtocol.REPLY_VISITORINFO); - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - return true; - } - } - - public static class WrongDistributionReplyFactory extends DocumentReplyFactory { - - @Override - protected DocumentReply doDecode(DocumentDeserializer buf) { - WrongDistributionReply reply = new WrongDistributionReply(); - reply.setSystemState(decodeString(buf)); - return reply; - } - - @Override - protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { - WrongDistributionReply reply = (WrongDistributionReply)obj; - encodeString(reply.getSystemState(), buf); - return true; - } - } - static void decodeTasCondition(TestAndSetMessage msg, DocumentDeserializer buf) { - msg.setCondition(new TestAndSetCondition(decodeString(buf))); - } - - static void encodeTasCondition(DocumentSerializer buf, TestAndSetMessage msg) { - encodeString(msg.getCondition().getSelection(), buf); - } -} diff --git a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories60.java b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories60.java index 723760df117..af3ff2992e5 100644 --- a/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories60.java +++ b/documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories60.java @@ -1,48 +1,955 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.documentapi.messagebus.protocol; +import com.yahoo.document.BucketId; +import com.yahoo.document.Document; +import com.yahoo.document.DocumentId; +import com.yahoo.document.DocumentPut; +import com.yahoo.document.DocumentUpdate; +import com.yahoo.document.FixedBucketSpaces; +import com.yahoo.document.TestAndSetCondition; +import com.yahoo.document.serialization.DocumentDeserializer; import com.yahoo.document.serialization.DocumentSerializer; +import com.yahoo.document.serialization.DocumentSerializerFactory; +import com.yahoo.documentapi.messagebus.loadtypes.LoadTypeSet; +import com.yahoo.log.LogLevel; +import com.yahoo.messagebus.Routable; +import com.yahoo.vdslib.DocumentSummary; +import com.yahoo.vdslib.SearchResult; +import com.yahoo.vdslib.VisitorStatistics; import com.yahoo.vespa.objects.Deserializer; +import com.yahoo.vespa.objects.Serializer; -public class RoutableFactories60 extends RoutableFactories52 { +import java.util.Map; +import java.util.logging.Logger; + +import static com.yahoo.documentapi.messagebus.protocol.AbstractRoutableFactory.decodeString; +import static com.yahoo.documentapi.messagebus.protocol.AbstractRoutableFactory.encodeString; + + +/** + * @author Vegard Sjonfjell + * This class encapsulates all the {@link RoutableFactory} classes needed to implement serialization for the document + * protocol. When adding new factories to this class, please KEEP THE THEM ORDERED alphabetically like they are now. + */ +public abstract class RoutableFactories60 { + + /** + * Implements the shared factory logic required for {@link DocumentMessage} objects, and it offers a more convenient + * interface for implementing {@link RoutableFactory}. + * + * @author Simon Thoresen Hult + */ + public static abstract class DocumentMessageFactory extends AbstractRoutableFactory { + + /** + * This method encodes the given message using the given serializer. You are guaranteed to only receive messages + * of the type that this factory was registered for. + * <p> + * This method is NOT exception safe. Return false to + * signal failure. + * + * @param msg The message to encode. + * @param serializer The serializer to use for encoding. + * @return True if the message was encoded. + */ + protected abstract boolean doEncode(DocumentMessage msg, DocumentSerializer serializer); + + /** + * This method decodes a message from the given deserializer. You are guaranteed to only receive byte buffers + * generated by a previous call to {@link #doEncode(DocumentMessage, DocumentSerializer)}. + * <p> + * This method is NOT exception safe. Return null to signal failure. + * + * @param deserializer The deserializer to use for decoding. + * @return The decoded message. + */ + protected abstract DocumentMessage doDecode(DocumentDeserializer deserializer); + + public boolean encode(Routable obj, DocumentSerializer out) { + if (!(obj instanceof DocumentMessage)) { + throw new AssertionError( + "Document message factory (" + getClass().getName() + ") registered for incompatible " + + "routable type " + obj.getType() + "(" + obj.getClass().getName() + ")."); + } + DocumentMessage msg = (DocumentMessage)obj; + out.putByte(null, (byte)(msg.getPriority().getValue())); + out.putInt(null, msg.getLoadType().getId()); + return doEncode(msg, out); + } + + public Routable decode(DocumentDeserializer in, LoadTypeSet loadTypes) { + byte pri = in.getByte(null); + int loadType = in.getInt(null); + DocumentMessage msg = doDecode(in); + if (msg != null) { + msg.setPriority(DocumentProtocol.getPriority(pri)); + msg.setLoadType(loadTypes.getIdMap().get(loadType)); + } + return msg; + } + } + + /** + * Implements the shared factory logic required for {@link DocumentReply} objects, and it offers a more convenient + * interface for implementing {@link RoutableFactory}. + * + * @author Simon Thoresen Hult + */ + public static abstract class DocumentReplyFactory extends AbstractRoutableFactory { + + /** + * This method encodes the given reply into the given byte buffer. You are guaranteed to only receive replies of + * the type that this factory was registered for. + * <p> + * This method is NOT exception safe. Return false to signal + * failure. + * + * @param reply The reply to encode. + * @param buf The byte buffer to write to. + * @return True if the message was encoded. + */ + protected abstract boolean doEncode(DocumentReply reply, DocumentSerializer buf); + + /** + * This method decodes a reply from the given byte buffer. You are guaranteed to only receive byte buffers + * generated by a previous call to {@link #doEncode(DocumentReply, com.yahoo.document.serialization.DocumentSerializer)}. + * + * <p> + * This method is NOT exception safe. Return null to signal failure. + * + * @param buf The byte buffer to read from. + * @return The decoded reply. + */ + protected abstract DocumentReply doDecode(DocumentDeserializer buf); + + public boolean encode(Routable obj, DocumentSerializer out) { + if (!(obj instanceof DocumentReply)) { + throw new AssertionError( + "Document reply factory (" + getClass().getName() + ") registered for incompatible " + + "routable type " + obj.getType() + "(" + obj.getClass().getName() + ")."); + } + DocumentReply reply = (DocumentReply)obj; + out.putByte(null, (byte)(reply.getPriority().getValue())); + return doEncode(reply, out); + } + + public Routable decode(DocumentDeserializer in, LoadTypeSet loadTypes) { + byte pri = in.getByte(null); + DocumentReply reply = doDecode(in); + if (reply != null) { + reply.setPriority(DocumentProtocol.getPriority(pri)); + } + return reply; + } + } + + public static class CreateVisitorMessageFactory extends DocumentMessageFactory { - public static class CreateVisitorMessageFactory extends RoutableFactories52.CreateVisitorMessageFactory { - @Override protected String decodeBucketSpace(Deserializer deserializer) { return decodeString(deserializer); } @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + CreateVisitorMessage msg = new CreateVisitorMessage(); + msg.setLibraryName(decodeString(buf)); + msg.setInstanceId(decodeString(buf)); + msg.setControlDestination(decodeString(buf)); + msg.setDataDestination(decodeString(buf)); + msg.setDocumentSelection(decodeString(buf)); + msg.setMaxPendingReplyCount(buf.getInt(null)); + + int size = buf.getInt(null); + for (int i = 0; i < size; i++) { + long reversed = buf.getLong(null); + long rawid = ((reversed >>> 56) & 0x00000000000000FFl) | ((reversed >>> 40) & 0x000000000000FF00l) | + ((reversed >>> 24) & 0x0000000000FF0000l) | ((reversed >>> 8) & 0x00000000FF000000l) | + ((reversed << 8) & 0x000000FF00000000l) | ((reversed << 24) & 0x0000FF0000000000l) | + ((reversed << 40) & 0x00FF000000000000l) | ((reversed << 56) & 0xFF00000000000000l); + msg.getBuckets().add(new BucketId(rawid)); + } + + msg.setFromTimestamp(buf.getLong(null)); + msg.setToTimestamp(buf.getLong(null)); + msg.setVisitRemoves(buf.getByte(null) == (byte)1); + msg.setFieldSet(decodeString(buf)); + msg.setVisitInconsistentBuckets(buf.getByte(null) == (byte)1); + + size = buf.getInt(null); + for (int i = 0; i < size; i++) { + String key = decodeString(buf); + int sz = buf.getInt(null); + msg.getParameters().put(key, buf.getBytes(null, sz)); + } + + msg.setVisitorOrdering(buf.getInt(null)); + msg.setMaxBucketsPerVisitor(buf.getInt(null)); + msg.setVisitorDispatcherVersion(50); + msg.setBucketSpace(decodeBucketSpace(buf)); + return msg; + } + protected boolean encodeBucketSpace(String bucketSpace, DocumentSerializer buf) { encodeString(bucketSpace, buf); return true; } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + CreateVisitorMessage msg = (CreateVisitorMessage)obj; + encodeString(msg.getLibraryName(), buf); + encodeString(msg.getInstanceId(), buf); + encodeString(msg.getControlDestination(), buf); + encodeString(msg.getDataDestination(), buf); + encodeString(msg.getDocumentSelection(), buf); + buf.putInt(null, msg.getMaxPendingReplyCount()); + + buf.putInt(null, msg.getBuckets().size()); + for (BucketId id : msg.getBuckets()) { + long rawid = id.getRawId(); + long reversed = ((rawid >>> 56) & 0x00000000000000FFl) | ((rawid >>> 40) & 0x000000000000FF00l) | + ((rawid >>> 24) & 0x0000000000FF0000l) | ((rawid >>> 8) & 0x00000000FF000000l) | + ((rawid << 8) & 0x000000FF00000000l) | ((rawid << 24) & 0x0000FF0000000000l) | + ((rawid << 40) & 0x00FF000000000000l) | ((rawid << 56) & 0xFF00000000000000l); + buf.putLong(null, reversed); + } + + buf.putLong(null, msg.getFromTimestamp()); + buf.putLong(null, msg.getToTimestamp()); + buf.putByte(null, msg.getVisitRemoves() ? (byte)1 : (byte)0); + encodeString(msg.getFieldSet(), buf); + buf.putByte(null, msg.getVisitInconsistentBuckets() ? (byte)1 : (byte)0); + + buf.putInt(null, msg.getParameters().size()); + for (Map.Entry<String, byte[]> pairs : msg.getParameters().entrySet()) { + encodeString(pairs.getKey(), buf); + byte[] b = pairs.getValue(); + buf.putInt(null, b.length); + buf.put(null, b); + } + + buf.putInt(null, msg.getVisitorOrdering()); + buf.putInt(null, msg.getMaxBucketsPerVisitor()); + return encodeBucketSpace(msg.getBucketSpace(), buf); + } + } + + public static class CreateVisitorReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + CreateVisitorReply reply = new CreateVisitorReply(DocumentProtocol.REPLY_CREATEVISITOR); + reply.setLastBucket(new BucketId(buf.getLong(null))); + + VisitorStatistics vs = new VisitorStatistics(); + vs.setBucketsVisited(buf.getInt(null)); + vs.setDocumentsVisited(buf.getLong(null)); + vs.setBytesVisited(buf.getLong(null)); + vs.setDocumentsReturned(buf.getLong(null)); + vs.setBytesReturned(buf.getLong(null)); + vs.setSecondPassDocumentsReturned(buf.getLong(null)); + vs.setSecondPassBytesReturned(buf.getLong(null)); + reply.setVisitorStatistics(vs); + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + CreateVisitorReply reply = (CreateVisitorReply)obj; + buf.putLong(null, reply.getLastBucket().getRawId()); + buf.putInt(null, reply.getVisitorStatistics().getBucketsVisited()); + buf.putLong(null, reply.getVisitorStatistics().getDocumentsVisited()); + buf.putLong(null, reply.getVisitorStatistics().getBytesVisited()); + buf.putLong(null, reply.getVisitorStatistics().getDocumentsReturned()); + buf.putLong(null, reply.getVisitorStatistics().getBytesReturned()); + buf.putLong(null, reply.getVisitorStatistics().getSecondPassDocumentsReturned()); + buf.putLong(null, reply.getVisitorStatistics().getSecondPassBytesReturned()); + return true; + } + } + + public static class DestroyVisitorMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + DestroyVisitorMessage msg = new DestroyVisitorMessage(); + msg.setInstanceId(decodeString(buf)); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + DestroyVisitorMessage msg = (DestroyVisitorMessage)obj; + encodeString(msg.getInstanceId(), buf); + return true; + } + } + + public static class DestroyVisitorReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_DESTROYVISITOR); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class DocumentIgnoredReplyFactory extends DocumentReplyFactory { + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new DocumentIgnoredReply(); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class DocumentListMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + DocumentListMessage msg = new DocumentListMessage(); + msg.setBucketId(new BucketId(buf.getLong(null))); + int len = buf.getInt(null); + for (int i = 0; i < len; i++) { + msg.getDocuments().add(new DocumentListEntry(buf)); + } + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + DocumentListMessage msg = (DocumentListMessage)obj; + buf.putLong(null, msg.getBucketId().getRawId()); + buf.putInt(null, msg.getDocuments().size()); + + for (int i = 0; i < msg.getDocuments().size(); i++) { + msg.getDocuments().get(i).serialize(buf); + } + return true; + } + } + + public static class DocumentListReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_DOCUMENTLIST); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class DocumentSummaryMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + DocumentSummaryMessage msg = new DocumentSummaryMessage(); + msg.setDocumentSummary(new DocumentSummary(buf)); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + return false; // not supported + } + } + + public static class DocumentSummaryReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_DOCUMENTSUMMARY); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class EmptyBucketsMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + EmptyBucketsMessage msg = new EmptyBucketsMessage(); + int size = buf.getInt(null); + for (int i = 0; i < size; ++i) { + msg.getBucketIds().add(new BucketId(buf.getLong(null))); + } + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + EmptyBucketsMessage msg = (EmptyBucketsMessage)obj; + buf.putInt(null, msg.getBucketIds().size()); + for (BucketId bid : msg.getBucketIds()) { + buf.putLong(null, bid.getRawId()); + } + return true; + } } - public static class StatBucketMessageFactory extends RoutableFactories52.StatBucketMessageFactory { + public static class EmptyBucketsReplyFactory extends DocumentReplyFactory { + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_EMPTYBUCKETS); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class GetBucketListMessageFactory extends DocumentMessageFactory { + protected String decodeBucketSpace(Deserializer deserializer) { return decodeString(deserializer); } @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + GetBucketListMessage msg = new GetBucketListMessage(); + msg.setBucketId(new BucketId(buf.getLong(null))); + msg.setBucketSpace(decodeBucketSpace(buf)); + return msg; + } + protected boolean encodeBucketSpace(String bucketSpace, DocumentSerializer buf) { encodeString(bucketSpace, buf); return true; } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + GetBucketListMessage msg = (GetBucketListMessage)obj; + buf.putLong(null, msg.getBucketId().getRawId()); + return encodeBucketSpace(msg.getBucketSpace(), buf); + } + } + + public static class GetBucketListReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + GetBucketListReply reply = new GetBucketListReply(); + int len = buf.getInt(null); + for (int i = 0; i < len; i++) { + GetBucketListReply.BucketInfo info = new GetBucketListReply.BucketInfo(); + info.bucket = new BucketId(buf.getLong(null)); + info.bucketInformation = decodeString(buf); + reply.getBuckets().add(info); + } + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + GetBucketListReply reply = (GetBucketListReply)obj; + buf.putInt(null, reply.getBuckets().size()); + for (GetBucketListReply.BucketInfo info : reply.getBuckets()) { + buf.putLong(null, info.bucket.getRawId()); + encodeString(info.bucketInformation, buf); + } + return true; + } + } + + public static class GetBucketStateMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + GetBucketStateMessage msg = new GetBucketStateMessage(); + msg.setBucketId(new BucketId(buf.getLong(null))); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + GetBucketStateMessage msg = (GetBucketStateMessage)obj; + buf.putLong(null, msg.getBucketId().getRawId()); + return true; + } + } + + public static class GetBucketStateReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + GetBucketStateReply reply = new GetBucketStateReply(); + int size = buf.getInt(null); + for (int i = 0; i < size; i++) { + reply.getBucketState().add(new DocumentState(buf)); + } + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + GetBucketStateReply reply = (GetBucketStateReply)obj; + buf.putInt(null, reply.getBucketState().size()); + for (DocumentState stat : reply.getBucketState()) { + stat.serialize(buf); + } + return true; + } + } + + public static class GetDocumentMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + return new GetDocumentMessage(new DocumentId(buf), decodeString(buf)); + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + GetDocumentMessage msg = (GetDocumentMessage)obj; + msg.getDocumentId().serialize(buf); + encodeString(msg.getFieldSet(), buf); + return true; + } } - public static class GetBucketListMessageFactory extends RoutableFactories52.GetBucketListMessageFactory { + public static class GetDocumentReplyFactory extends DocumentReplyFactory { + + private final LazyDecoder decoder = new LazyDecoder() { + + public void decode(Routable obj, DocumentDeserializer buf) { + GetDocumentReply reply = (GetDocumentReply)obj; + + Document doc = null; + byte flag = buf.getByte(null); + if (flag != 0) { + doc = Document.createDocument(buf); + reply.setDocument(doc); + } + long lastModified = buf.getLong(null); + reply.setLastModified(lastModified); + if (doc != null) { + doc.setLastModified(lastModified); + } + } + }; + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + GetDocumentReply reply = new GetDocumentReply(decoder, buf); + + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + GetDocumentReply reply = (GetDocumentReply)obj; + if (reply.getSerializedBuffer() != null) { + buf.put(null, reply.getSerializedBuffer()); + } else { + Document document = reply.getDocument(); + buf.putByte(null, (byte)(document == null ? 0 : 1)); + if (document != null) { + document.serialize(buf); + } + buf.putLong(null, reply.getLastModified()); + } + return true; + } + } + + public static class MapVisitorMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + MapVisitorMessage msg = new MapVisitorMessage(); + int size = buf.getInt(null); + for (int i = 0; i < size; i++) { + String key = decodeString(buf); + String value = decodeString(buf); + msg.getData().put(key, value); + } + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + MapVisitorMessage msg = (MapVisitorMessage)obj; + buf.putInt(null, msg.getData().size()); + for (Map.Entry<String, String> pairs : msg.getData().entrySet()) { + encodeString(pairs.getKey(), buf); + encodeString(pairs.getValue(), buf); + } + return true; + } + } + + public static class MapVisitorReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_MAPVISITOR); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class PutDocumentMessageFactory extends DocumentMessageFactory { + protected void decodeInto(PutDocumentMessage msg, DocumentDeserializer buf) { + msg.setDocumentPut(new DocumentPut(Document.createDocument(buf))); + msg.setTimestamp(buf.getLong(null)); + decodeTasCondition(msg, buf); + } + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buffer) { + final LazyDecoder decoder = (obj, buf) -> { + decodeInto((PutDocumentMessage) obj, buf); + }; + + return new PutDocumentMessage(decoder, buffer); + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + PutDocumentMessage msg = (PutDocumentMessage)obj; + if (msg.getSerializedBuffer() != null) { + buf.put(null, msg.getSerializedBuffer()); + } else { + msg.getDocumentPut().getDocument().serialize(buf); + buf.putLong(null, msg.getTimestamp()); + encodeTasCondition(buf, (TestAndSetMessage) obj); + } + return true; + } + } + + public static class PutDocumentReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + WriteDocumentReply rep = new WriteDocumentReply(DocumentProtocol.REPLY_PUTDOCUMENT); + rep.setHighestModificationTimestamp(buf.getLong(null)); + return rep; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + WriteDocumentReply rep = (WriteDocumentReply)obj; + buf.putLong(null, rep.getHighestModificationTimestamp()); + return true; + } + } + + public static class RemoveDocumentMessageFactory extends DocumentMessageFactory { + protected void decodeInto(RemoveDocumentMessage msg, DocumentDeserializer buf) { + msg.setDocumentId(new DocumentId(buf)); + decodeTasCondition(msg, buf); + } + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + RemoveDocumentMessage msg = new RemoveDocumentMessage(); + decodeInto(msg, buf); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + RemoveDocumentMessage msg = (RemoveDocumentMessage)obj; + msg.getDocumentId().serialize(buf); + encodeTasCondition(buf, (TestAndSetMessage) obj); + return true; + } + } + + public static class RemoveDocumentReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + RemoveDocumentReply reply = new RemoveDocumentReply(); + byte flag = buf.getByte(null); + reply.setWasFound(flag != 0); + reply.setHighestModificationTimestamp(buf.getLong(null)); + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + RemoveDocumentReply reply = (RemoveDocumentReply)obj; + buf.putByte(null, (byte)(reply.wasFound() ? 1 : 0)); + buf.putLong(null, reply.getHighestModificationTimestamp()); + return true; + } + } + + public static class RemoveLocationMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + return new RemoveLocationMessage(decodeString(buf)); + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + RemoveLocationMessage msg = (RemoveLocationMessage)obj; + encodeString(msg.getDocumentSelection(), buf); + return true; + } + } + + public static class RemoveLocationReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new DocumentReply(DocumentProtocol.REPLY_REMOVELOCATION); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class SearchResultMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + SearchResultMessage msg = new SearchResultMessage(); + msg.setSearchResult(new SearchResult(buf)); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + return false; // not supported + } + } + + public static class QueryResultMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + QueryResultMessage msg = new QueryResultMessage(); + msg.setSearchResult(new SearchResult(buf)); + msg.setSummary(new DocumentSummary(buf)); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + return false; // not supported + } + } + + public static class SearchResultReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_SEARCHRESULT); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class QueryResultReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_QUERYRESULT); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class StatBucketMessageFactory extends DocumentMessageFactory { + protected String decodeBucketSpace(Deserializer deserializer) { return decodeString(deserializer); } @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + StatBucketMessage msg = new StatBucketMessage(); + msg.setBucketId(new BucketId(buf.getLong(null))); + msg.setDocumentSelection(decodeString(buf)); + msg.setBucketSpace(decodeBucketSpace(buf)); + return msg; + } + protected boolean encodeBucketSpace(String bucketSpace, DocumentSerializer buf) { encodeString(bucketSpace, buf); return true; } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + StatBucketMessage msg = (StatBucketMessage)obj; + buf.putLong(null, msg.getBucketId().getRawId()); + encodeString(msg.getDocumentSelection(), buf); + return encodeBucketSpace(msg.getBucketSpace(), buf); + } + } + + public static class StatBucketReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + StatBucketReply reply = new StatBucketReply(); + reply.setResults(decodeString(buf)); + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + StatBucketReply reply = (StatBucketReply)obj; + encodeString(reply.getResults(), buf); + return true; + } } + public static class UpdateDocumentMessageFactory extends DocumentMessageFactory { + protected void decodeInto(UpdateDocumentMessage msg, DocumentDeserializer buf) { + msg.setDocumentUpdate(new DocumentUpdate(buf)); + msg.setOldTimestamp(buf.getLong(null)); + msg.setNewTimestamp(buf.getLong(null)); + decodeTasCondition(msg, buf); + } + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buffer) { + final LazyDecoder decoder = (obj, buf) -> { + decodeInto((UpdateDocumentMessage) obj, buf); + }; + + return new UpdateDocumentMessage(decoder, buffer); + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + UpdateDocumentMessage msg = (UpdateDocumentMessage)obj; + if (msg.getSerializedBuffer() != null) { + buf.put(null, msg.getSerializedBuffer()); + } else { + msg.getDocumentUpdate().serialize(buf); + buf.putLong(null, msg.getOldTimestamp()); + buf.putLong(null, msg.getNewTimestamp()); + encodeTasCondition(buf, (TestAndSetMessage) obj); + } + return true; + } + } + + public static class UpdateDocumentReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + UpdateDocumentReply rep = new UpdateDocumentReply(); + byte flag = buf.getByte(null); + rep.setWasFound(flag != 0); + rep.setHighestModificationTimestamp(buf.getLong(null)); + return rep; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + UpdateDocumentReply rep = (UpdateDocumentReply)obj; + buf.putByte(null, (byte)(rep.wasFound() ? 1 : 0)); + buf.putLong(null, rep.getHighestModificationTimestamp()); + return true; + } + } + + public static class VisitorInfoMessageFactory extends DocumentMessageFactory { + + @Override + protected DocumentMessage doDecode(DocumentDeserializer buf) { + VisitorInfoMessage msg = new VisitorInfoMessage(); + int size = buf.getInt(null); + for (int i = 0; i < size; i++) { + long reversed = buf.getLong(null); + long rawid = ((reversed >>> 56) & 0x00000000000000FFl) | ((reversed >>> 40) & 0x000000000000FF00l) | + ((reversed >>> 24) & 0x0000000000FF0000l) | ((reversed >>> 8) & 0x00000000FF000000l) | + ((reversed << 8) & 0x000000FF00000000l) | ((reversed << 24) & 0x0000FF0000000000l) | + ((reversed << 40) & 0x00FF000000000000l) | ((reversed << 56) & 0xFF00000000000000l); + msg.getFinishedBuckets().add(new BucketId(rawid)); + } + + msg.setErrorMessage(decodeString(buf)); + return msg; + } + + @Override + protected boolean doEncode(DocumentMessage obj, DocumentSerializer buf) { + VisitorInfoMessage msg = (VisitorInfoMessage)obj; + buf.putInt(null, msg.getFinishedBuckets().size()); + for (BucketId id : msg.getFinishedBuckets()) { + long rawid = id.getRawId(); + long reversed = ((rawid >>> 56) & 0x00000000000000FFl) | ((rawid >>> 40) & 0x000000000000FF00l) | + ((rawid >>> 24) & 0x0000000000FF0000l) | ((rawid >>> 8) & 0x00000000FF000000l) | + ((rawid << 8) & 0x000000FF00000000l) | ((rawid << 24) & 0x0000FF0000000000l) | + ((rawid << 40) & 0x00FF000000000000l) | ((rawid << 56) & 0xFF00000000000000l); + buf.putLong(null, reversed); + } + encodeString(msg.getErrorMessage(), buf); + return true; + } + } + + public static class VisitorInfoReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + return new VisitorReply(DocumentProtocol.REPLY_VISITORINFO); + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + return true; + } + } + + public static class WrongDistributionReplyFactory extends DocumentReplyFactory { + + @Override + protected DocumentReply doDecode(DocumentDeserializer buf) { + WrongDistributionReply reply = new WrongDistributionReply(); + reply.setSystemState(decodeString(buf)); + return reply; + } + + @Override + protected boolean doEncode(DocumentReply obj, DocumentSerializer buf) { + WrongDistributionReply reply = (WrongDistributionReply)obj; + encodeString(reply.getSystemState(), buf); + return true; + } + } + static void decodeTasCondition(TestAndSetMessage msg, DocumentDeserializer buf) { + msg.setCondition(new TestAndSetCondition(decodeString(buf))); + } + + static void encodeTasCondition(DocumentSerializer buf, TestAndSetMessage msg) { + encodeString(msg.getCondition().getSelection(), buf); + } } diff --git a/documentapi/src/test/java/com/yahoo/documentapi/VisitorDataQueueTest.java b/documentapi/src/test/java/com/yahoo/documentapi/VisitorDataQueueTest.java index fbe2abf2e20..7cd8cf05c8e 100644 --- a/documentapi/src/test/java/com/yahoo/documentapi/VisitorDataQueueTest.java +++ b/documentapi/src/test/java/com/yahoo/documentapi/VisitorDataQueueTest.java @@ -10,7 +10,6 @@ import com.yahoo.document.DocumentTypeManagerConfigurer; import com.yahoo.documentapi.messagebus.protocol.GetDocumentMessage; import com.yahoo.documentapi.messagebus.protocol.PutDocumentMessage; import com.yahoo.documentapi.messagebus.protocol.RemoveDocumentMessage; -import com.yahoo.vdslib.Entry; import org.junit.Before; import org.junit.Test; @@ -42,17 +41,15 @@ public class VisitorDataQueueTest { return new AckToken(new Object()); } - private static void assertNonNullDocumentListResponse(final VisitorResponse response) { + private static void assertNonNullDocumentOpResponse(final VisitorResponse response) { assertThat(response, notNullValue()); - assertThat(response, instanceOf(DocumentListVisitorResponse.class)); + assertThat(response, instanceOf(DocumentOpVisitorResponse.class)); } private static void assertResponseHasSinglePut(final VisitorResponse response, final DocumentPut expectedInstance) { - assertNonNullDocumentListResponse(response); - final DocumentListVisitorResponse visitorResponse = (DocumentListVisitorResponse)response; - assertThat(visitorResponse.getDocumentList().size(), equalTo(1)); - final Entry entry = visitorResponse.getDocumentList().get(0); - assertThat(entry.getDocumentOperation(), is(expectedInstance)); + assertNonNullDocumentOpResponse(response); + final DocumentOpVisitorResponse visitorResponse = (DocumentOpVisitorResponse)response; + assertThat(visitorResponse.getDocumentOperation(), is(expectedInstance)); } @Test @@ -78,13 +75,10 @@ public class VisitorDataQueueTest { } private static void assertResponseHasSingleRemove(final VisitorResponse response, final String docId) { - assertNonNullDocumentListResponse(response); - final DocumentListVisitorResponse visitorResponse = (DocumentListVisitorResponse)response; - assertThat(visitorResponse.getDocumentList().size(), equalTo(1)); - final Entry entry = visitorResponse.getDocumentList().get(0); - assertThat(entry.isRemoveEntry(), is(true)); - assertThat(entry.getDocumentOperation(), instanceOf(DocumentRemove.class)); - assertThat(entry.getDocumentOperation().getId(), equalTo(new DocumentId(docId))); + assertNonNullDocumentOpResponse(response); + final DocumentOpVisitorResponse visitorResponse = (DocumentOpVisitorResponse)response; + assertThat(visitorResponse.getDocumentOperation(), instanceOf(DocumentRemove.class)); + assertThat(visitorResponse.getDocumentOperation().getId(), equalTo(new DocumentId(docId))); } @Test diff --git a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages52TestCase.java b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages52TestCase.java deleted file mode 100644 index 448c8fcb520..00000000000 --- a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages52TestCase.java +++ /dev/null @@ -1,921 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.documentapi.messagebus.protocol.test; - -import com.yahoo.component.Version; -import com.yahoo.document.BucketId; -import com.yahoo.document.Document; -import com.yahoo.document.DocumentId; -import com.yahoo.document.DocumentPut; -import com.yahoo.document.DocumentType; -import com.yahoo.document.DocumentUpdate; -import com.yahoo.document.GlobalId; -import com.yahoo.document.TestAndSetCondition; -import com.yahoo.document.fieldpathupdate.RemoveFieldPathUpdate; -import com.yahoo.document.idstring.IdString; -import com.yahoo.document.select.OrderingSpecification; -import com.yahoo.documentapi.messagebus.protocol.CreateVisitorMessage; -import com.yahoo.documentapi.messagebus.protocol.CreateVisitorReply; -import com.yahoo.documentapi.messagebus.protocol.DestroyVisitorMessage; -import com.yahoo.documentapi.messagebus.protocol.DocumentIgnoredReply; -import com.yahoo.documentapi.messagebus.protocol.DocumentListMessage; -import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol; -import com.yahoo.documentapi.messagebus.protocol.DocumentReply; -import com.yahoo.documentapi.messagebus.protocol.DocumentState; -import com.yahoo.documentapi.messagebus.protocol.DocumentSummaryMessage; -import com.yahoo.documentapi.messagebus.protocol.EmptyBucketsMessage; -import com.yahoo.documentapi.messagebus.protocol.GetBucketListMessage; -import com.yahoo.documentapi.messagebus.protocol.GetBucketListReply; -import com.yahoo.documentapi.messagebus.protocol.GetBucketStateMessage; -import com.yahoo.documentapi.messagebus.protocol.GetBucketStateReply; -import com.yahoo.documentapi.messagebus.protocol.GetDocumentMessage; -import com.yahoo.documentapi.messagebus.protocol.GetDocumentReply; -import com.yahoo.documentapi.messagebus.protocol.MapVisitorMessage; -import com.yahoo.documentapi.messagebus.protocol.PutDocumentMessage; -import com.yahoo.documentapi.messagebus.protocol.QueryResultMessage; -import com.yahoo.documentapi.messagebus.protocol.RemoveDocumentMessage; -import com.yahoo.documentapi.messagebus.protocol.RemoveDocumentReply; -import com.yahoo.documentapi.messagebus.protocol.RemoveLocationMessage; -import com.yahoo.documentapi.messagebus.protocol.SearchResultMessage; -import com.yahoo.documentapi.messagebus.protocol.StatBucketMessage; -import com.yahoo.documentapi.messagebus.protocol.StatBucketReply; -import com.yahoo.documentapi.messagebus.protocol.UpdateDocumentMessage; -import com.yahoo.documentapi.messagebus.protocol.UpdateDocumentReply; -import com.yahoo.documentapi.messagebus.protocol.VisitorInfoMessage; -import com.yahoo.documentapi.messagebus.protocol.VisitorReply; -import com.yahoo.documentapi.messagebus.protocol.WriteDocumentReply; -import com.yahoo.documentapi.messagebus.protocol.WrongDistributionReply; -import com.yahoo.messagebus.Routable; -import com.yahoo.text.Utf8; -import com.yahoo.vdslib.SearchResult; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * @author Simon Thoresen Hult - * @author Vegard Sjonfjell - */ - -public class Messages52TestCase extends MessagesTestBase { - @Override - protected void registerTests(Map<Integer, RunnableTest> out) { - // This list MUST mirror the list of routable factories from the DocumentProtocol constructor that support - // version 5.2. When adding tests to this list, please KEEP THEM ORDERED alphabetically like they are now. - out.put(DocumentProtocol.MESSAGE_CREATEVISITOR, new testCreateVisitorMessage()); - out.put(DocumentProtocol.MESSAGE_DESTROYVISITOR, new testDestroyVisitorMessage()); - out.put(DocumentProtocol.MESSAGE_DOCUMENTLIST, new testDocumentListMessage()); - out.put(DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, new testDocumentSummaryMessage()); - out.put(DocumentProtocol.MESSAGE_EMPTYBUCKETS, new testEmptyBucketsMessage()); - out.put(DocumentProtocol.MESSAGE_GETBUCKETLIST, new testGetBucketListMessage()); - out.put(DocumentProtocol.MESSAGE_GETBUCKETSTATE, new testGetBucketStateMessage()); - out.put(DocumentProtocol.MESSAGE_GETDOCUMENT, new testGetDocumentMessage()); - out.put(DocumentProtocol.MESSAGE_MAPVISITOR, new testMapVisitorMessage()); - out.put(DocumentProtocol.MESSAGE_PUTDOCUMENT, new testPutDocumentMessage()); - out.put(DocumentProtocol.MESSAGE_QUERYRESULT, new testQueryResultMessage()); - out.put(DocumentProtocol.MESSAGE_REMOVEDOCUMENT, new testRemoveDocumentMessage()); - out.put(DocumentProtocol.MESSAGE_REMOVELOCATION, new testRemoveLocationMessage()); - out.put(DocumentProtocol.MESSAGE_SEARCHRESULT, new testSearchResultMessage()); - out.put(DocumentProtocol.MESSAGE_STATBUCKET, new testStatBucketMessage()); - out.put(DocumentProtocol.MESSAGE_UPDATEDOCUMENT, new testUpdateDocumentMessage()); - out.put(DocumentProtocol.MESSAGE_VISITORINFO, new testVisitorInfoMessage()); - out.put(DocumentProtocol.REPLY_CREATEVISITOR, new testCreateVisitorReply()); - out.put(DocumentProtocol.REPLY_DESTROYVISITOR, new testDestroyVisitorReply()); - out.put(DocumentProtocol.REPLY_DOCUMENTIGNORED, new testDocumentIgnoredReply()); - out.put(DocumentProtocol.REPLY_DOCUMENTLIST, new testDocumentListReply()); - out.put(DocumentProtocol.REPLY_DOCUMENTSUMMARY, new testDocumentSummaryReply()); - out.put(DocumentProtocol.REPLY_EMPTYBUCKETS, new testEmptyBucketsReply()); - out.put(DocumentProtocol.REPLY_GETBUCKETLIST, new testGetBucketListReply()); - out.put(DocumentProtocol.REPLY_GETBUCKETSTATE, new testGetBucketStateReply()); - out.put(DocumentProtocol.REPLY_GETDOCUMENT, new testGetDocumentReply()); - out.put(DocumentProtocol.REPLY_MAPVISITOR, new testMapVisitorReply()); - out.put(DocumentProtocol.REPLY_PUTDOCUMENT, new testPutDocumentReply()); - out.put(DocumentProtocol.REPLY_QUERYRESULT, new testQueryResultReply()); - out.put(DocumentProtocol.REPLY_REMOVEDOCUMENT, new testRemoveDocumentReply()); - out.put(DocumentProtocol.REPLY_REMOVELOCATION, new testRemoveLocationReply()); - out.put(DocumentProtocol.REPLY_SEARCHRESULT, new testSearchResultReply()); - out.put(DocumentProtocol.REPLY_STATBUCKET, new testStatBucketReply()); - out.put(DocumentProtocol.REPLY_UPDATEDOCUMENT, new testUpdateDocumentReply()); - out.put(DocumentProtocol.REPLY_VISITORINFO, new testVisitorInfoReply()); - out.put(DocumentProtocol.REPLY_WRONGDISTRIBUTION, new testWrongDistributionReply()); - } - - @Override - protected Version version() { - return new Version(5, 115, 0); - } - - @Override - protected boolean shouldTestCoverage() { - return true; - } - - //////////////////////////////////////////////////////////////////////////////// - // - // Tests - // - //////////////////////////////////////////////////////////////////////////////// - - protected static int BASE_MESSAGE_LENGTH = 5; - - public class testRemoveLocationMessage implements RunnableTest { - - @Override - public void run() { - { - RemoveLocationMessage msg = new RemoveLocationMessage("id.group == \"mygroup\""); - assertEquals(BASE_MESSAGE_LENGTH + 29, serialize("RemoveLocationMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (RemoveLocationMessage)deserialize("RemoveLocationMessage", DocumentProtocol.MESSAGE_REMOVELOCATION, lang); - assertEquals("id.group == \"mygroup\"", msg.getDocumentSelection()); - } - } - } - } - - public class testGetBucketListMessage implements RunnableTest { - - @Override - public void run() { - GetBucketListMessage msg = new GetBucketListMessage(new BucketId(16, 123)); - msg.setLoadType(loadTypes.getNameMap().get("foo")); - assertEquals(BASE_MESSAGE_LENGTH + 12, serialize("GetBucketListMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (GetBucketListMessage)deserialize("GetBucketListMessage", DocumentProtocol.MESSAGE_GETBUCKETLIST, lang); - assertEquals(new BucketId(16, 123), msg.getBucketId()); - assertEquals("foo", msg.getLoadType().getName()); - } - } - } - - - public class testStatBucketMessage implements RunnableTest { - - @Override - public void run() { - StatBucketMessage msg = new StatBucketMessage(new BucketId(16, 123), "id.user=123"); - msg.setLoadType(null); - assertEquals(BASE_MESSAGE_LENGTH + 27, serialize("StatBucketMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (StatBucketMessage)deserialize("StatBucketMessage", DocumentProtocol.MESSAGE_STATBUCKET, lang); - assertEquals(new BucketId(16, 123), msg.getBucketId()); - assertEquals("id.user=123", msg.getDocumentSelection()); - assertEquals("default", msg.getLoadType().getName()); - } - } - } - - public class testGetBucketStateMessage implements RunnableTest { - - @Override - public void run() { - GetBucketStateMessage msg = new GetBucketStateMessage(new BucketId(16, 666)); - assertEquals(BASE_MESSAGE_LENGTH + 12, serialize("GetBucketStateMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (GetBucketStateMessage)deserialize("GetBucketStateMessage", DocumentProtocol.MESSAGE_GETBUCKETSTATE, lang); - assertEquals(16, msg.getBucketId().getUsedBits()); - assertEquals(4611686018427388570l, msg.getBucketId().getId()); - } - } - } - - public class testCreateVisitorMessage implements RunnableTest { - - @Override - public void run() { - CreateVisitorMessage msg = new CreateVisitorMessage("SomeLibrary", "myvisitor", "newyork", "london"); - msg.setDocumentSelection("true and false or true"); - msg.getParameters().put("myvar", Utf8.toBytes("somevalue")); - msg.getParameters().put("anothervar", Utf8.toBytes("34")); - msg.getBuckets().add(new BucketId(16, 1234)); - msg.setVisitRemoves(true); - msg.setFieldSet("foo bar"); - msg.setVisitorOrdering(OrderingSpecification.DESCENDING); - msg.setMaxBucketsPerVisitor(2); - assertEquals(BASE_MESSAGE_LENGTH + 178, serialize("CreateVisitorMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (CreateVisitorMessage)deserialize("CreateVisitorMessage", DocumentProtocol.MESSAGE_CREATEVISITOR, lang); - assertEquals("SomeLibrary", msg.getLibraryName()); - assertEquals("myvisitor", msg.getInstanceId()); - assertEquals("newyork", msg.getControlDestination()); - assertEquals("london", msg.getDataDestination()); - assertEquals("true and false or true", msg.getDocumentSelection()); - assertEquals(8, msg.getMaxPendingReplyCount()); - assertEquals(true, msg.getVisitRemoves()); - assertEquals("foo bar", msg.getFieldSet()); - assertEquals(false, msg.getVisitInconsistentBuckets()); - assertEquals(1, msg.getBuckets().size()); - assertEquals(new BucketId(16, 1234), msg.getBuckets().iterator().next()); - assertEquals("somevalue", Utf8.toString(msg.getParameters().get("myvar"))); - assertEquals("34", Utf8.toString(msg.getParameters().get("anothervar"))); - assertEquals(OrderingSpecification.DESCENDING, msg.getVisitorOrdering()); - assertEquals(2, msg.getMaxBucketsPerVisitor()); - } - - msg.getBuckets().clear(); - - assertEquals("CreateVisitorMessage(" + - "No buckets, " + - "selection 'true and false or true', " + - "bucket space 'default', " + - "library SomeLibrary, including removes, " + - "get fields: foo bar" + - ")", - msg.toString()); - - msg.getBuckets().add(new BucketId(16, 1234)); - - assertEquals("CreateVisitorMessage(" + - "Bucket BucketId(0x40000000000004d2), " + - "selection 'true and false or true', " + - "bucket space 'default', " + - "library SomeLibrary, including removes, " + - "get fields: foo bar" + - ")", - msg.toString()); - - msg.getBuckets().add(new BucketId(16, 1235)); - msg.getBuckets().add(new BucketId(16, 1236)); - msg.getBuckets().add(new BucketId(16, 1237)); - msg.getBuckets().add(new BucketId(16, 1238)); - msg.setFromTimestamp(10001); - msg.setToTimestamp(20002); - msg.setVisitInconsistentBuckets(true); - assertEquals("CreateVisitorMessage(" + - "5 buckets: BucketId(0x40000000000004d2) BucketId(0x40000000000004d3) BucketId(0x40000000000004d4) ..., " + - "time 10001-20002, " + - "selection 'true and false or true', " + - "bucket space 'default', " + - "library SomeLibrary, including removes, " + - "get fields: foo bar, " + - "visit inconsistent buckets" + - ")", - msg.toString()); - } - } - - public class testCreateVisitorReply implements RunnableTest { - - @Override - public void run() { - CreateVisitorReply reply = new CreateVisitorReply(DocumentProtocol.REPLY_CREATEVISITOR); - reply.setLastBucket(new BucketId(16, 123)); - reply.getVisitorStatistics().setBucketsVisited(3); - reply.getVisitorStatistics().setDocumentsVisited(1000); - reply.getVisitorStatistics().setBytesVisited(1024000); - reply.getVisitorStatistics().setDocumentsReturned(123); - reply.getVisitorStatistics().setBytesReturned(512000); - reply.getVisitorStatistics().setSecondPassDocumentsReturned(456); - reply.getVisitorStatistics().setSecondPassBytesReturned(789100); - - assertEquals(65, serialize("CreateVisitorReply", reply)); - - for (Language lang : LANGUAGES) { - reply = (CreateVisitorReply)deserialize("CreateVisitorReply", DocumentProtocol.REPLY_CREATEVISITOR, lang); - assertNotNull(reply); - assertEquals(new BucketId(16, 123), reply.getLastBucket()); - assertEquals(3, reply.getVisitorStatistics().getBucketsVisited()); - assertEquals(1000, reply.getVisitorStatistics().getDocumentsVisited()); - assertEquals(1024000, reply.getVisitorStatistics().getBytesVisited()); - assertEquals(123, reply.getVisitorStatistics().getDocumentsReturned()); - assertEquals(512000, reply.getVisitorStatistics().getBytesReturned()); - assertEquals(456, reply.getVisitorStatistics().getSecondPassDocumentsReturned()); - assertEquals(789100, reply.getVisitorStatistics().getSecondPassBytesReturned()); - } - } - } - - public class testDestroyVisitorReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("DestroyVisitorReply", DocumentProtocol.REPLY_DESTROYVISITOR); - } - } - - public class testDocumentIgnoredReply implements RunnableTest { - - @Override - public void run() { - DocumentIgnoredReply reply = new DocumentIgnoredReply(); - assertEquals(BASE_MESSAGE_LENGTH, serialize("DocumentIgnoredReply", reply)); - - for (Language lang : LANGUAGES) { - reply = (DocumentIgnoredReply)deserialize("DocumentIgnoredReply", DocumentProtocol.REPLY_DOCUMENTIGNORED, lang); - } - } - } - - public class testDocumentListReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("DocumentListReply", DocumentProtocol.REPLY_DOCUMENTLIST); - } - } - - public class testDocumentSummaryReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("DocumentSummaryReply", DocumentProtocol.REPLY_DOCUMENTSUMMARY); - } - } - - public class testEmptyBucketsReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("EmptyBucketsReply", DocumentProtocol.REPLY_EMPTYBUCKETS); - } - } - - public class testDestroyVisitorMessage implements RunnableTest { - - @Override - public void run() { - DestroyVisitorMessage msg = new DestroyVisitorMessage("myvisitor"); - assertEquals(BASE_MESSAGE_LENGTH + 17, serialize("DestroyVisitorMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (DestroyVisitorMessage)deserialize("DestroyVisitorMessage", DocumentProtocol.MESSAGE_DESTROYVISITOR, lang); - assertEquals("myvisitor", msg.getInstanceId()); - } - } - } - - public class testDocumentListMessage implements RunnableTest { - - @Override - public void run() { - DocumentListMessage msg = (DocumentListMessage)deserialize("DocumentListMessage", DocumentProtocol.MESSAGE_DOCUMENTLIST, Language.CPP); - assertEquals("userdoc:scheme:1234:", msg.getDocuments().get(0).getDocument().getId().toString()); - assertEquals(1234, msg.getDocuments().get(0).getTimestamp()); - assertFalse(msg.getDocuments().get(0).isRemoveEntry()); - - assertEquals(BASE_MESSAGE_LENGTH + 63, serialize("DocumentListMessage", msg)); - msg = (DocumentListMessage)deserialize("DocumentListMessage", DocumentProtocol.MESSAGE_DOCUMENTLIST, Language.JAVA); - assertEquals("userdoc:scheme:1234:", msg.getDocuments().get(0).getDocument().getId().toString()); - assertEquals(1234, msg.getDocuments().get(0).getTimestamp()); - assertFalse(msg.getDocuments().get(0).isRemoveEntry()); - - } - } - - public class testEmptyBucketsMessage implements RunnableTest { - - @Override - public void run() { - List<BucketId> bids = new ArrayList<>(); - for (int i = 0; i < 13; ++i) { - bids.add(new BucketId(16, i)); - } - - EmptyBucketsMessage ebm = new EmptyBucketsMessage(bids); - assertEquals(BASE_MESSAGE_LENGTH + 112, serialize("EmptyBucketsMessage", ebm)); - for (Language lang : LANGUAGES) { - ebm = (EmptyBucketsMessage)deserialize("EmptyBucketsMessage", DocumentProtocol.MESSAGE_EMPTYBUCKETS, lang); - for (int i = 0; i < 13; ++i) { - assertEquals(new BucketId(16, i), ebm.getBucketIds().get(i)); - } - } - } - } - - public class testDocumentSummaryMessage implements RunnableTest { - - @Override - public void run() { - Routable routable = deserialize("DocumentSummaryMessage-1", DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, Language.CPP); - assertTrue(routable instanceof DocumentSummaryMessage); - - DocumentSummaryMessage msg = (DocumentSummaryMessage) routable; - assertEquals(0, msg.getResult().getSummaryCount()); - - routable = deserialize("DocumentSummaryMessage-2", DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, Language.CPP); - assertTrue(routable instanceof DocumentSummaryMessage); - - msg = (DocumentSummaryMessage) routable; - assertEquals(2, msg.getResult().getSummaryCount()); - com.yahoo.vdslib.DocumentSummary.Summary s = msg.getResult().getSummary(0); - assertEquals("doc1", s.getDocId()); - byte[] b = s.getSummary(); - assertEquals(8, b.length); - byte[] c = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '1'}; - for (int i = 0; i < b.length; i++) { - assertEquals(c[i], b[i]); - } - - s = msg.getResult().getSummary(1); - assertEquals("aoc17", s.getDocId()); - b = s.getSummary(); - assertEquals(9, b.length); - byte[] d = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '4', '5'}; - for (int i = 0; i < b.length; i++) { - assertEquals(d[i], b[i]); - } - routable = deserialize("DocumentSummaryMessage-3", DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, Language.CPP); - assertTrue(routable instanceof DocumentSummaryMessage); - - msg = (DocumentSummaryMessage) routable; - assertEquals(2, msg.getResult().getSummaryCount()); - - s = msg.getResult().getSummary(0); - assertEquals("aoc17", s.getDocId()); - b = s.getSummary(); - assertEquals(9, b.length); - byte[] e = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '4', '5'}; - for (int i = 0; i < b.length; i++) { - assertEquals(e[i], b[i]); - } - - s = msg.getResult().getSummary(1); - assertEquals("doc1", s.getDocId()); - b = s.getSummary(); - assertEquals(8, b.length); - byte[] f = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '1'}; - for (int i = 0; i < b.length; i++) { - assertEquals(f[i], b[i]); - } - } - } - - - public class testGetDocumentMessage implements RunnableTest { - - @Override - public void run() { - GetDocumentMessage msg = new GetDocumentMessage(new DocumentId("doc:scheme:"), "foo bar"); - assertEquals(BASE_MESSAGE_LENGTH + 27, serialize("GetDocumentMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (GetDocumentMessage)deserialize("GetDocumentMessage", DocumentProtocol.MESSAGE_GETDOCUMENT, lang); - assertEquals("doc:scheme:", msg.getDocumentId().toString()); - assertEquals("foo bar", msg.getFieldSet()); - } - } - } - - - public class testRemoveDocumentMessage implements RunnableTest { - - @Override - public void run() { - final RemoveDocumentMessage msg = new RemoveDocumentMessage(new DocumentId("doc:scheme:")); - msg.setCondition(new TestAndSetCondition(CONDITION_STRING)); - - assertEquals(BASE_MESSAGE_LENGTH + 16 + serializedLength(msg.getCondition().getSelection()), serialize("RemoveDocumentMessage", msg)); - - for (Language lang : LANGUAGES) { - final RemoveDocumentMessage deserializedMsg = (RemoveDocumentMessage)deserialize("RemoveDocumentMessage", DocumentProtocol.MESSAGE_REMOVEDOCUMENT, lang); - assertEquals(deserializedMsg.getDocumentId().toString(), msg.getDocumentId().toString()); - } - } - } - - public class testMapVisitorMessage implements RunnableTest { - - @Override - public void run() { - MapVisitorMessage msg = (MapVisitorMessage)deserialize("MapVisitorMessage", DocumentProtocol.MESSAGE_MAPVISITOR, Language.CPP); - assertEquals("3", msg.getData().get("foo")); - assertEquals("5", msg.getData().get("bar")); - - assertEquals(BASE_MESSAGE_LENGTH + 32, serialize("MapVisitorMessage", msg)); - - msg = (MapVisitorMessage)deserialize("MapVisitorMessage", DocumentProtocol.MESSAGE_MAPVISITOR, Language.JAVA); - assertEquals("3", msg.getData().get("foo")); - assertEquals("5", msg.getData().get("bar")); - } - } - - - public class testVisitorInfoMessage implements RunnableTest { - - @Override - public void run() { - VisitorInfoMessage msg = new VisitorInfoMessage(); - msg.getFinishedBuckets().add(new BucketId(16, 1)); - msg.getFinishedBuckets().add(new BucketId(16, 2)); - msg.getFinishedBuckets().add(new BucketId(16, 4)); - msg.setErrorMessage("error message: \u00e6\u00c6\u00f8\u00d8\u00e5\u00c5\u00f6\u00d6"); - assertEquals(BASE_MESSAGE_LENGTH + 67, serialize("VisitorInfoMessage", msg)); - - for (Language lang : LANGUAGES) { - msg = (VisitorInfoMessage)deserialize("VisitorInfoMessage", DocumentProtocol.MESSAGE_VISITORINFO, lang); - assertTrue(msg.getFinishedBuckets().contains(new BucketId(16, 1))); - assertTrue(msg.getFinishedBuckets().contains(new BucketId(16, 2))); - assertTrue(msg.getFinishedBuckets().contains(new BucketId(16, 4))); - assertEquals("error message: \u00e6\u00c6\u00f8\u00d8\u00e5\u00c5\u00f6\u00d6", msg.getErrorMessage()); - } - } - } - - public class testSearchResultMessage implements RunnableTest { - - @Override - public void run() throws Exception { - Routable routable = deserialize("SearchResultMessage-1", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); - assertTrue(routable instanceof SearchResultMessage); - - SearchResultMessage msg = (SearchResultMessage)routable; - assertEquals(0, msg.getResult().getHitCount()); - - routable = deserialize("SearchResultMessage-2", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); - assertTrue(routable instanceof SearchResultMessage); - - msg = (SearchResultMessage)routable; - assertEquals(2, msg.getResult().getHitCount()); - com.yahoo.vdslib.SearchResult.Hit h = msg.getResult().getHit(0); - assertEquals(89.0, h.getRank(), 1E-6); - assertEquals("doc1", h.getDocId()); - h = msg.getResult().getHit(1); - assertEquals(109.0, h.getRank(), 1E-6); - assertEquals("doc17", h.getDocId()); - - routable = deserialize("SearchResultMessage-3", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); - assertTrue(routable instanceof SearchResultMessage); - - msg = (SearchResultMessage)routable; - assertEquals(2, msg.getResult().getHitCount()); - h = msg.getResult().getHit(0); - assertEquals(109.0, h.getRank(), 1E-6); - assertEquals("doc17", h.getDocId()); - h = msg.getResult().getHit(1); - assertEquals(89.0, h.getRank(), 1E-6); - assertEquals("doc1", h.getDocId()); - - routable = deserialize("SearchResultMessage-4", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); - assertTrue(routable instanceof SearchResultMessage); - - msg = (SearchResultMessage)routable; - assertEquals(3, msg.getResult().getHitCount()); - h = msg.getResult().getHit(0); - assertTrue(h instanceof SearchResult.HitWithSortBlob); - assertEquals(89.0, h.getRank(), 1E-6); - assertEquals("doc1", h.getDocId()); - byte[] b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); - assertEquals(9, b.length); - byte[] e = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '2' }; - for (int i = 0; i < b.length; i++) { - assertEquals(e[i], b[i]); - } - h = msg.getResult().getHit(1); - assertTrue(h instanceof SearchResult.HitWithSortBlob); - assertEquals(109.0, h.getRank(), 1E-6); - assertEquals("doc17", h.getDocId()); - b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); - assertEquals(9, b.length); - byte[] d = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '1' }; - for (int i = 0; i < b.length; i++) { - assertEquals(d[i], b[i]); - } - h = msg.getResult().getHit(2); - assertTrue(h instanceof SearchResult.HitWithSortBlob); - assertEquals(90.0, h.getRank(), 1E-6); - assertEquals("doc18", h.getDocId()); - b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); - assertEquals(9, b.length); - byte[] c = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '3' }; - for (int i = 0; i < b.length; i++) { - assertEquals(c[i], b[i]); - } - } - } - - private static String CONDITION_STRING = "There's just one condition"; - - public class testPutDocumentMessage implements RunnableTest { - - @Override - public void run() { - PutDocumentMessage msg = new PutDocumentMessage(new DocumentPut(new Document(protocol.getDocumentTypeManager().getDocumentType("testdoc"), "doc:scheme:"))); - - msg.setTimestamp(666); - msg.setCondition(new TestAndSetCondition(CONDITION_STRING)); - - assertEquals(BASE_MESSAGE_LENGTH + 41 + serializedLength(msg.getCondition().getSelection()), serialize("PutDocumentMessage", msg)); - - for (Language lang : LANGUAGES) { - final PutDocumentMessage deserializedMsg = (PutDocumentMessage)deserialize("PutDocumentMessage", DocumentProtocol.MESSAGE_PUTDOCUMENT, lang); - assertEquals(msg.getDocumentPut().getDocument().getDataType().getName(), deserializedMsg.getDocumentPut().getDocument().getDataType().getName()); - assertEquals(msg.getDocumentPut().getDocument().getId().toString(), deserializedMsg.getDocumentPut().getDocument().getId().toString()); - assertEquals(msg.getTimestamp(), deserializedMsg.getTimestamp()); - assertEquals(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); - } - } - } - - public class testPutDocumentReply implements RunnableTest { - - @Override - public void run() { - WriteDocumentReply reply = new WriteDocumentReply(DocumentProtocol.REPLY_PUTDOCUMENT); - reply.setHighestModificationTimestamp(30); - - assertEquals(13, serialize("PutDocumentReply", reply)); - - for (Language lang : LANGUAGES) { - WriteDocumentReply obj = (WriteDocumentReply)deserialize("PutDocumentReply", DocumentProtocol.REPLY_PUTDOCUMENT, lang); - assertNotNull(obj); - assertEquals(30, obj.getHighestModificationTimestamp()); - } - } - } - - public class testUpdateDocumentMessage implements RunnableTest { - - @Override - public void run() { - DocumentType docType = protocol.getDocumentTypeManager().getDocumentType("testdoc"); - DocumentUpdate update = new DocumentUpdate(docType, new DocumentId("doc:scheme:")); - update.addFieldPathUpdate(new RemoveFieldPathUpdate(docType, "intfield", "testdoc.intfield > 0")); - - final UpdateDocumentMessage msg = new UpdateDocumentMessage(update); - msg.setNewTimestamp(777); - msg.setOldTimestamp(666); - msg.setCondition(new TestAndSetCondition(CONDITION_STRING)); - - assertEquals(BASE_MESSAGE_LENGTH + 89 + serializedLength(msg.getCondition().getSelection()), serialize("UpdateDocumentMessage", msg)); - - for (Language lang : LANGUAGES) { - final UpdateDocumentMessage deserializedMsg = (UpdateDocumentMessage) deserialize("UpdateDocumentMessage", DocumentProtocol.MESSAGE_UPDATEDOCUMENT, lang); - assertEquals(msg.getDocumentUpdate(), deserializedMsg.getDocumentUpdate()); - assertEquals(msg.getNewTimestamp(), deserializedMsg.getNewTimestamp()); - assertEquals(msg.getOldTimestamp(), deserializedMsg.getOldTimestamp()); - assertEquals(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); - } - } - } - - public class testUpdateDocumentReply implements RunnableTest { - - @Override - public void run() { - UpdateDocumentReply reply = new UpdateDocumentReply(); - reply.setHighestModificationTimestamp(30); - reply.setWasFound(false); - - assertEquals(14, serialize("UpdateDocumentReply", reply)); - - for (Language lang : LANGUAGES) { - UpdateDocumentReply obj = (UpdateDocumentReply)deserialize("UpdateDocumentReply", DocumentProtocol.REPLY_UPDATEDOCUMENT, lang); - assertNotNull(obj); - assertEquals(30, reply.getHighestModificationTimestamp()); - assertEquals(false, obj.wasFound()); - } - } - } - - public class testVisitorInfoReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("VisitorInfoReply", DocumentProtocol.REPLY_VISITORINFO); - } - } - - public class testWrongDistributionReply implements RunnableTest { - - @Override - public void run() { - WrongDistributionReply reply = new WrongDistributionReply("distributor:3 storage:2"); - assertEquals(32, serialize("WrongDistributionReply", reply)); - - for (Language lang : LANGUAGES) { - reply = (WrongDistributionReply)deserialize("WrongDistributionReply", DocumentProtocol.REPLY_WRONGDISTRIBUTION, lang); - assertEquals("distributor:3 storage:2", reply.getSystemState()); - } - } - } - - public class testRemoveDocumentReply implements RunnableTest { - - @Override - public void run() { - RemoveDocumentReply reply = new RemoveDocumentReply(); - reply.setHighestModificationTimestamp(30); - reply.setWasFound(false); - - assertEquals(14, serialize("RemoveDocumentReply", reply)); - - for (Language lang : LANGUAGES) { - RemoveDocumentReply obj = (RemoveDocumentReply)deserialize("RemoveDocumentReply", DocumentProtocol.REPLY_REMOVEDOCUMENT, lang); - assertNotNull(obj); - assertEquals(30, obj.getHighestModificationTimestamp()); - assertEquals(false, obj.wasFound()); - } - } - } - - public class testRemoveLocationReply implements RunnableTest { - - @Override - public void run() { - testDocumentReply("RemoveLocationReply", DocumentProtocol.REPLY_REMOVELOCATION); - } - } - - public class testSearchResultReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("SearchResultReply", DocumentProtocol.REPLY_SEARCHRESULT); - } - } - - public class testStatBucketReply implements RunnableTest { - - @Override - public void run() { - StatBucketReply msg = new StatBucketReply(); - msg.setResults("These are the votes of the Norwegian jury"); - - assertEquals(50, serialize("StatBucketReply", msg)); - - for (Language lang : LANGUAGES) { - msg = (StatBucketReply)deserialize("StatBucketReply", DocumentProtocol.REPLY_STATBUCKET, lang); - assertEquals("These are the votes of the Norwegian jury", msg.getResults()); - } - } - } - - public class testQueryResultReply implements RunnableTest { - - @Override - public void run() { - testVisitorReply("QueryResultReply", DocumentProtocol.REPLY_QUERYRESULT); - } - } - - public class testQueryResultMessage implements RunnableTest { - - @Override - public void run() throws Exception { - Routable routable = deserialize("QueryResultMessage-1", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); - assertTrue(routable instanceof QueryResultMessage); - - QueryResultMessage msg = (QueryResultMessage)routable; - assertEquals(0, msg.getResult().getHitCount()); - - routable = deserialize("QueryResultMessage-2", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); - assertTrue(routable instanceof QueryResultMessage); - - msg = (QueryResultMessage)routable; - assertEquals(2, msg.getResult().getHitCount()); - com.yahoo.vdslib.SearchResult.Hit h = msg.getResult().getHit(0); - assertEquals(89.0, h.getRank(), 1E-6); - assertEquals("doc1", h.getDocId()); - h = msg.getResult().getHit(1); - assertEquals(109.0, h.getRank(), 1E-6); - assertEquals("doc17", h.getDocId()); - - routable = deserialize("QueryResultMessage-3", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); - assertTrue(routable instanceof QueryResultMessage); - - msg = (QueryResultMessage)routable; - assertEquals(2, msg.getResult().getHitCount()); - h = msg.getResult().getHit(0); - assertEquals(109.0, h.getRank(), 1E-6); - assertEquals("doc17", h.getDocId()); - h = msg.getResult().getHit(1); - assertEquals(89.0, h.getRank(), 1E-6); - assertEquals("doc1", h.getDocId()); - - routable = deserialize("QueryResultMessage-4", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); - assertTrue(routable instanceof QueryResultMessage); - - msg = (QueryResultMessage)routable; - assertEquals(3, msg.getResult().getHitCount()); - h = msg.getResult().getHit(0); - assertTrue(h instanceof SearchResult.HitWithSortBlob); - assertEquals(89.0, h.getRank(), 1E-6); - assertEquals("doc1", h.getDocId()); - byte[] b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); - assertEquals(9, b.length); - byte[] e = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '2' }; - for (int i = 0; i < b.length; i++) { - assertEquals(e[i], b[i]); - } - h = msg.getResult().getHit(1); - assertTrue(h instanceof SearchResult.HitWithSortBlob); - assertEquals(109.0, h.getRank(), 1E-6); - assertEquals("doc17", h.getDocId()); - b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); - assertEquals(9, b.length); - byte[] d = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '1' }; - for (int i = 0; i < b.length; i++) { - assertEquals(d[i], b[i]); - } - h = msg.getResult().getHit(2); - assertTrue(h instanceof SearchResult.HitWithSortBlob); - assertEquals(90.0, h.getRank(), 1E-6); - assertEquals("doc18", h.getDocId()); - b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); - assertEquals(9, b.length); - byte[] c = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '3' }; - for (int i = 0; i < b.length; i++) { - assertEquals(c[i], b[i]); - } - } - } - - public class testGetBucketListReply implements RunnableTest { - - public void run() { - GetBucketListReply reply = new GetBucketListReply(); - reply.getBuckets().add(new GetBucketListReply.BucketInfo(new BucketId(16, 123), "foo")); - reply.getBuckets().add(new GetBucketListReply.BucketInfo(new BucketId(17, 1123), "bar")); - reply.getBuckets().add(new GetBucketListReply.BucketInfo(new BucketId(18, 11123), "zoink")); - - assertEquals(56, serialize("GetBucketListReply", reply)); - - for (Language lang : LANGUAGES) { - reply = (GetBucketListReply)deserialize("GetBucketListReply", DocumentProtocol.REPLY_GETBUCKETLIST, lang); - assertEquals(reply.getBuckets().get(0), new GetBucketListReply.BucketInfo(new BucketId(16, 123), "foo")); - assertEquals(reply.getBuckets().get(1), new GetBucketListReply.BucketInfo(new BucketId(17, 1123), "bar")); - assertEquals(reply.getBuckets().get(2), new GetBucketListReply.BucketInfo(new BucketId(18, 11123), "zoink")); - } - } - } - - public class testGetBucketStateReply implements RunnableTest { - - public void run() { - GlobalId foo = new GlobalId(IdString.createIdString("doc:scheme:foo")); - GlobalId bar = new GlobalId(IdString.createIdString("doc:scheme:bar")); - - GetBucketStateReply reply = new GetBucketStateReply(); - List<DocumentState> state = new ArrayList<>(2); - state.add(new DocumentState(foo, 777, false)); - state.add(new DocumentState(bar, 888, true)); - reply.setBucketState(state); - assertEquals(53, serialize("GetBucketStateReply", reply)); - - for (Language lang : LANGUAGES) { - reply = (GetBucketStateReply)deserialize("GetBucketStateReply", DocumentProtocol.REPLY_GETBUCKETSTATE, lang); - assertEquals(777, reply.getBucketState().get(0).getTimestamp()); - assertEquals(foo, reply.getBucketState().get(0).getGid()); - assertEquals(false, reply.getBucketState().get(0).isRemoveEntry()); - assertEquals(888, reply.getBucketState().get(1).getTimestamp()); - assertEquals(bar, reply.getBucketState().get(1).getGid()); - assertEquals(true, reply.getBucketState().get(1).isRemoveEntry()); - } - } - } - - public class testGetDocumentReply implements RunnableTest { - - public void run() { - GetDocumentReply reply = new GetDocumentReply(new Document(protocol.getDocumentTypeManager().getDocumentType("testdoc"), "doc:scheme:")); - assertEquals(43, serialize("GetDocumentReply", reply)); - - for (Language lang : LANGUAGES) { - reply = (GetDocumentReply)deserialize("GetDocumentReply", DocumentProtocol.REPLY_GETDOCUMENT, lang); - assertEquals("testdoc", reply.getDocument().getDataType().getName()); - assertEquals("doc:scheme:", reply.getDocument().getId().toString()); - } - } - } - - public class testMapVisitorReply implements RunnableTest { - - public void run() { - testVisitorReply("MapVisitorReply", DocumentProtocol.REPLY_MAPVISITOR); - } - } - - protected void testDocumentReply(String filename, int type) { - DocumentReply reply = new DocumentReply(type); - assertEquals(5, serialize(filename, reply)); - - for (Language lang : LANGUAGES) { - reply = (DocumentReply)deserialize(filename, type, lang); - assertNotNull(reply); - } - } - - protected void testVisitorReply(String filename, int type) { - VisitorReply reply = new VisitorReply(type); - assertEquals(5, serialize(filename, reply)); - - for (Language lang : LANGUAGES) { - reply = (VisitorReply)deserialize(filename, type, lang); - assertNotNull(reply); - } - } - - static int serializedLength(String str) { - return 4 + str.length(); - } -} diff --git a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages60TestCase.java b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages60TestCase.java index 4d914c03a2b..ac09acf646c 100644 --- a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages60TestCase.java +++ b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/Messages60TestCase.java @@ -3,22 +3,111 @@ package com.yahoo.documentapi.messagebus.protocol.test; import com.yahoo.component.Version; import com.yahoo.document.BucketId; +import com.yahoo.document.Document; +import com.yahoo.document.DocumentId; +import com.yahoo.document.DocumentPut; +import com.yahoo.document.DocumentType; +import com.yahoo.document.DocumentUpdate; +import com.yahoo.document.GlobalId; +import com.yahoo.document.TestAndSetCondition; +import com.yahoo.document.fieldpathupdate.RemoveFieldPathUpdate; +import com.yahoo.document.idstring.IdString; import com.yahoo.document.select.OrderingSpecification; import com.yahoo.documentapi.messagebus.protocol.CreateVisitorMessage; +import com.yahoo.documentapi.messagebus.protocol.CreateVisitorReply; +import com.yahoo.documentapi.messagebus.protocol.DestroyVisitorMessage; +import com.yahoo.documentapi.messagebus.protocol.DocumentIgnoredReply; +import com.yahoo.documentapi.messagebus.protocol.DocumentListMessage; import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol; +import com.yahoo.documentapi.messagebus.protocol.DocumentReply; +import com.yahoo.documentapi.messagebus.protocol.DocumentState; +import com.yahoo.documentapi.messagebus.protocol.DocumentSummaryMessage; +import com.yahoo.documentapi.messagebus.protocol.EmptyBucketsMessage; import com.yahoo.documentapi.messagebus.protocol.GetBucketListMessage; +import com.yahoo.documentapi.messagebus.protocol.GetBucketListReply; +import com.yahoo.documentapi.messagebus.protocol.GetBucketStateMessage; +import com.yahoo.documentapi.messagebus.protocol.GetBucketStateReply; +import com.yahoo.documentapi.messagebus.protocol.GetDocumentMessage; +import com.yahoo.documentapi.messagebus.protocol.GetDocumentReply; +import com.yahoo.documentapi.messagebus.protocol.MapVisitorMessage; +import com.yahoo.documentapi.messagebus.protocol.PutDocumentMessage; +import com.yahoo.documentapi.messagebus.protocol.QueryResultMessage; +import com.yahoo.documentapi.messagebus.protocol.RemoveDocumentMessage; +import com.yahoo.documentapi.messagebus.protocol.RemoveDocumentReply; +import com.yahoo.documentapi.messagebus.protocol.RemoveLocationMessage; +import com.yahoo.documentapi.messagebus.protocol.SearchResultMessage; import com.yahoo.documentapi.messagebus.protocol.StatBucketMessage; +import com.yahoo.documentapi.messagebus.protocol.StatBucketReply; +import com.yahoo.documentapi.messagebus.protocol.UpdateDocumentMessage; +import com.yahoo.documentapi.messagebus.protocol.UpdateDocumentReply; +import com.yahoo.documentapi.messagebus.protocol.VisitorInfoMessage; +import com.yahoo.documentapi.messagebus.protocol.VisitorReply; +import com.yahoo.documentapi.messagebus.protocol.WriteDocumentReply; +import com.yahoo.documentapi.messagebus.protocol.WrongDistributionReply; +import com.yahoo.messagebus.Routable; import com.yahoo.text.Utf8; +import com.yahoo.vdslib.SearchResult; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -public class Messages60TestCase extends Messages52TestCase { +/** + * @author Simon Thoresen Hult + * @author Vegard Sjonfjell + */ + +public class Messages60TestCase extends MessagesTestBase { + @Override + protected void registerTests(Map<Integer, RunnableTest> out) { + // This list MUST mirror the list of routable factories from the DocumentProtocol constructor that support + // version 6. When adding tests to this list, please KEEP THEM ORDERED alphabetically like they are now. + out.put(DocumentProtocol.MESSAGE_CREATEVISITOR, new testCreateVisitorMessage()); + out.put(DocumentProtocol.MESSAGE_DESTROYVISITOR, new testDestroyVisitorMessage()); + out.put(DocumentProtocol.MESSAGE_DOCUMENTLIST, new testDocumentListMessage()); + out.put(DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, new testDocumentSummaryMessage()); + out.put(DocumentProtocol.MESSAGE_EMPTYBUCKETS, new testEmptyBucketsMessage()); + out.put(DocumentProtocol.MESSAGE_GETBUCKETLIST, new testGetBucketListMessage()); + out.put(DocumentProtocol.MESSAGE_GETBUCKETSTATE, new testGetBucketStateMessage()); + out.put(DocumentProtocol.MESSAGE_GETDOCUMENT, new testGetDocumentMessage()); + out.put(DocumentProtocol.MESSAGE_MAPVISITOR, new testMapVisitorMessage()); + out.put(DocumentProtocol.MESSAGE_PUTDOCUMENT, new testPutDocumentMessage()); + out.put(DocumentProtocol.MESSAGE_QUERYRESULT, new testQueryResultMessage()); + out.put(DocumentProtocol.MESSAGE_REMOVEDOCUMENT, new testRemoveDocumentMessage()); + out.put(DocumentProtocol.MESSAGE_REMOVELOCATION, new testRemoveLocationMessage()); + out.put(DocumentProtocol.MESSAGE_SEARCHRESULT, new testSearchResultMessage()); + out.put(DocumentProtocol.MESSAGE_STATBUCKET, new testStatBucketMessage()); + out.put(DocumentProtocol.MESSAGE_UPDATEDOCUMENT, new testUpdateDocumentMessage()); + out.put(DocumentProtocol.MESSAGE_VISITORINFO, new testVisitorInfoMessage()); + out.put(DocumentProtocol.REPLY_CREATEVISITOR, new testCreateVisitorReply()); + out.put(DocumentProtocol.REPLY_DESTROYVISITOR, new testDestroyVisitorReply()); + out.put(DocumentProtocol.REPLY_DOCUMENTIGNORED, new testDocumentIgnoredReply()); + out.put(DocumentProtocol.REPLY_DOCUMENTLIST, new testDocumentListReply()); + out.put(DocumentProtocol.REPLY_DOCUMENTSUMMARY, new testDocumentSummaryReply()); + out.put(DocumentProtocol.REPLY_EMPTYBUCKETS, new testEmptyBucketsReply()); + out.put(DocumentProtocol.REPLY_GETBUCKETLIST, new testGetBucketListReply()); + out.put(DocumentProtocol.REPLY_GETBUCKETSTATE, new testGetBucketStateReply()); + out.put(DocumentProtocol.REPLY_GETDOCUMENT, new testGetDocumentReply()); + out.put(DocumentProtocol.REPLY_MAPVISITOR, new testMapVisitorReply()); + out.put(DocumentProtocol.REPLY_PUTDOCUMENT, new testPutDocumentReply()); + out.put(DocumentProtocol.REPLY_QUERYRESULT, new testQueryResultReply()); + out.put(DocumentProtocol.REPLY_REMOVEDOCUMENT, new testRemoveDocumentReply()); + out.put(DocumentProtocol.REPLY_REMOVELOCATION, new testRemoveLocationReply()); + out.put(DocumentProtocol.REPLY_SEARCHRESULT, new testSearchResultReply()); + out.put(DocumentProtocol.REPLY_STATBUCKET, new testStatBucketReply()); + out.put(DocumentProtocol.REPLY_UPDATEDOCUMENT, new testUpdateDocumentReply()); + out.put(DocumentProtocol.REPLY_VISITORINFO, new testVisitorInfoReply()); + out.put(DocumentProtocol.REPLY_WRONGDISTRIBUTION, new testWrongDistributionReply()); + } @Override protected Version version() { - return new Version(6, 221); + return new Version(6, 221, 0); } @Override @@ -26,25 +115,90 @@ public class Messages60TestCase extends Messages52TestCase { return true; } - @Override - protected void registerTests(Map<Integer, MessagesTestBase.RunnableTest> out) { - super.registerTests(out); + //////////////////////////////////////////////////////////////////////////////// + // + // Tests + // + //////////////////////////////////////////////////////////////////////////////// - // This list MUST mirror the list of routable factories from the DocumentProtocol constructor that support - // version 6.0. When adding tests to this list, please KEEP THEM ORDERED alphabetically like they are now. + protected static int BASE_MESSAGE_LENGTH = 5; + + public class testRemoveLocationMessage implements RunnableTest { + + @Override + public void run() { + { + RemoveLocationMessage msg = new RemoveLocationMessage("id.group == \"mygroup\""); + assertEquals(BASE_MESSAGE_LENGTH + 29, serialize("RemoveLocationMessage", msg)); + + for (Language lang : LANGUAGES) { + msg = (RemoveLocationMessage)deserialize("RemoveLocationMessage", DocumentProtocol.MESSAGE_REMOVELOCATION, lang); + assertEquals("id.group == \"mygroup\"", msg.getDocumentSelection()); + } + } + } + } + + public class testGetBucketListMessage implements RunnableTest { + + private static final String BUCKET_SPACE = "beartato"; + + @Override + public void run() { + GetBucketListMessage msg = new GetBucketListMessage(new BucketId(16, 123)); + msg.setLoadType(loadTypes.getNameMap().get("foo")); + msg.setBucketSpace(BUCKET_SPACE); + assertEquals(BASE_MESSAGE_LENGTH + 12 + serializedLength(BUCKET_SPACE), serialize("GetBucketListMessage", msg)); - out.put(DocumentProtocol.MESSAGE_CREATEVISITOR, new Messages60TestCase.testCreateVisitorMessage()); - out.put(DocumentProtocol.MESSAGE_STATBUCKET, new Messages60TestCase.testStatBucketMessage()); - out.put(DocumentProtocol.MESSAGE_GETBUCKETLIST, new Messages60TestCase.testGetBucketListMessage()); + for (Language lang : LANGUAGES) { + msg = (GetBucketListMessage)deserialize("GetBucketListMessage", DocumentProtocol.MESSAGE_GETBUCKETLIST, lang); + assertEquals(new BucketId(16, 123), msg.getBucketId()); + assertEquals("foo", msg.getLoadType().getName()); + assertEquals(BUCKET_SPACE, msg.getBucketSpace()); + } + } + } + + public class testStatBucketMessage implements RunnableTest { + + private static final String BUCKET_SPACE = "andrei"; + + @Override + public void run() { + StatBucketMessage msg = new StatBucketMessage(new BucketId(16, 123), "id.user=123"); + msg.setLoadType(null); + msg.setBucketSpace(BUCKET_SPACE); + assertEquals(BASE_MESSAGE_LENGTH + 27 + serializedLength(BUCKET_SPACE), serialize("StatBucketMessage", msg)); + + for (Language lang : LANGUAGES) { + msg = (StatBucketMessage)deserialize("StatBucketMessage", DocumentProtocol.MESSAGE_STATBUCKET, lang); + assertEquals(new BucketId(16, 123), msg.getBucketId()); + assertEquals("id.user=123", msg.getDocumentSelection()); + assertEquals("default", msg.getLoadType().getName()); + assertEquals(BUCKET_SPACE, msg.getBucketSpace()); + } + } + } + + public class testGetBucketStateMessage implements RunnableTest { + + @Override + public void run() { + GetBucketStateMessage msg = new GetBucketStateMessage(new BucketId(16, 666)); + assertEquals(BASE_MESSAGE_LENGTH + 12, serialize("GetBucketStateMessage", msg)); + + for (Language lang : LANGUAGES) { + msg = (GetBucketStateMessage)deserialize("GetBucketStateMessage", DocumentProtocol.MESSAGE_GETBUCKETSTATE, lang); + assertEquals(16, msg.getBucketId().getUsedBits()); + assertEquals(4611686018427388570l, msg.getBucketId().getId()); + } + } } public class testCreateVisitorMessage implements RunnableTest { private static final String BUCKET_SPACE = "bjarne"; - // FIXME there is a large amount of code duplication across version tests, presumably - // to ensure that fields survive across version boundaries, but it makes code very bloated. - // TODO head towards a blissful Protobuf future instead... @Override public void run() { CreateVisitorMessage msg = new CreateVisitorMessage("SomeLibrary", "myvisitor", "newyork", "london"); @@ -78,48 +232,701 @@ public class Messages60TestCase extends Messages52TestCase { assertEquals(2, msg.getMaxBucketsPerVisitor()); assertEquals(BUCKET_SPACE, msg.getBucketSpace()); } + + msg.getBuckets().clear(); + + assertEquals("CreateVisitorMessage(" + + "No buckets, " + + "selection 'true and false or true', " + + "bucket space 'bjarne', " + + "library SomeLibrary, including removes, " + + "get fields: foo bar" + + ")", + msg.toString()); + + msg.getBuckets().add(new BucketId(16, 1234)); + + assertEquals("CreateVisitorMessage(" + + "Bucket BucketId(0x40000000000004d2), " + + "selection 'true and false or true', " + + "bucket space 'bjarne', " + + "library SomeLibrary, including removes, " + + "get fields: foo bar" + + ")", + msg.toString()); + + msg.getBuckets().add(new BucketId(16, 1235)); + msg.getBuckets().add(new BucketId(16, 1236)); + msg.getBuckets().add(new BucketId(16, 1237)); + msg.getBuckets().add(new BucketId(16, 1238)); + msg.setFromTimestamp(10001); + msg.setToTimestamp(20002); + msg.setVisitInconsistentBuckets(true); + assertEquals("CreateVisitorMessage(" + + "5 buckets: BucketId(0x40000000000004d2) BucketId(0x40000000000004d3) BucketId(0x40000000000004d4) ..., " + + "time 10001-20002, " + + "selection 'true and false or true', " + + "bucket space 'bjarne', " + + "library SomeLibrary, including removes, " + + "get fields: foo bar, " + + "visit inconsistent buckets" + + ")", + msg.toString()); } } - public class testStatBucketMessage implements RunnableTest { + public class testCreateVisitorReply implements RunnableTest { - private static final String BUCKET_SPACE = "andrei"; + @Override + public void run() { + CreateVisitorReply reply = new CreateVisitorReply(DocumentProtocol.REPLY_CREATEVISITOR); + reply.setLastBucket(new BucketId(16, 123)); + reply.getVisitorStatistics().setBucketsVisited(3); + reply.getVisitorStatistics().setDocumentsVisited(1000); + reply.getVisitorStatistics().setBytesVisited(1024000); + reply.getVisitorStatistics().setDocumentsReturned(123); + reply.getVisitorStatistics().setBytesReturned(512000); + reply.getVisitorStatistics().setSecondPassDocumentsReturned(456); + reply.getVisitorStatistics().setSecondPassBytesReturned(789100); + + assertEquals(65, serialize("CreateVisitorReply", reply)); + + for (Language lang : LANGUAGES) { + reply = (CreateVisitorReply)deserialize("CreateVisitorReply", DocumentProtocol.REPLY_CREATEVISITOR, lang); + assertNotNull(reply); + assertEquals(new BucketId(16, 123), reply.getLastBucket()); + assertEquals(3, reply.getVisitorStatistics().getBucketsVisited()); + assertEquals(1000, reply.getVisitorStatistics().getDocumentsVisited()); + assertEquals(1024000, reply.getVisitorStatistics().getBytesVisited()); + assertEquals(123, reply.getVisitorStatistics().getDocumentsReturned()); + assertEquals(512000, reply.getVisitorStatistics().getBytesReturned()); + assertEquals(456, reply.getVisitorStatistics().getSecondPassDocumentsReturned()); + assertEquals(789100, reply.getVisitorStatistics().getSecondPassBytesReturned()); + } + } + } + + public class testDestroyVisitorReply implements RunnableTest { @Override public void run() { - StatBucketMessage msg = new StatBucketMessage(new BucketId(16, 123), "id.user=123"); - msg.setLoadType(null); - msg.setBucketSpace(BUCKET_SPACE); - assertEquals(BASE_MESSAGE_LENGTH + 27 + serializedLength(BUCKET_SPACE), serialize("StatBucketMessage", msg)); + testVisitorReply("DestroyVisitorReply", DocumentProtocol.REPLY_DESTROYVISITOR); + } + } + + public class testDocumentIgnoredReply implements RunnableTest { + + @Override + public void run() { + DocumentIgnoredReply reply = new DocumentIgnoredReply(); + assertEquals(BASE_MESSAGE_LENGTH, serialize("DocumentIgnoredReply", reply)); for (Language lang : LANGUAGES) { - msg = (StatBucketMessage)deserialize("StatBucketMessage", DocumentProtocol.MESSAGE_STATBUCKET, lang); - assertEquals(new BucketId(16, 123), msg.getBucketId()); - assertEquals("id.user=123", msg.getDocumentSelection()); - assertEquals("default", msg.getLoadType().getName()); - assertEquals(BUCKET_SPACE, msg.getBucketSpace()); + reply = (DocumentIgnoredReply)deserialize("DocumentIgnoredReply", DocumentProtocol.REPLY_DOCUMENTIGNORED, lang); } } } - public class testGetBucketListMessage implements RunnableTest { + public class testDocumentListReply implements RunnableTest { - private static final String BUCKET_SPACE = "beartato"; + @Override + public void run() { + testVisitorReply("DocumentListReply", DocumentProtocol.REPLY_DOCUMENTLIST); + } + } + + public class testDocumentSummaryReply implements RunnableTest { @Override public void run() { - GetBucketListMessage msg = new GetBucketListMessage(new BucketId(16, 123)); - msg.setLoadType(loadTypes.getNameMap().get("foo")); - msg.setBucketSpace(BUCKET_SPACE); - assertEquals(BASE_MESSAGE_LENGTH + 12 + serializedLength(BUCKET_SPACE), serialize("GetBucketListMessage", msg)); + testVisitorReply("DocumentSummaryReply", DocumentProtocol.REPLY_DOCUMENTSUMMARY); + } + } + + public class testEmptyBucketsReply implements RunnableTest { + + @Override + public void run() { + testVisitorReply("EmptyBucketsReply", DocumentProtocol.REPLY_EMPTYBUCKETS); + } + } + + public class testDestroyVisitorMessage implements RunnableTest { + + @Override + public void run() { + DestroyVisitorMessage msg = new DestroyVisitorMessage("myvisitor"); + assertEquals(BASE_MESSAGE_LENGTH + 17, serialize("DestroyVisitorMessage", msg)); for (Language lang : LANGUAGES) { - msg = (GetBucketListMessage)deserialize("GetBucketListMessage", DocumentProtocol.MESSAGE_GETBUCKETLIST, lang); - assertEquals(new BucketId(16, 123), msg.getBucketId()); - assertEquals("foo", msg.getLoadType().getName()); - assertEquals(BUCKET_SPACE, msg.getBucketSpace()); + msg = (DestroyVisitorMessage)deserialize("DestroyVisitorMessage", DocumentProtocol.MESSAGE_DESTROYVISITOR, lang); + assertEquals("myvisitor", msg.getInstanceId()); } } } + public class testDocumentListMessage implements RunnableTest { + + @Override + public void run() { + DocumentListMessage msg = (DocumentListMessage)deserialize("DocumentListMessage", DocumentProtocol.MESSAGE_DOCUMENTLIST, Language.CPP); + assertEquals("userdoc:scheme:1234:", msg.getDocuments().get(0).getDocument().getId().toString()); + assertEquals(1234, msg.getDocuments().get(0).getTimestamp()); + assertFalse(msg.getDocuments().get(0).isRemoveEntry()); + + assertEquals(BASE_MESSAGE_LENGTH + 63, serialize("DocumentListMessage", msg)); + msg = (DocumentListMessage)deserialize("DocumentListMessage", DocumentProtocol.MESSAGE_DOCUMENTLIST, Language.JAVA); + assertEquals("userdoc:scheme:1234:", msg.getDocuments().get(0).getDocument().getId().toString()); + assertEquals(1234, msg.getDocuments().get(0).getTimestamp()); + assertFalse(msg.getDocuments().get(0).isRemoveEntry()); + + } + } + + public class testEmptyBucketsMessage implements RunnableTest { + + @Override + public void run() { + List<BucketId> bids = new ArrayList<>(); + for (int i = 0; i < 13; ++i) { + bids.add(new BucketId(16, i)); + } + + EmptyBucketsMessage ebm = new EmptyBucketsMessage(bids); + assertEquals(BASE_MESSAGE_LENGTH + 112, serialize("EmptyBucketsMessage", ebm)); + for (Language lang : LANGUAGES) { + ebm = (EmptyBucketsMessage)deserialize("EmptyBucketsMessage", DocumentProtocol.MESSAGE_EMPTYBUCKETS, lang); + for (int i = 0; i < 13; ++i) { + assertEquals(new BucketId(16, i), ebm.getBucketIds().get(i)); + } + } + } + } + + public class testDocumentSummaryMessage implements RunnableTest { + + @Override + public void run() { + Routable routable = deserialize("DocumentSummaryMessage-1", DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, Language.CPP); + assertTrue(routable instanceof DocumentSummaryMessage); + + DocumentSummaryMessage msg = (DocumentSummaryMessage) routable; + assertEquals(0, msg.getResult().getSummaryCount()); + + routable = deserialize("DocumentSummaryMessage-2", DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, Language.CPP); + assertTrue(routable instanceof DocumentSummaryMessage); + + msg = (DocumentSummaryMessage) routable; + assertEquals(2, msg.getResult().getSummaryCount()); + com.yahoo.vdslib.DocumentSummary.Summary s = msg.getResult().getSummary(0); + assertEquals("doc1", s.getDocId()); + byte[] b = s.getSummary(); + assertEquals(8, b.length); + byte[] c = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '1'}; + for (int i = 0; i < b.length; i++) { + assertEquals(c[i], b[i]); + } + + s = msg.getResult().getSummary(1); + assertEquals("aoc17", s.getDocId()); + b = s.getSummary(); + assertEquals(9, b.length); + byte[] d = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '4', '5'}; + for (int i = 0; i < b.length; i++) { + assertEquals(d[i], b[i]); + } + routable = deserialize("DocumentSummaryMessage-3", DocumentProtocol.MESSAGE_DOCUMENTSUMMARY, Language.CPP); + assertTrue(routable instanceof DocumentSummaryMessage); + + msg = (DocumentSummaryMessage) routable; + assertEquals(2, msg.getResult().getSummaryCount()); + + s = msg.getResult().getSummary(0); + assertEquals("aoc17", s.getDocId()); + b = s.getSummary(); + assertEquals(9, b.length); + byte[] e = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '4', '5'}; + for (int i = 0; i < b.length; i++) { + assertEquals(e[i], b[i]); + } + + s = msg.getResult().getSummary(1); + assertEquals("doc1", s.getDocId()); + b = s.getSummary(); + assertEquals(8, b.length); + byte[] f = {'s', 'u', 'm', 'm', 'a', 'r', 'y', '1'}; + for (int i = 0; i < b.length; i++) { + assertEquals(f[i], b[i]); + } + } + } + + + public class testGetDocumentMessage implements RunnableTest { + + @Override + public void run() { + GetDocumentMessage msg = new GetDocumentMessage(new DocumentId("doc:scheme:"), "foo bar"); + assertEquals(BASE_MESSAGE_LENGTH + 27, serialize("GetDocumentMessage", msg)); + + for (Language lang : LANGUAGES) { + msg = (GetDocumentMessage)deserialize("GetDocumentMessage", DocumentProtocol.MESSAGE_GETDOCUMENT, lang); + assertEquals("doc:scheme:", msg.getDocumentId().toString()); + assertEquals("foo bar", msg.getFieldSet()); + } + } + } + + + public class testRemoveDocumentMessage implements RunnableTest { + + @Override + public void run() { + final RemoveDocumentMessage msg = new RemoveDocumentMessage(new DocumentId("doc:scheme:")); + msg.setCondition(new TestAndSetCondition(CONDITION_STRING)); + + assertEquals(BASE_MESSAGE_LENGTH + 16 + serializedLength(msg.getCondition().getSelection()), serialize("RemoveDocumentMessage", msg)); + + for (Language lang : LANGUAGES) { + final RemoveDocumentMessage deserializedMsg = (RemoveDocumentMessage)deserialize("RemoveDocumentMessage", DocumentProtocol.MESSAGE_REMOVEDOCUMENT, lang); + assertEquals(deserializedMsg.getDocumentId().toString(), msg.getDocumentId().toString()); + } + } + } + + public class testMapVisitorMessage implements RunnableTest { + + @Override + public void run() { + MapVisitorMessage msg = (MapVisitorMessage)deserialize("MapVisitorMessage", DocumentProtocol.MESSAGE_MAPVISITOR, Language.CPP); + assertEquals("3", msg.getData().get("foo")); + assertEquals("5", msg.getData().get("bar")); + + assertEquals(BASE_MESSAGE_LENGTH + 32, serialize("MapVisitorMessage", msg)); + + msg = (MapVisitorMessage)deserialize("MapVisitorMessage", DocumentProtocol.MESSAGE_MAPVISITOR, Language.JAVA); + assertEquals("3", msg.getData().get("foo")); + assertEquals("5", msg.getData().get("bar")); + } + } + + + public class testVisitorInfoMessage implements RunnableTest { + + @Override + public void run() { + VisitorInfoMessage msg = new VisitorInfoMessage(); + msg.getFinishedBuckets().add(new BucketId(16, 1)); + msg.getFinishedBuckets().add(new BucketId(16, 2)); + msg.getFinishedBuckets().add(new BucketId(16, 4)); + msg.setErrorMessage("error message: \u00e6\u00c6\u00f8\u00d8\u00e5\u00c5\u00f6\u00d6"); + assertEquals(BASE_MESSAGE_LENGTH + 67, serialize("VisitorInfoMessage", msg)); + + for (Language lang : LANGUAGES) { + msg = (VisitorInfoMessage)deserialize("VisitorInfoMessage", DocumentProtocol.MESSAGE_VISITORINFO, lang); + assertTrue(msg.getFinishedBuckets().contains(new BucketId(16, 1))); + assertTrue(msg.getFinishedBuckets().contains(new BucketId(16, 2))); + assertTrue(msg.getFinishedBuckets().contains(new BucketId(16, 4))); + assertEquals("error message: \u00e6\u00c6\u00f8\u00d8\u00e5\u00c5\u00f6\u00d6", msg.getErrorMessage()); + } + } + } + + public class testSearchResultMessage implements RunnableTest { + + @Override + public void run() throws Exception { + Routable routable = deserialize("SearchResultMessage-1", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); + assertTrue(routable instanceof SearchResultMessage); + + SearchResultMessage msg = (SearchResultMessage)routable; + assertEquals(0, msg.getResult().getHitCount()); + + routable = deserialize("SearchResultMessage-2", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); + assertTrue(routable instanceof SearchResultMessage); + + msg = (SearchResultMessage)routable; + assertEquals(2, msg.getResult().getHitCount()); + com.yahoo.vdslib.SearchResult.Hit h = msg.getResult().getHit(0); + assertEquals(89.0, h.getRank(), 1E-6); + assertEquals("doc1", h.getDocId()); + h = msg.getResult().getHit(1); + assertEquals(109.0, h.getRank(), 1E-6); + assertEquals("doc17", h.getDocId()); + + routable = deserialize("SearchResultMessage-3", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); + assertTrue(routable instanceof SearchResultMessage); + + msg = (SearchResultMessage)routable; + assertEquals(2, msg.getResult().getHitCount()); + h = msg.getResult().getHit(0); + assertEquals(109.0, h.getRank(), 1E-6); + assertEquals("doc17", h.getDocId()); + h = msg.getResult().getHit(1); + assertEquals(89.0, h.getRank(), 1E-6); + assertEquals("doc1", h.getDocId()); + + routable = deserialize("SearchResultMessage-4", DocumentProtocol.MESSAGE_SEARCHRESULT, Language.CPP); + assertTrue(routable instanceof SearchResultMessage); + + msg = (SearchResultMessage)routable; + assertEquals(3, msg.getResult().getHitCount()); + h = msg.getResult().getHit(0); + assertTrue(h instanceof SearchResult.HitWithSortBlob); + assertEquals(89.0, h.getRank(), 1E-6); + assertEquals("doc1", h.getDocId()); + byte[] b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); + assertEquals(9, b.length); + byte[] e = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '2' }; + for (int i = 0; i < b.length; i++) { + assertEquals(e[i], b[i]); + } + h = msg.getResult().getHit(1); + assertTrue(h instanceof SearchResult.HitWithSortBlob); + assertEquals(109.0, h.getRank(), 1E-6); + assertEquals("doc17", h.getDocId()); + b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); + assertEquals(9, b.length); + byte[] d = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '1' }; + for (int i = 0; i < b.length; i++) { + assertEquals(d[i], b[i]); + } + h = msg.getResult().getHit(2); + assertTrue(h instanceof SearchResult.HitWithSortBlob); + assertEquals(90.0, h.getRank(), 1E-6); + assertEquals("doc18", h.getDocId()); + b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); + assertEquals(9, b.length); + byte[] c = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '3' }; + for (int i = 0; i < b.length; i++) { + assertEquals(c[i], b[i]); + } + } + } + + private static String CONDITION_STRING = "There's just one condition"; + + public class testPutDocumentMessage implements RunnableTest { + + @Override + public void run() { + PutDocumentMessage msg = new PutDocumentMessage(new DocumentPut(new Document(protocol.getDocumentTypeManager().getDocumentType("testdoc"), "doc:scheme:"))); + + msg.setTimestamp(666); + msg.setCondition(new TestAndSetCondition(CONDITION_STRING)); + + assertEquals(BASE_MESSAGE_LENGTH + 41 + serializedLength(msg.getCondition().getSelection()), serialize("PutDocumentMessage", msg)); + + for (Language lang : LANGUAGES) { + final PutDocumentMessage deserializedMsg = (PutDocumentMessage)deserialize("PutDocumentMessage", DocumentProtocol.MESSAGE_PUTDOCUMENT, lang); + assertEquals(msg.getDocumentPut().getDocument().getDataType().getName(), deserializedMsg.getDocumentPut().getDocument().getDataType().getName()); + assertEquals(msg.getDocumentPut().getDocument().getId().toString(), deserializedMsg.getDocumentPut().getDocument().getId().toString()); + assertEquals(msg.getTimestamp(), deserializedMsg.getTimestamp()); + assertEquals(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); + } + } + } + + public class testPutDocumentReply implements RunnableTest { + + @Override + public void run() { + WriteDocumentReply reply = new WriteDocumentReply(DocumentProtocol.REPLY_PUTDOCUMENT); + reply.setHighestModificationTimestamp(30); + + assertEquals(13, serialize("PutDocumentReply", reply)); + + for (Language lang : LANGUAGES) { + WriteDocumentReply obj = (WriteDocumentReply)deserialize("PutDocumentReply", DocumentProtocol.REPLY_PUTDOCUMENT, lang); + assertNotNull(obj); + assertEquals(30, obj.getHighestModificationTimestamp()); + } + } + } + + public class testUpdateDocumentMessage implements RunnableTest { + + @Override + public void run() { + DocumentType docType = protocol.getDocumentTypeManager().getDocumentType("testdoc"); + DocumentUpdate update = new DocumentUpdate(docType, new DocumentId("doc:scheme:")); + update.addFieldPathUpdate(new RemoveFieldPathUpdate(docType, "intfield", "testdoc.intfield > 0")); + + final UpdateDocumentMessage msg = new UpdateDocumentMessage(update); + msg.setNewTimestamp(777); + msg.setOldTimestamp(666); + msg.setCondition(new TestAndSetCondition(CONDITION_STRING)); + + assertEquals(BASE_MESSAGE_LENGTH + 89 + serializedLength(msg.getCondition().getSelection()), serialize("UpdateDocumentMessage", msg)); + + for (Language lang : LANGUAGES) { + final UpdateDocumentMessage deserializedMsg = (UpdateDocumentMessage) deserialize("UpdateDocumentMessage", DocumentProtocol.MESSAGE_UPDATEDOCUMENT, lang); + assertEquals(msg.getDocumentUpdate(), deserializedMsg.getDocumentUpdate()); + assertEquals(msg.getNewTimestamp(), deserializedMsg.getNewTimestamp()); + assertEquals(msg.getOldTimestamp(), deserializedMsg.getOldTimestamp()); + assertEquals(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); + } + } + } + + public class testUpdateDocumentReply implements RunnableTest { + + @Override + public void run() { + UpdateDocumentReply reply = new UpdateDocumentReply(); + reply.setHighestModificationTimestamp(30); + reply.setWasFound(false); + + assertEquals(14, serialize("UpdateDocumentReply", reply)); + + for (Language lang : LANGUAGES) { + UpdateDocumentReply obj = (UpdateDocumentReply)deserialize("UpdateDocumentReply", DocumentProtocol.REPLY_UPDATEDOCUMENT, lang); + assertNotNull(obj); + assertEquals(30, reply.getHighestModificationTimestamp()); + assertEquals(false, obj.wasFound()); + } + } + } + + public class testVisitorInfoReply implements RunnableTest { + + @Override + public void run() { + testVisitorReply("VisitorInfoReply", DocumentProtocol.REPLY_VISITORINFO); + } + } + + public class testWrongDistributionReply implements RunnableTest { + + @Override + public void run() { + WrongDistributionReply reply = new WrongDistributionReply("distributor:3 storage:2"); + assertEquals(32, serialize("WrongDistributionReply", reply)); + + for (Language lang : LANGUAGES) { + reply = (WrongDistributionReply)deserialize("WrongDistributionReply", DocumentProtocol.REPLY_WRONGDISTRIBUTION, lang); + assertEquals("distributor:3 storage:2", reply.getSystemState()); + } + } + } + + public class testRemoveDocumentReply implements RunnableTest { + + @Override + public void run() { + RemoveDocumentReply reply = new RemoveDocumentReply(); + reply.setHighestModificationTimestamp(30); + reply.setWasFound(false); + + assertEquals(14, serialize("RemoveDocumentReply", reply)); + + for (Language lang : LANGUAGES) { + RemoveDocumentReply obj = (RemoveDocumentReply)deserialize("RemoveDocumentReply", DocumentProtocol.REPLY_REMOVEDOCUMENT, lang); + assertNotNull(obj); + assertEquals(30, obj.getHighestModificationTimestamp()); + assertEquals(false, obj.wasFound()); + } + } + } + + public class testRemoveLocationReply implements RunnableTest { + + @Override + public void run() { + testDocumentReply("RemoveLocationReply", DocumentProtocol.REPLY_REMOVELOCATION); + } + } + + public class testSearchResultReply implements RunnableTest { + + @Override + public void run() { + testVisitorReply("SearchResultReply", DocumentProtocol.REPLY_SEARCHRESULT); + } + } + + public class testStatBucketReply implements RunnableTest { + + @Override + public void run() { + StatBucketReply msg = new StatBucketReply(); + msg.setResults("These are the votes of the Norwegian jury"); + + assertEquals(50, serialize("StatBucketReply", msg)); + + for (Language lang : LANGUAGES) { + msg = (StatBucketReply)deserialize("StatBucketReply", DocumentProtocol.REPLY_STATBUCKET, lang); + assertEquals("These are the votes of the Norwegian jury", msg.getResults()); + } + } + } + + public class testQueryResultReply implements RunnableTest { + + @Override + public void run() { + testVisitorReply("QueryResultReply", DocumentProtocol.REPLY_QUERYRESULT); + } + } + + public class testQueryResultMessage implements RunnableTest { + + @Override + public void run() throws Exception { + Routable routable = deserialize("QueryResultMessage-1", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); + assertTrue(routable instanceof QueryResultMessage); + + QueryResultMessage msg = (QueryResultMessage)routable; + assertEquals(0, msg.getResult().getHitCount()); + + routable = deserialize("QueryResultMessage-2", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); + assertTrue(routable instanceof QueryResultMessage); + + msg = (QueryResultMessage)routable; + assertEquals(2, msg.getResult().getHitCount()); + com.yahoo.vdslib.SearchResult.Hit h = msg.getResult().getHit(0); + assertEquals(89.0, h.getRank(), 1E-6); + assertEquals("doc1", h.getDocId()); + h = msg.getResult().getHit(1); + assertEquals(109.0, h.getRank(), 1E-6); + assertEquals("doc17", h.getDocId()); + + routable = deserialize("QueryResultMessage-3", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); + assertTrue(routable instanceof QueryResultMessage); + + msg = (QueryResultMessage)routable; + assertEquals(2, msg.getResult().getHitCount()); + h = msg.getResult().getHit(0); + assertEquals(109.0, h.getRank(), 1E-6); + assertEquals("doc17", h.getDocId()); + h = msg.getResult().getHit(1); + assertEquals(89.0, h.getRank(), 1E-6); + assertEquals("doc1", h.getDocId()); + + routable = deserialize("QueryResultMessage-4", DocumentProtocol.MESSAGE_QUERYRESULT, Language.CPP); + assertTrue(routable instanceof QueryResultMessage); + + msg = (QueryResultMessage)routable; + assertEquals(3, msg.getResult().getHitCount()); + h = msg.getResult().getHit(0); + assertTrue(h instanceof SearchResult.HitWithSortBlob); + assertEquals(89.0, h.getRank(), 1E-6); + assertEquals("doc1", h.getDocId()); + byte[] b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); + assertEquals(9, b.length); + byte[] e = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '2' }; + for (int i = 0; i < b.length; i++) { + assertEquals(e[i], b[i]); + } + h = msg.getResult().getHit(1); + assertTrue(h instanceof SearchResult.HitWithSortBlob); + assertEquals(109.0, h.getRank(), 1E-6); + assertEquals("doc17", h.getDocId()); + b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); + assertEquals(9, b.length); + byte[] d = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '1' }; + for (int i = 0; i < b.length; i++) { + assertEquals(d[i], b[i]); + } + h = msg.getResult().getHit(2); + assertTrue(h instanceof SearchResult.HitWithSortBlob); + assertEquals(90.0, h.getRank(), 1E-6); + assertEquals("doc18", h.getDocId()); + b = ((SearchResult.HitWithSortBlob)h).getSortBlob(); + assertEquals(9, b.length); + byte[] c = { 's', 'o', 'r', 't', 'd', 'a', 't', 'a', '3' }; + for (int i = 0; i < b.length; i++) { + assertEquals(c[i], b[i]); + } + } + } + + public class testGetBucketListReply implements RunnableTest { + + public void run() { + GetBucketListReply reply = new GetBucketListReply(); + reply.getBuckets().add(new GetBucketListReply.BucketInfo(new BucketId(16, 123), "foo")); + reply.getBuckets().add(new GetBucketListReply.BucketInfo(new BucketId(17, 1123), "bar")); + reply.getBuckets().add(new GetBucketListReply.BucketInfo(new BucketId(18, 11123), "zoink")); + + assertEquals(56, serialize("GetBucketListReply", reply)); + + for (Language lang : LANGUAGES) { + reply = (GetBucketListReply)deserialize("GetBucketListReply", DocumentProtocol.REPLY_GETBUCKETLIST, lang); + assertEquals(reply.getBuckets().get(0), new GetBucketListReply.BucketInfo(new BucketId(16, 123), "foo")); + assertEquals(reply.getBuckets().get(1), new GetBucketListReply.BucketInfo(new BucketId(17, 1123), "bar")); + assertEquals(reply.getBuckets().get(2), new GetBucketListReply.BucketInfo(new BucketId(18, 11123), "zoink")); + } + } + } + + public class testGetBucketStateReply implements RunnableTest { + + public void run() { + GlobalId foo = new GlobalId(IdString.createIdString("doc:scheme:foo")); + GlobalId bar = new GlobalId(IdString.createIdString("doc:scheme:bar")); + + GetBucketStateReply reply = new GetBucketStateReply(); + List<DocumentState> state = new ArrayList<>(2); + state.add(new DocumentState(foo, 777, false)); + state.add(new DocumentState(bar, 888, true)); + reply.setBucketState(state); + assertEquals(53, serialize("GetBucketStateReply", reply)); + + for (Language lang : LANGUAGES) { + reply = (GetBucketStateReply)deserialize("GetBucketStateReply", DocumentProtocol.REPLY_GETBUCKETSTATE, lang); + assertEquals(777, reply.getBucketState().get(0).getTimestamp()); + assertEquals(foo, reply.getBucketState().get(0).getGid()); + assertEquals(false, reply.getBucketState().get(0).isRemoveEntry()); + assertEquals(888, reply.getBucketState().get(1).getTimestamp()); + assertEquals(bar, reply.getBucketState().get(1).getGid()); + assertEquals(true, reply.getBucketState().get(1).isRemoveEntry()); + } + } + } + + public class testGetDocumentReply implements RunnableTest { + + public void run() { + GetDocumentReply reply = new GetDocumentReply(new Document(protocol.getDocumentTypeManager().getDocumentType("testdoc"), "doc:scheme:")); + assertEquals(43, serialize("GetDocumentReply", reply)); + + for (Language lang : LANGUAGES) { + reply = (GetDocumentReply)deserialize("GetDocumentReply", DocumentProtocol.REPLY_GETDOCUMENT, lang); + assertEquals("testdoc", reply.getDocument().getDataType().getName()); + assertEquals("doc:scheme:", reply.getDocument().getId().toString()); + } + } + } + + public class testMapVisitorReply implements RunnableTest { + + public void run() { + testVisitorReply("MapVisitorReply", DocumentProtocol.REPLY_MAPVISITOR); + } + } + + protected void testDocumentReply(String filename, int type) { + DocumentReply reply = new DocumentReply(type); + assertEquals(5, serialize(filename, reply)); + + for (Language lang : LANGUAGES) { + reply = (DocumentReply)deserialize(filename, type, lang); + assertNotNull(reply); + } + } + + protected void testVisitorReply(String filename, int type) { + VisitorReply reply = new VisitorReply(type); + assertEquals(5, serialize(filename, reply)); + + for (Language lang : LANGUAGES) { + reply = (VisitorReply)deserialize(filename, type, lang); + assertNotNull(reply); + } + } + + static int serializedLength(String str) { + return 4 + str.length(); + } } diff --git a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/RoutableFactoryTestCase.java b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/RoutableFactoryTestCase.java index 59cbf5b65ae..d9fd307d9d9 100755 --- a/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/RoutableFactoryTestCase.java +++ b/documentapi/src/test/java/com/yahoo/documentapi/messagebus/protocol/test/RoutableFactoryTestCase.java @@ -8,7 +8,7 @@ import com.yahoo.document.serialization.DocumentSerializer; import com.yahoo.documentapi.messagebus.protocol.DocumentMessage; import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol; import com.yahoo.documentapi.messagebus.protocol.DocumentReply; -import com.yahoo.documentapi.messagebus.protocol.RoutableFactories52; +import com.yahoo.documentapi.messagebus.protocol.RoutableFactories60; import com.yahoo.jrt.ListenFailedException; import com.yahoo.jrt.slobrok.server.Slobrok; import com.yahoo.messagebus.DestinationSession; @@ -130,7 +130,7 @@ public class RoutableFactoryTestCase { assertFalse(reply.hasErrors()); } - private static class MyMessageFactory extends RoutableFactories52.DocumentMessageFactory { + private static class MyMessageFactory extends RoutableFactories60.DocumentMessageFactory { @Override protected DocumentMessage doDecode(DocumentDeserializer buf) { @@ -143,7 +143,7 @@ public class RoutableFactoryTestCase { } } - private static class MyReplyFactory extends RoutableFactories52.DocumentReplyFactory { + private static class MyReplyFactory extends RoutableFactories60.DocumentReplyFactory { @Override protected DocumentReply doDecode(DocumentDeserializer buf) { diff --git a/documentapi/src/tests/messagebus/messagebus_test.cpp b/documentapi/src/tests/messagebus/messagebus_test.cpp index 22a46951ecc..05275870a2e 100644 --- a/documentapi/src/tests/messagebus/messagebus_test.cpp +++ b/documentapi/src/tests/messagebus/messagebus_test.cpp @@ -70,10 +70,10 @@ void Test::testMessage() { LoadTypeSet set; DocumentProtocol protocol(set, _repo); - Blob blob = protocol.encode(vespalib::Version(5,115), upd1); + Blob blob = protocol.encode(vespalib::Version(6,221), upd1); EXPECT_TRUE(blob.size() > 0); - Routable::UP dec1 = protocol.decode(vespalib::Version(5,115), blob); + Routable::UP dec1 = protocol.decode(vespalib::Version(6,221), blob); EXPECT_TRUE(dec1.get() != NULL); EXPECT_TRUE(dec1->isReply() == false); EXPECT_TRUE(dec1->getType() == DocumentProtocol::MESSAGE_UPDATEDOCUMENT); diff --git a/documentapi/src/tests/messages/CMakeLists.txt b/documentapi/src/tests/messages/CMakeLists.txt index 576557968e8..87f8d4d01cd 100644 --- a/documentapi/src/tests/messages/CMakeLists.txt +++ b/documentapi/src/tests/messages/CMakeLists.txt @@ -1,17 +1,7 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(documentapi_messages52_test_app TEST - SOURCES - testbase.cpp - messages52test.cpp - messages52app.cpp - DEPENDS - documentapi -) -vespa_add_test(NAME documentapi_messages52_test_app COMMAND documentapi_messages52_test_app) vespa_add_executable(documentapi_messages60_test_app TEST SOURCES testbase.cpp - messages52test.cpp messages60test.cpp messages60app.cpp DEPENDS diff --git a/documentapi/src/tests/messages/messages52app.cpp b/documentapi/src/tests/messages/messages52app.cpp deleted file mode 100644 index 4a925fd554f..00000000000 --- a/documentapi/src/tests/messages/messages52app.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "messages52test.h" - -TEST_APPHOOK(Messages52Test); diff --git a/documentapi/src/tests/messages/messages52test.cpp b/documentapi/src/tests/messages/messages52test.cpp deleted file mode 100644 index 21307326a75..00000000000 --- a/documentapi/src/tests/messages/messages52test.cpp +++ /dev/null @@ -1,1061 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -// @author Vegard Sjonfjell - -#include "messages52test.h" -#include <vespa/document/bucket/bucketidfactory.h> -#include <vespa/document/datatype/documenttype.h> -#include <vespa/document/select/parser.h> -#include <vespa/document/repo/documenttyperepo.h> -#include <vespa/document/update/documentupdate.h> -#include <vespa/document/update/fieldpathupdates.h> -#include <vespa/documentapi/documentapi.h> -#include <vespa/document/bucket/fixed_bucket_spaces.h> - -using document::DataType; -using document::DocumentTypeRepo; - -/////////////////////////////////////////////////////////////////////////////// -// -// Setup -// -/////////////////////////////////////////////////////////////////////////////// - -Messages52Test::Messages52Test() -{ - // This list MUST mirror the list of routable factories from the DocumentProtocol constructor that support - // version 5.0. When adding tests to this list, please KEEP THEM ORDERED alphabetically like they are now. - putTest(DocumentProtocol::MESSAGE_CREATEVISITOR, TEST_METHOD(Messages52Test::testCreateVisitorMessage)); - putTest(DocumentProtocol::MESSAGE_DESTROYVISITOR, TEST_METHOD(Messages52Test::testDestroyVisitorMessage)); - putTest(DocumentProtocol::MESSAGE_DOCUMENTLIST, TEST_METHOD(Messages52Test::testDocumentListMessage)); - putTest(DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, TEST_METHOD(Messages52Test::testDocumentSummaryMessage)); - putTest(DocumentProtocol::MESSAGE_EMPTYBUCKETS, TEST_METHOD(Messages52Test::testEmptyBucketsMessage)); - putTest(DocumentProtocol::MESSAGE_GETBUCKETLIST, TEST_METHOD(Messages52Test::testGetBucketListMessage)); - putTest(DocumentProtocol::MESSAGE_GETBUCKETSTATE, TEST_METHOD(Messages52Test::testGetBucketStateMessage)); - putTest(DocumentProtocol::MESSAGE_GETDOCUMENT, TEST_METHOD(Messages52Test::testGetDocumentMessage)); - putTest(DocumentProtocol::MESSAGE_MAPVISITOR, TEST_METHOD(Messages52Test::testMapVisitorMessage)); - putTest(DocumentProtocol::MESSAGE_PUTDOCUMENT, TEST_METHOD(Messages52Test::testPutDocumentMessage)); - putTest(DocumentProtocol::MESSAGE_QUERYRESULT, TEST_METHOD(Messages52Test::testQueryResultMessage)); - putTest(DocumentProtocol::MESSAGE_REMOVEDOCUMENT, TEST_METHOD(Messages52Test::testRemoveDocumentMessage)); - putTest(DocumentProtocol::MESSAGE_REMOVELOCATION, TEST_METHOD(Messages52Test::testRemoveLocationMessage)); - putTest(DocumentProtocol::MESSAGE_SEARCHRESULT, TEST_METHOD(Messages52Test::testSearchResultMessage)); - putTest(DocumentProtocol::MESSAGE_STATBUCKET, TEST_METHOD(Messages52Test::testStatBucketMessage)); - putTest(DocumentProtocol::MESSAGE_UPDATEDOCUMENT, TEST_METHOD(Messages52Test::testUpdateDocumentMessage)); - putTest(DocumentProtocol::MESSAGE_VISITORINFO, TEST_METHOD(Messages52Test::testVisitorInfoMessage)); - - putTest(DocumentProtocol::REPLY_CREATEVISITOR, TEST_METHOD(Messages52Test::testCreateVisitorReply)); - putTest(DocumentProtocol::REPLY_DESTROYVISITOR, TEST_METHOD(Messages52Test::testDestroyVisitorReply)); - putTest(DocumentProtocol::REPLY_DOCUMENTIGNORED, TEST_METHOD(Messages52Test::testDocumentIgnoredReply)); - putTest(DocumentProtocol::REPLY_DOCUMENTLIST, TEST_METHOD(Messages52Test::testDocumentListReply)); - putTest(DocumentProtocol::REPLY_DOCUMENTSUMMARY, TEST_METHOD(Messages52Test::testDocumentSummaryReply)); - putTest(DocumentProtocol::REPLY_EMPTYBUCKETS, TEST_METHOD(Messages52Test::testEmptyBucketsReply)); - putTest(DocumentProtocol::REPLY_GETBUCKETLIST, TEST_METHOD(Messages52Test::testGetBucketListReply)); - putTest(DocumentProtocol::REPLY_GETBUCKETSTATE, TEST_METHOD(Messages52Test::testGetBucketStateReply)); - putTest(DocumentProtocol::REPLY_GETDOCUMENT, TEST_METHOD(Messages52Test::testGetDocumentReply)); - putTest(DocumentProtocol::REPLY_MAPVISITOR, TEST_METHOD(Messages52Test::testMapVisitorReply)); - putTest(DocumentProtocol::REPLY_PUTDOCUMENT, TEST_METHOD(Messages52Test::testPutDocumentReply)); - putTest(DocumentProtocol::REPLY_QUERYRESULT, TEST_METHOD(Messages52Test::testQueryResultReply)); - putTest(DocumentProtocol::REPLY_REMOVEDOCUMENT, TEST_METHOD(Messages52Test::testRemoveDocumentReply)); - putTest(DocumentProtocol::REPLY_REMOVELOCATION, TEST_METHOD(Messages52Test::testRemoveLocationReply)); - putTest(DocumentProtocol::REPLY_SEARCHRESULT, TEST_METHOD(Messages52Test::testSearchResultReply)); - putTest(DocumentProtocol::REPLY_STATBUCKET, TEST_METHOD(Messages52Test::testStatBucketReply)); - putTest(DocumentProtocol::REPLY_UPDATEDOCUMENT, TEST_METHOD(Messages52Test::testUpdateDocumentReply)); - putTest(DocumentProtocol::REPLY_VISITORINFO, TEST_METHOD(Messages52Test::testVisitorInfoReply)); - putTest(DocumentProtocol::REPLY_WRONGDISTRIBUTION, TEST_METHOD(Messages52Test::testWrongDistributionReply)); -} - - - -/////////////////////////////////////////////////////////////////////////////// -// -// Tests -// -/////////////////////////////////////////////////////////////////////////////// - -static const int MESSAGE_BASE_LENGTH = 5; - -namespace { - -document::Document::SP -createDoc(const DocumentTypeRepo &repo, const string &type_name, const string &id) -{ - return document::Document::SP(new document::Document( - *repo.getDocumentType(type_name), - document::DocumentId(id))); -} - -} // namespace - -bool -Messages52Test::testGetBucketListMessage() -{ - GetBucketListMessage msg(document::BucketId(16, 123)); - msg.setLoadType(_loadTypes["foo"]); - EXPECT_EQUAL(string("foo"), msg.getLoadType().getName()); - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 12u, serialize("GetBucketListMessage", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetBucketListMessage", DocumentProtocol::MESSAGE_GETBUCKETLIST, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - GetBucketListMessage &ref = static_cast<GetBucketListMessage&>(*obj); - EXPECT_EQUAL(string("foo"), ref.getLoadType().getName()); - EXPECT_EQUAL(document::BucketId(16, 123), ref.getBucketId()); - } - } - return true; -} - -bool -Messages52Test::testEmptyBucketsMessage() -{ - std::vector<document::BucketId> bids; - for (size_t i=0; i < 13; ++i) { - bids.push_back(document::BucketId(16, i)); - } - - EmptyBucketsMessage msg(bids); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 112u, serialize("EmptyBucketsMessage", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("EmptyBucketsMessage", DocumentProtocol::MESSAGE_EMPTYBUCKETS, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - EmptyBucketsMessage &ref = static_cast<EmptyBucketsMessage&>(*obj); - for (size_t i=0; i < 13; ++i) { - EXPECT_EQUAL(document::BucketId(16, i), ref.getBucketIds()[i]); - } - } - } - return true; -} - - -bool -Messages52Test::testStatBucketMessage() -{ - StatBucketMessage msg(document::BucketId(16, 123), "id.user=123"); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 27u, serialize("StatBucketMessage", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("StatBucketMessage", DocumentProtocol::MESSAGE_STATBUCKET, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - StatBucketMessage &ref = static_cast<StatBucketMessage&>(*obj); - EXPECT_EQUAL(document::BucketId(16, 123), ref.getBucketId()); - EXPECT_EQUAL("id.user=123", ref.getDocumentSelection()); - } - } - return true; -} - -bool -Messages52Test::testCreateVisitorMessage() { - CreateVisitorMessage tmp("SomeLibrary", "myvisitor", "newyork", "london"); - tmp.setDocumentSelection("true and false or true"); - tmp.getParameters().set("myvar", "somevalue"); - tmp.getParameters().set("anothervar", uint64_t(34)); - tmp.getBuckets().push_back(document::BucketId(16, 1234)); - tmp.setVisitRemoves(true); - tmp.setFieldSet("foo bar"); - tmp.setVisitorOrdering(document::OrderingSpecification::DESCENDING); - tmp.setMaxBucketsPerVisitor(2); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)178, serialize("CreateVisitorMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("CreateVisitorMessage", DocumentProtocol::MESSAGE_CREATEVISITOR, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - CreateVisitorMessage &ref = static_cast<CreateVisitorMessage&>(*obj); - - EXPECT_EQUAL(string("SomeLibrary"), ref.getLibraryName()); - EXPECT_EQUAL(string("myvisitor"), ref.getInstanceId()); - EXPECT_EQUAL(string("newyork"), ref.getControlDestination()); - EXPECT_EQUAL(string("london"), ref.getDataDestination()); - EXPECT_EQUAL(string("true and false or true"), ref.getDocumentSelection()); - EXPECT_EQUAL(string("foo bar"), ref.getFieldSet()); - EXPECT_EQUAL(uint32_t(8), ref.getMaximumPendingReplyCount()); - EXPECT_EQUAL(true, ref.visitRemoves()); - EXPECT_EQUAL(false, ref.visitHeadersOnly()); - EXPECT_EQUAL(false, ref.visitInconsistentBuckets()); - EXPECT_EQUAL(size_t(1), ref.getBuckets().size()); - EXPECT_EQUAL(document::BucketId(16, 1234), ref.getBuckets()[0]); - EXPECT_EQUAL(string("somevalue"), ref.getParameters().get("myvar")); - EXPECT_EQUAL(uint64_t(34), ref.getParameters().get("anothervar", uint64_t(1))); - EXPECT_EQUAL(document::OrderingSpecification::DESCENDING, ref.getVisitorOrdering()); - EXPECT_EQUAL(uint32_t(2), ref.getMaxBucketsPerVisitor()); - } - } - return true; -} - -bool -Messages52Test::testDestroyVisitorMessage() -{ - DestroyVisitorMessage tmp("myvisitor"); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)17, serialize("DestroyVisitorMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("DestroyVisitorMessage", DocumentProtocol::MESSAGE_DESTROYVISITOR, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - DestroyVisitorMessage &ref = static_cast<DestroyVisitorMessage&>(*obj); - EXPECT_EQUAL(string("myvisitor"), ref.getInstanceId()); - } - } - return true; -} - -bool -Messages52Test::testDocumentListMessage() -{ - document::Document::SP doc = - createDoc(getTypeRepo(), "testdoc", "userdoc:scheme:1234:"); - DocumentListMessage::Entry entry(1234, doc, false); - - DocumentListMessage tmp(document::BucketId(16, 1234)); - tmp.getDocuments().push_back(entry); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)63, serialize("DocumentListMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("DocumentListMessage", DocumentProtocol::MESSAGE_DOCUMENTLIST, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - DocumentListMessage &ref = static_cast<DocumentListMessage&>(*obj); - - EXPECT_EQUAL("userdoc:scheme:1234:", ref.getDocuments()[0].getDocument()->getId().toString()); - EXPECT_EQUAL(1234, ref.getDocuments()[0].getTimestamp()); - EXPECT_TRUE(!ref.getDocuments()[0].isRemoveEntry()); - } - } - return true; -} - - -bool -Messages52Test::testRemoveLocationMessage() -{ - { - document::BucketIdFactory factory; - document::select::Parser parser(getTypeRepo(), factory); - RemoveLocationMessage msg(factory, parser, "id.group == \"mygroup\""); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 29u, serialize("RemoveLocationMessage", msg)); - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("RemoveLocationMessage", DocumentProtocol::MESSAGE_REMOVELOCATION, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - RemoveLocationMessage &ref = static_cast<RemoveLocationMessage&>(*obj); - EXPECT_EQUAL(string("id.group == \"mygroup\""), ref.getDocumentSelection()); - // FIXME add to wire format, currently hardcoded. - EXPECT_EQUAL(string(document::FixedBucketSpaces::default_space_name()), ref.getBucketSpace()); - } - } - } - - return true; -} - - - -bool -Messages52Test::testDocumentSummaryMessage() -{ - DocumentSummaryMessage srm; - EXPECT_EQUAL(srm.hasSequenceId(), false); - EXPECT_EQUAL(srm.getSummaryCount(), size_t(0)); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(12), serialize("DocumentSummaryMessage-1", srm)); - - mbus::Routable::UP routable = deserialize("DocumentSummaryMessage-1", DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - DocumentSummaryMessage * dm = static_cast<DocumentSummaryMessage *>(routable.get()); - EXPECT_EQUAL(dm->getSummaryCount(), size_t(0)); - - srm.addSummary("doc1", "summary1", 8); - srm.addSummary("aoc17", "summary45", 9); - - const void *summary(NULL); - const char *docId(NULL); - size_t sz(0); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 52u, serialize("DocumentSummaryMessage-2", srm)); - routable = deserialize("DocumentSummaryMessage-2", DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<DocumentSummaryMessage *>(routable.get()); - EXPECT_EQUAL(dm->getSummaryCount(), size_t(2)); - dm->getSummary(0, docId, summary, sz); - EXPECT_EQUAL(sz, 8u); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - EXPECT_EQUAL(memcmp("summary1", summary, sz), 0); - dm->getSummary(1, docId, summary, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(strcmp("aoc17", docId), 0); - EXPECT_EQUAL(memcmp("summary45", summary, sz), 0); - - srm.sort(); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 52u, serialize("DocumentSummaryMessage-3", srm)); - routable = deserialize("DocumentSummaryMessage-3", DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<DocumentSummaryMessage *>(routable.get()); - EXPECT_EQUAL(dm->getSummaryCount(), size_t(2)); - dm->getSummary(0, docId, summary, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(strcmp("aoc17", docId), 0); - EXPECT_EQUAL(memcmp("summary45", summary, sz), 0); - dm->getSummary(1, docId, summary, sz); - EXPECT_EQUAL(sz, 8u); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - EXPECT_EQUAL(memcmp("summary1", summary, sz), 0); - return true; -} - -bool -Messages52Test::testGetDocumentMessage() -{ - GetDocumentMessage tmp(document::DocumentId("doc:scheme:"), "foo bar"); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)27, serialize("GetDocumentMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetDocumentMessage", DocumentProtocol::MESSAGE_GETDOCUMENT, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - GetDocumentMessage &ref = static_cast<GetDocumentMessage&>(*obj); - EXPECT_EQUAL(string("doc:scheme:"), ref.getDocumentId().toString()); - EXPECT_EQUAL(string("foo bar"), ref.getFieldSet()); - } - } - return true; -} - -bool -Messages52Test::testMapVisitorMessage() -{ - MapVisitorMessage tmp; - tmp.getData().set("foo", 3); - tmp.getData().set("bar", 5); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)32, serialize("MapVisitorMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("MapVisitorMessage", DocumentProtocol::MESSAGE_MAPVISITOR, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - MapVisitorMessage &ref = static_cast<MapVisitorMessage&>(*obj); - EXPECT_EQUAL(3, ref.getData().get("foo", 0)); - EXPECT_EQUAL(5, ref.getData().get("bar", 0)); - } - } - return true; -} - -bool -Messages52Test::testCreateVisitorReply() -{ - CreateVisitorReply reply(DocumentProtocol::REPLY_CREATEVISITOR); - reply.setLastBucket(document::BucketId(16, 123)); - vdslib::VisitorStatistics vs; - vs.setBucketsVisited(3); - vs.setDocumentsVisited(1000); - vs.setBytesVisited(1024000); - vs.setDocumentsReturned(123); - vs.setBytesReturned(512000); - vs.setSecondPassDocumentsReturned(456); - vs.setSecondPassBytesReturned(789100); - reply.setVisitorStatistics(vs); - - EXPECT_EQUAL(65u, serialize("CreateVisitorReply", reply)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("CreateVisitorReply", DocumentProtocol::REPLY_CREATEVISITOR, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - CreateVisitorReply &ref = static_cast<CreateVisitorReply&>(*obj); - - EXPECT_EQUAL(ref.getLastBucket(), document::BucketId(16, 123)); - EXPECT_EQUAL(ref.getVisitorStatistics().getBucketsVisited(), (uint32_t)3); - EXPECT_EQUAL(ref.getVisitorStatistics().getDocumentsVisited(), (uint64_t)1000); - EXPECT_EQUAL(ref.getVisitorStatistics().getBytesVisited(), (uint64_t)1024000); - EXPECT_EQUAL(ref.getVisitorStatistics().getDocumentsReturned(), (uint64_t)123); - EXPECT_EQUAL(ref.getVisitorStatistics().getBytesReturned(), (uint64_t)512000); - EXPECT_EQUAL(ref.getVisitorStatistics().getSecondPassDocumentsReturned(), (uint64_t)456); - EXPECT_EQUAL(ref.getVisitorStatistics().getSecondPassBytesReturned(), (uint64_t)789100); - } - } - return true; -} - -bool -Messages52Test::testPutDocumentMessage() -{ - auto doc = createDoc(getTypeRepo(), "testdoc", "doc:scheme:"); - PutDocumentMessage msg(doc); - - msg.setTimestamp(666); - msg.setCondition(TestAndSetCondition("There's just one condition")); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + - 41u + - serializedLength(msg.getCondition().getSelection()), - serialize("PutDocumentMessage", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - auto routableUp = deserialize("PutDocumentMessage", DocumentProtocol::MESSAGE_PUTDOCUMENT, lang); - if (EXPECT_TRUE(routableUp.get() != nullptr)) { - auto & deserializedMsg = static_cast<PutDocumentMessage &>(*routableUp); - - EXPECT_EQUAL(msg.getDocument().getType().getName(), deserializedMsg.getDocument().getType().getName()); - EXPECT_EQUAL(msg.getDocument().getId().toString(), deserializedMsg.getDocument().getId().toString()); - EXPECT_EQUAL(msg.getTimestamp(), deserializedMsg.getTimestamp()); - EXPECT_EQUAL(67u, deserializedMsg.getApproxSize()); - EXPECT_EQUAL(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); - } - } - - return true; -} - -bool -Messages52Test::testGetBucketStateMessage() -{ - GetBucketStateMessage tmp; - tmp.setBucketId(document::BucketId(16, 666)); - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 12u, serialize("GetBucketStateMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetBucketStateMessage", DocumentProtocol::MESSAGE_GETBUCKETSTATE, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - GetBucketStateMessage &ref = static_cast<GetBucketStateMessage&>(*obj); - - EXPECT_EQUAL(16u, ref.getBucketId().getUsedBits()); - EXPECT_EQUAL(4611686018427388570ull, ref.getBucketId().getId()); - } - } - return true; -} - -bool -Messages52Test::testPutDocumentReply() -{ - WriteDocumentReply reply(DocumentProtocol::REPLY_PUTDOCUMENT); - reply.setHighestModificationTimestamp(30); - - EXPECT_EQUAL(13u, serialize("PutDocumentReply", reply)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("PutDocumentReply", DocumentProtocol::REPLY_PUTDOCUMENT, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - WriteDocumentReply &ref = static_cast<WriteDocumentReply&>(*obj); - EXPECT_EQUAL(30u, ref.getHighestModificationTimestamp()); - } - } - return true; -} - -bool -Messages52Test::testUpdateDocumentReply() -{ - UpdateDocumentReply reply; - reply.setWasFound(false); - reply.setHighestModificationTimestamp(30); - - EXPECT_EQUAL(14u, serialize("UpdateDocumentReply", reply)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("UpdateDocumentReply", DocumentProtocol::REPLY_UPDATEDOCUMENT, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - UpdateDocumentReply &ref = static_cast<UpdateDocumentReply&>(*obj); - EXPECT_EQUAL(30u, ref.getHighestModificationTimestamp()); - EXPECT_EQUAL(false, ref.wasFound()); - } - } - return true; -} - -bool -Messages52Test::testRemoveDocumentMessage() -{ - RemoveDocumentMessage msg(document::DocumentId("doc:scheme:")); - - msg.setCondition(TestAndSetCondition("There's just one condition")); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(16) + serializedLength(msg.getCondition().getSelection()), serialize("RemoveDocumentMessage", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - auto routablePtr = deserialize("RemoveDocumentMessage", DocumentProtocol::MESSAGE_REMOVEDOCUMENT, lang); - - if (EXPECT_TRUE(routablePtr.get() != nullptr)) { - auto & ref = static_cast<RemoveDocumentMessage &>(*routablePtr); - EXPECT_EQUAL(string("doc:scheme:"), ref.getDocumentId().toString()); - EXPECT_EQUAL(msg.getCondition().getSelection(), ref.getCondition().getSelection()); - } - } - return true; -} - -bool -Messages52Test::testRemoveDocumentReply() -{ - RemoveDocumentReply reply; - std::vector<uint64_t> ts; - reply.setWasFound(false); - reply.setHighestModificationTimestamp(30); - - EXPECT_EQUAL(14u, serialize("RemoveDocumentReply", reply)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("RemoveDocumentReply", DocumentProtocol::REPLY_REMOVEDOCUMENT, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - RemoveDocumentReply &ref = static_cast<RemoveDocumentReply&>(*obj); - EXPECT_EQUAL(30u, ref.getHighestModificationTimestamp()); - EXPECT_EQUAL(false, ref.wasFound()); - } - } - return true; -} - -bool -Messages52Test::testSearchResultMessage() -{ - SearchResultMessage srm; - EXPECT_EQUAL(srm.getSequenceId(), 0u); - EXPECT_EQUAL(srm.getHitCount(), 0u); - EXPECT_EQUAL(srm.getAggregatorList().getSerializedSize(), 4u); - EXPECT_EQUAL(srm.vdslib::SearchResult::getSerializedSize(), 20u); - EXPECT_EQUAL(srm.getSerializedSize(), 20u); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(24), serialize("SearchResultMessage-1", srm)); - - mbus::Routable::UP routable = deserialize("SearchResultMessage-1", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - SearchResultMessage * dm = static_cast<SearchResultMessage *>(routable.get()); - EXPECT_EQUAL(dm->getSequenceId(), size_t(0)); - EXPECT_EQUAL(dm->getHitCount(), size_t(0)); - - srm.addHit(0, "doc1", 89); - srm.addHit(1, "doc17", 109); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 55u, serialize("SearchResultMessage-2", srm)); - routable = deserialize("SearchResultMessage-2", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<SearchResultMessage *>(routable.get()); - EXPECT_EQUAL(dm->getHitCount(), size_t(2)); - const char *docId; - SearchResultMessage::RankType rank; - dm->getHit(0, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - dm->getHit(1, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - - srm.sort(); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 55u, serialize("SearchResultMessage-3", srm)); - routable = deserialize("SearchResultMessage-3", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<SearchResultMessage *>(routable.get()); - EXPECT_EQUAL(dm->getHitCount(), size_t(2)); - dm->getHit(0, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - dm->getHit(1, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - - SearchResultMessage srm2; - srm2.addHit(0, "doc1", 89, "sortdata2", 9); - srm2.addHit(1, "doc17", 109, "sortdata1", 9); - srm2.addHit(2, "doc18", 90, "sortdata3", 9); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 108u, serialize("SearchResultMessage-4", srm2)); - routable = deserialize("SearchResultMessage-4", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<SearchResultMessage *>(routable.get()); - EXPECT_EQUAL(dm->getHitCount(), size_t(3)); - dm->getHit(0, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - dm->getHit(1, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - dm->getHit(2, docId, rank); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(90)); - EXPECT_EQUAL(strcmp("doc18", docId), 0); - - srm2.sort(); - const void *buf; - size_t sz; - srm2.getHit(0, docId, rank); - srm2.getSortBlob(0, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - srm2.getHit(1, docId, rank); - srm2.getSortBlob(1, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - srm2.getHit(2, docId, rank); - srm2.getSortBlob(2, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(90)); - EXPECT_EQUAL(strcmp("doc18", docId), 0); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 108u, serialize("SearchResultMessage-5", srm2)); - routable = deserialize("SearchResultMessage-5", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<SearchResultMessage *>(routable.get()); - EXPECT_EQUAL(dm->getHitCount(), size_t(3)); - dm->getHit(0, docId, rank); - dm->getSortBlob(0, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - dm->getHit(1, docId, rank); - dm->getSortBlob(1, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - dm->getHit(2, docId, rank); - dm->getSortBlob(2, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); - EXPECT_EQUAL(rank, SearchResultMessage::RankType(90)); - EXPECT_EQUAL(strcmp("doc18", docId), 0); - return true; -} - -bool -Messages52Test::testUpdateDocumentMessage() -{ - const DocumentTypeRepo & repo = getTypeRepo(); - const document::DocumentType & docType = *repo.getDocumentType("testdoc"); - - auto docUpdate = std::make_shared<document::DocumentUpdate>(repo, docType, document::DocumentId("doc:scheme:")); - - docUpdate->addFieldPathUpdate(document::FieldPathUpdate::CP( - new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); - - UpdateDocumentMessage msg(docUpdate); - msg.setOldTimestamp(666u); - msg.setNewTimestamp(777u); - msg.setCondition(TestAndSetCondition("There's just one condition")); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 89u + serializedLength(msg.getCondition().getSelection()), serialize("UpdateDocumentMessage", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - auto routableUp = deserialize("UpdateDocumentMessage", DocumentProtocol::MESSAGE_UPDATEDOCUMENT, lang); - - if (EXPECT_TRUE(routableUp.get() != nullptr)) { - auto & deserializedMsg = static_cast<UpdateDocumentMessage &>(*routableUp); - EXPECT_EQUAL(msg.getDocumentUpdate(), deserializedMsg.getDocumentUpdate()); - EXPECT_EQUAL(msg.getOldTimestamp(), deserializedMsg.getOldTimestamp()); - EXPECT_EQUAL(msg.getNewTimestamp(), deserializedMsg.getNewTimestamp()); - EXPECT_EQUAL(115u, deserializedMsg.getApproxSize()); - EXPECT_EQUAL(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); - } - } - return true; -} - -bool -Messages52Test::testQueryResultMessage() -{ - QueryResultMessage srm; - vdslib::SearchResult & sr(srm.getSearchResult()); - EXPECT_EQUAL(srm.getSequenceId(), 0u); - EXPECT_EQUAL(sr.getHitCount(), 0u); - EXPECT_EQUAL(sr.getAggregatorList().getSerializedSize(), 4u); - EXPECT_EQUAL(sr.getSerializedSize(), 20u); - EXPECT_EQUAL(srm.getApproxSize(), 28u); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(32), serialize("QueryResultMessage-1", srm)); - - mbus::Routable::UP routable = deserialize("QueryResultMessage-1", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - QueryResultMessage * dm = static_cast<QueryResultMessage *>(routable.get()); - vdslib::SearchResult * dr(&dm->getSearchResult()); - EXPECT_EQUAL(dm->getSequenceId(), size_t(0)); - EXPECT_EQUAL(dr->getHitCount(), size_t(0)); - - sr.addHit(0, "doc1", 89); - sr.addHit(1, "doc17", 109); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 63u, serialize("QueryResultMessage-2", srm)); - routable = deserialize("QueryResultMessage-2", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<QueryResultMessage *>(routable.get()); - dr = &dm->getSearchResult(); - EXPECT_EQUAL(dr->getHitCount(), size_t(2)); - const char *docId; - vdslib::SearchResult::RankType rank; - dr->getHit(0, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - dr->getHit(1, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - - sr.sort(); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 63u, serialize("QueryResultMessage-3", srm)); - routable = deserialize("QueryResultMessage-3", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<QueryResultMessage *>(routable.get()); - dr = &dm->getSearchResult(); - EXPECT_EQUAL(dr->getHitCount(), size_t(2)); - dr->getHit(0, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - dr->getHit(1, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - - QueryResultMessage srm2; - vdslib::SearchResult & sr2(srm2.getSearchResult()); - sr2.addHit(0, "doc1", 89, "sortdata2", 9); - sr2.addHit(1, "doc17", 109, "sortdata1", 9); - sr2.addHit(2, "doc18", 90, "sortdata3", 9); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 116u, serialize("QueryResultMessage-4", srm2)); - routable = deserialize("QueryResultMessage-4", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<QueryResultMessage *>(routable.get()); - dr = &dm->getSearchResult(); - EXPECT_EQUAL(dr->getHitCount(), size_t(3)); - dr->getHit(0, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - dr->getHit(1, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - dr->getHit(2, docId, rank); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(90)); - EXPECT_EQUAL(strcmp("doc18", docId), 0); - - sr2.sort(); - const void *buf; - size_t sz; - sr2.getHit(0, docId, rank); - sr2.getSortBlob(0, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - sr2.getHit(1, docId, rank); - sr2.getSortBlob(1, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - sr2.getHit(2, docId, rank); - sr2.getSortBlob(2, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(90)); - EXPECT_EQUAL(strcmp("doc18", docId), 0); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 116u, serialize("QueryResultMessage-5", srm2)); - routable = deserialize("QueryResultMessage-5", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); - if (!EXPECT_TRUE(routable.get() != NULL)) { - return false; - } - dm = static_cast<QueryResultMessage *>(routable.get()); - dr = &dm->getSearchResult(); - EXPECT_EQUAL(dr->getHitCount(), size_t(3)); - dr->getHit(0, docId, rank); - dr->getSortBlob(0, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); - EXPECT_EQUAL(strcmp("doc17", docId), 0); - dr->getHit(1, docId, rank); - dr->getSortBlob(1, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); - EXPECT_EQUAL(strcmp("doc1", docId), 0); - dr->getHit(2, docId, rank); - dr->getSortBlob(2, buf, sz); - EXPECT_EQUAL(sz, 9u); - EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); - EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(90)); - EXPECT_EQUAL(strcmp("doc18", docId), 0); - return true; -} - -bool -Messages52Test::testQueryResultReply() -{ - return tryVisitorReply("QueryResultReply", DocumentProtocol::REPLY_QUERYRESULT); -} - -bool -Messages52Test::testVisitorInfoMessage() -{ - - VisitorInfoMessage tmp; - tmp.getFinishedBuckets().push_back(document::BucketId(16, 1)); - tmp.getFinishedBuckets().push_back(document::BucketId(16, 2)); - tmp.getFinishedBuckets().push_back(document::BucketId(16, 4)); - string utf8 = "error message: \u00e6\u00c6\u00f8\u00d8\u00e5\u00c5\u00f6\u00d6"; - tmp.setErrorMessage(utf8); - - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 67u, serialize("VisitorInfoMessage", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("VisitorInfoMessage", DocumentProtocol::MESSAGE_VISITORINFO, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - VisitorInfoMessage &ref = static_cast<VisitorInfoMessage&>(*obj); - EXPECT_EQUAL(document::BucketId(16, 1), ref.getFinishedBuckets()[0]); - EXPECT_EQUAL(document::BucketId(16, 2), ref.getFinishedBuckets()[1]); - EXPECT_EQUAL(document::BucketId(16, 4), ref.getFinishedBuckets()[2]); - EXPECT_EQUAL(utf8, ref.getErrorMessage()); - } - } - return true; -} - -bool -Messages52Test::testDestroyVisitorReply() -{ - return tryDocumentReply("DestroyVisitorReply", DocumentProtocol::REPLY_DESTROYVISITOR); -} - -bool -Messages52Test::testDocumentIgnoredReply() -{ - DocumentIgnoredReply tmp; - serialize("DocumentIgnoredReply", tmp); - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj( - deserialize("DocumentIgnoredReply", - DocumentProtocol::REPLY_DOCUMENTIGNORED, lang)); - EXPECT_TRUE(obj.get() != NULL); - } - return true; -} - -bool -Messages52Test::testDocumentListReply() -{ - return tryVisitorReply("DocumentListReply", DocumentProtocol::REPLY_DOCUMENTLIST); -} - -bool -Messages52Test::testDocumentSummaryReply() -{ - return tryVisitorReply("DocumentSummaryReply", DocumentProtocol::REPLY_DOCUMENTSUMMARY); -} - -bool -Messages52Test::testGetDocumentReply() -{ - document::Document::SP doc = - createDoc(getTypeRepo(), "testdoc", "doc:scheme:"); - GetDocumentReply tmp(doc); - - EXPECT_EQUAL((size_t)43, serialize("GetDocumentReply", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetDocumentReply", DocumentProtocol::REPLY_GETDOCUMENT, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - GetDocumentReply &ref = static_cast<GetDocumentReply&>(*obj); - - EXPECT_EQUAL(string("testdoc"), ref.getDocument().getType().getName()); - EXPECT_EQUAL(string("doc:scheme:"), ref.getDocument().getId().toString()); - } - } - return true; -} - -bool -Messages52Test::testMapVisitorReply() -{ - return tryVisitorReply("MapVisitorReply", DocumentProtocol::REPLY_MAPVISITOR); -} - -bool -Messages52Test::testSearchResultReply() -{ - return tryVisitorReply("SearchResultReply", DocumentProtocol::REPLY_SEARCHRESULT); -} - -bool -Messages52Test::testStatBucketReply() -{ - StatBucketReply msg; - msg.setResults("These are the votes of the Norwegian jury"); - - EXPECT_EQUAL(50u, serialize("StatBucketReply", msg)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("StatBucketReply", DocumentProtocol::REPLY_STATBUCKET, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - StatBucketReply &ref = static_cast<StatBucketReply&>(*obj); - EXPECT_EQUAL("These are the votes of the Norwegian jury", ref.getResults()); - } - } - return true; -} - -bool -Messages52Test::testVisitorInfoReply() -{ - return tryVisitorReply("VisitorInfoReply", DocumentProtocol::REPLY_VISITORINFO); -} - -bool -Messages52Test::testWrongDistributionReply() -{ - WrongDistributionReply tmp("distributor:3 storage:2"); - - serialize("WrongDistributionReply", tmp); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("WrongDistributionReply", DocumentProtocol::REPLY_WRONGDISTRIBUTION, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - WrongDistributionReply &ref = static_cast<WrongDistributionReply&>(*obj); - EXPECT_EQUAL(string("distributor:3 storage:2"), ref.getSystemState()); - } - } - return true; -} - -bool -Messages52Test::testGetBucketListReply() -{ - GetBucketListReply reply; - reply.getBuckets().push_back(GetBucketListReply::BucketInfo(document::BucketId(16, 123), "foo")); - reply.getBuckets().push_back(GetBucketListReply::BucketInfo(document::BucketId(17, 1123), "bar")); - reply.getBuckets().push_back(GetBucketListReply::BucketInfo(document::BucketId(18, 11123), "zoink")); - - EXPECT_EQUAL(56u, serialize("GetBucketListReply", reply)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetBucketListReply", DocumentProtocol::REPLY_GETBUCKETLIST, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - GetBucketListReply &ref = static_cast<GetBucketListReply&>(*obj); - - EXPECT_EQUAL(ref.getBuckets()[0], GetBucketListReply::BucketInfo(document::BucketId(16, 123), "foo")); - EXPECT_EQUAL(ref.getBuckets()[1], GetBucketListReply::BucketInfo(document::BucketId(17, 1123), "bar")); - EXPECT_EQUAL(ref.getBuckets()[2], GetBucketListReply::BucketInfo(document::BucketId(18, 11123), "zoink")); - } - } - return true; -} - -bool -Messages52Test::testGetBucketStateReply() -{ - document::GlobalId foo = document::DocumentId("doc:scheme:foo").getGlobalId(); - document::GlobalId bar = document::DocumentId("doc:scheme:bar").getGlobalId(); - - GetBucketStateReply reply; - reply.getBucketState().push_back(DocumentState(foo, 777, false)); - reply.getBucketState().push_back(DocumentState(bar, 888, true)); - EXPECT_EQUAL(53u, serialize("GetBucketStateReply", reply)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetBucketStateReply", DocumentProtocol::REPLY_GETBUCKETSTATE, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - GetBucketStateReply &ref = static_cast<GetBucketStateReply&>(*obj); - - EXPECT_EQUAL(777u, ref.getBucketState()[0].getTimestamp()); - EXPECT_EQUAL(foo, ref.getBucketState()[0].getGlobalId()); - EXPECT_EQUAL(false, ref.getBucketState()[0].isRemoveEntry()); - EXPECT_EQUAL(888u, ref.getBucketState()[1].getTimestamp()); - EXPECT_EQUAL(bar, ref.getBucketState()[1].getGlobalId()); - EXPECT_EQUAL(true, ref.getBucketState()[1].isRemoveEntry()); - } - } - return true; -} - -bool -Messages52Test::testEmptyBucketsReply() -{ - return tryVisitorReply("EmptyBucketsReply", DocumentProtocol::REPLY_EMPTYBUCKETS); -} - -bool -Messages52Test::testRemoveLocationReply() -{ - DocumentReply tmp(DocumentProtocol::REPLY_REMOVELOCATION); - - EXPECT_EQUAL((uint32_t)5, serialize("RemoveLocationReply", tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("RemoveLocationReply", DocumentProtocol::REPLY_REMOVELOCATION, lang); - EXPECT_TRUE(obj.get() != NULL); - } - return true; -} - - - -//////////////////////////////////////////////////////////////////////////////// -// -// Utilities -// -//////////////////////////////////////////////////////////////////////////////// - -bool -Messages52Test::tryDocumentReply(const string &filename, uint32_t type) -{ - DocumentReply tmp(type); - - EXPECT_EQUAL((uint32_t)5, serialize(filename, tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize(filename, type, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - DocumentReply *ref = dynamic_cast<DocumentReply*>(obj.get()); - EXPECT_TRUE(ref != NULL); - } - } - return true; -} - -bool -Messages52Test::tryVisitorReply(const string &filename, uint32_t type) -{ - VisitorReply tmp(type); - - EXPECT_EQUAL((uint32_t)5, serialize(filename, tmp)); - - for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize(filename, type, lang); - if (EXPECT_TRUE(obj.get() != NULL)) { - VisitorReply *ref = dynamic_cast<VisitorReply*>(obj.get()); - EXPECT_TRUE(ref != NULL); - } - } - return true; -} diff --git a/documentapi/src/tests/messages/messages52test.h b/documentapi/src/tests/messages/messages52test.h deleted file mode 100644 index 6b019d77bde..00000000000 --- a/documentapi/src/tests/messages/messages52test.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -// @author Vegard Sjonfjell -#pragma once - -#include "testbase.h" - -class Messages52Test : public TestBase { -protected: - const vespalib::Version getVersion() const override { return vespalib::Version(5, 115); } - bool shouldTestCoverage() const override { return true; } - bool tryDocumentReply(const string &filename, uint32_t type); - bool tryVisitorReply(const string &filename, uint32_t type); - - static size_t serializedLength(const string & str) { return sizeof(int32_t) + str.size(); } - -public: - Messages52Test(); - - bool testCreateVisitorMessage(); - bool testCreateVisitorReply(); - bool testDestroyVisitorMessage(); - bool testDestroyVisitorReply(); - bool testDocumentIgnoredReply(); - bool testDocumentListMessage(); - bool testDocumentListReply(); - bool testDocumentSummaryMessage(); - bool testDocumentSummaryReply(); - bool testEmptyBucketsMessage(); - bool testEmptyBucketsReply(); - bool testGetBucketListMessage(); - bool testGetBucketListReply(); - bool testGetBucketStateMessage(); - bool testGetBucketStateReply(); - bool testGetDocumentMessage(); - bool testGetDocumentReply(); - bool testMapVisitorMessage(); - bool testMapVisitorReply(); - bool testPutDocumentMessage(); - bool testPutDocumentReply(); - bool testQueryResultMessage(); - bool testQueryResultReply(); - bool testRemoveDocumentMessage(); - bool testRemoveDocumentReply(); - bool testRemoveLocationMessage(); - bool testRemoveLocationReply(); - bool testSearchResultMessage(); - bool testSearchResultReply(); - bool testStatBucketMessage(); - bool testStatBucketReply(); - bool testUpdateDocumentMessage(); - bool testUpdateDocumentReply(); - bool testVisitorInfoMessage(); - bool testVisitorInfoReply(); - bool testWrongDistributionReply(); -}; - diff --git a/documentapi/src/tests/messages/messages60test.cpp b/documentapi/src/tests/messages/messages60test.cpp index e553744452b..2fdb4c12fd0 100644 --- a/documentapi/src/tests/messages/messages60test.cpp +++ b/documentapi/src/tests/messages/messages60test.cpp @@ -1,20 +1,159 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// @author Vegard Sjonfjell #include "messages60test.h" +#include <vespa/document/bucket/bucketidfactory.h> +#include <vespa/document/datatype/documenttype.h> +#include <vespa/document/select/parser.h> +#include <vespa/document/repo/documenttyperepo.h> +#include <vespa/document/update/documentupdate.h> +#include <vespa/document/update/fieldpathupdates.h> #include <vespa/documentapi/documentapi.h> +#include <vespa/document/bucket/fixed_bucket_spaces.h> -static constexpr int MESSAGE_BASE_LENGTH = 5; +using document::DataType; +using document::DocumentTypeRepo; -Messages60Test::Messages60Test() { +/////////////////////////////////////////////////////////////////////////////// +// +// Setup +// +/////////////////////////////////////////////////////////////////////////////// + +Messages60Test::Messages60Test() +{ // This list MUST mirror the list of routable factories from the DocumentProtocol constructor that support - // version 6.x. When adding tests to this list, please KEEP THEM ORDERED alphabetically like they are now. + // version 5.0. When adding tests to this list, please KEEP THEM ORDERED alphabetically like they are now. putTest(DocumentProtocol::MESSAGE_CREATEVISITOR, TEST_METHOD(Messages60Test::testCreateVisitorMessage)); - putTest(DocumentProtocol::MESSAGE_STATBUCKET, TEST_METHOD(Messages60Test::testStatBucketMessage)); + putTest(DocumentProtocol::MESSAGE_DESTROYVISITOR, TEST_METHOD(Messages60Test::testDestroyVisitorMessage)); + putTest(DocumentProtocol::MESSAGE_DOCUMENTLIST, TEST_METHOD(Messages60Test::testDocumentListMessage)); + putTest(DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, TEST_METHOD(Messages60Test::testDocumentSummaryMessage)); + putTest(DocumentProtocol::MESSAGE_EMPTYBUCKETS, TEST_METHOD(Messages60Test::testEmptyBucketsMessage)); putTest(DocumentProtocol::MESSAGE_GETBUCKETLIST, TEST_METHOD(Messages60Test::testGetBucketListMessage)); + putTest(DocumentProtocol::MESSAGE_GETBUCKETSTATE, TEST_METHOD(Messages60Test::testGetBucketStateMessage)); + putTest(DocumentProtocol::MESSAGE_GETDOCUMENT, TEST_METHOD(Messages60Test::testGetDocumentMessage)); + putTest(DocumentProtocol::MESSAGE_MAPVISITOR, TEST_METHOD(Messages60Test::testMapVisitorMessage)); + putTest(DocumentProtocol::MESSAGE_PUTDOCUMENT, TEST_METHOD(Messages60Test::testPutDocumentMessage)); + putTest(DocumentProtocol::MESSAGE_QUERYRESULT, TEST_METHOD(Messages60Test::testQueryResultMessage)); + putTest(DocumentProtocol::MESSAGE_REMOVEDOCUMENT, TEST_METHOD(Messages60Test::testRemoveDocumentMessage)); + putTest(DocumentProtocol::MESSAGE_REMOVELOCATION, TEST_METHOD(Messages60Test::testRemoveLocationMessage)); + putTest(DocumentProtocol::MESSAGE_SEARCHRESULT, TEST_METHOD(Messages60Test::testSearchResultMessage)); + putTest(DocumentProtocol::MESSAGE_STATBUCKET, TEST_METHOD(Messages60Test::testStatBucketMessage)); + putTest(DocumentProtocol::MESSAGE_UPDATEDOCUMENT, TEST_METHOD(Messages60Test::testUpdateDocumentMessage)); + putTest(DocumentProtocol::MESSAGE_VISITORINFO, TEST_METHOD(Messages60Test::testVisitorInfoMessage)); + + putTest(DocumentProtocol::REPLY_CREATEVISITOR, TEST_METHOD(Messages60Test::testCreateVisitorReply)); + putTest(DocumentProtocol::REPLY_DESTROYVISITOR, TEST_METHOD(Messages60Test::testDestroyVisitorReply)); + putTest(DocumentProtocol::REPLY_DOCUMENTIGNORED, TEST_METHOD(Messages60Test::testDocumentIgnoredReply)); + putTest(DocumentProtocol::REPLY_DOCUMENTLIST, TEST_METHOD(Messages60Test::testDocumentListReply)); + putTest(DocumentProtocol::REPLY_DOCUMENTSUMMARY, TEST_METHOD(Messages60Test::testDocumentSummaryReply)); + putTest(DocumentProtocol::REPLY_EMPTYBUCKETS, TEST_METHOD(Messages60Test::testEmptyBucketsReply)); + putTest(DocumentProtocol::REPLY_GETBUCKETLIST, TEST_METHOD(Messages60Test::testGetBucketListReply)); + putTest(DocumentProtocol::REPLY_GETBUCKETSTATE, TEST_METHOD(Messages60Test::testGetBucketStateReply)); + putTest(DocumentProtocol::REPLY_GETDOCUMENT, TEST_METHOD(Messages60Test::testGetDocumentReply)); + putTest(DocumentProtocol::REPLY_MAPVISITOR, TEST_METHOD(Messages60Test::testMapVisitorReply)); + putTest(DocumentProtocol::REPLY_PUTDOCUMENT, TEST_METHOD(Messages60Test::testPutDocumentReply)); + putTest(DocumentProtocol::REPLY_QUERYRESULT, TEST_METHOD(Messages60Test::testQueryResultReply)); + putTest(DocumentProtocol::REPLY_REMOVEDOCUMENT, TEST_METHOD(Messages60Test::testRemoveDocumentReply)); + putTest(DocumentProtocol::REPLY_REMOVELOCATION, TEST_METHOD(Messages60Test::testRemoveLocationReply)); + putTest(DocumentProtocol::REPLY_SEARCHRESULT, TEST_METHOD(Messages60Test::testSearchResultReply)); + putTest(DocumentProtocol::REPLY_STATBUCKET, TEST_METHOD(Messages60Test::testStatBucketReply)); + putTest(DocumentProtocol::REPLY_UPDATEDOCUMENT, TEST_METHOD(Messages60Test::testUpdateDocumentReply)); + putTest(DocumentProtocol::REPLY_VISITORINFO, TEST_METHOD(Messages60Test::testVisitorInfoReply)); + putTest(DocumentProtocol::REPLY_WRONGDISTRIBUTION, TEST_METHOD(Messages60Test::testWrongDistributionReply)); +} + + + +/////////////////////////////////////////////////////////////////////////////// +// +// Tests +// +/////////////////////////////////////////////////////////////////////////////// + +static const int MESSAGE_BASE_LENGTH = 5; + +namespace { + +document::Document::SP +createDoc(const DocumentTypeRepo &repo, const string &type_name, const string &id) +{ + return document::Document::SP(new document::Document( + *repo.getDocumentType(type_name), + document::DocumentId(id))); +} + +} // namespace + +bool +Messages60Test::testGetBucketListMessage() +{ + GetBucketListMessage msg(document::BucketId(16, 123)); + msg.setLoadType(_loadTypes["foo"]); + msg.setBucketSpace("beartato"); + EXPECT_EQUAL(string("foo"), msg.getLoadType().getName()); + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 12u + serializedLength("beartato"), serialize("GetBucketListMessage", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("GetBucketListMessage", DocumentProtocol::MESSAGE_GETBUCKETLIST, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + GetBucketListMessage &ref = static_cast<GetBucketListMessage&>(*obj); + EXPECT_EQUAL(string("foo"), ref.getLoadType().getName()); + EXPECT_EQUAL(document::BucketId(16, 123), ref.getBucketId()); + EXPECT_EQUAL("beartato", ref.getBucketSpace()); + } + } + return true; +} + +bool +Messages60Test::testEmptyBucketsMessage() +{ + std::vector<document::BucketId> bids; + for (size_t i=0; i < 13; ++i) { + bids.push_back(document::BucketId(16, i)); + } + + EmptyBucketsMessage msg(bids); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 112u, serialize("EmptyBucketsMessage", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("EmptyBucketsMessage", DocumentProtocol::MESSAGE_EMPTYBUCKETS, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + EmptyBucketsMessage &ref = static_cast<EmptyBucketsMessage&>(*obj); + for (size_t i=0; i < 13; ++i) { + EXPECT_EQUAL(document::BucketId(16, i), ref.getBucketIds()[i]); + } + } + } + return true; } -// TODO code dupe with parent classes -bool Messages60Test::testCreateVisitorMessage() { + +bool +Messages60Test::testStatBucketMessage() +{ + StatBucketMessage msg(document::BucketId(16, 123), "id.user=123"); + msg.setBucketSpace("andrei"); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 27u + serializedLength("andrei"), serialize("StatBucketMessage", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("StatBucketMessage", DocumentProtocol::MESSAGE_STATBUCKET, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + StatBucketMessage &ref = static_cast<StatBucketMessage&>(*obj); + EXPECT_EQUAL(document::BucketId(16, 123), ref.getBucketId()); + EXPECT_EQUAL("id.user=123", ref.getDocumentSelection()); + EXPECT_EQUAL("andrei", ref.getBucketSpace()); + } + } + return true; +} + +bool +Messages60Test::testCreateVisitorMessage() +{ CreateVisitorMessage tmp("SomeLibrary", "myvisitor", "newyork", "london"); tmp.setDocumentSelection("true and false or true"); tmp.getParameters().set("myvar", "somevalue"); @@ -41,7 +180,6 @@ bool Messages60Test::testCreateVisitorMessage() { EXPECT_EQUAL(string("foo bar"), ref.getFieldSet()); EXPECT_EQUAL(uint32_t(8), ref.getMaximumPendingReplyCount()); EXPECT_EQUAL(true, ref.visitRemoves()); - EXPECT_EQUAL(false, ref.visitHeadersOnly()); EXPECT_EQUAL(false, ref.visitInconsistentBuckets()); EXPECT_EQUAL(size_t(1), ref.getBuckets().size()); EXPECT_EQUAL(document::BucketId(16, 1234), ref.getBuckets()[0]); @@ -55,39 +193,875 @@ bool Messages60Test::testCreateVisitorMessage() { return true; } -bool Messages60Test::testStatBucketMessage() { - StatBucketMessage msg(document::BucketId(16, 123), "id.user=123"); - msg.setBucketSpace("andrei"); +bool +Messages60Test::testDestroyVisitorMessage() +{ + DestroyVisitorMessage tmp("myvisitor"); - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 27u + serializedLength("andrei"), serialize("StatBucketMessage", msg)); + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)17, serialize("DestroyVisitorMessage", tmp)); for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("StatBucketMessage", DocumentProtocol::MESSAGE_STATBUCKET, lang); + mbus::Routable::UP obj = deserialize("DestroyVisitorMessage", DocumentProtocol::MESSAGE_DESTROYVISITOR, lang); if (EXPECT_TRUE(obj.get() != NULL)) { - StatBucketMessage &ref = static_cast<StatBucketMessage&>(*obj); - EXPECT_EQUAL(document::BucketId(16, 123), ref.getBucketId()); - EXPECT_EQUAL("id.user=123", ref.getDocumentSelection()); - EXPECT_EQUAL("andrei", ref.getBucketSpace()); + DestroyVisitorMessage &ref = static_cast<DestroyVisitorMessage&>(*obj); + EXPECT_EQUAL(string("myvisitor"), ref.getInstanceId()); } } return true; } -bool Messages60Test::testGetBucketListMessage() { - GetBucketListMessage msg(document::BucketId(16, 123)); - msg.setLoadType(_loadTypes["foo"]); - msg.setBucketSpace("beartato"); - EXPECT_EQUAL(string("foo"), msg.getLoadType().getName()); - EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 12u + serializedLength("beartato"), serialize("GetBucketListMessage", msg)); +bool +Messages60Test::testDocumentListMessage() +{ + document::Document::SP doc = + createDoc(getTypeRepo(), "testdoc", "userdoc:scheme:1234:"); + DocumentListMessage::Entry entry(1234, doc, false); + + DocumentListMessage tmp(document::BucketId(16, 1234)); + tmp.getDocuments().push_back(entry); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)63, serialize("DocumentListMessage", tmp)); for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { - mbus::Routable::UP obj = deserialize("GetBucketListMessage", DocumentProtocol::MESSAGE_GETBUCKETLIST, lang); + mbus::Routable::UP obj = deserialize("DocumentListMessage", DocumentProtocol::MESSAGE_DOCUMENTLIST, lang); if (EXPECT_TRUE(obj.get() != NULL)) { - GetBucketListMessage &ref = static_cast<GetBucketListMessage&>(*obj); - EXPECT_EQUAL(string("foo"), ref.getLoadType().getName()); - EXPECT_EQUAL(document::BucketId(16, 123), ref.getBucketId()); - EXPECT_EQUAL("beartato", ref.getBucketSpace()); + DocumentListMessage &ref = static_cast<DocumentListMessage&>(*obj); + + EXPECT_EQUAL("userdoc:scheme:1234:", ref.getDocuments()[0].getDocument()->getId().toString()); + EXPECT_EQUAL(1234, ref.getDocuments()[0].getTimestamp()); + EXPECT_TRUE(!ref.getDocuments()[0].isRemoveEntry()); + } + } + return true; +} + + +bool +Messages60Test::testRemoveLocationMessage() +{ + { + document::BucketIdFactory factory; + document::select::Parser parser(getTypeRepo(), factory); + RemoveLocationMessage msg(factory, parser, "id.group == \"mygroup\""); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 29u, serialize("RemoveLocationMessage", msg)); + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("RemoveLocationMessage", DocumentProtocol::MESSAGE_REMOVELOCATION, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + RemoveLocationMessage &ref = static_cast<RemoveLocationMessage&>(*obj); + EXPECT_EQUAL(string("id.group == \"mygroup\""), ref.getDocumentSelection()); + // FIXME add to wire format, currently hardcoded. + EXPECT_EQUAL(string(document::FixedBucketSpaces::default_space_name()), ref.getBucketSpace()); + } + } + } + + return true; +} + + + +bool +Messages60Test::testDocumentSummaryMessage() +{ + DocumentSummaryMessage srm; + EXPECT_EQUAL(srm.hasSequenceId(), false); + EXPECT_EQUAL(srm.getSummaryCount(), size_t(0)); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(12), serialize("DocumentSummaryMessage-1", srm)); + + mbus::Routable::UP routable = deserialize("DocumentSummaryMessage-1", DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + DocumentSummaryMessage * dm = static_cast<DocumentSummaryMessage *>(routable.get()); + EXPECT_EQUAL(dm->getSummaryCount(), size_t(0)); + + srm.addSummary("doc1", "summary1", 8); + srm.addSummary("aoc17", "summary45", 9); + + const void *summary(NULL); + const char *docId(NULL); + size_t sz(0); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 52u, serialize("DocumentSummaryMessage-2", srm)); + routable = deserialize("DocumentSummaryMessage-2", DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<DocumentSummaryMessage *>(routable.get()); + EXPECT_EQUAL(dm->getSummaryCount(), size_t(2)); + dm->getSummary(0, docId, summary, sz); + EXPECT_EQUAL(sz, 8u); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + EXPECT_EQUAL(memcmp("summary1", summary, sz), 0); + dm->getSummary(1, docId, summary, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(strcmp("aoc17", docId), 0); + EXPECT_EQUAL(memcmp("summary45", summary, sz), 0); + + srm.sort(); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 52u, serialize("DocumentSummaryMessage-3", srm)); + routable = deserialize("DocumentSummaryMessage-3", DocumentProtocol::MESSAGE_DOCUMENTSUMMARY, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<DocumentSummaryMessage *>(routable.get()); + EXPECT_EQUAL(dm->getSummaryCount(), size_t(2)); + dm->getSummary(0, docId, summary, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(strcmp("aoc17", docId), 0); + EXPECT_EQUAL(memcmp("summary45", summary, sz), 0); + dm->getSummary(1, docId, summary, sz); + EXPECT_EQUAL(sz, 8u); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + EXPECT_EQUAL(memcmp("summary1", summary, sz), 0); + return true; +} + +bool +Messages60Test::testGetDocumentMessage() +{ + GetDocumentMessage tmp(document::DocumentId("doc:scheme:"), "foo bar"); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)27, serialize("GetDocumentMessage", tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("GetDocumentMessage", DocumentProtocol::MESSAGE_GETDOCUMENT, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + GetDocumentMessage &ref = static_cast<GetDocumentMessage&>(*obj); + EXPECT_EQUAL(string("doc:scheme:"), ref.getDocumentId().toString()); + EXPECT_EQUAL(string("foo bar"), ref.getFieldSet()); + } + } + return true; +} + +bool +Messages60Test::testMapVisitorMessage() +{ + MapVisitorMessage tmp; + tmp.getData().set("foo", 3); + tmp.getData().set("bar", 5); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + (size_t)32, serialize("MapVisitorMessage", tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("MapVisitorMessage", DocumentProtocol::MESSAGE_MAPVISITOR, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + MapVisitorMessage &ref = static_cast<MapVisitorMessage&>(*obj); + EXPECT_EQUAL(3, ref.getData().get("foo", 0)); + EXPECT_EQUAL(5, ref.getData().get("bar", 0)); + } + } + return true; +} + +bool +Messages60Test::testCreateVisitorReply() +{ + CreateVisitorReply reply(DocumentProtocol::REPLY_CREATEVISITOR); + reply.setLastBucket(document::BucketId(16, 123)); + vdslib::VisitorStatistics vs; + vs.setBucketsVisited(3); + vs.setDocumentsVisited(1000); + vs.setBytesVisited(1024000); + vs.setDocumentsReturned(123); + vs.setBytesReturned(512000); + vs.setSecondPassDocumentsReturned(456); + vs.setSecondPassBytesReturned(789100); + reply.setVisitorStatistics(vs); + + EXPECT_EQUAL(65u, serialize("CreateVisitorReply", reply)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("CreateVisitorReply", DocumentProtocol::REPLY_CREATEVISITOR, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + CreateVisitorReply &ref = static_cast<CreateVisitorReply&>(*obj); + + EXPECT_EQUAL(ref.getLastBucket(), document::BucketId(16, 123)); + EXPECT_EQUAL(ref.getVisitorStatistics().getBucketsVisited(), (uint32_t)3); + EXPECT_EQUAL(ref.getVisitorStatistics().getDocumentsVisited(), (uint64_t)1000); + EXPECT_EQUAL(ref.getVisitorStatistics().getBytesVisited(), (uint64_t)1024000); + EXPECT_EQUAL(ref.getVisitorStatistics().getDocumentsReturned(), (uint64_t)123); + EXPECT_EQUAL(ref.getVisitorStatistics().getBytesReturned(), (uint64_t)512000); + EXPECT_EQUAL(ref.getVisitorStatistics().getSecondPassDocumentsReturned(), (uint64_t)456); + EXPECT_EQUAL(ref.getVisitorStatistics().getSecondPassBytesReturned(), (uint64_t)789100); + } + } + return true; +} + +bool +Messages60Test::testPutDocumentMessage() +{ + auto doc = createDoc(getTypeRepo(), "testdoc", "doc:scheme:"); + PutDocumentMessage msg(doc); + + msg.setTimestamp(666); + msg.setCondition(TestAndSetCondition("There's just one condition")); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + + 41u + + serializedLength(msg.getCondition().getSelection()), + serialize("PutDocumentMessage", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + auto routableUp = deserialize("PutDocumentMessage", DocumentProtocol::MESSAGE_PUTDOCUMENT, lang); + if (EXPECT_TRUE(routableUp.get() != nullptr)) { + auto & deserializedMsg = static_cast<PutDocumentMessage &>(*routableUp); + + EXPECT_EQUAL(msg.getDocument().getType().getName(), deserializedMsg.getDocument().getType().getName()); + EXPECT_EQUAL(msg.getDocument().getId().toString(), deserializedMsg.getDocument().getId().toString()); + EXPECT_EQUAL(msg.getTimestamp(), deserializedMsg.getTimestamp()); + EXPECT_EQUAL(67u, deserializedMsg.getApproxSize()); + EXPECT_EQUAL(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); + } + } + + return true; +} + +bool +Messages60Test::testGetBucketStateMessage() +{ + GetBucketStateMessage tmp; + tmp.setBucketId(document::BucketId(16, 666)); + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 12u, serialize("GetBucketStateMessage", tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("GetBucketStateMessage", DocumentProtocol::MESSAGE_GETBUCKETSTATE, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + GetBucketStateMessage &ref = static_cast<GetBucketStateMessage&>(*obj); + + EXPECT_EQUAL(16u, ref.getBucketId().getUsedBits()); + EXPECT_EQUAL(4611686018427388570ull, ref.getBucketId().getId()); + } + } + return true; +} + +bool +Messages60Test::testPutDocumentReply() +{ + WriteDocumentReply reply(DocumentProtocol::REPLY_PUTDOCUMENT); + reply.setHighestModificationTimestamp(30); + + EXPECT_EQUAL(13u, serialize("PutDocumentReply", reply)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("PutDocumentReply", DocumentProtocol::REPLY_PUTDOCUMENT, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + WriteDocumentReply &ref = static_cast<WriteDocumentReply&>(*obj); + EXPECT_EQUAL(30u, ref.getHighestModificationTimestamp()); + } + } + return true; +} + +bool +Messages60Test::testUpdateDocumentReply() +{ + UpdateDocumentReply reply; + reply.setWasFound(false); + reply.setHighestModificationTimestamp(30); + + EXPECT_EQUAL(14u, serialize("UpdateDocumentReply", reply)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("UpdateDocumentReply", DocumentProtocol::REPLY_UPDATEDOCUMENT, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + UpdateDocumentReply &ref = static_cast<UpdateDocumentReply&>(*obj); + EXPECT_EQUAL(30u, ref.getHighestModificationTimestamp()); + EXPECT_EQUAL(false, ref.wasFound()); + } + } + return true; +} + +bool +Messages60Test::testRemoveDocumentMessage() +{ + RemoveDocumentMessage msg(document::DocumentId("doc:scheme:")); + + msg.setCondition(TestAndSetCondition("There's just one condition")); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(16) + serializedLength(msg.getCondition().getSelection()), serialize("RemoveDocumentMessage", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + auto routablePtr = deserialize("RemoveDocumentMessage", DocumentProtocol::MESSAGE_REMOVEDOCUMENT, lang); + + if (EXPECT_TRUE(routablePtr.get() != nullptr)) { + auto & ref = static_cast<RemoveDocumentMessage &>(*routablePtr); + EXPECT_EQUAL(string("doc:scheme:"), ref.getDocumentId().toString()); + EXPECT_EQUAL(msg.getCondition().getSelection(), ref.getCondition().getSelection()); + } + } + return true; +} + +bool +Messages60Test::testRemoveDocumentReply() +{ + RemoveDocumentReply reply; + std::vector<uint64_t> ts; + reply.setWasFound(false); + reply.setHighestModificationTimestamp(30); + + EXPECT_EQUAL(14u, serialize("RemoveDocumentReply", reply)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("RemoveDocumentReply", DocumentProtocol::REPLY_REMOVEDOCUMENT, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + RemoveDocumentReply &ref = static_cast<RemoveDocumentReply&>(*obj); + EXPECT_EQUAL(30u, ref.getHighestModificationTimestamp()); + EXPECT_EQUAL(false, ref.wasFound()); } } return true; -}
\ No newline at end of file +} + +bool +Messages60Test::testSearchResultMessage() +{ + SearchResultMessage srm; + EXPECT_EQUAL(srm.getSequenceId(), 0u); + EXPECT_EQUAL(srm.getHitCount(), 0u); + EXPECT_EQUAL(srm.getAggregatorList().getSerializedSize(), 4u); + EXPECT_EQUAL(srm.vdslib::SearchResult::getSerializedSize(), 20u); + EXPECT_EQUAL(srm.getSerializedSize(), 20u); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(24), serialize("SearchResultMessage-1", srm)); + + mbus::Routable::UP routable = deserialize("SearchResultMessage-1", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + SearchResultMessage * dm = static_cast<SearchResultMessage *>(routable.get()); + EXPECT_EQUAL(dm->getSequenceId(), size_t(0)); + EXPECT_EQUAL(dm->getHitCount(), size_t(0)); + + srm.addHit(0, "doc1", 89); + srm.addHit(1, "doc17", 109); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 55u, serialize("SearchResultMessage-2", srm)); + routable = deserialize("SearchResultMessage-2", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<SearchResultMessage *>(routable.get()); + EXPECT_EQUAL(dm->getHitCount(), size_t(2)); + const char *docId; + SearchResultMessage::RankType rank; + dm->getHit(0, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + dm->getHit(1, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + + srm.sort(); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 55u, serialize("SearchResultMessage-3", srm)); + routable = deserialize("SearchResultMessage-3", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<SearchResultMessage *>(routable.get()); + EXPECT_EQUAL(dm->getHitCount(), size_t(2)); + dm->getHit(0, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + dm->getHit(1, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + + SearchResultMessage srm2; + srm2.addHit(0, "doc1", 89, "sortdata2", 9); + srm2.addHit(1, "doc17", 109, "sortdata1", 9); + srm2.addHit(2, "doc18", 90, "sortdata3", 9); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 108u, serialize("SearchResultMessage-4", srm2)); + routable = deserialize("SearchResultMessage-4", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<SearchResultMessage *>(routable.get()); + EXPECT_EQUAL(dm->getHitCount(), size_t(3)); + dm->getHit(0, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + dm->getHit(1, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + dm->getHit(2, docId, rank); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(90)); + EXPECT_EQUAL(strcmp("doc18", docId), 0); + + srm2.sort(); + const void *buf; + size_t sz; + srm2.getHit(0, docId, rank); + srm2.getSortBlob(0, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + srm2.getHit(1, docId, rank); + srm2.getSortBlob(1, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + srm2.getHit(2, docId, rank); + srm2.getSortBlob(2, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(90)); + EXPECT_EQUAL(strcmp("doc18", docId), 0); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 108u, serialize("SearchResultMessage-5", srm2)); + routable = deserialize("SearchResultMessage-5", DocumentProtocol::MESSAGE_SEARCHRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<SearchResultMessage *>(routable.get()); + EXPECT_EQUAL(dm->getHitCount(), size_t(3)); + dm->getHit(0, docId, rank); + dm->getSortBlob(0, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + dm->getHit(1, docId, rank); + dm->getSortBlob(1, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + dm->getHit(2, docId, rank); + dm->getSortBlob(2, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); + EXPECT_EQUAL(rank, SearchResultMessage::RankType(90)); + EXPECT_EQUAL(strcmp("doc18", docId), 0); + return true; +} + +bool +Messages60Test::testUpdateDocumentMessage() +{ + const DocumentTypeRepo & repo = getTypeRepo(); + const document::DocumentType & docType = *repo.getDocumentType("testdoc"); + + auto docUpdate = std::make_shared<document::DocumentUpdate>(repo, docType, document::DocumentId("doc:scheme:")); + + docUpdate->addFieldPathUpdate(document::FieldPathUpdate::CP( + new document::RemoveFieldPathUpdate("intfield", "testdoc.intfield > 0"))); + + UpdateDocumentMessage msg(docUpdate); + msg.setOldTimestamp(666u); + msg.setNewTimestamp(777u); + msg.setCondition(TestAndSetCondition("There's just one condition")); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 89u + serializedLength(msg.getCondition().getSelection()), serialize("UpdateDocumentMessage", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + auto routableUp = deserialize("UpdateDocumentMessage", DocumentProtocol::MESSAGE_UPDATEDOCUMENT, lang); + + if (EXPECT_TRUE(routableUp.get() != nullptr)) { + auto & deserializedMsg = static_cast<UpdateDocumentMessage &>(*routableUp); + EXPECT_EQUAL(msg.getDocumentUpdate(), deserializedMsg.getDocumentUpdate()); + EXPECT_EQUAL(msg.getOldTimestamp(), deserializedMsg.getOldTimestamp()); + EXPECT_EQUAL(msg.getNewTimestamp(), deserializedMsg.getNewTimestamp()); + EXPECT_EQUAL(115u, deserializedMsg.getApproxSize()); + EXPECT_EQUAL(msg.getCondition().getSelection(), deserializedMsg.getCondition().getSelection()); + } + } + return true; +} + +bool +Messages60Test::testQueryResultMessage() +{ + QueryResultMessage srm; + vdslib::SearchResult & sr(srm.getSearchResult()); + EXPECT_EQUAL(srm.getSequenceId(), 0u); + EXPECT_EQUAL(sr.getHitCount(), 0u); + EXPECT_EQUAL(sr.getAggregatorList().getSerializedSize(), 4u); + EXPECT_EQUAL(sr.getSerializedSize(), 20u); + EXPECT_EQUAL(srm.getApproxSize(), 28u); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + size_t(32), serialize("QueryResultMessage-1", srm)); + + mbus::Routable::UP routable = deserialize("QueryResultMessage-1", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + QueryResultMessage * dm = static_cast<QueryResultMessage *>(routable.get()); + vdslib::SearchResult * dr(&dm->getSearchResult()); + EXPECT_EQUAL(dm->getSequenceId(), size_t(0)); + EXPECT_EQUAL(dr->getHitCount(), size_t(0)); + + sr.addHit(0, "doc1", 89); + sr.addHit(1, "doc17", 109); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 63u, serialize("QueryResultMessage-2", srm)); + routable = deserialize("QueryResultMessage-2", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<QueryResultMessage *>(routable.get()); + dr = &dm->getSearchResult(); + EXPECT_EQUAL(dr->getHitCount(), size_t(2)); + const char *docId; + vdslib::SearchResult::RankType rank; + dr->getHit(0, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + dr->getHit(1, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + + sr.sort(); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 63u, serialize("QueryResultMessage-3", srm)); + routable = deserialize("QueryResultMessage-3", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<QueryResultMessage *>(routable.get()); + dr = &dm->getSearchResult(); + EXPECT_EQUAL(dr->getHitCount(), size_t(2)); + dr->getHit(0, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + dr->getHit(1, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + + QueryResultMessage srm2; + vdslib::SearchResult & sr2(srm2.getSearchResult()); + sr2.addHit(0, "doc1", 89, "sortdata2", 9); + sr2.addHit(1, "doc17", 109, "sortdata1", 9); + sr2.addHit(2, "doc18", 90, "sortdata3", 9); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 116u, serialize("QueryResultMessage-4", srm2)); + routable = deserialize("QueryResultMessage-4", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<QueryResultMessage *>(routable.get()); + dr = &dm->getSearchResult(); + EXPECT_EQUAL(dr->getHitCount(), size_t(3)); + dr->getHit(0, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + dr->getHit(1, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + dr->getHit(2, docId, rank); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(90)); + EXPECT_EQUAL(strcmp("doc18", docId), 0); + + sr2.sort(); + const void *buf; + size_t sz; + sr2.getHit(0, docId, rank); + sr2.getSortBlob(0, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + sr2.getHit(1, docId, rank); + sr2.getSortBlob(1, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + sr2.getHit(2, docId, rank); + sr2.getSortBlob(2, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(90)); + EXPECT_EQUAL(strcmp("doc18", docId), 0); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 116u, serialize("QueryResultMessage-5", srm2)); + routable = deserialize("QueryResultMessage-5", DocumentProtocol::MESSAGE_QUERYRESULT, LANG_CPP); + if (!EXPECT_TRUE(routable.get() != NULL)) { + return false; + } + dm = static_cast<QueryResultMessage *>(routable.get()); + dr = &dm->getSearchResult(); + EXPECT_EQUAL(dr->getHitCount(), size_t(3)); + dr->getHit(0, docId, rank); + dr->getSortBlob(0, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata1", buf, sz), 0); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(109)); + EXPECT_EQUAL(strcmp("doc17", docId), 0); + dr->getHit(1, docId, rank); + dr->getSortBlob(1, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata2", buf, sz), 0); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(89)); + EXPECT_EQUAL(strcmp("doc1", docId), 0); + dr->getHit(2, docId, rank); + dr->getSortBlob(2, buf, sz); + EXPECT_EQUAL(sz, 9u); + EXPECT_EQUAL(memcmp("sortdata3", buf, sz), 0); + EXPECT_EQUAL(rank, vdslib::SearchResult::RankType(90)); + EXPECT_EQUAL(strcmp("doc18", docId), 0); + return true; +} + +bool +Messages60Test::testQueryResultReply() +{ + return tryVisitorReply("QueryResultReply", DocumentProtocol::REPLY_QUERYRESULT); +} + +bool +Messages60Test::testVisitorInfoMessage() +{ + + VisitorInfoMessage tmp; + tmp.getFinishedBuckets().push_back(document::BucketId(16, 1)); + tmp.getFinishedBuckets().push_back(document::BucketId(16, 2)); + tmp.getFinishedBuckets().push_back(document::BucketId(16, 4)); + string utf8 = "error message: \u00e6\u00c6\u00f8\u00d8\u00e5\u00c5\u00f6\u00d6"; + tmp.setErrorMessage(utf8); + + EXPECT_EQUAL(MESSAGE_BASE_LENGTH + 67u, serialize("VisitorInfoMessage", tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("VisitorInfoMessage", DocumentProtocol::MESSAGE_VISITORINFO, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + VisitorInfoMessage &ref = static_cast<VisitorInfoMessage&>(*obj); + EXPECT_EQUAL(document::BucketId(16, 1), ref.getFinishedBuckets()[0]); + EXPECT_EQUAL(document::BucketId(16, 2), ref.getFinishedBuckets()[1]); + EXPECT_EQUAL(document::BucketId(16, 4), ref.getFinishedBuckets()[2]); + EXPECT_EQUAL(utf8, ref.getErrorMessage()); + } + } + return true; +} + +bool +Messages60Test::testDestroyVisitorReply() +{ + return tryDocumentReply("DestroyVisitorReply", DocumentProtocol::REPLY_DESTROYVISITOR); +} + +bool +Messages60Test::testDocumentIgnoredReply() +{ + DocumentIgnoredReply tmp; + serialize("DocumentIgnoredReply", tmp); + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj( + deserialize("DocumentIgnoredReply", + DocumentProtocol::REPLY_DOCUMENTIGNORED, lang)); + EXPECT_TRUE(obj.get() != NULL); + } + return true; +} + +bool +Messages60Test::testDocumentListReply() +{ + return tryVisitorReply("DocumentListReply", DocumentProtocol::REPLY_DOCUMENTLIST); +} + +bool +Messages60Test::testDocumentSummaryReply() +{ + return tryVisitorReply("DocumentSummaryReply", DocumentProtocol::REPLY_DOCUMENTSUMMARY); +} + +bool +Messages60Test::testGetDocumentReply() +{ + document::Document::SP doc = + createDoc(getTypeRepo(), "testdoc", "doc:scheme:"); + GetDocumentReply tmp(doc); + + EXPECT_EQUAL((size_t)43, serialize("GetDocumentReply", tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("GetDocumentReply", DocumentProtocol::REPLY_GETDOCUMENT, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + GetDocumentReply &ref = static_cast<GetDocumentReply&>(*obj); + + EXPECT_EQUAL(string("testdoc"), ref.getDocument().getType().getName()); + EXPECT_EQUAL(string("doc:scheme:"), ref.getDocument().getId().toString()); + } + } + return true; +} + +bool +Messages60Test::testMapVisitorReply() +{ + return tryVisitorReply("MapVisitorReply", DocumentProtocol::REPLY_MAPVISITOR); +} + +bool +Messages60Test::testSearchResultReply() +{ + return tryVisitorReply("SearchResultReply", DocumentProtocol::REPLY_SEARCHRESULT); +} + +bool +Messages60Test::testStatBucketReply() +{ + StatBucketReply msg; + msg.setResults("These are the votes of the Norwegian jury"); + + EXPECT_EQUAL(50u, serialize("StatBucketReply", msg)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("StatBucketReply", DocumentProtocol::REPLY_STATBUCKET, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + StatBucketReply &ref = static_cast<StatBucketReply&>(*obj); + EXPECT_EQUAL("These are the votes of the Norwegian jury", ref.getResults()); + } + } + return true; +} + +bool +Messages60Test::testVisitorInfoReply() +{ + return tryVisitorReply("VisitorInfoReply", DocumentProtocol::REPLY_VISITORINFO); +} + +bool +Messages60Test::testWrongDistributionReply() +{ + WrongDistributionReply tmp("distributor:3 storage:2"); + + serialize("WrongDistributionReply", tmp); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("WrongDistributionReply", DocumentProtocol::REPLY_WRONGDISTRIBUTION, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + WrongDistributionReply &ref = static_cast<WrongDistributionReply&>(*obj); + EXPECT_EQUAL(string("distributor:3 storage:2"), ref.getSystemState()); + } + } + return true; +} + +bool +Messages60Test::testGetBucketListReply() +{ + GetBucketListReply reply; + reply.getBuckets().push_back(GetBucketListReply::BucketInfo(document::BucketId(16, 123), "foo")); + reply.getBuckets().push_back(GetBucketListReply::BucketInfo(document::BucketId(17, 1123), "bar")); + reply.getBuckets().push_back(GetBucketListReply::BucketInfo(document::BucketId(18, 11123), "zoink")); + + EXPECT_EQUAL(56u, serialize("GetBucketListReply", reply)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("GetBucketListReply", DocumentProtocol::REPLY_GETBUCKETLIST, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + GetBucketListReply &ref = static_cast<GetBucketListReply&>(*obj); + + EXPECT_EQUAL(ref.getBuckets()[0], GetBucketListReply::BucketInfo(document::BucketId(16, 123), "foo")); + EXPECT_EQUAL(ref.getBuckets()[1], GetBucketListReply::BucketInfo(document::BucketId(17, 1123), "bar")); + EXPECT_EQUAL(ref.getBuckets()[2], GetBucketListReply::BucketInfo(document::BucketId(18, 11123), "zoink")); + } + } + return true; +} + +bool +Messages60Test::testGetBucketStateReply() +{ + document::GlobalId foo = document::DocumentId("doc:scheme:foo").getGlobalId(); + document::GlobalId bar = document::DocumentId("doc:scheme:bar").getGlobalId(); + + GetBucketStateReply reply; + reply.getBucketState().push_back(DocumentState(foo, 777, false)); + reply.getBucketState().push_back(DocumentState(bar, 888, true)); + EXPECT_EQUAL(53u, serialize("GetBucketStateReply", reply)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("GetBucketStateReply", DocumentProtocol::REPLY_GETBUCKETSTATE, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + GetBucketStateReply &ref = static_cast<GetBucketStateReply&>(*obj); + + EXPECT_EQUAL(777u, ref.getBucketState()[0].getTimestamp()); + EXPECT_EQUAL(foo, ref.getBucketState()[0].getGlobalId()); + EXPECT_EQUAL(false, ref.getBucketState()[0].isRemoveEntry()); + EXPECT_EQUAL(888u, ref.getBucketState()[1].getTimestamp()); + EXPECT_EQUAL(bar, ref.getBucketState()[1].getGlobalId()); + EXPECT_EQUAL(true, ref.getBucketState()[1].isRemoveEntry()); + } + } + return true; +} + +bool +Messages60Test::testEmptyBucketsReply() +{ + return tryVisitorReply("EmptyBucketsReply", DocumentProtocol::REPLY_EMPTYBUCKETS); +} + +bool +Messages60Test::testRemoveLocationReply() +{ + DocumentReply tmp(DocumentProtocol::REPLY_REMOVELOCATION); + + EXPECT_EQUAL((uint32_t)5, serialize("RemoveLocationReply", tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize("RemoveLocationReply", DocumentProtocol::REPLY_REMOVELOCATION, lang); + EXPECT_TRUE(obj.get() != NULL); + } + return true; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// Utilities +// +//////////////////////////////////////////////////////////////////////////////// + +bool +Messages60Test::tryDocumentReply(const string &filename, uint32_t type) +{ + DocumentReply tmp(type); + + EXPECT_EQUAL((uint32_t)5, serialize(filename, tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize(filename, type, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + DocumentReply *ref = dynamic_cast<DocumentReply*>(obj.get()); + EXPECT_TRUE(ref != NULL); + } + } + return true; +} + +bool +Messages60Test::tryVisitorReply(const string &filename, uint32_t type) +{ + VisitorReply tmp(type); + + EXPECT_EQUAL((uint32_t)5, serialize(filename, tmp)); + + for (uint32_t lang = 0; lang < NUM_LANGUAGES; ++lang) { + mbus::Routable::UP obj = deserialize(filename, type, lang); + if (EXPECT_TRUE(obj.get() != NULL)) { + VisitorReply *ref = dynamic_cast<VisitorReply*>(obj.get()); + EXPECT_TRUE(ref != NULL); + } + } + return true; +} diff --git a/documentapi/src/tests/messages/messages60test.h b/documentapi/src/tests/messages/messages60test.h index 78224e5a808..87954310536 100644 --- a/documentapi/src/tests/messages/messages60test.h +++ b/documentapi/src/tests/messages/messages60test.h @@ -1,14 +1,56 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// @author Vegard Sjonfjell #pragma once -#include "messages52test.h" +#include "testbase.h" -class Messages60Test : public Messages52Test { +class Messages60Test : public TestBase { protected: const vespalib::Version getVersion() const override { return vespalib::Version(6, 221); } + bool shouldTestCoverage() const override { return true; } + bool tryDocumentReply(const string &filename, uint32_t type); + bool tryVisitorReply(const string &filename, uint32_t type); + + static size_t serializedLength(const string & str) { return sizeof(int32_t) + str.size(); } + public: Messages60Test(); + bool testCreateVisitorMessage(); - bool testStatBucketMessage(); + bool testCreateVisitorReply(); + bool testDestroyVisitorMessage(); + bool testDestroyVisitorReply(); + bool testDocumentIgnoredReply(); + bool testDocumentListMessage(); + bool testDocumentListReply(); + bool testDocumentSummaryMessage(); + bool testDocumentSummaryReply(); + bool testEmptyBucketsMessage(); + bool testEmptyBucketsReply(); bool testGetBucketListMessage(); + bool testGetBucketListReply(); + bool testGetBucketStateMessage(); + bool testGetBucketStateReply(); + bool testGetDocumentMessage(); + bool testGetDocumentReply(); + bool testMapVisitorMessage(); + bool testMapVisitorReply(); + bool testPutDocumentMessage(); + bool testPutDocumentReply(); + bool testQueryResultMessage(); + bool testQueryResultReply(); + bool testRemoveDocumentMessage(); + bool testRemoveDocumentReply(); + bool testRemoveLocationMessage(); + bool testRemoveLocationReply(); + bool testSearchResultMessage(); + bool testSearchResultReply(); + bool testStatBucketMessage(); + bool testStatBucketReply(); + bool testUpdateDocumentMessage(); + bool testUpdateDocumentReply(); + bool testVisitorInfoMessage(); + bool testVisitorInfoReply(); + bool testWrongDistributionReply(); }; + diff --git a/documentapi/src/tests/routablefactory/routablefactory.cpp b/documentapi/src/tests/routablefactory/routablefactory.cpp index 13ebd45fdc6..3f94d120d66 100644 --- a/documentapi/src/tests/routablefactory/routablefactory.cpp +++ b/documentapi/src/tests/routablefactory/routablefactory.cpp @@ -1,7 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/document/repo/documenttyperepo.h> #include <vespa/documentapi/messagebus/documentprotocol.h> -#include <vespa/documentapi/messagebus/routablefactories52.h> +#include <vespa/documentapi/messagebus/routablefactories60.h> #include <vespa/messagebus/testlib/receptor.h> #include <vespa/messagebus/testlib/slobrok.h> #include <vespa/messagebus/testlib/testserver.h> @@ -48,7 +48,7 @@ public: } }; -class MyMessageFactory : public RoutableFactories52::DocumentMessageFactory { +class MyMessageFactory : public RoutableFactories60::DocumentMessageFactory { protected: DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { (void)buf; @@ -62,7 +62,7 @@ protected: } }; -class MyReplyFactory : public RoutableFactories52::DocumentReplyFactory { +class MyReplyFactory : public RoutableFactories60::DocumentReplyFactory { protected: DocumentReply::UP doDecode(document::ByteBuffer &buf) const override { (void)buf; diff --git a/documentapi/src/vespa/documentapi/messagebus/CMakeLists.txt b/documentapi/src/vespa/documentapi/messagebus/CMakeLists.txt index 6f65b3c67a9..13852c7b1d7 100644 --- a/documentapi/src/vespa/documentapi/messagebus/CMakeLists.txt +++ b/documentapi/src/vespa/documentapi/messagebus/CMakeLists.txt @@ -3,7 +3,6 @@ vespa_add_library(documentapi_documentapimessagebus OBJECT SOURCES documentprotocol.cpp replymerger.cpp - routablefactories52.cpp routablefactories60.cpp routablerepository.cpp routingpolicyfactories.cpp diff --git a/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp b/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp index b70a76690f9..e8cc7a03e94 100644 --- a/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp +++ b/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp @@ -1,6 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "routablefactories52.h" #include "routablefactories60.h" #include "routingpolicyfactories.h" #include "routablerepository.h" @@ -44,54 +43,47 @@ DocumentProtocol::DocumentProtocol(const LoadTypeSet& loadTypes, putRoutingPolicyFactory("LoadBalancer", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::LoadBalancerPolicyFactory())); // Prepare version specifications to use when adding routable factories. - vespalib::VersionSpecification version52(5, 115); vespalib::VersionSpecification version6(6, 221); - std::vector<vespalib::VersionSpecification> from52 = { version52, version6 }; std::vector<vespalib::VersionSpecification> from6 = { version6 }; - // Add 5.2 serialization - putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories52::CreateVisitorMessageFactory(*_repo)), from52); - putRoutableFactory(MESSAGE_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories52::DestroyVisitorMessageFactory()), from52); - putRoutableFactory(MESSAGE_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories52::DocumentListMessageFactory(*_repo)), from52); - putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories52::DocumentSummaryMessageFactory()), from52); - putRoutableFactory(MESSAGE_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories52::EmptyBucketsMessageFactory()), from52); - putRoutableFactory(MESSAGE_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories52::GetBucketListMessageFactory()), from52); - putRoutableFactory(MESSAGE_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories52::GetBucketStateMessageFactory()), from52); - putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::GetDocumentMessageFactory()), from52); - putRoutableFactory(MESSAGE_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories52::MapVisitorMessageFactory(*_repo)), from52); - putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::PutDocumentMessageFactory(*_repo)), from52); - putRoutableFactory(MESSAGE_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories52::QueryResultMessageFactory()), from52); - putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::RemoveDocumentMessageFactory()), from52); - putRoutableFactory(MESSAGE_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories52::RemoveLocationMessageFactory(*_repo)), from52); - putRoutableFactory(MESSAGE_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories52::SearchResultMessageFactory()), from52); - putRoutableFactory(MESSAGE_STATBUCKET, IRoutableFactory::SP(new RoutableFactories52::StatBucketMessageFactory()), from52); - putRoutableFactory(MESSAGE_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::UpdateDocumentMessageFactory(*_repo)), from52); - putRoutableFactory(MESSAGE_VISITORINFO, IRoutableFactory::SP(new RoutableFactories52::VisitorInfoMessageFactory()), from52); - putRoutableFactory(REPLY_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories52::CreateVisitorReplyFactory()), from52); - putRoutableFactory(REPLY_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories52::DestroyVisitorReplyFactory()), from52); - putRoutableFactory(REPLY_DOCUMENTIGNORED, IRoutableFactory::SP(new RoutableFactories52::DocumentIgnoredReplyFactory()), from52); - putRoutableFactory(REPLY_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories52::DocumentListReplyFactory()), from52); - putRoutableFactory(REPLY_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories52::DocumentSummaryReplyFactory()), from52); - putRoutableFactory(REPLY_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories52::EmptyBucketsReplyFactory()), from52); - putRoutableFactory(REPLY_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories52::GetBucketListReplyFactory()), from52); - putRoutableFactory(REPLY_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories52::GetBucketStateReplyFactory()), from52); - putRoutableFactory(REPLY_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::GetDocumentReplyFactory(*_repo)), from52); - putRoutableFactory(REPLY_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories52::MapVisitorReplyFactory()), from52); - putRoutableFactory(REPLY_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::PutDocumentReplyFactory()), from52); - putRoutableFactory(REPLY_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories52::QueryResultReplyFactory()), from52); - putRoutableFactory(REPLY_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::RemoveDocumentReplyFactory()), from52); - putRoutableFactory(REPLY_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories52::RemoveLocationReplyFactory()), from52); - putRoutableFactory(REPLY_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories52::SearchResultReplyFactory()), from52); - putRoutableFactory(REPLY_STATBUCKET, IRoutableFactory::SP(new RoutableFactories52::StatBucketReplyFactory()), from52); - putRoutableFactory(REPLY_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::UpdateDocumentReplyFactory()), from52); - putRoutableFactory(REPLY_VISITORINFO, IRoutableFactory::SP(new RoutableFactories52::VisitorInfoReplyFactory()), from52); - putRoutableFactory(REPLY_WRONGDISTRIBUTION, IRoutableFactory::SP(new RoutableFactories52::WrongDistributionReplyFactory()), from52); - - // Add 6.x serialization (TODO finalize version) + // Add 6.x serialization putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories60::CreateVisitorMessageFactory(*_repo)), from6); - putRoutableFactory(MESSAGE_STATBUCKET, IRoutableFactory::SP(new RoutableFactories60::StatBucketMessageFactory()), from6); + putRoutableFactory(MESSAGE_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories60::DestroyVisitorMessageFactory()), from6); + putRoutableFactory(MESSAGE_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories60::DocumentListMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories60::DocumentSummaryMessageFactory()), from6); + putRoutableFactory(MESSAGE_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories60::EmptyBucketsMessageFactory()), from6); putRoutableFactory(MESSAGE_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories60::GetBucketListMessageFactory()), from6); + putRoutableFactory(MESSAGE_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories60::GetBucketStateMessageFactory()), from6); + putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::GetDocumentMessageFactory()), from6); + putRoutableFactory(MESSAGE_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories60::MapVisitorMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::PutDocumentMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories60::QueryResultMessageFactory()), from6); + putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::RemoveDocumentMessageFactory()), from6); + putRoutableFactory(MESSAGE_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories60::RemoveLocationMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories60::SearchResultMessageFactory()), from6); + putRoutableFactory(MESSAGE_STATBUCKET, IRoutableFactory::SP(new RoutableFactories60::StatBucketMessageFactory()), from6); + putRoutableFactory(MESSAGE_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::UpdateDocumentMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_VISITORINFO, IRoutableFactory::SP(new RoutableFactories60::VisitorInfoMessageFactory()), from6); + putRoutableFactory(REPLY_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories60::CreateVisitorReplyFactory()), from6); + putRoutableFactory(REPLY_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories60::DestroyVisitorReplyFactory()), from6); + putRoutableFactory(REPLY_DOCUMENTIGNORED, IRoutableFactory::SP(new RoutableFactories60::DocumentIgnoredReplyFactory()), from6); + putRoutableFactory(REPLY_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories60::DocumentListReplyFactory()), from6); + putRoutableFactory(REPLY_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories60::DocumentSummaryReplyFactory()), from6); + putRoutableFactory(REPLY_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories60::EmptyBucketsReplyFactory()), from6); + putRoutableFactory(REPLY_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories60::GetBucketListReplyFactory()), from6); + putRoutableFactory(REPLY_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories60::GetBucketStateReplyFactory()), from6); + putRoutableFactory(REPLY_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::GetDocumentReplyFactory(*_repo)), from6); + putRoutableFactory(REPLY_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories60::MapVisitorReplyFactory()), from6); + putRoutableFactory(REPLY_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::PutDocumentReplyFactory()), from6); + putRoutableFactory(REPLY_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories60::QueryResultReplyFactory()), from6); + putRoutableFactory(REPLY_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::RemoveDocumentReplyFactory()), from6); + putRoutableFactory(REPLY_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories60::RemoveLocationReplyFactory()), from6); + putRoutableFactory(REPLY_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories60::SearchResultReplyFactory()), from6); + putRoutableFactory(REPLY_STATBUCKET, IRoutableFactory::SP(new RoutableFactories60::StatBucketReplyFactory()), from6); + putRoutableFactory(REPLY_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::UpdateDocumentReplyFactory()), from6); + putRoutableFactory(REPLY_VISITORINFO, IRoutableFactory::SP(new RoutableFactories60::VisitorInfoReplyFactory()), from6); + putRoutableFactory(REPLY_WRONGDISTRIBUTION, IRoutableFactory::SP(new RoutableFactories60::WrongDistributionReplyFactory()), from6); } DocumentProtocol::~DocumentProtocol() = default; diff --git a/documentapi/src/vespa/documentapi/messagebus/messages/visitor.h b/documentapi/src/vespa/documentapi/messagebus/messages/visitor.h index 2e6f094bf47..e748e1cbc40 100644 --- a/documentapi/src/vespa/documentapi/messagebus/messages/visitor.h +++ b/documentapi/src/vespa/documentapi/messagebus/messages/visitor.h @@ -89,14 +89,6 @@ public: bool visitRemoves() const { return _visitRemoves; } void setVisitRemoves(bool val) { _visitRemoves = val; } - void setVisitHeadersOnly(bool visitHeadersOnly_) { - _fieldSet = (visitHeadersOnly_ ? "[header]" : "[all]"); - } - - bool visitHeadersOnly() const { - return (_fieldSet == "[header]"); - } - const string & getFieldSet() const { return _fieldSet; } void setFieldSet(vespalib::stringref fieldSet) { _fieldSet = fieldSet; } diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories51.cpp b/documentapi/src/vespa/documentapi/messagebus/routablefactories51.cpp deleted file mode 100644 index 01d0c5b6c0e..00000000000 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories51.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "routablefactories51.h" -#include <vespa/document/bucket/fixed_bucket_spaces.h> -#include <vespa/document/document.h> -#include <vespa/documentapi/documentapi.h> -#include <vespa/documentapi/loadtypes/loadtypeset.h> -#include <vespa/vespalib/objects/nbostream.h> - -using document::FixedBucketSpaces; -using vespalib::nbostream; - -namespace documentapi { - -DocumentMessage::UP -RoutableFactories51::CreateVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - DocumentMessage::UP ret(new CreateVisitorMessage()); - CreateVisitorMessage &msg = static_cast<CreateVisitorMessage&>(*ret); - - msg.setLibraryName(decodeString(buf)); - msg.setInstanceId(decodeString(buf)); - msg.setControlDestination(decodeString(buf)); - msg.setDataDestination(decodeString(buf)); - msg.setDocumentSelection(decodeString(buf)); - msg.setMaximumPendingReplyCount(decodeInt(buf)); - - int32_t len = decodeInt(buf); - msg.getBuckets().reserve(len); - for (int32_t i = 0; i < len; i++) { - int64_t val; - buf.getLong(val); // NOT using getLongNetwork - msg.getBuckets().push_back(document::BucketId(val)); - } - - msg.setFromTimestamp(decodeLong(buf)); - msg.setToTimestamp(decodeLong(buf)); - msg.setVisitRemoves(decodeBoolean(buf)); - msg.setFieldSet(decodeString(buf)); - msg.setVisitInconsistentBuckets(decodeBoolean(buf)); - msg.getParameters().deserialize(_repo, buf); - msg.setVisitorDispatcherVersion(50); - msg.setVisitorOrdering((document::OrderingSpecification::Order)decodeInt(buf)); - msg.setMaxBucketsPerVisitor(decodeInt(buf)); - msg.setBucketSpace(decodeBucketSpace(buf)); - - return ret; -} - -bool -RoutableFactories51::CreateVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const CreateVisitorMessage &msg = static_cast<const CreateVisitorMessage&>(obj); - - buf.putString(msg.getLibraryName()); - buf.putString(msg.getInstanceId()); - buf.putString(msg.getControlDestination()); - buf.putString(msg.getDataDestination()); - buf.putString(msg.getDocumentSelection()); - buf.putInt(msg.getMaximumPendingReplyCount()); - buf.putInt(msg.getBuckets().size()); - - const std::vector<document::BucketId> &buckets = msg.getBuckets(); - for (std::vector<document::BucketId>::const_iterator it = buckets.begin(); - it != buckets.end(); ++it) - { - uint64_t val = it->getRawId(); - buf.putBytes((const char*)&val, 8); - } - - buf.putLong(msg.getFromTimestamp()); - buf.putLong(msg.getToTimestamp()); - buf.putBoolean(msg.visitRemoves()); - buf.putString(msg.getFieldSet()); - buf.putBoolean(msg.visitInconsistentBuckets()); - - int len = msg.getParameters().getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - msg.getParameters().serialize(dbuf); - - buf.putInt(msg.getVisitorOrdering()); - buf.putInt(msg.getMaxBucketsPerVisitor()); - return encodeBucketSpace(msg.getBucketSpace(), buf); -} - -bool RoutableFactories51::CreateVisitorMessageFactory::encodeBucketSpace( - vespalib::stringref bucketSpace, - vespalib::GrowableByteBuffer& buf) const { - (void) buf; - return (bucketSpace == FixedBucketSpaces::default_space_name()); -} - -string RoutableFactories51::CreateVisitorMessageFactory::decodeBucketSpace(document::ByteBuffer&) const { - return FixedBucketSpaces::default_space_name(); -} - -DocumentMessage::UP -RoutableFactories51::GetDocumentMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - return DocumentMessage::UP( - new GetDocumentMessage(decodeDocumentId(buf), - decodeString(buf))); -} - -bool -RoutableFactories51::GetDocumentMessageFactory::doEncode(const DocumentMessage &obj, - vespalib::GrowableByteBuffer &buf) const -{ - const GetDocumentMessage &msg = static_cast<const GetDocumentMessage&>(obj); - - encodeDocumentId(msg.getDocumentId(), buf); - buf.putString(msg.getFieldSet()); - return true; -} - -DocumentReply::UP -RoutableFactories51::DocumentIgnoredReplyFactory::doDecode(document::ByteBuffer& buf) const -{ - (void) buf; - return DocumentReply::UP(new DocumentIgnoredReply()); -} - -bool -RoutableFactories51::DocumentIgnoredReplyFactory::doEncode( - const DocumentReply& obj, - vespalib::GrowableByteBuffer& buf) const -{ - (void) obj; - (void) buf; - return true; -} - -} diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories51.h b/documentapi/src/vespa/documentapi/messagebus/routablefactories51.h deleted file mode 100644 index 913b05f109b..00000000000 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories51.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include "routablefactories50.h" - -namespace document { class DocumentTypeRepo; } - -namespace documentapi { -/** - * This class encapsulates all the {@link RoutableFactory} classes needed to implement factories for the document - * routable. When adding new factories to this class, please KEEP THE THEM ORDERED alphabetically like they are now. - */ -class RoutableFactories51 : public RoutableFactories50 { -public: - RoutableFactories51() = delete; - - class DocumentIgnoredReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - // Factories - // - //////////////////////////////////////////////////////////////////////////////// - - class CreateVisitorMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - - virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; - virtual string decodeBucketSpace(document::ByteBuffer&) const; - public: - CreateVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - - class GetDocumentMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - - /////////////////////////////////////////////////////////////////////////// - // - // Utilities - // - /////////////////////////////////////////////////////////////////////////// - protected: - /** - * This is a complement for the vespalib::GrowableByteBuffer.putString() method. - * - * @param in The byte buffer to read from. - * @return The decoded string. - */ - static string decodeString(document::ByteBuffer &in) - { return RoutableFactories50::decodeString(in); } - - /** - * This is a complement for the vespalib::GrowableByteBuffer.putBoolean() method. - * - * @param in The byte buffer to read from. - * @return The decoded bool. - */ - static bool decodeBoolean(document::ByteBuffer &in) - { return RoutableFactories50::decodeBoolean(in); } - - /** - * Convenience method to decode a 32-bit int from the given byte buffer. - * - * @param in The byte buffer to read from. - * @return The decoded int. - */ - static int32_t decodeInt(document::ByteBuffer &in) - { return RoutableFactories50::decodeInt(in); } - - /** - * Convenience method to decode a 64-bit int from the given byte buffer. - * - * @param in The byte buffer to read from. - * @return The decoded int. - */ - static int64_t decodeLong(document::ByteBuffer &in) - { return RoutableFactories50::decodeLong(in); } - - - /** - * Convenience method to decode a document id from the given byte buffer. - * - * @param in The byte buffer to read from. - * @return The decoded document id. - */ - static document::DocumentId decodeDocumentId(document::ByteBuffer &in) - { return RoutableFactories50::decodeDocumentId(in); } - - /** - * Convenience method to encode a document id to the given byte buffer. - * - * @param id The document id to encode. - * @param out The byte buffer to write to. - */ - static void encodeDocumentId(const document::DocumentId &id, - vespalib::GrowableByteBuffer &out) - { return RoutableFactories50::encodeDocumentId(id, out); } -}; - -} - diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories52.cpp b/documentapi/src/vespa/documentapi/messagebus/routablefactories52.cpp deleted file mode 100644 index 6a49d812957..00000000000 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories52.cpp +++ /dev/null @@ -1,949 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -// @author Vegard Sjonfjell - -#include "routablefactories52.h" -#include <vespa/document/bucket/bucketidfactory.h> -#include <vespa/document/bucket/fixed_bucket_spaces.h> -#include <vespa/document/select/parser.h> -#include <vespa/document/update/documentupdate.h> -#include <vespa/documentapi/documentapi.h> -#include <vespa/documentapi/loadtypes/loadtypeset.h> -#include <vespa/vespalib/objects/nbostream.h> - -using document::FixedBucketSpaces; -using vespalib::nbostream; -using std::make_shared; -using std::make_unique; - -namespace documentapi { - -bool -RoutableFactories52::DocumentMessageFactory::encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const -{ - const DocumentMessage &msg = static_cast<const DocumentMessage&>(obj); - out.putByte(msg.getPriority()); - out.putInt(msg.getLoadType().getId()); - return doEncode(msg, out); -} - -mbus::Routable::UP -RoutableFactories52::DocumentMessageFactory::decode(document::ByteBuffer &in, const LoadTypeSet& loadTypes) const -{ - uint8_t pri; - in.getByte(pri); - uint32_t loadClass = decodeInt(in); - - DocumentMessage::UP msg = doDecode(in); - if (msg) { - msg->setPriority((Priority::Value)pri); - msg->setLoadType(loadTypes[loadClass]); - } - - return mbus::Routable::UP(msg.release()); -} - -bool -RoutableFactories52::DocumentReplyFactory::encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const -{ - const DocumentReply &msg = static_cast<const DocumentReply&>(obj); - out.putByte(msg.getPriority()); - return doEncode(msg, out); -} - -mbus::Routable::UP -RoutableFactories52::DocumentReplyFactory::decode(document::ByteBuffer &in, const LoadTypeSet&) const -{ - uint8_t pri; - in.getByte(pri); - DocumentReply::UP reply = doDecode(in); - if (reply) { - reply->setPriority((Priority::Value)pri); - } - return mbus::Routable::UP(reply.release()); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Factories -// -//////////////////////////////////////////////////////////////////////////////// - -DocumentMessage::UP -RoutableFactories52::CreateVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<CreateVisitorMessage>(); - - msg->setLibraryName(decodeString(buf)); - msg->setInstanceId(decodeString(buf)); - msg->setControlDestination(decodeString(buf)); - msg->setDataDestination(decodeString(buf)); - msg->setDocumentSelection(decodeString(buf)); - msg->setMaximumPendingReplyCount(decodeInt(buf)); - - int32_t len = decodeInt(buf); - msg->getBuckets().reserve(len); - for (int32_t i = 0; i < len; i++) { - int64_t val; - buf.getLong(val); // NOT using getLongNetwork - msg->getBuckets().push_back(document::BucketId(val)); - } - - msg->setFromTimestamp(decodeLong(buf)); - msg->setToTimestamp(decodeLong(buf)); - msg->setVisitRemoves(decodeBoolean(buf)); - msg->setFieldSet(decodeString(buf)); - msg->setVisitInconsistentBuckets(decodeBoolean(buf)); - msg->getParameters().deserialize(_repo, buf); - msg->setVisitorDispatcherVersion(50); - msg->setVisitorOrdering((document::OrderingSpecification::Order)decodeInt(buf)); - msg->setMaxBucketsPerVisitor(decodeInt(buf)); - msg->setBucketSpace(decodeBucketSpace(buf)); - - return msg; -} - -bool -RoutableFactories52::CreateVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const CreateVisitorMessage &msg = static_cast<const CreateVisitorMessage&>(obj); - - buf.putString(msg.getLibraryName()); - buf.putString(msg.getInstanceId()); - buf.putString(msg.getControlDestination()); - buf.putString(msg.getDataDestination()); - buf.putString(msg.getDocumentSelection()); - buf.putInt(msg.getMaximumPendingReplyCount()); - buf.putInt(msg.getBuckets().size()); - - for (const auto & bucketId : msg.getBuckets()) { - uint64_t val = bucketId.getRawId(); - buf.putBytes((const char*)&val, 8); - } - - buf.putLong(msg.getFromTimestamp()); - buf.putLong(msg.getToTimestamp()); - buf.putBoolean(msg.visitRemoves()); - buf.putString(msg.getFieldSet()); - buf.putBoolean(msg.visitInconsistentBuckets()); - - int len = msg.getParameters().getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - msg.getParameters().serialize(dbuf); - - buf.putInt(msg.getVisitorOrdering()); - buf.putInt(msg.getMaxBucketsPerVisitor()); - return encodeBucketSpace(msg.getBucketSpace(), buf); -} - -bool RoutableFactories52::CreateVisitorMessageFactory::encodeBucketSpace( - vespalib::stringref bucketSpace, - vespalib::GrowableByteBuffer& buf) const { - (void) buf; - return (bucketSpace == FixedBucketSpaces::default_space_name()); -} - -string RoutableFactories52::CreateVisitorMessageFactory::decodeBucketSpace(document::ByteBuffer&) const { - return FixedBucketSpaces::default_space_name(); -} - -DocumentMessage::UP -RoutableFactories52::DestroyVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<DestroyVisitorMessage>(); - msg->setInstanceId(decodeString(buf)); - return msg; -} - -bool -RoutableFactories52::DestroyVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const DestroyVisitorMessage &msg = static_cast<const DestroyVisitorMessage&>(obj); - buf.putString(msg.getInstanceId()); - return true; -} - -DocumentReply::UP -RoutableFactories52::CreateVisitorReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<CreateVisitorReply>(DocumentProtocol::REPLY_CREATEVISITOR); - reply->setLastBucket(document::BucketId((uint64_t)decodeLong(buf))); - vdslib::VisitorStatistics vs; - vs.setBucketsVisited(decodeInt(buf)); - vs.setDocumentsVisited(decodeLong(buf)); - vs.setBytesVisited(decodeLong(buf)); - vs.setDocumentsReturned(decodeLong(buf)); - vs.setBytesReturned(decodeLong(buf)); - vs.setSecondPassDocumentsReturned(decodeLong(buf)); - vs.setSecondPassBytesReturned(decodeLong(buf)); - reply->setVisitorStatistics(vs); - - return reply; -} - -bool -RoutableFactories52::CreateVisitorReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const CreateVisitorReply &reply = static_cast<const CreateVisitorReply&>(obj); - buf.putLong(reply.getLastBucket().getRawId()); - buf.putInt(reply.getVisitorStatistics().getBucketsVisited()); - buf.putLong(reply.getVisitorStatistics().getDocumentsVisited()); - buf.putLong(reply.getVisitorStatistics().getBytesVisited()); - buf.putLong(reply.getVisitorStatistics().getDocumentsReturned()); - buf.putLong(reply.getVisitorStatistics().getBytesReturned()); - buf.putLong(reply.getVisitorStatistics().getSecondPassDocumentsReturned()); - buf.putLong(reply.getVisitorStatistics().getSecondPassBytesReturned()); - return true; -} - -DocumentReply::UP -RoutableFactories52::DestroyVisitorReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_DESTROYVISITOR); -} - -bool -RoutableFactories52::DestroyVisitorReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -DocumentReply::UP -RoutableFactories52::DocumentIgnoredReplyFactory::doDecode(document::ByteBuffer& buf) const -{ - (void) buf; - return DocumentReply::UP(new DocumentIgnoredReply()); -} - -bool -RoutableFactories52::DocumentIgnoredReplyFactory::doEncode( - const DocumentReply& obj, - vespalib::GrowableByteBuffer& buf) const -{ - (void) obj; - (void) buf; - return true; -} - -DocumentMessage::UP -RoutableFactories52::DocumentListMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<DocumentListMessage>(); - msg->setBucketId(document::BucketId(decodeLong(buf))); - - int32_t len = decodeInt(buf); - for (int32_t i = 0; i < len; i++) { - DocumentListMessage::Entry entry(_repo, buf); - msg->getDocuments().push_back(entry); - } - - return msg; -} - -bool -RoutableFactories52::DocumentListMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const DocumentListMessage &msg = static_cast<const DocumentListMessage&>(obj); - - buf.putLong(msg.getBucketId().getRawId()); - buf.putInt(msg.getDocuments().size()); - for (const auto & document : msg.getDocuments()) { - int len = document.getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - document.serialize(dbuf); - } - - return true; -} - -DocumentReply::UP -RoutableFactories52::DocumentListReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_DOCUMENTLIST); -} - -bool -RoutableFactories52::DocumentListReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -DocumentMessage::UP -RoutableFactories52::DocumentSummaryMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<DocumentSummaryMessage>(); - - msg->deserialize(buf); - - return msg; -} - -bool -RoutableFactories52::DocumentSummaryMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const DocumentSummaryMessage &msg = static_cast<const DocumentSummaryMessage&>(obj); - - int32_t len = msg.getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - msg.serialize(dbuf); - - return true; -} - -DocumentReply::UP -RoutableFactories52::DocumentSummaryReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_DOCUMENTSUMMARY); -} - -bool -RoutableFactories52::DocumentSummaryReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -DocumentMessage::UP -RoutableFactories52::EmptyBucketsMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<EmptyBucketsMessage>(); - - int32_t len = decodeInt(buf); - std::vector<document::BucketId> buckets(len); - for (int32_t i = 0; i < len; ++i) { - buckets[i] = document::BucketId(decodeLong(buf)); - } - msg->getBucketIds().swap(buckets); - - return msg; -} - -bool -RoutableFactories52::EmptyBucketsMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const EmptyBucketsMessage &msg = static_cast<const EmptyBucketsMessage&>(obj); - - buf.putInt(msg.getBucketIds().size()); - for (const auto & bucketId : msg.getBucketIds()) { - buf.putLong(bucketId.getRawId()); - } - - return true; -} - -DocumentReply::UP -RoutableFactories52::EmptyBucketsReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_EMPTYBUCKETS); -} - -bool -RoutableFactories52::EmptyBucketsReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -bool RoutableFactories52::GetBucketListMessageFactory::encodeBucketSpace(vespalib::stringref bucketSpace, - vespalib::GrowableByteBuffer& ) const -{ - return (bucketSpace == FixedBucketSpaces::default_space_name()); -} - -string RoutableFactories52::GetBucketListMessageFactory::decodeBucketSpace(document::ByteBuffer&) const { - return FixedBucketSpaces::default_space_name(); -} - -DocumentMessage::UP -RoutableFactories52::GetBucketListMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - document::BucketId bucketId(decodeLong(buf)); - auto msg = std::make_unique<GetBucketListMessage>(bucketId); - msg->setBucketSpace(decodeBucketSpace(buf)); - return msg; -} - -bool -RoutableFactories52::GetBucketListMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const GetBucketListMessage &msg = static_cast<const GetBucketListMessage&>(obj); - buf.putLong(msg.getBucketId().getRawId()); - return encodeBucketSpace(msg.getBucketSpace(), buf); -} - -DocumentReply::UP -RoutableFactories52::GetBucketListReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<GetBucketListReply>(); - - int32_t len = decodeInt(buf); - reply->getBuckets().reserve(len); - for (int32_t i = 0; i < len; i++) { - GetBucketListReply::BucketInfo info; - info._bucket = document::BucketId((uint64_t)decodeLong(buf)); - info._bucketInformation = decodeString(buf); - reply->getBuckets().push_back(info); - } - - return reply; -} - -bool -RoutableFactories52::GetBucketListReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const GetBucketListReply &reply = static_cast<const GetBucketListReply&>(obj); - - const std::vector<GetBucketListReply::BucketInfo> &buckets = reply.getBuckets(); - buf.putInt(buckets.size()); - for (const auto & bucketInfo : buckets) { - buf.putLong(bucketInfo._bucket.getRawId()); - buf.putString(bucketInfo._bucketInformation); - } - - return true; -} - -DocumentMessage::UP -RoutableFactories52::GetBucketStateMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<GetBucketStateMessage>(); - - msg->setBucketId(document::BucketId((uint64_t)decodeLong(buf))); - - return msg; -} - -bool -RoutableFactories52::GetBucketStateMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const GetBucketStateMessage &msg = static_cast<const GetBucketStateMessage&>(obj); - buf.putLong(msg.getBucketId().getRawId()); - return true; -} - -DocumentReply::UP -RoutableFactories52::GetBucketStateReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<GetBucketStateReply>(); - - int32_t len = decodeInt(buf); - reply->getBucketState().reserve(len); - for (int32_t i = 0; i < len; i++) { - reply->getBucketState().emplace_back(buf); - } - - return reply; -} - -bool -RoutableFactories52::GetBucketStateReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const GetBucketStateReply &reply = static_cast<const GetBucketStateReply&>(obj); - - buf.putInt(reply.getBucketState().size()); - for (const auto & state : reply.getBucketState()) { - state.serialize(buf); - } - - return true; -} - -DocumentMessage::UP -RoutableFactories52::GetDocumentMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - return DocumentMessage::UP( - new GetDocumentMessage(decodeDocumentId(buf), - decodeString(buf))); -} - -bool -RoutableFactories52::GetDocumentMessageFactory::doEncode(const DocumentMessage &obj, - vespalib::GrowableByteBuffer &buf) const -{ - const GetDocumentMessage &msg = static_cast<const GetDocumentMessage&>(obj); - - encodeDocumentId(msg.getDocumentId(), buf); - buf.putString(msg.getFieldSet()); - return true; -} - -DocumentReply::UP -RoutableFactories52::GetDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<GetDocumentReply>(); - - bool hasDocument = decodeBoolean(buf); - document::Document * document = nullptr; - if (hasDocument) { - auto doc = std::make_shared<document::Document>(_repo, buf); - document = doc.get(); - reply->setDocument(std::move(doc)); - } - int64_t lastModified = decodeLong(buf); - reply->setLastModified(lastModified); - if (hasDocument) { - document->setLastModified(lastModified); - } - - return reply; -} - -bool -RoutableFactories52::GetDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const GetDocumentReply &reply = static_cast<const GetDocumentReply&>(obj); - - buf.putByte(reply.hasDocument() ? 1 : 0); - if (reply.hasDocument()) { - nbostream stream; - reply.getDocument().serialize(stream); - buf.putBytes(stream.peek(), stream.size()); - } - buf.putLong(reply.getLastModified()); - - return true; -} - -DocumentMessage::UP -RoutableFactories52::MapVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<MapVisitorMessage>(); - msg->getData().deserialize(_repo, buf); - return msg; -} - -bool -RoutableFactories52::MapVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const MapVisitorMessage &msg = static_cast<const MapVisitorMessage&>(obj); - - int32_t len = msg.getData().getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - msg.getData().serialize(dbuf); - - return true; -} - -DocumentReply::UP -RoutableFactories52::MapVisitorReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_MAPVISITOR); -} - -bool -RoutableFactories52::MapVisitorReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -void -RoutableFactories52::PutDocumentMessageFactory::decodeInto(PutDocumentMessage & msg, document::ByteBuffer & buf) const { - msg.setDocument(make_shared<document::Document>(_repo, buf)); - msg.setTimestamp(static_cast<uint64_t>(decodeLong(buf))); - decodeTasCondition(msg, buf); -} - -bool -RoutableFactories52::PutDocumentMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - auto & msg = static_cast<const PutDocumentMessage &>(obj); - nbostream stream; - - msg.getDocument().serialize(stream); - buf.putBytes(stream.peek(), stream.size()); - buf.putLong(static_cast<int64_t>(msg.getTimestamp())); - encodeTasCondition(buf, msg); - - return true; -} - -DocumentReply::UP -RoutableFactories52::PutDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = make_unique<WriteDocumentReply>(DocumentProtocol::REPLY_PUTDOCUMENT); - reply->setHighestModificationTimestamp(decodeLong(buf)); - - // Doing an explicit move here to force converting result to an rvalue. - // This is done automatically in GCC >= 5. - return std::move(reply); -} - -bool -RoutableFactories52::PutDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const WriteDocumentReply& reply = (const WriteDocumentReply&)obj; - buf.putLong(reply.getHighestModificationTimestamp()); - return true; -} - -void -RoutableFactories52::RemoveDocumentMessageFactory::decodeInto(RemoveDocumentMessage & msg, document::ByteBuffer & buf) const { - msg.setDocumentId(decodeDocumentId(buf)); - decodeTasCondition(msg, buf); -} - -bool -RoutableFactories52::RemoveDocumentMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const RemoveDocumentMessage &msg = static_cast<const RemoveDocumentMessage&>(obj); - encodeDocumentId(msg.getDocumentId(), buf); - encodeTasCondition(buf, msg); - return true; -} - -DocumentReply::UP -RoutableFactories52::RemoveDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<RemoveDocumentReply>(); - reply->setWasFound(decodeBoolean(buf)); - reply->setHighestModificationTimestamp(decodeLong(buf)); - return reply; -} - -bool -RoutableFactories52::RemoveDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const RemoveDocumentReply &reply = static_cast<const RemoveDocumentReply&>(obj); - buf.putBoolean(reply.getWasFound()); - buf.putLong(reply.getHighestModificationTimestamp()); - return true; -} - -DocumentMessage::UP -RoutableFactories52::RemoveLocationMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - string selection = decodeString(buf); - - document::BucketIdFactory factory; - document::select::Parser parser(_repo, factory); - - auto msg = std::make_unique<RemoveLocationMessage>(factory, parser, selection); - // FIXME bucket space not part of wire format, implicitly limiting to only default space for now. - msg->setBucketSpace(document::FixedBucketSpaces::default_space_name()); - return msg; -} - -bool -RoutableFactories52::RemoveLocationMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const RemoveLocationMessage &msg = static_cast<const RemoveLocationMessage&>(obj); - buf.putString(msg.getDocumentSelection()); - return true; -} - -DocumentReply::UP -RoutableFactories52::RemoveLocationReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<DocumentReply>(DocumentProtocol::REPLY_REMOVELOCATION); -} - -bool -RoutableFactories52::RemoveLocationReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -DocumentMessage::UP -RoutableFactories52::SearchResultMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<SearchResultMessage>(); - msg->deserialize(buf); - return msg; -} - -bool -RoutableFactories52::SearchResultMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const SearchResultMessage &msg = static_cast<const SearchResultMessage&>(obj); - - int len = msg.getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - msg.serialize(dbuf); - - return true; -} - -DocumentMessage::UP -RoutableFactories52::QueryResultMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<QueryResultMessage>(); - msg->getSearchResult().deserialize(buf); - msg->getDocumentSummary().deserialize(buf); - - return msg; -} - -bool -RoutableFactories52::QueryResultMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const QueryResultMessage &msg = static_cast<const QueryResultMessage&>(obj); - - int len = msg.getSearchResult().getSerializedSize() + msg.getDocumentSummary().getSerializedSize(); - char *tmp = buf.allocate(len); - document::ByteBuffer dbuf(tmp, len); - msg.getSearchResult().serialize(dbuf); - msg.getDocumentSummary().serialize(dbuf); - - return true; -} - -DocumentReply::UP -RoutableFactories52::SearchResultReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_SEARCHRESULT); -} - -bool -RoutableFactories52::SearchResultReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -DocumentReply::UP -RoutableFactories52::QueryResultReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_QUERYRESULT); -} - -bool -RoutableFactories52::QueryResultReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -bool RoutableFactories52::StatBucketMessageFactory::encodeBucketSpace(vespalib::stringref bucketSpace, - vespalib::GrowableByteBuffer& ) const -{ - return (bucketSpace == FixedBucketSpaces::default_space_name()); -} - -string RoutableFactories52::StatBucketMessageFactory::decodeBucketSpace(document::ByteBuffer&) const { - return FixedBucketSpaces::default_space_name(); -} - -DocumentMessage::UP -RoutableFactories52::StatBucketMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<StatBucketMessage>(); - - msg->setBucketId(document::BucketId(decodeLong(buf))); - msg->setDocumentSelection(decodeString(buf)); - msg->setBucketSpace(decodeBucketSpace(buf)); - - return msg; -} - -bool -RoutableFactories52::StatBucketMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const StatBucketMessage &msg = static_cast<const StatBucketMessage&>(obj); - - buf.putLong(msg.getBucketId().getRawId()); - buf.putString(msg.getDocumentSelection()); - return encodeBucketSpace(msg.getBucketSpace(), buf); -} - -DocumentReply::UP -RoutableFactories52::StatBucketReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<StatBucketReply>(); - reply->setResults(decodeString(buf)); - return reply; -} - -bool -RoutableFactories52::StatBucketReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const StatBucketReply &reply = static_cast<const StatBucketReply&>(obj); - buf.putString(reply.getResults()); - return true; -} - -DocumentMessage::UP -RoutableFactories52::StatDocumentMessageFactory::doDecode(document::ByteBuffer &) const -{ - return DocumentMessage::UP(); // TODO: remove message type -} - -bool -RoutableFactories52::StatDocumentMessageFactory::doEncode(const DocumentMessage &, vespalib::GrowableByteBuffer &) const -{ - return false; -} - -DocumentReply::UP -RoutableFactories52::StatDocumentReplyFactory::doDecode(document::ByteBuffer &) const -{ - return DocumentReply::UP(); // TODO: remove reply type -} - -bool -RoutableFactories52::StatDocumentReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return false; -} - -void -RoutableFactories52::UpdateDocumentMessageFactory::decodeInto(UpdateDocumentMessage & msg, document::ByteBuffer & buf) const { - msg.setDocumentUpdate(document::DocumentUpdate::createHEAD(_repo, buf)); - msg.setOldTimestamp(static_cast<uint64_t>(decodeLong(buf))); - msg.setNewTimestamp(static_cast<uint64_t>(decodeLong(buf))); - decodeTasCondition(msg, buf); -} - -bool -RoutableFactories52::UpdateDocumentMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const UpdateDocumentMessage &msg = static_cast<const UpdateDocumentMessage&>(obj); - - vespalib::nbostream stream; - msg.getDocumentUpdate().serializeHEAD(stream); - buf.putBytes(stream.peek(), stream.size()); - buf.putLong((int64_t)msg.getOldTimestamp()); - buf.putLong((int64_t)msg.getNewTimestamp()); - encodeTasCondition(buf, msg); - - return true; -} - -DocumentReply::UP -RoutableFactories52::UpdateDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<UpdateDocumentReply>(); - reply->setWasFound(decodeBoolean(buf)); - reply->setHighestModificationTimestamp(decodeLong(buf)); - return reply; -} - -bool -RoutableFactories52::UpdateDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const UpdateDocumentReply &reply = static_cast<const UpdateDocumentReply&>(obj); - buf.putBoolean(reply.getWasFound()); - buf.putLong(reply.getHighestModificationTimestamp()); - return true; -} - -DocumentMessage::UP -RoutableFactories52::VisitorInfoMessageFactory::doDecode(document::ByteBuffer &buf) const -{ - auto msg = std::make_unique<VisitorInfoMessage>(); - - int32_t len = decodeInt(buf); - msg->getFinishedBuckets().reserve(len); - for (int32_t i = 0; i < len; i++) { - int64_t val; - buf.getLong(val); // NOT using getLongNetwork - msg->getFinishedBuckets().emplace_back(val); - } - msg->setErrorMessage(decodeString(buf)); - - return msg; -} - -bool -RoutableFactories52::VisitorInfoMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const -{ - const VisitorInfoMessage &msg = static_cast<const VisitorInfoMessage&>(obj); - - buf.putInt(msg.getFinishedBuckets().size()); - for (const auto & bucketId : msg.getFinishedBuckets()) { - uint64_t val = bucketId.getRawId(); - buf.putBytes((const char*)&val, 8); - } - buf.putString(msg.getErrorMessage()); - - return true; -} - -DocumentReply::UP -RoutableFactories52::VisitorInfoReplyFactory::doDecode(document::ByteBuffer &) const -{ - return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_VISITORINFO); -} - -bool -RoutableFactories52::VisitorInfoReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const -{ - return true; -} - -DocumentReply::UP -RoutableFactories52::WrongDistributionReplyFactory::doDecode(document::ByteBuffer &buf) const -{ - auto reply = std::make_unique<WrongDistributionReply>(); - reply->setSystemState(decodeString(buf)); - return reply; -} - -bool -RoutableFactories52::WrongDistributionReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const -{ - const WrongDistributionReply &reply = static_cast<const WrongDistributionReply&>(obj); - buf.putString(reply.getSystemState()); - return true; -} - -string -RoutableFactories52::decodeString(document::ByteBuffer &in) -{ - int32_t len = decodeInt(in); - string ret = string(in.getBufferAtPos(), len); - in.incPos(len); - return ret; -} - -bool -RoutableFactories52::decodeBoolean(document::ByteBuffer &in) -{ - char ret; - in.getBytes(&ret, 1); - return (bool)ret; -} - -int32_t -RoutableFactories52::decodeInt(document::ByteBuffer &in) -{ - int32_t ret; - in.getIntNetwork(ret); - return ret; -} - -int64_t -RoutableFactories52::decodeLong(document::ByteBuffer &in) -{ - int64_t ret; - in.getLongNetwork(ret); - return ret; -} - -document::DocumentId -RoutableFactories52::decodeDocumentId(document::ByteBuffer &in) -{ - nbostream stream(in.getBufferAtPos(), in.getRemaining()); - document::DocumentId ret(stream); - in.incPos(stream.rp()); - return ret; -} - -void -RoutableFactories52::encodeDocumentId(const document::DocumentId &id, vespalib::GrowableByteBuffer &out) -{ - string str = id.toString(); - out.putBytes(str.c_str(), str.size() + 1); -} - -void RoutableFactories52::decodeTasCondition(DocumentMessage & docMsg, document::ByteBuffer & buf) { - auto & msg = static_cast<TestAndSetMessage &>(docMsg); - msg.setCondition(TestAndSetCondition(decodeString(buf))); -} - -void RoutableFactories52::encodeTasCondition(vespalib::GrowableByteBuffer & buf, const DocumentMessage & docMsg) { - auto & msg = static_cast<const TestAndSetMessage &>(docMsg); - buf.putString(msg.getCondition().getSelection()); -} - - -} diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories52.h b/documentapi/src/vespa/documentapi/messagebus/routablefactories52.h deleted file mode 100644 index 9c614bde487..00000000000 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories52.h +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -// @author Vegard Sjonfjell -#pragma once - -#include <vespa/document/util/bytebuffer.h> -#include <vespa/vespalib/util/growablebytebuffer.h> -#include "iroutablefactory.h" -#include <vespa/documentapi/messagebus/messages/putdocumentmessage.h> -#include <vespa/documentapi/messagebus/messages/removedocumentmessage.h> -#include <vespa/documentapi/messagebus/messages/updatedocumentmessage.h> - -namespace document { class DocumentTypeRepo; } - -/** - * Utility class for invoking setApproxSize on a DocumentMessage with the delta - * between the read position of a ByteBuffer at construction and destruction - * time. The assumption being made is that the in-memory footprint of a message - * is reasonably close to its wire-serialized form. - */ -class ScopedApproxSizeSetter { -public: - ScopedApproxSizeSetter(documentapi::DocumentMessage& msg, - const document::ByteBuffer& buf) - : _msg(msg), - _buf(buf), - _posBefore(_buf.getPos()) - { - } - - ~ScopedApproxSizeSetter() { - _msg.setApproxSize(static_cast<uint32_t>(_buf.getPos() - _posBefore)); - } - -private: - documentapi::DocumentMessage& _msg; - const document::ByteBuffer& _buf; - const size_t _posBefore; -}; - -namespace documentapi { - -template<typename MessageType, typename FactoryType> -DocumentMessage::UP -decodeMessage(const FactoryType * self, document::ByteBuffer & buf) { - auto msg = std::make_unique<MessageType>(); - ScopedApproxSizeSetter sizeSetter(*msg, buf); - self->decodeInto(*msg, buf); - return msg; -} - -/** - * This class encapsulates all the {@link RoutableFactory} classes needed to implement factories for the document - * routable. When adding new factories to this class, please KEEP THE THEM ORDERED alphabetically like they are now. - */ -class RoutableFactories52 { -public: - RoutableFactories52() = delete; - - /** - * Implements the shared factory logic required for {@link DocumentMessage} objects, and it offers a more - * convenient interface for implementing {@link RoutableFactory}. - */ - class DocumentMessageFactory : public IRoutableFactory { - protected: - /** - * This method encodes the given message into the given byte buffer. You are guaranteed to only receive messages of - * the type that this factory was registered for. - * - * This method is NOT exception safe. Return false to signal failure. - * - * @param msg The message to encode. - * @param buf The byte buffer to write to. - * @return True if the message was encoded. - */ - virtual bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const = 0; - - /** - * This method decodes a message from the given byte buffer. You are guaranteed to only receive byte buffers - * generated by a previous call to {@link #doEncode(DocumentMessage, GrowableByteBuffer)}. - * - * This method is NOT exception safe. Return null to signal failure. - * - * @param buf The byte buffer to read from. - * @return The decoded message. - */ - virtual DocumentMessage::UP doDecode(document::ByteBuffer &buf) const = 0; - - public: - bool encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const override; - mbus::Routable::UP decode(document::ByteBuffer &in, const LoadTypeSet& loadTypes) const override; - }; - - /** - * Implements the shared factory logic required for {@link DocumentReply} objects, and it offers a more - * convenient interface for implementing {@link RoutableFactory}. - */ - class DocumentReplyFactory : public IRoutableFactory { - protected: - /** - * This method encodes the given reply into the given byte buffer. You are guaranteed to only receive - * replies of the type that this factory was registered for. - * - * This method is NOT exception safe. Return false to signal failure. - * - * @param reply The reply to encode. - * @param buf The byte buffer to write to. - * @return True if the message was encoded. - */ - virtual bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const = 0; - - /** - * This method decodes a reply from the given byte buffer. You are guaranteed to only receive byte buffers - * generated by a previous call to {@link #doEncode(DocumentReply, GrowableByteBuffer)}. - * - * This method is NOT exception safe. Return null to signal failure. - * - * @param buf The byte buffer to read from. - * @return The decoded reply. - */ - virtual DocumentReply::UP doDecode(document::ByteBuffer &buf) const = 0; - - public: - bool encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const override; - mbus::Routable::UP decode(document::ByteBuffer &in, const LoadTypeSet& loadTypes) const override; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - // Factories - // - //////////////////////////////////////////////////////////////////////////////// - class CreateVisitorMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - - virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; - virtual string decodeBucketSpace(document::ByteBuffer&) const; - public: - CreateVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - class CreateVisitorReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class DestroyVisitorMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class DestroyVisitorReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class DocumentIgnoredReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class DocumentListMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - DocumentListMessageFactory(const document::DocumentTypeRepo &r) - : _repo(r) {} - }; - class DocumentListReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class DocumentSummaryMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class DocumentSummaryReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class EmptyBucketsMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class EmptyBucketsReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class GetBucketListMessageFactory : public DocumentMessageFactory { - virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; - virtual string decodeBucketSpace(document::ByteBuffer&) const; - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class GetBucketListReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class GetBucketStateMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class GetBucketStateReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class GetDocumentMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class GetDocumentReplyFactory : public DocumentReplyFactory { - const document::DocumentTypeRepo &_repo; - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - GetDocumentReplyFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - class MapVisitorMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - MapVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - class MapVisitorReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class PutDocumentMessageFactory : public DocumentMessageFactory { - protected: - const document::DocumentTypeRepo &_repo; - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { - return decodeMessage<PutDocumentMessage>(this, buf); - } - - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - void decodeInto(PutDocumentMessage & msg, document::ByteBuffer & buf) const; - PutDocumentMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - class PutDocumentReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class RemoveDocumentMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { - return decodeMessage<RemoveDocumentMessage>(this, buf); - } - - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - void decodeInto(RemoveDocumentMessage & msg, document::ByteBuffer & buf) const; - }; - class RemoveDocumentReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class RemoveLocationMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - RemoveLocationMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - class RemoveLocationReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class SearchResultMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class SearchResultReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class StatBucketMessageFactory : public DocumentMessageFactory { - virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; - virtual string decodeBucketSpace(document::ByteBuffer&) const; - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class StatBucketReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class StatDocumentMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class StatDocumentReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class UpdateDocumentMessageFactory : public DocumentMessageFactory { - protected: - const document::DocumentTypeRepo &_repo; - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { - return decodeMessage<UpdateDocumentMessage>(this, buf); - } - - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - public: - void decodeInto(UpdateDocumentMessage & msg, document::ByteBuffer & buf) const; - UpdateDocumentMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} - }; - class UpdateDocumentReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class VisitorInfoMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class VisitorInfoReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class WrongDistributionReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - class QueryResultMessageFactory : public DocumentMessageFactory { - protected: - DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; - }; - class QueryResultReplyFactory : public DocumentReplyFactory { - protected: - DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; - bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; - }; - - /////////////////////////////////////////////////////////////////////////// - // - // Utilities - // - /////////////////////////////////////////////////////////////////////////// - - /** - * This is a complement for the vespalib::GrowableByteBuffer.putString() method. - * - * @param in The byte buffer to read from. - * @return The decoded string. - */ - static string decodeString(document::ByteBuffer &in); - - /** - * This is a complement for the vespalib::GrowableByteBuffer.putBoolean() method. - * - * @param in The byte buffer to read from. - * @return The decoded bool. - */ - static bool decodeBoolean(document::ByteBuffer &in); - - /** - * Convenience method to decode a 32-bit int from the given byte buffer. - * - * @param in The byte buffer to read from. - * @return The decoded int. - */ - static int32_t decodeInt(document::ByteBuffer &in); - - /** - * Convenience method to decode a 64-bit int from the given byte buffer. - * - * @param in The byte buffer to read from. - * @return The decoded int. - */ - static int64_t decodeLong(document::ByteBuffer &in); - - /** - * Convenience method to decode a document id from the given byte buffer. - * - * @param in The byte buffer to read from. - * @return The decoded document id. - */ - static document::DocumentId decodeDocumentId(document::ByteBuffer &in); - - /** - * Convenience method to encode a document id to the given byte buffer. - * - * @param id The document id to encode. - * @param out The byte buffer to write to. - */ - static void encodeDocumentId(const document::DocumentId &id, - vespalib::GrowableByteBuffer &out); - - static void decodeTasCondition(DocumentMessage & docMsg, document::ByteBuffer & buf); - static void encodeTasCondition(vespalib::GrowableByteBuffer & buf, const DocumentMessage & docMsg); -}; - -} diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories60.cpp b/documentapi/src/vespa/documentapi/messagebus/routablefactories60.cpp index 5823cc6720e..c34291c634f 100644 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories60.cpp +++ b/documentapi/src/vespa/documentapi/messagebus/routablefactories60.cpp @@ -1,10 +1,140 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// @author Vegard Sjonfjell #include "routablefactories60.h" +#include <vespa/document/bucket/bucketidfactory.h> +#include <vespa/document/bucket/fixed_bucket_spaces.h> +#include <vespa/document/select/parser.h> +#include <vespa/document/update/documentupdate.h> +#include <vespa/documentapi/documentapi.h> +#include <vespa/documentapi/loadtypes/loadtypeset.h> +#include <vespa/vespalib/objects/nbostream.h> + +using document::FixedBucketSpaces; +using vespalib::nbostream; +using std::make_shared; +using std::make_unique; namespace documentapi { -// TODO dedupe +bool +RoutableFactories60::DocumentMessageFactory::encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const +{ + const DocumentMessage &msg = static_cast<const DocumentMessage&>(obj); + out.putByte(msg.getPriority()); + out.putInt(msg.getLoadType().getId()); + return doEncode(msg, out); +} + +mbus::Routable::UP +RoutableFactories60::DocumentMessageFactory::decode(document::ByteBuffer &in, const LoadTypeSet& loadTypes) const +{ + uint8_t pri; + in.getByte(pri); + uint32_t loadClass = decodeInt(in); + + DocumentMessage::UP msg = doDecode(in); + if (msg) { + msg->setPriority((Priority::Value)pri); + msg->setLoadType(loadTypes[loadClass]); + } + + return mbus::Routable::UP(msg.release()); +} + +bool +RoutableFactories60::DocumentReplyFactory::encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const +{ + const DocumentReply &msg = static_cast<const DocumentReply&>(obj); + out.putByte(msg.getPriority()); + return doEncode(msg, out); +} + +mbus::Routable::UP +RoutableFactories60::DocumentReplyFactory::decode(document::ByteBuffer &in, const LoadTypeSet&) const +{ + uint8_t pri; + in.getByte(pri); + DocumentReply::UP reply = doDecode(in); + if (reply) { + reply->setPriority((Priority::Value)pri); + } + return mbus::Routable::UP(reply.release()); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Factories +// +//////////////////////////////////////////////////////////////////////////////// + +DocumentMessage::UP +RoutableFactories60::CreateVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<CreateVisitorMessage>(); + + msg->setLibraryName(decodeString(buf)); + msg->setInstanceId(decodeString(buf)); + msg->setControlDestination(decodeString(buf)); + msg->setDataDestination(decodeString(buf)); + msg->setDocumentSelection(decodeString(buf)); + msg->setMaximumPendingReplyCount(decodeInt(buf)); + + int32_t len = decodeInt(buf); + msg->getBuckets().reserve(len); + for (int32_t i = 0; i < len; i++) { + int64_t val; + buf.getLong(val); // NOT using getLongNetwork + msg->getBuckets().push_back(document::BucketId(val)); + } + + msg->setFromTimestamp(decodeLong(buf)); + msg->setToTimestamp(decodeLong(buf)); + msg->setVisitRemoves(decodeBoolean(buf)); + msg->setFieldSet(decodeString(buf)); + msg->setVisitInconsistentBuckets(decodeBoolean(buf)); + msg->getParameters().deserialize(_repo, buf); + msg->setVisitorDispatcherVersion(50); + msg->setVisitorOrdering((document::OrderingSpecification::Order)decodeInt(buf)); + msg->setMaxBucketsPerVisitor(decodeInt(buf)); + msg->setBucketSpace(decodeBucketSpace(buf)); + + return msg; +} + +bool +RoutableFactories60::CreateVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const CreateVisitorMessage &msg = static_cast<const CreateVisitorMessage&>(obj); + + buf.putString(msg.getLibraryName()); + buf.putString(msg.getInstanceId()); + buf.putString(msg.getControlDestination()); + buf.putString(msg.getDataDestination()); + buf.putString(msg.getDocumentSelection()); + buf.putInt(msg.getMaximumPendingReplyCount()); + buf.putInt(msg.getBuckets().size()); + + for (const auto & bucketId : msg.getBuckets()) { + uint64_t val = bucketId.getRawId(); + buf.putBytes((const char*)&val, 8); + } + + buf.putLong(msg.getFromTimestamp()); + buf.putLong(msg.getToTimestamp()); + buf.putBoolean(msg.visitRemoves()); + buf.putString(msg.getFieldSet()); + buf.putBoolean(msg.visitInconsistentBuckets()); + + int len = msg.getParameters().getSerializedSize(); + char *tmp = buf.allocate(len); + document::ByteBuffer dbuf(tmp, len); + msg.getParameters().serialize(dbuf); + + buf.putInt(msg.getVisitorOrdering()); + buf.putInt(msg.getMaxBucketsPerVisitor()); + return encodeBucketSpace(msg.getBucketSpace(), buf); +} bool RoutableFactories60::CreateVisitorMessageFactory::encodeBucketSpace( vespalib::stringref bucketSpace, @@ -13,32 +143,810 @@ bool RoutableFactories60::CreateVisitorMessageFactory::encodeBucketSpace( return true; } -string RoutableFactories60::CreateVisitorMessageFactory::decodeBucketSpace(document::ByteBuffer& buf) const { +string RoutableFactories60::CreateVisitorMessageFactory::decodeBucketSpace(document::ByteBuffer &buf) const { return doDecodeBucketSpace(buf); } -bool RoutableFactories60::StatBucketMessageFactory::encodeBucketSpace( - vespalib::stringref bucketSpace, - vespalib::GrowableByteBuffer& buf) const { +DocumentMessage::UP +RoutableFactories60::DestroyVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<DestroyVisitorMessage>(); + msg->setInstanceId(decodeString(buf)); + return msg; +} + +bool +RoutableFactories60::DestroyVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const DestroyVisitorMessage &msg = static_cast<const DestroyVisitorMessage&>(obj); + buf.putString(msg.getInstanceId()); + return true; +} + +DocumentReply::UP +RoutableFactories60::CreateVisitorReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<CreateVisitorReply>(DocumentProtocol::REPLY_CREATEVISITOR); + reply->setLastBucket(document::BucketId((uint64_t)decodeLong(buf))); + vdslib::VisitorStatistics vs; + vs.setBucketsVisited(decodeInt(buf)); + vs.setDocumentsVisited(decodeLong(buf)); + vs.setBytesVisited(decodeLong(buf)); + vs.setDocumentsReturned(decodeLong(buf)); + vs.setBytesReturned(decodeLong(buf)); + vs.setSecondPassDocumentsReturned(decodeLong(buf)); + vs.setSecondPassBytesReturned(decodeLong(buf)); + reply->setVisitorStatistics(vs); + + return reply; +} + +bool +RoutableFactories60::CreateVisitorReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const CreateVisitorReply &reply = static_cast<const CreateVisitorReply&>(obj); + buf.putLong(reply.getLastBucket().getRawId()); + buf.putInt(reply.getVisitorStatistics().getBucketsVisited()); + buf.putLong(reply.getVisitorStatistics().getDocumentsVisited()); + buf.putLong(reply.getVisitorStatistics().getBytesVisited()); + buf.putLong(reply.getVisitorStatistics().getDocumentsReturned()); + buf.putLong(reply.getVisitorStatistics().getBytesReturned()); + buf.putLong(reply.getVisitorStatistics().getSecondPassDocumentsReturned()); + buf.putLong(reply.getVisitorStatistics().getSecondPassBytesReturned()); + return true; +} + +DocumentReply::UP +RoutableFactories60::DestroyVisitorReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_DESTROYVISITOR); +} + +bool +RoutableFactories60::DestroyVisitorReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +DocumentReply::UP +RoutableFactories60::DocumentIgnoredReplyFactory::doDecode(document::ByteBuffer& buf) const +{ + (void) buf; + return DocumentReply::UP(new DocumentIgnoredReply()); +} + +bool +RoutableFactories60::DocumentIgnoredReplyFactory::doEncode( + const DocumentReply& obj, + vespalib::GrowableByteBuffer& buf) const +{ + (void) obj; + (void) buf; + return true; +} + +DocumentMessage::UP +RoutableFactories60::DocumentListMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<DocumentListMessage>(); + msg->setBucketId(document::BucketId(decodeLong(buf))); + + int32_t len = decodeInt(buf); + for (int32_t i = 0; i < len; i++) { + DocumentListMessage::Entry entry(_repo, buf); + msg->getDocuments().push_back(entry); + } + + return msg; +} + +bool +RoutableFactories60::DocumentListMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const DocumentListMessage &msg = static_cast<const DocumentListMessage&>(obj); + + buf.putLong(msg.getBucketId().getRawId()); + buf.putInt(msg.getDocuments().size()); + for (const auto & document : msg.getDocuments()) { + int len = document.getSerializedSize(); + char *tmp = buf.allocate(len); + document::ByteBuffer dbuf(tmp, len); + document.serialize(dbuf); + } + + return true; +} + +DocumentReply::UP +RoutableFactories60::DocumentListReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_DOCUMENTLIST); +} + +bool +RoutableFactories60::DocumentListReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +DocumentMessage::UP +RoutableFactories60::DocumentSummaryMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<DocumentSummaryMessage>(); + + msg->deserialize(buf); + + return msg; +} + +bool +RoutableFactories60::DocumentSummaryMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const DocumentSummaryMessage &msg = static_cast<const DocumentSummaryMessage&>(obj); + + int32_t len = msg.getSerializedSize(); + char *tmp = buf.allocate(len); + document::ByteBuffer dbuf(tmp, len); + msg.serialize(dbuf); + + return true; +} + +DocumentReply::UP +RoutableFactories60::DocumentSummaryReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_DOCUMENTSUMMARY); +} + +bool +RoutableFactories60::DocumentSummaryReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +DocumentMessage::UP +RoutableFactories60::EmptyBucketsMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<EmptyBucketsMessage>(); + + int32_t len = decodeInt(buf); + std::vector<document::BucketId> buckets(len); + for (int32_t i = 0; i < len; ++i) { + buckets[i] = document::BucketId(decodeLong(buf)); + } + msg->getBucketIds().swap(buckets); + + return msg; +} + +bool +RoutableFactories60::EmptyBucketsMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const EmptyBucketsMessage &msg = static_cast<const EmptyBucketsMessage&>(obj); + + buf.putInt(msg.getBucketIds().size()); + for (const auto & bucketId : msg.getBucketIds()) { + buf.putLong(bucketId.getRawId()); + } + + return true; +} + +DocumentReply::UP +RoutableFactories60::EmptyBucketsReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_EMPTYBUCKETS); +} + +bool +RoutableFactories60::EmptyBucketsReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +bool RoutableFactories60::GetBucketListMessageFactory::encodeBucketSpace(vespalib::stringref bucketSpace, + vespalib::GrowableByteBuffer &buf) const +{ doEncodeBucketSpace(bucketSpace, buf); return true; } -string RoutableFactories60::StatBucketMessageFactory::decodeBucketSpace(document::ByteBuffer& buf) const { +string RoutableFactories60::GetBucketListMessageFactory::decodeBucketSpace(document::ByteBuffer &buf) const { return doDecodeBucketSpace(buf); } -bool RoutableFactories60::GetBucketListMessageFactory::encodeBucketSpace( - vespalib::stringref bucketSpace, - vespalib::GrowableByteBuffer& buf) const { +DocumentMessage::UP +RoutableFactories60::GetBucketListMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + document::BucketId bucketId(decodeLong(buf)); + auto msg = std::make_unique<GetBucketListMessage>(bucketId); + msg->setBucketSpace(decodeBucketSpace(buf)); + return msg; +} + +bool +RoutableFactories60::GetBucketListMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const GetBucketListMessage &msg = static_cast<const GetBucketListMessage&>(obj); + buf.putLong(msg.getBucketId().getRawId()); + return encodeBucketSpace(msg.getBucketSpace(), buf); +} + +DocumentReply::UP +RoutableFactories60::GetBucketListReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<GetBucketListReply>(); + + int32_t len = decodeInt(buf); + reply->getBuckets().reserve(len); + for (int32_t i = 0; i < len; i++) { + GetBucketListReply::BucketInfo info; + info._bucket = document::BucketId((uint64_t)decodeLong(buf)); + info._bucketInformation = decodeString(buf); + reply->getBuckets().push_back(info); + } + + return reply; +} + +bool +RoutableFactories60::GetBucketListReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const GetBucketListReply &reply = static_cast<const GetBucketListReply&>(obj); + + const std::vector<GetBucketListReply::BucketInfo> &buckets = reply.getBuckets(); + buf.putInt(buckets.size()); + for (const auto & bucketInfo : buckets) { + buf.putLong(bucketInfo._bucket.getRawId()); + buf.putString(bucketInfo._bucketInformation); + } + + return true; +} + +DocumentMessage::UP +RoutableFactories60::GetBucketStateMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<GetBucketStateMessage>(); + + msg->setBucketId(document::BucketId((uint64_t)decodeLong(buf))); + + return msg; +} + +bool +RoutableFactories60::GetBucketStateMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const GetBucketStateMessage &msg = static_cast<const GetBucketStateMessage&>(obj); + buf.putLong(msg.getBucketId().getRawId()); + return true; +} + +DocumentReply::UP +RoutableFactories60::GetBucketStateReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<GetBucketStateReply>(); + + int32_t len = decodeInt(buf); + reply->getBucketState().reserve(len); + for (int32_t i = 0; i < len; i++) { + reply->getBucketState().emplace_back(buf); + } + + return reply; +} + +bool +RoutableFactories60::GetBucketStateReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const GetBucketStateReply &reply = static_cast<const GetBucketStateReply&>(obj); + + buf.putInt(reply.getBucketState().size()); + for (const auto & state : reply.getBucketState()) { + state.serialize(buf); + } + + return true; +} + +DocumentMessage::UP +RoutableFactories60::GetDocumentMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + return DocumentMessage::UP( + new GetDocumentMessage(decodeDocumentId(buf), + decodeString(buf))); +} + +bool +RoutableFactories60::GetDocumentMessageFactory::doEncode(const DocumentMessage &obj, + vespalib::GrowableByteBuffer &buf) const +{ + const GetDocumentMessage &msg = static_cast<const GetDocumentMessage&>(obj); + + encodeDocumentId(msg.getDocumentId(), buf); + buf.putString(msg.getFieldSet()); + return true; +} + +DocumentReply::UP +RoutableFactories60::GetDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<GetDocumentReply>(); + + bool hasDocument = decodeBoolean(buf); + document::Document * document = nullptr; + if (hasDocument) { + auto doc = std::make_shared<document::Document>(_repo, buf); + document = doc.get(); + reply->setDocument(std::move(doc)); + } + int64_t lastModified = decodeLong(buf); + reply->setLastModified(lastModified); + if (hasDocument) { + document->setLastModified(lastModified); + } + + return reply; +} + +bool +RoutableFactories60::GetDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const GetDocumentReply &reply = static_cast<const GetDocumentReply&>(obj); + + buf.putByte(reply.hasDocument() ? 1 : 0); + if (reply.hasDocument()) { + nbostream stream; + reply.getDocument().serialize(stream); + buf.putBytes(stream.peek(), stream.size()); + } + buf.putLong(reply.getLastModified()); + + return true; +} + +DocumentMessage::UP +RoutableFactories60::MapVisitorMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<MapVisitorMessage>(); + msg->getData().deserialize(_repo, buf); + return msg; +} + +bool +RoutableFactories60::MapVisitorMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const MapVisitorMessage &msg = static_cast<const MapVisitorMessage&>(obj); + + int32_t len = msg.getData().getSerializedSize(); + char *tmp = buf.allocate(len); + document::ByteBuffer dbuf(tmp, len); + msg.getData().serialize(dbuf); + + return true; +} + +DocumentReply::UP +RoutableFactories60::MapVisitorReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_MAPVISITOR); +} + +bool +RoutableFactories60::MapVisitorReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +void +RoutableFactories60::PutDocumentMessageFactory::decodeInto(PutDocumentMessage & msg, document::ByteBuffer & buf) const { + msg.setDocument(make_shared<document::Document>(_repo, buf)); + msg.setTimestamp(static_cast<uint64_t>(decodeLong(buf))); + decodeTasCondition(msg, buf); +} + +bool +RoutableFactories60::PutDocumentMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + auto & msg = static_cast<const PutDocumentMessage &>(obj); + nbostream stream; + + msg.getDocument().serialize(stream); + buf.putBytes(stream.peek(), stream.size()); + buf.putLong(static_cast<int64_t>(msg.getTimestamp())); + encodeTasCondition(buf, msg); + + return true; +} + +DocumentReply::UP +RoutableFactories60::PutDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = make_unique<WriteDocumentReply>(DocumentProtocol::REPLY_PUTDOCUMENT); + reply->setHighestModificationTimestamp(decodeLong(buf)); + + // Doing an explicit move here to force converting result to an rvalue. + // This is done automatically in GCC >= 5. + return std::move(reply); +} + +bool +RoutableFactories60::PutDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const WriteDocumentReply& reply = (const WriteDocumentReply&)obj; + buf.putLong(reply.getHighestModificationTimestamp()); + return true; +} + +void +RoutableFactories60::RemoveDocumentMessageFactory::decodeInto(RemoveDocumentMessage & msg, document::ByteBuffer & buf) const { + msg.setDocumentId(decodeDocumentId(buf)); + decodeTasCondition(msg, buf); +} + +bool +RoutableFactories60::RemoveDocumentMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const RemoveDocumentMessage &msg = static_cast<const RemoveDocumentMessage&>(obj); + encodeDocumentId(msg.getDocumentId(), buf); + encodeTasCondition(buf, msg); + return true; +} + +DocumentReply::UP +RoutableFactories60::RemoveDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<RemoveDocumentReply>(); + reply->setWasFound(decodeBoolean(buf)); + reply->setHighestModificationTimestamp(decodeLong(buf)); + return reply; +} + +bool +RoutableFactories60::RemoveDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const RemoveDocumentReply &reply = static_cast<const RemoveDocumentReply&>(obj); + buf.putBoolean(reply.getWasFound()); + buf.putLong(reply.getHighestModificationTimestamp()); + return true; +} + +DocumentMessage::UP +RoutableFactories60::RemoveLocationMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + string selection = decodeString(buf); + + document::BucketIdFactory factory; + document::select::Parser parser(_repo, factory); + + auto msg = std::make_unique<RemoveLocationMessage>(factory, parser, selection); + // FIXME bucket space not part of wire format, implicitly limiting to only default space for now. + msg->setBucketSpace(document::FixedBucketSpaces::default_space_name()); + return msg; +} + +bool +RoutableFactories60::RemoveLocationMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const RemoveLocationMessage &msg = static_cast<const RemoveLocationMessage&>(obj); + buf.putString(msg.getDocumentSelection()); + return true; +} + +DocumentReply::UP +RoutableFactories60::RemoveLocationReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<DocumentReply>(DocumentProtocol::REPLY_REMOVELOCATION); +} + +bool +RoutableFactories60::RemoveLocationReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +DocumentMessage::UP +RoutableFactories60::SearchResultMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<SearchResultMessage>(); + msg->deserialize(buf); + return msg; +} + +bool +RoutableFactories60::SearchResultMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const SearchResultMessage &msg = static_cast<const SearchResultMessage&>(obj); + + int len = msg.getSerializedSize(); + char *tmp = buf.allocate(len); + document::ByteBuffer dbuf(tmp, len); + msg.serialize(dbuf); + + return true; +} + +DocumentMessage::UP +RoutableFactories60::QueryResultMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<QueryResultMessage>(); + msg->getSearchResult().deserialize(buf); + msg->getDocumentSummary().deserialize(buf); + + return msg; +} + +bool +RoutableFactories60::QueryResultMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const QueryResultMessage &msg = static_cast<const QueryResultMessage&>(obj); + + int len = msg.getSearchResult().getSerializedSize() + msg.getDocumentSummary().getSerializedSize(); + char *tmp = buf.allocate(len); + document::ByteBuffer dbuf(tmp, len); + msg.getSearchResult().serialize(dbuf); + msg.getDocumentSummary().serialize(dbuf); + + return true; +} + +DocumentReply::UP +RoutableFactories60::SearchResultReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_SEARCHRESULT); +} + +bool +RoutableFactories60::SearchResultReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +DocumentReply::UP +RoutableFactories60::QueryResultReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_QUERYRESULT); +} + +bool +RoutableFactories60::QueryResultReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +bool RoutableFactories60::StatBucketMessageFactory::encodeBucketSpace(vespalib::stringref bucketSpace, + vespalib::GrowableByteBuffer &buf) const +{ doEncodeBucketSpace(bucketSpace, buf); return true; } -string RoutableFactories60::GetBucketListMessageFactory::decodeBucketSpace(document::ByteBuffer& buf) const { +string RoutableFactories60::StatBucketMessageFactory::decodeBucketSpace(document::ByteBuffer &buf) const { return doDecodeBucketSpace(buf); } +DocumentMessage::UP +RoutableFactories60::StatBucketMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<StatBucketMessage>(); + + msg->setBucketId(document::BucketId(decodeLong(buf))); + msg->setDocumentSelection(decodeString(buf)); + msg->setBucketSpace(decodeBucketSpace(buf)); + + return msg; +} + +bool +RoutableFactories60::StatBucketMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const StatBucketMessage &msg = static_cast<const StatBucketMessage&>(obj); + + buf.putLong(msg.getBucketId().getRawId()); + buf.putString(msg.getDocumentSelection()); + return encodeBucketSpace(msg.getBucketSpace(), buf); +} + +DocumentReply::UP +RoutableFactories60::StatBucketReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<StatBucketReply>(); + reply->setResults(decodeString(buf)); + return reply; +} + +bool +RoutableFactories60::StatBucketReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const StatBucketReply &reply = static_cast<const StatBucketReply&>(obj); + buf.putString(reply.getResults()); + return true; +} + +DocumentMessage::UP +RoutableFactories60::StatDocumentMessageFactory::doDecode(document::ByteBuffer &) const +{ + return DocumentMessage::UP(); // TODO: remove message type +} + +bool +RoutableFactories60::StatDocumentMessageFactory::doEncode(const DocumentMessage &, vespalib::GrowableByteBuffer &) const +{ + return false; +} + +DocumentReply::UP +RoutableFactories60::StatDocumentReplyFactory::doDecode(document::ByteBuffer &) const +{ + return DocumentReply::UP(); // TODO: remove reply type +} + +bool +RoutableFactories60::StatDocumentReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return false; +} + +void +RoutableFactories60::UpdateDocumentMessageFactory::decodeInto(UpdateDocumentMessage & msg, document::ByteBuffer & buf) const { + msg.setDocumentUpdate(document::DocumentUpdate::createHEAD(_repo, buf)); + msg.setOldTimestamp(static_cast<uint64_t>(decodeLong(buf))); + msg.setNewTimestamp(static_cast<uint64_t>(decodeLong(buf))); + decodeTasCondition(msg, buf); +} + +bool +RoutableFactories60::UpdateDocumentMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const UpdateDocumentMessage &msg = static_cast<const UpdateDocumentMessage&>(obj); + + vespalib::nbostream stream; + msg.getDocumentUpdate().serializeHEAD(stream); + buf.putBytes(stream.peek(), stream.size()); + buf.putLong((int64_t)msg.getOldTimestamp()); + buf.putLong((int64_t)msg.getNewTimestamp()); + encodeTasCondition(buf, msg); + + return true; +} + +DocumentReply::UP +RoutableFactories60::UpdateDocumentReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<UpdateDocumentReply>(); + reply->setWasFound(decodeBoolean(buf)); + reply->setHighestModificationTimestamp(decodeLong(buf)); + return reply; +} + +bool +RoutableFactories60::UpdateDocumentReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const UpdateDocumentReply &reply = static_cast<const UpdateDocumentReply&>(obj); + buf.putBoolean(reply.getWasFound()); + buf.putLong(reply.getHighestModificationTimestamp()); + return true; +} + +DocumentMessage::UP +RoutableFactories60::VisitorInfoMessageFactory::doDecode(document::ByteBuffer &buf) const +{ + auto msg = std::make_unique<VisitorInfoMessage>(); + + int32_t len = decodeInt(buf); + msg->getFinishedBuckets().reserve(len); + for (int32_t i = 0; i < len; i++) { + int64_t val; + buf.getLong(val); // NOT using getLongNetwork + msg->getFinishedBuckets().emplace_back(val); + } + msg->setErrorMessage(decodeString(buf)); + + return msg; +} + +bool +RoutableFactories60::VisitorInfoMessageFactory::doEncode(const DocumentMessage &obj, vespalib::GrowableByteBuffer &buf) const +{ + const VisitorInfoMessage &msg = static_cast<const VisitorInfoMessage&>(obj); + + buf.putInt(msg.getFinishedBuckets().size()); + for (const auto & bucketId : msg.getFinishedBuckets()) { + uint64_t val = bucketId.getRawId(); + buf.putBytes((const char*)&val, 8); + } + buf.putString(msg.getErrorMessage()); + + return true; +} + +DocumentReply::UP +RoutableFactories60::VisitorInfoReplyFactory::doDecode(document::ByteBuffer &) const +{ + return std::make_unique<VisitorReply>(DocumentProtocol::REPLY_VISITORINFO); +} + +bool +RoutableFactories60::VisitorInfoReplyFactory::doEncode(const DocumentReply &, vespalib::GrowableByteBuffer &) const +{ + return true; +} + +DocumentReply::UP +RoutableFactories60::WrongDistributionReplyFactory::doDecode(document::ByteBuffer &buf) const +{ + auto reply = std::make_unique<WrongDistributionReply>(); + reply->setSystemState(decodeString(buf)); + return reply; +} + +bool +RoutableFactories60::WrongDistributionReplyFactory::doEncode(const DocumentReply &obj, vespalib::GrowableByteBuffer &buf) const +{ + const WrongDistributionReply &reply = static_cast<const WrongDistributionReply&>(obj); + buf.putString(reply.getSystemState()); + return true; +} + +string +RoutableFactories60::decodeString(document::ByteBuffer &in) +{ + int32_t len = decodeInt(in); + string ret = string(in.getBufferAtPos(), len); + in.incPos(len); + return ret; +} + +bool +RoutableFactories60::decodeBoolean(document::ByteBuffer &in) +{ + char ret; + in.getBytes(&ret, 1); + return (bool)ret; +} + +int32_t +RoutableFactories60::decodeInt(document::ByteBuffer &in) +{ + int32_t ret; + in.getIntNetwork(ret); + return ret; +} + +int64_t +RoutableFactories60::decodeLong(document::ByteBuffer &in) +{ + int64_t ret; + in.getLongNetwork(ret); + return ret; +} + +document::DocumentId +RoutableFactories60::decodeDocumentId(document::ByteBuffer &in) +{ + nbostream stream(in.getBufferAtPos(), in.getRemaining()); + document::DocumentId ret(stream); + in.incPos(stream.rp()); + return ret; +} + +void +RoutableFactories60::encodeDocumentId(const document::DocumentId &id, vespalib::GrowableByteBuffer &out) +{ + string str = id.toString(); + out.putBytes(str.c_str(), str.size() + 1); +} + +void RoutableFactories60::decodeTasCondition(DocumentMessage & docMsg, document::ByteBuffer & buf) { + auto & msg = static_cast<TestAndSetMessage &>(docMsg); + msg.setCondition(TestAndSetCondition(decodeString(buf))); +} + +void RoutableFactories60::encodeTasCondition(vespalib::GrowableByteBuffer & buf, const DocumentMessage & docMsg) { + auto & msg = static_cast<const TestAndSetMessage &>(docMsg); + buf.putString(msg.getCondition().getSelection()); +} + void RoutableFactories60::doEncodeBucketSpace( vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) { @@ -48,4 +956,4 @@ string RoutableFactories60::doDecodeBucketSpace(document::ByteBuffer& buf) { return decodeString(buf); } -}
\ No newline at end of file +} diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h b/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h index e91c9a773f2..75404f1dea1 100644 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h +++ b/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h @@ -1,41 +1,421 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// @author Vegard Sjonfjell #pragma once -#include "routablefactories52.h" +#include <vespa/document/util/bytebuffer.h> +#include <vespa/vespalib/util/growablebytebuffer.h> +#include "iroutablefactory.h" +#include <vespa/documentapi/messagebus/messages/putdocumentmessage.h> +#include <vespa/documentapi/messagebus/messages/removedocumentmessage.h> +#include <vespa/documentapi/messagebus/messages/updatedocumentmessage.h> + +namespace document { class DocumentTypeRepo; } + +/** + * Utility class for invoking setApproxSize on a DocumentMessage with the delta + * between the read position of a ByteBuffer at construction and destruction + * time. The assumption being made is that the in-memory footprint of a message + * is reasonably close to its wire-serialized form. + */ +class ScopedApproxSizeSetter { +public: + ScopedApproxSizeSetter(documentapi::DocumentMessage& msg, + const document::ByteBuffer& buf) + : _msg(msg), + _buf(buf), + _posBefore(_buf.getPos()) + { + } + + ~ScopedApproxSizeSetter() { + _msg.setApproxSize(static_cast<uint32_t>(_buf.getPos() - _posBefore)); + } + +private: + documentapi::DocumentMessage& _msg; + const document::ByteBuffer& _buf; + const size_t _posBefore; +}; namespace documentapi { + +template<typename MessageType, typename FactoryType> +DocumentMessage::UP +decodeMessage(const FactoryType * self, document::ByteBuffer & buf) { + auto msg = std::make_unique<MessageType>(); + ScopedApproxSizeSetter sizeSetter(*msg, buf); + self->decodeInto(*msg, buf); + return msg; +} + /** * This class encapsulates all the {@link RoutableFactory} classes needed to implement factories for the document * routable. When adding new factories to this class, please KEEP THE THEM ORDERED alphabetically like they are now. */ -class RoutableFactories60 : public RoutableFactories52 { +class RoutableFactories60 { public: RoutableFactories60() = delete; - // TODO dedupe bucket space codec code + /** + * Implements the shared factory logic required for {@link DocumentMessage} objects, and it offers a more + * convenient interface for implementing {@link RoutableFactory}. + */ + class DocumentMessageFactory : public IRoutableFactory { + protected: + /** + * This method encodes the given message into the given byte buffer. You are guaranteed to only receive messages of + * the type that this factory was registered for. + * + * This method is NOT exception safe. Return false to signal failure. + * + * @param msg The message to encode. + * @param buf The byte buffer to write to. + * @return True if the message was encoded. + */ + virtual bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const = 0; + + /** + * This method decodes a message from the given byte buffer. You are guaranteed to only receive byte buffers + * generated by a previous call to {@link #doEncode(DocumentMessage, GrowableByteBuffer)}. + * + * This method is NOT exception safe. Return null to signal failure. + * + * @param buf The byte buffer to read from. + * @return The decoded message. + */ + virtual DocumentMessage::UP doDecode(document::ByteBuffer &buf) const = 0; - class CreateVisitorMessageFactory : public RoutableFactories52::CreateVisitorMessageFactory { - bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const override; - string decodeBucketSpace(document::ByteBuffer&) const override; public: - CreateVisitorMessageFactory(const document::DocumentTypeRepo& r) - : RoutableFactories52::CreateVisitorMessageFactory(r) {} + bool encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const override; + mbus::Routable::UP decode(document::ByteBuffer &in, const LoadTypeSet& loadTypes) const override; }; - class StatBucketMessageFactory : public RoutableFactories52::StatBucketMessageFactory { - bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const override; - string decodeBucketSpace(document::ByteBuffer&) const override; + /** + * Implements the shared factory logic required for {@link DocumentReply} objects, and it offers a more + * convenient interface for implementing {@link RoutableFactory}. + */ + class DocumentReplyFactory : public IRoutableFactory { + protected: + /** + * This method encodes the given reply into the given byte buffer. You are guaranteed to only receive + * replies of the type that this factory was registered for. + * + * This method is NOT exception safe. Return false to signal failure. + * + * @param reply The reply to encode. + * @param buf The byte buffer to write to. + * @return True if the message was encoded. + */ + virtual bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const = 0; + + /** + * This method decodes a reply from the given byte buffer. You are guaranteed to only receive byte buffers + * generated by a previous call to {@link #doEncode(DocumentReply, GrowableByteBuffer)}. + * + * This method is NOT exception safe. Return null to signal failure. + * + * @param buf The byte buffer to read from. + * @return The decoded reply. + */ + virtual DocumentReply::UP doDecode(document::ByteBuffer &buf) const = 0; + public: - StatBucketMessageFactory() = default; + bool encode(const mbus::Routable &obj, vespalib::GrowableByteBuffer &out) const override; + mbus::Routable::UP decode(document::ByteBuffer &in, const LoadTypeSet& loadTypes) const override; }; - class GetBucketListMessageFactory : public RoutableFactories52::GetBucketListMessageFactory { - bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const override; - string decodeBucketSpace(document::ByteBuffer&) const override; + //////////////////////////////////////////////////////////////////////////////// + // + // Factories + // + //////////////////////////////////////////////////////////////////////////////// + class CreateVisitorMessageFactory : public DocumentMessageFactory { + const document::DocumentTypeRepo &_repo; + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + + virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; + virtual string decodeBucketSpace(document::ByteBuffer&) const; + public: + CreateVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + }; + class CreateVisitorReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class DestroyVisitorMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class DestroyVisitorReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class DocumentIgnoredReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class DocumentListMessageFactory : public DocumentMessageFactory { + const document::DocumentTypeRepo &_repo; + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + public: + DocumentListMessageFactory(const document::DocumentTypeRepo &r) + : _repo(r) {} + }; + class DocumentListReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class DocumentSummaryMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class DocumentSummaryReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class EmptyBucketsMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class EmptyBucketsReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class GetBucketListMessageFactory : public DocumentMessageFactory { + virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; + virtual string decodeBucketSpace(document::ByteBuffer&) const; + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class GetBucketListReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class GetBucketStateMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class GetBucketStateReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class GetDocumentMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class GetDocumentReplyFactory : public DocumentReplyFactory { + const document::DocumentTypeRepo &_repo; + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &msg, vespalib::GrowableByteBuffer &buf) const override; + public: + GetDocumentReplyFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + }; + class MapVisitorMessageFactory : public DocumentMessageFactory { + const document::DocumentTypeRepo &_repo; + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; public: - GetBucketListMessageFactory() = default; + MapVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} }; + class MapVisitorReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class PutDocumentMessageFactory : public DocumentMessageFactory { + protected: + const document::DocumentTypeRepo &_repo; + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { + return decodeMessage<PutDocumentMessage>(this, buf); + } + + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + public: + void decodeInto(PutDocumentMessage & msg, document::ByteBuffer & buf) const; + PutDocumentMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + }; + class PutDocumentReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class RemoveDocumentMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { + return decodeMessage<RemoveDocumentMessage>(this, buf); + } + + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + public: + void decodeInto(RemoveDocumentMessage & msg, document::ByteBuffer & buf) const; + }; + class RemoveDocumentReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class RemoveLocationMessageFactory : public DocumentMessageFactory { + const document::DocumentTypeRepo &_repo; + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + public: + RemoveLocationMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + }; + class RemoveLocationReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class SearchResultMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class SearchResultReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class StatBucketMessageFactory : public DocumentMessageFactory { + virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; + virtual string decodeBucketSpace(document::ByteBuffer&) const; + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class StatBucketReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class StatDocumentMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class StatDocumentReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class UpdateDocumentMessageFactory : public DocumentMessageFactory { + protected: + const document::DocumentTypeRepo &_repo; + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override { + return decodeMessage<UpdateDocumentMessage>(this, buf); + } + + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + public: + void decodeInto(UpdateDocumentMessage & msg, document::ByteBuffer & buf) const; + UpdateDocumentMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + }; + class UpdateDocumentReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class VisitorInfoMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class VisitorInfoReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class WrongDistributionReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + class QueryResultMessageFactory : public DocumentMessageFactory { + protected: + DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; + }; + class QueryResultReplyFactory : public DocumentReplyFactory { + protected: + DocumentReply::UP doDecode(document::ByteBuffer &buf) const override; + bool doEncode(const DocumentReply &reply, vespalib::GrowableByteBuffer &buf) const override; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // Utilities + // + /////////////////////////////////////////////////////////////////////////// + + /** + * This is a complement for the vespalib::GrowableByteBuffer.putString() method. + * + * @param in The byte buffer to read from. + * @return The decoded string. + */ + static string decodeString(document::ByteBuffer &in); + + /** + * This is a complement for the vespalib::GrowableByteBuffer.putBoolean() method. + * + * @param in The byte buffer to read from. + * @return The decoded bool. + */ + static bool decodeBoolean(document::ByteBuffer &in); + + /** + * Convenience method to decode a 32-bit int from the given byte buffer. + * + * @param in The byte buffer to read from. + * @return The decoded int. + */ + static int32_t decodeInt(document::ByteBuffer &in); + + /** + * Convenience method to decode a 64-bit int from the given byte buffer. + * + * @param in The byte buffer to read from. + * @return The decoded int. + */ + static int64_t decodeLong(document::ByteBuffer &in); + + /** + * Convenience method to decode a document id from the given byte buffer. + * + * @param in The byte buffer to read from. + * @return The decoded document id. + */ + static document::DocumentId decodeDocumentId(document::ByteBuffer &in); + + /** + * Convenience method to encode a document id to the given byte buffer. + * + * @param id The document id to encode. + * @param out The byte buffer to write to. + */ + static void encodeDocumentId(const document::DocumentId &id, + vespalib::GrowableByteBuffer &out); + static void decodeTasCondition(DocumentMessage & docMsg, document::ByteBuffer & buf); + static void encodeTasCondition(vespalib::GrowableByteBuffer & buf, const DocumentMessage & docMsg); static void doEncodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf); static string doDecodeBucketSpace(document::ByteBuffer&); }; |