All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.couchbase.client.core.classic.kv.ClassicCoreKvBinaryOps Maven / Gradle / Ivy

There is a newer version: 3.7.2
Show newest version
/*
 * Copyright 2023 Couchbase, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.couchbase.client.core.classic.kv;

import com.couchbase.client.core.Core;
import com.couchbase.client.core.CoreContext;
import com.couchbase.client.core.CoreKeyspace;
import com.couchbase.client.core.annotation.Stability;
import com.couchbase.client.core.api.kv.CoreAsyncResponse;
import com.couchbase.client.core.api.kv.CoreCounterResult;
import com.couchbase.client.core.api.kv.CoreDurability;
import com.couchbase.client.core.api.kv.CoreExpiry;
import com.couchbase.client.core.api.kv.CoreKvBinaryOps;
import com.couchbase.client.core.api.kv.CoreKvBinaryParamValidators;
import com.couchbase.client.core.api.kv.CoreMutationResult;
import com.couchbase.client.core.classic.ClassicHelper;
import com.couchbase.client.core.cnc.RequestSpan;
import com.couchbase.client.core.cnc.TracingIdentifiers;
import com.couchbase.client.core.endpoint.http.CoreCommonOptions;
import com.couchbase.client.core.env.CoreEnvironment;
import com.couchbase.client.core.error.CasMismatchException;
import com.couchbase.client.core.error.CouchbaseException;
import com.couchbase.client.core.error.DocumentNotFoundException;
import com.couchbase.client.core.error.TimeoutException;
import com.couchbase.client.core.error.context.ReducedKeyValueErrorContext;
import com.couchbase.client.core.io.CollectionIdentifier;
import com.couchbase.client.core.msg.kv.AppendRequest;
import com.couchbase.client.core.msg.kv.DecrementRequest;
import com.couchbase.client.core.msg.kv.IncrementRequest;
import com.couchbase.client.core.msg.kv.PrependRequest;
import com.couchbase.client.core.retry.RetryStrategy;

import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import static com.couchbase.client.core.classic.ClassicExpiryHelper.encode;
import static com.couchbase.client.core.util.Validators.notNull;
import static com.couchbase.client.core.util.Validators.notNullOrEmpty;
import static java.util.Objects.requireNonNull;

@Stability.Internal
public class ClassicCoreKvBinaryOps implements CoreKvBinaryOps {

  private final Core core;
  private final CoreKeyspace keyspace;
  private final Duration defaultKvTimeout;
  private final Duration defaultKvDurableTimeout;

  public ClassicCoreKvBinaryOps(Core core, CoreKeyspace keyspace) {
    this.core = requireNonNull(core);
    this.defaultKvTimeout = core.context().environment().timeoutConfig().kvTimeout();
    this.defaultKvDurableTimeout = core.context().environment().timeoutConfig().kvDurableTimeout();
    this.keyspace = requireNonNull(keyspace);
  }

  /**
   * Appends binary content to the document with custom options.
   *
   * @param id the document id which is used to uniquely identify it.
   * @param content the binary content to append to the document.
   * @param options custom options to customize the append behavior.
   * @return a {@link CoreMutationResult} once completed.
   * @throws DocumentNotFoundException the given document id is not found in the collection.
   * @throws CasMismatchException if the document has been concurrently modified on the server.
   * @throws TimeoutException if the operation times out before getting a result.
   * @throws CouchbaseException for all other error reasons (acts as a base type and catch-all).
   */
  @Override
  public CoreAsyncResponse appendAsync(final String id, final byte[] content,
                                                           final CoreCommonOptions options, final long cas, final CoreDurability durability) {
    AppendRequest request = appendRequestClassic(id, content, options, cas, durability);
    CompletableFuture future =  BinaryAccessor.append(core, request, id, keyspace, durability);
    return ClassicHelper.newAsyncResponse(request, future);
  }

  private AppendRequest appendRequestClassic(final String id, final byte[] content, final CoreCommonOptions options, long cas,
                                             final CoreDurability durability) {
    CoreKvBinaryParamValidators.validateAppendPrependArgs(id, keyspace, options, content, cas, durability);
    Duration timeout = timeout(options, durability);
    RetryStrategy retryStrategy = options.retryStrategy().orElse(environment().retryStrategy());
    RequestSpan span = environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_APPEND,
      options.parentSpan().orElse(null));
    AppendRequest request = new AppendRequest(timeout, context(), collectionIdentifier(), retryStrategy, id,
      content, cas, durability.levelIfSynchronous(), span);
    request.context().clientContext(options.clientContext());
    return request;
  }


  /**
   * Prepends binary content to the document with custom options.
   *
   * @param id the document id which is used to uniquely identify it.
   * @param content the binary content to append to the document.
   * @param options custom options to customize the prepend behavior.
   * @return a {@link CoreMutationResult} once completed.
   * @throws DocumentNotFoundException the given document id is not found in the collection.
   * @throws CasMismatchException if the document has been concurrently modified on the server.
   * @throws TimeoutException if the operation times out before getting a result.
   * @throws CouchbaseException for all other error reasons (acts as a base type and catch-all).
   */
  @Override
  public CoreAsyncResponse prependAsync(final String id, final byte[] content,
      final CoreCommonOptions options, final long cas, final CoreDurability durability) {
    PrependRequest request = prependRequestClassic(id, content, options, cas, durability);
    CompletableFuture future =  BinaryAccessor.prepend(core, request, id, keyspace, durability);
    return ClassicHelper.newAsyncResponse(request, future);
  }

  private PrependRequest prependRequestClassic(final String id, final byte[] content, final CoreCommonOptions options,
                                               long cas, final CoreDurability durability) {
    CoreKvBinaryParamValidators.validateAppendPrependArgs(id, keyspace, options, content,  cas, durability);
    Duration timeout = timeout(options, durability);
    RetryStrategy retryStrategy = options.retryStrategy().orElse(environment().retryStrategy());
    RequestSpan span = environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_PREPEND,
      options.parentSpan().orElse(null));
    PrependRequest request = new PrependRequest(timeout, context(), collectionIdentifier(), retryStrategy, id,
      content, cas, durability.levelIfSynchronous(), span);
    request.context().clientContext(options.clientContext());
    return request;
  }

  /**
   * Increments the counter document by one or the number defined in the options.
   *
   * @param id the document id which is used to uniquely identify it.
   * @param options custom options to customize the increment behavior.
   * @return a {@link CoreCounterResult} once completed.
   * @throws DocumentNotFoundException the given document id is not found in the collection.
   * @throws TimeoutException if the operation times out before getting a result.
   * @throws CouchbaseException for all other error reasons (acts as a base type and catch-all).
   */
  @Override
  public CoreAsyncResponse incrementAsync(final String id, final CoreCommonOptions options, CoreExpiry expiry,
      long delta, Optional initial, CoreDurability durability) {
    IncrementRequest request = incrementRequestClassic(id, options, expiry, delta, initial, durability);
    CompletableFuture future =   BinaryAccessor.increment(core, request, id,
        keyspace, durability);
    return ClassicHelper.newAsyncResponse(request, future);
  }

  private IncrementRequest incrementRequestClassic(final String id, final CoreCommonOptions options, final CoreExpiry expiry,
                                                final long delta, final Optional initial, final CoreDurability durability) {
    CoreKvBinaryParamValidators.validateIncrementDecrementArgs(id, keyspace, options, expiry, delta, initial,
        durability);
    Duration timeout = timeout(options, durability);
    RetryStrategy retryStrategy = options.retryStrategy().orElse(environment().retryStrategy());
    RequestSpan span = environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_INCREMENT,
      options.parentSpan().orElse(null));

    IncrementRequest request = new IncrementRequest(timeout, context(), collectionIdentifier(), retryStrategy, id,
      delta, initial, encode(expiry), durability.levelIfSynchronous(), span);
    request.context().clientContext(options.clientContext());
    return request;
  }

  /**
   * Decrements the counter document by one or the number defined in the options.
   *
   * @param id the document id which is used to uniquely identify it.
   * @param options custom options to customize the decrement behavior.
   * @return a {@link CoreCounterResult} once completed.
   * @throws DocumentNotFoundException the given document id is not found in the collection.
   * @throws TimeoutException if the operation times out before getting a result.
   * @throws CouchbaseException for all other error reasons (acts as a base type and catch-all).
   */
  @Override
  public CoreAsyncResponse decrementAsync(final String id, final CoreCommonOptions options, CoreExpiry expiry,
      long delta, Optional initial, CoreDurability durability) {
    notNull(options, "DecrementOptions", () -> ReducedKeyValueErrorContext.create(id, collectionIdentifier()));
    DecrementRequest request = decrementRequestClassic(id, options, expiry, delta, initial, durability);
    CompletableFuture future =   BinaryAccessor.decrement(core, request, id,
        keyspace, durability);
    return ClassicHelper.newAsyncResponse(request, future);
  }

  private DecrementRequest decrementRequestClassic(final String id, final CoreCommonOptions opts, final CoreExpiry expiry,
                                                   final long delta, final Optional initial, final CoreDurability durability) {
    notNullOrEmpty(id, "Id", () -> ReducedKeyValueErrorContext.create(id, collectionIdentifier()));
    Duration timeout = timeout(opts, durability);
    RetryStrategy retryStrategy = opts.retryStrategy().orElse(environment().retryStrategy());
    RequestSpan span = environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_DECREMENT,
      opts.parentSpan().orElse(null));

    DecrementRequest request = new DecrementRequest(timeout, context(), collectionIdentifier(), retryStrategy, id,
      delta, initial, encode(expiry), durability.levelIfSynchronous(), span);
    request.context().clientContext(opts.clientContext());
    return request;
  }

  private CoreContext context() {
    return core.context();
  }

  private CoreEnvironment environment() {
    return core.context().environment();
  }

  private CollectionIdentifier collectionIdentifier() {
    return keyspace.toCollectionIdentifier();
  }

  private Duration timeout(CoreCommonOptions common, CoreDurability durability) {
    return common.timeout().orElse(durability.isPersistent() ? defaultKvDurableTimeout : defaultKvTimeout);
  }
  
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy