Java Code Examples for com.couchbase.client.core.DocumentConcurrentlyModifiedException

The following examples show how to use com.couchbase.client.core.DocumentConcurrentlyModifiedException. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: couchbase-jvm-core   Source File: ObserveTest.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * When the returned observe response is from the master but it contains a different cas
 * than requested, it is an indication that the document has been concurrently modified.
 */
@Test(expected = DocumentConcurrentlyModifiedException.class)
public void shouldFailWhenConcurrentlyModified() {
    CoreContext ctx = new CoreContext(ENV, null);
    ClusterFacade cluster = mock(ClusterFacade.class);
    when(cluster.ctx()).thenReturn(ctx);

    // Setup a mocked config which returns no replica configured
    CouchbaseBucketConfig bucketConfig = mock(CouchbaseBucketConfig.class);
    when(bucketConfig.numberOfReplicas()).thenReturn(1);
    ClusterConfig clusterConfig = mock(ClusterConfig.class);
    when(clusterConfig.bucketConfig("bucket")).thenReturn(bucketConfig);
    GetClusterConfigResponse clusterConfigResponse = new GetClusterConfigResponse(
            clusterConfig, ResponseStatus.SUCCESS
    );
    when(cluster.send(isA(GetClusterConfigRequest.class))).thenReturn(
            Observable.just((CouchbaseResponse) clusterConfigResponse)
    );
    ObserveResponse observeResponse = new ObserveResponse(
            ResponseStatus.SUCCESS, KeyValueStatus.SUCCESS.code(),
            ObserveResponse.ObserveStatus.FOUND_NOT_PERSISTED.value(),
            true,
            45678,
            "bucket",
            mock(CouchbaseRequest.class)
    );
    when(cluster.send(isA(ObserveRequest.class))).thenReturn(
            Observable.just((CouchbaseResponse) observeResponse)
    );

    Observable<Boolean> result = Observe.call(
            cluster, "bucket", "id", 1234, false, Observe.PersistTo.NONE, Observe.ReplicateTo.ONE,
            BestEffortRetryStrategy.INSTANCE
    );
    result
        .timeout(5, TimeUnit.SECONDS)
        .toBlocking()
        .single();
}
 
Example 2
Source Project: couchbase-jvm-core   Source File: ObserveViaCAS.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Build an {@link ObserveItem} state from a {@link ObserveResponse}.
 *
 * @param id the observed key.
 * @param response the {@link ObserveResponse} received for that key.
 * @param cas the cas that we expect.
 * @param remove true if this is a remove operation, false otherwise.
 * @param persistIdentifier the {@link ObserveResponse.ObserveStatus} to watch for in persistence.
 * @param replicaIdentifier the {@link ObserveResponse.ObserveStatus} to watch for in replication.
 * @throws DocumentConcurrentlyModifiedException if the cas observed on master copy isn't the expected one.
 */
public ObserveItem(String id, ObserveResponse response, long cas, boolean remove,
                   ObserveResponse.ObserveStatus persistIdentifier,
                   ObserveResponse.ObserveStatus replicaIdentifier) {
    int replicated = 0;
    int persisted = 0;
    boolean persistedMaster = false;


    if (response.content() != null && response.content().refCnt() > 0) {
        response.content().release();
    }
    ObserveResponse.ObserveStatus status = response.observeStatus();

    if (response.status() == ResponseStatus.ACCESS_ERROR) {
        String details = ResponseStatusDetails.stringify(response.status(), response.statusDetails());
        throw new AuthenticationException("The application is not authorized to perform the \"observe\" "
            + "operation, make sure you have read privileges on this bucket: " + details);
    }

    // the CAS values always need to match up to make sure we are still observing the right
    // document. The only exclusion from that rule is when a real delete is returned, because
    // then the cas value is 0.
    boolean validCas = cas == response.cas()
            || (remove && response.cas() == 0 && status == persistIdentifier);

    if (response.master()) {
        if (!validCas) {
            throw new DocumentConcurrentlyModifiedException("The CAS on the active node "
                    + "changed for ID \"" + id + "\", indicating it has been modified in the "
                    + "meantime.", cas);
        }

        if (status == persistIdentifier) {
            persisted++;
            persistedMaster = true;
        }
    } else if (validCas) {
        if (status == persistIdentifier) {
            persisted++;
            replicated++;
        } else if (status == replicaIdentifier) {
            replicated++;
        }
    }

    this.replicated = replicated;
    this.persisted = persisted;
    this.persistedMaster = persistedMaster;
}