Search in sources :

Example 1 with DocumentAlreadyAliveException

use of com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException in project couchbase-jvm-clients by couchbase.

the class SubdocMutateRequest method decode.

@Override
public SubdocMutateResponse decode(final ByteBuf response, KeyValueChannelContext ctx) {
    Optional<ByteBuf> maybeBody = body(response);
    short rawOverallStatus = status(response);
    ResponseStatus overallStatus = decodeStatus(response);
    Optional<CouchbaseException> error = Optional.empty();
    SubDocumentField[] values = null;
    if (maybeBody.isPresent()) {
        ByteBuf body = maybeBody.get();
        // If there's a multi-mutation failure we only get the first failure back
        if (rawOverallStatus == Status.SUBDOC_MULTI_PATH_FAILURE.status() || rawOverallStatus == Status.SUBDOC_MULTI_PATH_FAILURE_DELETED.status()) {
            byte index = body.readByte();
            short opStatusRaw = body.readShort();
            SubDocumentOpResponseStatus opStatus = decodeSubDocumentStatus(opStatusRaw);
            Command c = commands.get(index);
            error = Optional.of(mapSubDocumentError(this, opStatus, c.path, c.originalIndex));
            values = new SubDocumentField[0];
        } else if (overallStatus.success()) {
            // "For successful multi mutations, there will be zero or more results; each of the results containing a value."
            values = new SubDocumentField[commands.size()];
            // Check we can read index (1 byte) and status (2 bytes), else we're done
            int INDEX_PLUS_STATUS_FIELDS_BYTES = 3;
            while (body.isReadable(INDEX_PLUS_STATUS_FIELDS_BYTES)) {
                byte index = body.readByte();
                Command command = commands.get(index);
                // "Status of the mutation. If the status indicates success, the next two fields are applicable. If it is an
                // error then the result has been fully read"
                short statusRaw = body.readShort();
                SubDocumentOpResponseStatus status = decodeSubDocumentStatus(statusRaw);
                if (status != SubDocumentOpResponseStatus.SUCCESS) {
                    CouchbaseException err = mapSubDocumentError(this, status, command.path, command.originalIndex);
                    SubDocumentField op = new SubDocumentField(status, Optional.of(err), Bytes.EMPTY_BYTE_ARRAY, command.path, command.type);
                    values[command.originalIndex] = op;
                } else {
                    int valueLength = body.readInt();
                    byte[] value = new byte[valueLength];
                    body.readBytes(value, 0, valueLength);
                    SubDocumentField op = new SubDocumentField(status, Optional.empty(), value, command.path, command.type);
                    values[command.originalIndex] = op;
                }
            }
        }
    }
    if (values == null) {
        values = new SubDocumentField[0];
    }
    // Handle any document-level failures here
    if (rawOverallStatus == Status.SUBDOC_DOC_NOT_JSON.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.DOC_NOT_JSON);
        error = Optional.of(new DocumentNotJsonException(e));
    } else if (rawOverallStatus == Status.SUBDOC_DOC_TOO_DEEP.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.DOC_TOO_DEEP);
        error = Optional.of(new DocumentTooDeepException(e));
    } else if (rawOverallStatus == Status.SUBDOC_XATTR_INVALID_KEY_COMBO.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.XATTR_INVALID_KEY_COMBO);
        error = Optional.of(new XattrInvalidKeyComboException(e));
    } else if (rawOverallStatus == Status.SUBDOC_CAN_ONLY_REVIVE_DELETED_DOCUMENTS.status()) {
        SubDocumentErrorContext e = createSubDocumentExceptionContext(SubDocumentOpResponseStatus.CAN_ONLY_REVIVE_DELETED_DOCUMENTS);
        error = Optional.of(new DocumentAlreadyAliveException(e));
    }
    // Do not handle SUBDOC_INVALID_COMBO here, it indicates a client-side bug
    return new SubdocMutateResponse(overallStatus, error, values, cas(response), extractToken(ctx.mutationTokensEnabled(), partition(), response, ctx.bucket().get()));
}
Also used : DocumentNotJsonException(com.couchbase.client.core.error.subdoc.DocumentNotJsonException) CompositeByteBuf(com.couchbase.client.core.deps.io.netty.buffer.CompositeByteBuf) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) SubDocumentErrorContext(com.couchbase.client.core.error.context.SubDocumentErrorContext) DocumentAlreadyAliveException(com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException) CouchbaseException(com.couchbase.client.core.error.CouchbaseException) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) DocumentTooDeepException(com.couchbase.client.core.error.subdoc.DocumentTooDeepException) XattrInvalidKeyComboException(com.couchbase.client.core.error.subdoc.XattrInvalidKeyComboException)

Example 2 with DocumentAlreadyAliveException

use of com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException in project couchbase-jvm-clients by couchbase.

the class SubdocMutateIntegrationTest method reviveDocumentOnAlreadyAliveDocument.

@IgnoreWhen(missesCapabilities = { Capabilities.SUBDOC_REVIVE_DOCUMENT })
@Test
void reviveDocumentOnAlreadyAliveDocument() {
    String docId = docId();
    JsonObject body = JsonObject.create().put("foo", "bar");
    coll.insert(docId, body);
    try {
        coll.mutateIn(docId, Collections.singletonList(upsert("foo", "bar").xattr()), MutateInOptions.mutateInOptions().accessDeleted(true).storeSemantics(StoreSemantics.REVIVE));
        fail();
    } catch (DocumentAlreadyAliveException ignored) {
        assertEquals(CAN_ONLY_REVIVE_DELETED_DOCUMENTS.name(), ignored.context().exportAsMap().get("subdocStatus"));
    }
}
Also used : DocumentAlreadyAliveException(com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException) JsonObject(com.couchbase.client.java.json.JsonObject) IgnoreWhen(com.couchbase.client.test.IgnoreWhen) JavaIntegrationTest(com.couchbase.client.java.util.JavaIntegrationTest) Test(org.junit.jupiter.api.Test)

Aggregations

DocumentAlreadyAliveException (com.couchbase.client.core.error.subdoc.DocumentAlreadyAliveException)2 ByteBuf (com.couchbase.client.core.deps.io.netty.buffer.ByteBuf)1 CompositeByteBuf (com.couchbase.client.core.deps.io.netty.buffer.CompositeByteBuf)1 CouchbaseException (com.couchbase.client.core.error.CouchbaseException)1 SubDocumentErrorContext (com.couchbase.client.core.error.context.SubDocumentErrorContext)1 DocumentNotJsonException (com.couchbase.client.core.error.subdoc.DocumentNotJsonException)1 DocumentTooDeepException (com.couchbase.client.core.error.subdoc.DocumentTooDeepException)1 XattrInvalidKeyComboException (com.couchbase.client.core.error.subdoc.XattrInvalidKeyComboException)1 ResponseStatus (com.couchbase.client.core.msg.ResponseStatus)1 JsonObject (com.couchbase.client.java.json.JsonObject)1 JavaIntegrationTest (com.couchbase.client.java.util.JavaIntegrationTest)1 IgnoreWhen (com.couchbase.client.test.IgnoreWhen)1 Test (org.junit.jupiter.api.Test)1