Search in sources :

Example 1 with CollectionIdentifier

use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.

the class KeyValueIntegrationTest method shortCircuitCollectionsIfNotAvailable.

@Test
@IgnoreWhen(hasCapabilities = { Capabilities.COLLECTIONS })
void shortCircuitCollectionsIfNotAvailable() {
    String id = UUID.randomUUID().toString();
    byte[] content = "hello, world".getBytes(UTF_8);
    InsertRequest insertRequest = new InsertRequest(id, content, 0, 0, kvTimeout, core.context(), new CollectionIdentifier(config().bucketname(), Optional.of(CollectionIdentifier.DEFAULT_SCOPE), Optional.of("my_collection_name")), env.retryStrategy(), Optional.empty(), null);
    core.send(insertRequest);
    ExecutionException exception = assertThrows(ExecutionException.class, () -> insertRequest.response().get());
    assertTrue(exception.getCause() instanceof FeatureNotAvailableException);
    InsertRequest insertRequest2 = new InsertRequest(id, content, 0, 0, kvTimeout, core.context(), new CollectionIdentifier(config().bucketname(), Optional.of("my_custom_scope"), Optional.of(CollectionIdentifier.DEFAULT_COLLECTION)), env.retryStrategy(), Optional.empty(), null);
    core.send(insertRequest2);
    exception = assertThrows(ExecutionException.class, () -> insertRequest2.response().get());
    assertTrue(exception.getCause() instanceof FeatureNotAvailableException);
}
Also used : FeatureNotAvailableException(com.couchbase.client.core.error.FeatureNotAvailableException) InsertRequest(com.couchbase.client.core.msg.kv.InsertRequest) ExecutionException(java.util.concurrent.ExecutionException) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) IgnoreWhen(com.couchbase.client.test.IgnoreWhen) CoreIntegrationTest(com.couchbase.client.core.util.CoreIntegrationTest) Test(org.junit.jupiter.api.Test)

Example 2 with CollectionIdentifier

use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.

the class AsyncCollection method mutateInRequest.

/**
 * Helper method to create the underlying subdoc mutate request.
 *
 * @param id the outer document ID.
 * @param specs the spec which specifies the type of mutations to perform.
 * @param opts custom options to modify the mutation options.
 * @return the subdoc mutate request.
 */
