william
February 26, 2020, 8:46am
1
Hi
There is a bug with subdoc mutate requests in the latest java sdk (3.0.1) when using both document flags and an expiration, e.g.:
collection.mutateIn(keyname, Arrays.asList(
upsert("a", "b"),
upsert("c", "d"),
),
mutateInOptions().storeSemantics(StoreSemantics.UPSERT).expiry(Duration.ofSeconds(60 * 60 * 24)));
This generates the following packet:
As seen the expiration is being read as part of the flags (0x01
) and therefore the wrong value. This command then gives an error, presumably for an incorrect expiration value (More than 30 days but has passed).
The flags and the expiration are the wrong order here: https://github.com/couchbase/couchbase-jvm-clients/blob/master/core-io/src/main/java/com/couchbase/client/core/msg/kv/SubdocMutateRequest.java#L117-L123
The old sdk writes them in the correct order (expiration first): https://github.com/couchbase/couchbase-jvm-core/blob/63ede7f5811c818c7519200761bf4eae02b8b437/src/main/java/com/couchbase/client/core/endpoint/kv/KeyValueHandler.java#L883-L907
Thanks
1 Like
daschl
February 26, 2020, 8:58am
2
@william thanks for reporting! We’ll take a look soon
Yes, thank you for the detailed investigation @william . I’ve logged Loading... for this.
For now, the workaround is to do a set-and-replace on the document - e.g. full document rather than Sub-Document.
william
February 27, 2020, 12:44am
4
Thanks. I’ve just rebuilt the jar myself with the fix and that is working ok.
diff:
diff --git a/core-io/src/main/java/com/couchbase/client/core/msg/kv/SubdocMutateRequest.java b/core-io/src/main/java/com/couchbase/client/core/msg/kv/SubdocMutateRequest.java
index 3615bbd..b3f057c 100644
--- a/core-io/src/main/java/com/couchbase/client/core/msg/kv/SubdocMutateRequest.java
+++ b/core-io/src/main/java/com/couchbase/client/core/msg/kv/SubdocMutateRequest.java
@@ -115,12 +115,12 @@ public class SubdocMutateRequest extends BaseKeyValueRequest<SubdocMutateRespons
key = encodedKeyWithCollection(alloc, ctx);
extras = alloc.buffer();
- if (flags != 0) {
- extras.writeByte(flags);
- }
if (expiration != 0) {
extras.writeInt((int) expiration);
}
+ if (flags != 0) {
+ extras.writeByte(flags);
+ }
Yes, that’s the fix. I’ve got it checked in today so it should make the next java-client release. Thanks again for reporting this!