Get document xattr._sync.rev value using SDK 3 sub document

Hi Guys,
I am trying to get xattr._sync.rev value from an document. How do i do it? Currently i am trying with below method

List docIds=Arrays.asList(“C::100001”,“C::100007”);
for (String metaId : docIds) {
LookupInResult tst=coll.lookupIn(metaId,Collections.singletonList(LookupInSpec.get(LookupInMacro.DOCUMENT).xattr()),LookupInOptions.lookupInOptions().timeout(Duration.ofMinutes(2)));
if(tst!=null)
tst.contentAsObject(0).getString(“rev”);

Is this a correct way?

Thanks.

Hi Nagarajan,

You’ve almost got it. Try this:

public static Optional<String> getSyncGatewayRevision(Collection c,
                                                      String documentId) {
  try {
    LookupInResult result = c.lookupIn(documentId,
        singletonList(LookupInSpec.get("_sync.rev").xattr()));
    return Optional.of(result.contentAs(0, String.class));

  } catch (PathNotFoundException notFound) {
    // document doesn't have Sync Gateway revision
    return Optional.empty();
  }
}

However, I’m not sure if accessing the revision like this is supported. To quote @jens in the SG REST Admin API gives misleading response - #7 by benjamin_glatzeder thread:

the best way to get the revision of a document is to use the SG REST API. Just GET the document and look at the _rev property of the response. Or if you’ve just created/updated the document with a PUT, the revision will also be available in the response.

Thanks,
David

Thanks David. I am always getting subdocument path is not correct exception but i see the metadata section this attribute is available.

LookupInResult{encoded=[SubdocField{status=UNKNOWN, value=, path=’_sync.rev’}], cas=0x1626101535fa0000}

Any idea why?

Thanks.

Hi Nagarajan,

i see the metadata section this attribute is available.

Can you show me what you mean?

Thanks,
David

Hi David,
i see the _sync.rev is available under meta data section but above code is not those values
image

Hi Nagarajan,

Can you post the stack trace please, including the exception name?

Thanks,
David

Hi David, Is this fine?
com.couchbase.client.core.error.CouchbaseException: Unknown SubDocument response code {“completed”:true,“coreId”:“0x6ae3259a00000001”,“idempotent”:true,“index”:0,“lastChannelId”:“6AE3259A00000001/0000000014D355DB”,“lastDispatchedFrom”:“XXXX,“lastDispatchedTo”:“XXXX”,“path”:”_sync",“requestId”:201,“requestType”:“SubdocGetRequest”,“retried”:0,“service”:{“bucket”:“poc”,“collection”:"_default",“documentId”:“C::XXXXX_157”,“opaque”:“0x131”,“scope”:"_default",“type”:“kv”},“status”:“SUBDOC_FAILURE”,“subdocStatus”:“UNKNOWN”,“timeoutMs”:120000,“timings”:{“dispatchMicros”:1025887,“totalMicros”:1026761,“serverMicros”:0}}
at com.couchbase.client.core.io.netty.kv.MemcacheProtocol.mapSubDocumentError(MemcacheProtocol.java:657)
at com.couchbase.client.core.msg.kv.SubdocGetRequest.decode(SubdocGetRequest.java:142)
at com.couchbase.client.core.msg.kv.SubdocGetRequest.decode(SubdocGetRequest.java:45)
at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decodeAndComplete(KeyValueMessageHandler.java:319)
at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decode(KeyValueMessageHandler.java:299)
at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.channelRead(KeyValueMessageHandler.java:226)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.io.netty.kv.MemcacheProtocolVerificationHandler.channelRead(MemcacheProtocolVerificationHandler.java:84)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:321)
at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.deps.io.netty.handler.flush.FlushConsolidationHandler.channelRead(FlushConsolidationHandler.java:152)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at com.couchbase.client.core.deps.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at com.couchbase.client.core.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at com.couchbase.client.core.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at com.couchbase.client.core.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:813)

Hi David,
Any suggestion?

Thanks.

Hi Nagarajan,

I’m concerned about that “Unknown SubDocument response code” message.

What versions of Couchbase Server and SDK 3 are you using?

Can you try with the latest SDK: 3.0.7?

Thanks,
David

Hi David,
I have tried with SDK 3.0.7 and Couch base 6.5, i am getting same error.

at com.couchbase.client.core.io.netty.kv.MemcacheProtocol.mapSubDocumentError(MemcacheProtocol.java:659)
at com.couchbase.client.core.msg.kv.SubdocGetRequest.decode(SubdocGetRequest.java:142)
at com.couchbase.client.core.msg.kv.SubdocGetRequest.decode(SubdocGetRequest.java:45)
at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decodeAndComplete(KeyValueMessageHandler.java:321)
at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.decode(KeyValueMessageHandler.java:301)
at com.couchbase.client.core.io.netty.kv.KeyValueMessageHandler.channelRead(KeyValueMessageHandler.java:228)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.io.netty.kv.MemcacheProtocolVerificationHandler.channelRead(MemcacheProtocolVerificationHandler.java:84)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at com.couchbase.client.core.deps.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.deps.io.netty.handler.flush.FlushConsolidationHandler.channelRead(FlushConsolidationHandler.java:152)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at com.couchbase.client.core.deps.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at com.couchbase.client.core.deps.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at com.couchbase.client.core.deps.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at com.couchbase.client.core.deps.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at com.couchbase.client.core.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at com.couchbase.client.core.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at com.couchbase.client.core.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:813)

Hi Nagarajan,

Does the server’s memcached.log contain more details about the failure?

I have a hunch it might be related to access control. Can you try with an admin user?

Thanks,
David

Hi David, I have tried with Admin user, it is working fine. So to make this work do we need admin user? or we have to provide a specific access to the user type?

Appreciate your time and help.

Thanks.

Aha! That’s great news. Make sure the user has the Data Reader role for the bucket, and you should be fine.

Hi David,
I tired with Data Reader user but it is throwing the old error, but it works fine with Full Admin role.
com.couchbase.client.core.error.CouchbaseException: Unknown SubDocument response code.
Below is the role access we have provided for the problematic user, anything missing?

Thanks.

Hi Nagarajan,

Looks like I gave you some bad advice. The required role is Bucket Roles > Application Access (not “Data Reader”, despite what the docs say). The “Unknown SubDocument response code” is code 0x24… which is “No Access”. I’ll follow up with the KV engineering team, but in the mean time let me know if adding that “Application Access” role gets you unstuck.

Thanks,
David

Hi David,
Yes i tried with Application Access which resolved the issue so as of now i use Application Access but please let us know if you hear back anything from KV team

Thanks.

Hi Nagarajan,

Thanks for your patience. As it turns out, the SystemXattrRead permission is required to access “system” XATTRs. (A system XATTR is one whose name starts with an underscore.)

The roles with this permission are:

  • Mobile Service > Sync Gateway
  • Bucket Roles > Application Access
  • Data Service > Data Backup & Restore
  • Administrative Roles > Full Admin

For non-system XATTRs, the “Data Reader” role is sufficient.

Thanks,
David