CompletableFuture<SubdocMutateRequest> mutateInRequest(final String id, final List<MutateInSpec> specs, final MutateInOptions.Built opts, final Duration timeout) {
    notNullOrEmpty(id, "Id", () -> ReducedKeyValueErrorContext.create(id, collectionIdentifier));
    notNullOrEmpty(specs, "MutateInSpecs", () -> ReducedKeyValueErrorContext.create(id, collectionIdentifier));
    if (specs.isEmpty()) {
        throw SubdocMutateRequest.errIfNoCommands(ReducedKeyValueErrorContext.create(id, collectionIdentifier));
    } else if (specs.size() > SubdocMutateRequest.SUBDOC_MAX_FIELDS) {
        throw SubdocMutateRequest.errIfTooManyCommands(ReducedKeyValueErrorContext.create(id, collectionIdentifier));
    }
    final boolean requiresBucketConfig = opts.createAsDeleted() || opts.storeSemantics() == StoreSemantics.REVIVE;
    CompletableFuture<BucketConfig> bucketConfigFuture;
    if (requiresBucketConfig) {
        bucketConfigFuture = BucketConfigUtil.waitForBucketConfig(core, bucketName(), timeout).toFuture();
    } else {
        // Nothing will be using the bucket config so just provide null
        bucketConfigFuture = CompletableFuture.completedFuture(null);
    }
    return bucketConfigFuture.thenCompose(bucketConfig -> {
        RetryStrategy retryStrategy = opts.retryStrategy().orElse(environment.retryStrategy());
        JsonSerializer serializer = opts.serializer() == null ? environment.jsonSerializer() : opts.serializer();
        final RequestSpan span = environment.requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_MUTATE_IN, opts.parentSpan().orElse(null));
        ArrayList<SubdocMutateRequest.Command> commands = new ArrayList<>(specs.size());
        final RequestSpan encodeSpan = environment.requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_ENCODING, span);
        long start = System.nanoTime();
        try {
            for (int i = 0; i < specs.size(); i++) {
                MutateInSpec spec = specs.get(i);
                commands.add(spec.encode(serializer, i));
            }
        } finally {
            encodeSpan.end();
        }
        long end = System.nanoTime();
        // xattrs come first
        commands.sort(Comparator.comparing(v -> !v.xattr()));
        long expiry = opts.expiry().encode();
        SubdocMutateRequest request = new SubdocMutateRequest(timeout, coreContext, collectionIdentifier, bucketConfig, retryStrategy, id, opts.storeSemantics() == StoreSemantics.INSERT, opts.storeSemantics() == StoreSemantics.UPSERT, opts.storeSemantics() == StoreSemantics.REVIVE, opts.accessDeleted(), opts.createAsDeleted(), commands, expiry, opts.preserveExpiry(), opts.cas(), opts.durabilityLevel(), span);
        request.context().clientContext(opts.clientContext()).encodeLatency(end - start);
        final CompletableFuture<SubdocMutateRequest> future = new CompletableFuture<>();
        future.complete(request);
        return future;
    });
}
Also used : MutateInAccessor(com.couchbase.client.java.kv.MutateInAccessor) JsonSerializer(com.couchbase.client.java.codec.JsonSerializer) InsertOptions(com.couchbase.client.java.kv.InsertOptions) MutationResult(com.couchbase.client.java.kv.MutationResult) DEFAULT_REPLACE_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_REPLACE_OPTIONS) Validators.notNull(com.couchbase.client.core.util.Validators.notNull) PersistTo(com.couchbase.client.java.kv.PersistTo) ReplaceAccessor(com.couchbase.client.java.kv.ReplaceAccessor) TouchAccessor(com.couchbase.client.java.kv.TouchAccessor) DEFAULT_GET_AND_LOCK_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_GET_AND_LOCK_OPTIONS) CoreContext(com.couchbase.client.core.CoreContext) Duration(java.time.Duration) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) ClusterEnvironment(com.couchbase.client.java.env.ClusterEnvironment) GetAndTouchOptions(com.couchbase.client.java.kv.GetAndTouchOptions) LookupInMacro(com.couchbase.client.java.kv.LookupInMacro) BucketConfig(com.couchbase.client.core.config.BucketConfig) GetAllReplicasOptions(com.couchbase.client.java.kv.GetAllReplicasOptions) TouchRequest(com.couchbase.client.core.msg.kv.TouchRequest) RemoveOptions(com.couchbase.client.java.kv.RemoveOptions) ExistsOptions(com.couchbase.client.java.kv.ExistsOptions) InsertAccessor(com.couchbase.client.java.kv.InsertAccessor) DEFAULT_INSERT_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_INSERT_OPTIONS) GetAndTouchRequest(com.couchbase.client.core.msg.kv.GetAndTouchRequest) GetReplicaResult(com.couchbase.client.java.kv.GetReplicaResult) ExistsResult(com.couchbase.client.java.kv.ExistsResult) UnlockAccessor(com.couchbase.client.java.kv.UnlockAccessor) InvalidArgumentException(com.couchbase.client.core.error.InvalidArgumentException) Validators.notNullOrEmpty(com.couchbase.client.core.util.Validators.notNullOrEmpty) ReplicaHelper(com.couchbase.client.core.service.kv.ReplicaHelper) Expiry(com.couchbase.client.java.kv.Expiry) List(java.util.List) SubdocGetRequest(com.couchbase.client.core.msg.kv.SubdocGetRequest) GetAndLockRequest(com.couchbase.client.core.msg.kv.GetAndLockRequest) LookupInOptions(com.couchbase.client.java.kv.LookupInOptions) SubdocMutateRequest(com.couchbase.client.core.msg.kv.SubdocMutateRequest) GetAccessor(com.couchbase.client.java.kv.GetAccessor) GetRequest(com.couchbase.client.core.msg.kv.GetRequest) Optional(java.util.Optional) ReplaceRequest(com.couchbase.client.core.msg.kv.ReplaceRequest) DEFAULT_GET_ALL_REPLICAS_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_GET_ALL_REPLICAS_OPTIONS) DEFAULT_MUTATE_IN_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_MUTATE_IN_OPTIONS) GetOptions(com.couchbase.client.java.kv.GetOptions) UpsertAccessor(com.couchbase.client.java.kv.UpsertAccessor) RemoveAccessor(com.couchbase.client.java.kv.RemoveAccessor) GetResult(com.couchbase.client.java.kv.GetResult) ExistsAccessor(com.couchbase.client.java.kv.ExistsAccessor) TouchOptions(com.couchbase.client.java.kv.TouchOptions) UnlockOptions(com.couchbase.client.java.kv.UnlockOptions) DEFAULT_GET_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_GET_OPTIONS) RemoveRequest(com.couchbase.client.core.msg.kv.RemoveRequest) StoreSemantics(com.couchbase.client.java.kv.StoreSemantics) CompletableFuture(java.util.concurrent.CompletableFuture) CommonDurabilityOptions(com.couchbase.client.java.kv.CommonDurabilityOptions) GetMetaRequest(com.couchbase.client.core.msg.kv.GetMetaRequest) ArrayList(java.util.ArrayList) DEFAULT_TOUCH_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_TOUCH_OPTIONS) GetAnyReplicaOptions(com.couchbase.client.java.kv.GetAnyReplicaOptions) ReplaceOptions(com.couchbase.client.java.kv.ReplaceOptions) InsertRequest(com.couchbase.client.core.msg.kv.InsertRequest) TracingIdentifiers(com.couchbase.client.core.cnc.TracingIdentifiers) GetAndLockOptions(com.couchbase.client.java.kv.GetAndLockOptions) DEFAULT_REMOVE_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_REMOVE_OPTIONS) MutateInSpec(com.couchbase.client.java.kv.MutateInSpec) Stability(com.couchbase.client.core.annotation.Stability) DEFAULT_EXISTS_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_EXISTS_OPTIONS) DEFAULT_GET_ANY_REPLICA_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_GET_ANY_REPLICA_OPTIONS) UpsertOptions(com.couchbase.client.java.kv.UpsertOptions) LookupInResult(com.couchbase.client.java.kv.LookupInResult) MutateInOptions(com.couchbase.client.java.kv.MutateInOptions) MutateInResult(com.couchbase.client.java.kv.MutateInResult) DEFAULT_UPSERT_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_UPSERT_OPTIONS) UnlockRequest(com.couchbase.client.core.msg.kv.UnlockRequest) LookupInAccessor(com.couchbase.client.java.kv.LookupInAccessor) DEFAULT_GET_AND_TOUCH_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_GET_AND_TOUCH_OPTIONS) UpsertRequest(com.couchbase.client.core.msg.kv.UpsertRequest) LookupInSpec(com.couchbase.client.java.kv.LookupInSpec) DEFAULT_LOOKUP_IN_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_LOOKUP_IN_OPTIONS) Transcoder(com.couchbase.client.java.codec.Transcoder) DurabilityLevel(com.couchbase.client.core.msg.kv.DurabilityLevel) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) RetryStrategy(com.couchbase.client.core.retry.RetryStrategy) Core(com.couchbase.client.core.Core) ReducedKeyValueErrorContext(com.couchbase.client.core.error.context.ReducedKeyValueErrorContext) Comparator(java.util.Comparator) DEFAULT_UNLOCK_OPTIONS(com.couchbase.client.java.ReactiveCollection.DEFAULT_UNLOCK_OPTIONS) TimeoutConfig(com.couchbase.client.core.env.TimeoutConfig) SubdocCommandType(com.couchbase.client.core.msg.kv.SubdocCommandType) BucketConfigUtil(com.couchbase.client.core.util.BucketConfigUtil) ArrayList(java.util.ArrayList) MutateInSpec(com.couchbase.client.java.kv.MutateInSpec) JsonSerializer(com.couchbase.client.java.codec.JsonSerializer) BucketConfig(com.couchbase.client.core.config.BucketConfig) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) CompletableFuture(java.util.concurrent.CompletableFuture) SubdocMutateRequest(com.couchbase.client.core.msg.kv.SubdocMutateRequest) RetryStrategy(com.couchbase.client.core.retry.RetryStrategy)

Example 3 with CollectionIdentifier

use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.

the class ReplicaHelper method getAnyReplicaAsync.

/**
 * @param clientContext (nullable)
 * @param parentSpan (nullable)
 * @param responseMapper converts the GetReplicaResponse to the client's native result type
 */
public static <R> CompletableFuture<R> getAnyReplicaAsync(final Core core, final CollectionIdentifier collectionIdentifier, final String documentId, final Duration timeout, final RetryStrategy retryStrategy, final Map<String, Object> clientContext, final RequestSpan parentSpan, final Function<GetReplicaResponse, R> responseMapper) {
    RequestSpan getAnySpan = core.context().environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_GET_ANY_REPLICA, parentSpan);
    CompletableFuture<List<CompletableFuture<R>>> listOfFutures = getAllReplicasAsync(core, collectionIdentifier, documentId, timeout, retryStrategy, clientContext, getAnySpan, responseMapper);
    // Aggregating the futures here will discard the individual errors, which we don't need
    CompletableFuture<R> anyReplicaFuture = new CompletableFuture<>();
    listOfFutures.whenComplete((futures, throwable) -> {
        if (throwable != null) {
            anyReplicaFuture.completeExceptionally(throwable);
        }
        final AtomicBoolean successCompleted = new AtomicBoolean(false);
        final AtomicInteger totalCompleted = new AtomicInteger(0);
        final List<ErrorContext> nestedContexts = Collections.synchronizedList(new ArrayList<>());
        futures.forEach(individual -> individual.whenComplete((result, error) -> {
            int completed = totalCompleted.incrementAndGet();
            if (error != null) {
                if (error instanceof CompletionException && error.getCause() instanceof CouchbaseException) {
                    nestedContexts.add(((CouchbaseException) error.getCause()).context());
                }
            }
            if (result != null && successCompleted.compareAndSet(false, true)) {
                anyReplicaFuture.complete(result);
            }
            if (!successCompleted.get() && completed == futures.size()) {
                anyReplicaFuture.completeExceptionally(new DocumentUnretrievableException(new AggregateErrorContext(nestedContexts)));
            }
        }));
    });
    return anyReplicaFuture.whenComplete((getReplicaResult, throwable) -> getAnySpan.end());
}
Also used : CouchbaseException(com.couchbase.client.core.error.CouchbaseException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) CouchbaseBucketConfig(com.couchbase.client.core.config.CouchbaseBucketConfig) ArrayList(java.util.ArrayList) DefaultErrorUtil.keyValueStatusToException(com.couchbase.client.core.error.DefaultErrorUtil.keyValueStatusToException) TracingIdentifiers(com.couchbase.client.core.cnc.TracingIdentifiers) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DocumentUnretrievableException(com.couchbase.client.core.error.DocumentUnretrievableException) CoreContext(com.couchbase.client.core.CoreContext) Duration(java.time.Duration) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) Stability(com.couchbase.client.core.annotation.Stability) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) GetResponse(com.couchbase.client.core.msg.kv.GetResponse) IndividualReplicaGetFailedEvent(com.couchbase.client.core.cnc.events.request.IndividualReplicaGetFailedEvent) BucketConfig(com.couchbase.client.core.config.BucketConfig) Reactor(com.couchbase.client.core.Reactor) CommonExceptions(com.couchbase.client.core.error.CommonExceptions) Mono(reactor.core.publisher.Mono) CompletionException(java.util.concurrent.CompletionException) CoreEnvironment(com.couchbase.client.core.env.CoreEnvironment) Collectors(java.util.stream.Collectors) Validators.notNullOrEmpty(com.couchbase.client.core.util.Validators.notNullOrEmpty) Flux(reactor.core.publisher.Flux) List(java.util.List) Stream(java.util.stream.Stream) GetRequest(com.couchbase.client.core.msg.kv.GetRequest) ReplicaGetRequest(com.couchbase.client.core.msg.kv.ReplicaGetRequest) ErrorContext(com.couchbase.client.core.error.context.ErrorContext) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) RetryStrategy(com.couchbase.client.core.retry.RetryStrategy) Core(com.couchbase.client.core.Core) ReducedKeyValueErrorContext(com.couchbase.client.core.error.context.ReducedKeyValueErrorContext) Collections(java.util.Collections) AggregateErrorContext(com.couchbase.client.core.error.context.AggregateErrorContext) DocumentUnretrievableException(com.couchbase.client.core.error.DocumentUnretrievableException) ErrorContext(com.couchbase.client.core.error.context.ErrorContext) ReducedKeyValueErrorContext(com.couchbase.client.core.error.context.ReducedKeyValueErrorContext) AggregateErrorContext(com.couchbase.client.core.error.context.AggregateErrorContext) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) CouchbaseException(com.couchbase.client.core.error.CouchbaseException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AggregateErrorContext(com.couchbase.client.core.error.context.AggregateErrorContext) CompletionException(java.util.concurrent.CompletionException) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with CollectionIdentifier

use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.

the class GetCollectionIdRequest method encode.

@Override
public ByteBuf encode(ByteBufAllocator alloc, int opaque, KeyValueChannelContext ctx) {
    ByteBuf body = null;
    try {
        CollectionIdentifier ci = collectionIdentifier();
        if (!ci.collection().isPresent()) {
            throw InvalidArgumentException.fromMessage("A collection name needs to be present");
        }
        // Note that the scope can be empty, according to spec it is the same as _default scope
        body = Unpooled.copiedBuffer(ci.scope().orElse("") + "." + ci.collection().get(), UTF_8);
        return request(alloc, MemcacheProtocol.Opcode.COLLECTIONS_GET_CID, noDatatype(), noPartition(), opaque, noCas(), noExtras(), noKey(), body);
    } finally {
        ReferenceCountUtil.release(body);
    }
}
Also used : ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier)

Example 5 with CollectionIdentifier

use of com.couchbase.client.core.io.CollectionIdentifier in project couchbase-jvm-clients by couchbase.

the class CircuitBreakerIntegrationTest method shouldTriggerWithTimeouts.

@Test
void shouldTriggerWithTimeouts() {
    int threshold = collection.environment().ioConfig().kvCircuitBreakerConfig().volumeThreshold();
    int timeouts = 0;
    int cancellations = 0;
    for (int i = 0; i < threshold * 3; i++) {
        FailingGetRequestOnEncode request = new FailingGetRequestOnEncode("foo", Duration.ofMillis(1), collection.core().context(), new CollectionIdentifier(config().bucketname(), Optional.of(collection.scopeName()), Optional.of(collection.name())), FailFastRetryStrategy.INSTANCE);
        collection.core().send(request);
        try {
            request.response().get();
            fail();
        } catch (ExecutionException ex) {
            if (ex.getCause() instanceof TimeoutException) {
                timeouts++;
            } else if (ex.getCause() instanceof RequestCanceledException) {
                cancellations++;
                CancellationReason reason = ((RequestCanceledException) ex.getCause()).context().requestContext().request().cancellationReason();
                assertEquals(reason.innerReason(), RetryReason.ENDPOINT_CIRCUIT_OPEN);
            }
        } catch (Throwable t) {
            fail(t);
        }
    }
    assertTrue(timeouts > 0);
    assertTrue(cancellations > 0);
}
Also used : CancellationReason(com.couchbase.client.core.msg.CancellationReason) RequestCanceledException(com.couchbase.client.core.error.RequestCanceledException) ExecutionException(java.util.concurrent.ExecutionException) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) TimeoutException(com.couchbase.client.core.error.TimeoutException) JavaIntegrationTest(com.couchbase.client.java.util.JavaIntegrationTest) Test(org.junit.jupiter.api.Test)

Aggregations

CollectionIdentifier (com.couchbase.client.core.io.CollectionIdentifier)14 Core (com.couchbase.client.core.Core)10 Stability (com.couchbase.client.core.annotation.Stability)9 BucketConfig (com.couchbase.client.core.config.BucketConfig)9 Duration (java.time.Duration)9 ArrayList (java.util.ArrayList)9 CoreContext (com.couchbase.client.core.CoreContext)8 List (java.util.List)8 Reactor (com.couchbase.client.core.Reactor)7 RetryStrategy (com.couchbase.client.core.retry.RetryStrategy)7 Map (java.util.Map)7 Flux (reactor.core.publisher.Flux)7 Mono (reactor.core.publisher.Mono)7 RequestSpan (com.couchbase.client.core.cnc.RequestSpan)6 TracingIdentifiers (com.couchbase.client.core.cnc.TracingIdentifiers)6 ReducedKeyValueErrorContext (com.couchbase.client.core.error.context.ReducedKeyValueErrorContext)6 GetRequest (com.couchbase.client.core.msg.kv.GetRequest)6 Validators.notNullOrEmpty (com.couchbase.client.core.util.Validators.notNullOrEmpty)6 CompletableFuture (java.util.concurrent.CompletableFuture)6 CouchbaseBucketConfig (com.couchbase.client.core.config.CouchbaseBucketConfig)5