Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.couchbase.client.java.CouchbaseAsyncBucket Maven / Gradle / Ivy
/*
* Copyright (c) 2016 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
*
* http://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.java;
import com.couchbase.client.core.ClusterFacade;
import com.couchbase.client.core.CouchbaseException;
import com.couchbase.client.core.lang.Tuple2;
import com.couchbase.client.core.logging.CouchbaseLogger;
import com.couchbase.client.core.logging.CouchbaseLoggerFactory;
import com.couchbase.client.core.message.CouchbaseResponse;
import com.couchbase.client.core.message.ResponseStatus;
import com.couchbase.client.core.message.cluster.CloseBucketRequest;
import com.couchbase.client.core.message.cluster.CloseBucketResponse;
import com.couchbase.client.core.message.internal.PingReport;
import com.couchbase.client.core.message.kv.AppendRequest;
import com.couchbase.client.core.message.kv.AppendResponse;
import com.couchbase.client.core.message.kv.CounterRequest;
import com.couchbase.client.core.message.kv.CounterResponse;
import com.couchbase.client.core.message.kv.GetRequest;
import com.couchbase.client.core.message.kv.GetResponse;
import com.couchbase.client.core.message.kv.InsertRequest;
import com.couchbase.client.core.message.kv.InsertResponse;
import com.couchbase.client.core.message.kv.ObserveRequest;
import com.couchbase.client.core.message.kv.ObserveResponse;
import com.couchbase.client.core.message.kv.PrependRequest;
import com.couchbase.client.core.message.kv.PrependResponse;
import com.couchbase.client.core.message.kv.RemoveRequest;
import com.couchbase.client.core.message.kv.RemoveResponse;
import com.couchbase.client.core.message.kv.ReplaceRequest;
import com.couchbase.client.core.message.kv.ReplaceResponse;
import com.couchbase.client.core.message.kv.TouchRequest;
import com.couchbase.client.core.message.kv.TouchResponse;
import com.couchbase.client.core.message.kv.UnlockRequest;
import com.couchbase.client.core.message.kv.UnlockResponse;
import com.couchbase.client.core.message.kv.UpsertRequest;
import com.couchbase.client.core.message.kv.UpsertResponse;
import com.couchbase.client.core.message.kv.subdoc.multi.Lookup;
import com.couchbase.client.core.message.kv.subdoc.multi.Mutation;
import com.couchbase.client.core.message.observe.Observe;
import com.couchbase.client.core.message.search.SearchQueryRequest;
import com.couchbase.client.core.message.search.SearchQueryResponse;
import com.couchbase.client.core.message.view.ViewQueryRequest;
import com.couchbase.client.core.message.view.ViewQueryResponse;
import com.couchbase.client.core.service.ServiceType;
import com.couchbase.client.core.tracing.ThresholdLogReporter;
import com.couchbase.client.core.tracing.ThresholdLogSpan;
import com.couchbase.client.core.utils.HealthPinger;
import com.couchbase.client.deps.io.netty.buffer.ByteBuf;
import com.couchbase.client.java.analytics.AnalyticsQuery;
import com.couchbase.client.java.analytics.AnalyticsQueryExecutor;
import com.couchbase.client.java.analytics.AsyncAnalyticsQueryResult;
import com.couchbase.client.java.bucket.AsyncBucketManager;
import com.couchbase.client.java.bucket.DefaultAsyncBucketManager;
import com.couchbase.client.java.bucket.ReplicaReader;
import com.couchbase.client.java.bucket.api.Exists;
import com.couchbase.client.java.bucket.api.Get;
import com.couchbase.client.java.bucket.api.Mutate;
import com.couchbase.client.java.bucket.api.Utils;
import com.couchbase.client.java.datastructures.MutationOptionBuilder;
import com.couchbase.client.java.datastructures.ResultMappingUtils;
import com.couchbase.client.java.document.Document;
import com.couchbase.client.java.document.JsonArrayDocument;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.JsonLongDocument;
import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.error.CASMismatchException;
import com.couchbase.client.java.error.CouchbaseOutOfMemoryException;
import com.couchbase.client.java.error.DocumentAlreadyExistsException;
import com.couchbase.client.java.error.DocumentDoesNotExistException;
import com.couchbase.client.java.error.DurabilityException;
import com.couchbase.client.java.error.RequestTooBigException;
import com.couchbase.client.java.error.TemporaryFailureException;
import com.couchbase.client.java.error.TemporaryLockFailureException;
import com.couchbase.client.java.error.subdoc.MultiMutationException;
import com.couchbase.client.java.error.subdoc.PathNotFoundException;
import com.couchbase.client.java.query.AsyncN1qlQueryResult;
import com.couchbase.client.java.query.N1qlQuery;
import com.couchbase.client.java.query.Statement;
import com.couchbase.client.java.query.core.N1qlQueryExecutor;
import com.couchbase.client.java.repository.AsyncRepository;
import com.couchbase.client.java.repository.CouchbaseAsyncRepository;
import com.couchbase.client.java.search.SearchQuery;
import com.couchbase.client.java.search.core.SearchQueryExecutor;
import com.couchbase.client.java.search.result.AsyncSearchQueryResult;
import com.couchbase.client.java.search.result.impl.DefaultAsyncSearchQueryResult;
import com.couchbase.client.java.subdoc.AsyncLookupInBuilder;
import com.couchbase.client.java.subdoc.AsyncMutateInBuilder;
import com.couchbase.client.java.subdoc.DocumentFragment;
import com.couchbase.client.java.transcoder.BinaryTranscoder;
import com.couchbase.client.java.transcoder.ByteArrayTranscoder;
import com.couchbase.client.java.transcoder.JacksonTransformers;
import com.couchbase.client.java.transcoder.JsonArrayTranscoder;
import com.couchbase.client.java.transcoder.JsonBooleanTranscoder;
import com.couchbase.client.java.transcoder.crypto.JsonCryptoTranscoder;
import com.couchbase.client.java.transcoder.JsonDoubleTranscoder;
import com.couchbase.client.java.transcoder.JsonLongTranscoder;
import com.couchbase.client.java.transcoder.JsonStringTranscoder;
import com.couchbase.client.java.transcoder.JsonTranscoder;
import com.couchbase.client.java.transcoder.LegacyTranscoder;
import com.couchbase.client.java.transcoder.RawJsonTranscoder;
import com.couchbase.client.java.transcoder.SerializableTranscoder;
import com.couchbase.client.java.transcoder.StringTranscoder;
import com.couchbase.client.java.transcoder.Transcoder;
import com.couchbase.client.java.transcoder.subdoc.FragmentTranscoder;
import com.couchbase.client.java.transcoder.subdoc.JacksonFragmentTranscoder;
import com.couchbase.client.java.view.AsyncSpatialViewResult;
import com.couchbase.client.java.view.AsyncViewResult;
import com.couchbase.client.java.view.SpatialViewQuery;
import com.couchbase.client.java.view.ViewQuery;
import com.couchbase.client.java.view.ViewQueryResponseMapper;
import com.couchbase.client.java.view.ViewRetryHandler;
import io.opentracing.Scope;
import io.opentracing.Span;
import rx.Observable;
import rx.Single;
import rx.Subscriber;
import rx.functions.Action0;
import rx.functions.Func0;
import rx.functions.Func1;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import static com.couchbase.client.java.bucket.api.Utils.addRequestSpan;
import static com.couchbase.client.java.bucket.api.Utils.applyTimeout;
import static com.couchbase.client.java.util.OnSubscribeDeferAndWatch.deferAndWatch;
public class CouchbaseAsyncBucket implements AsyncBucket {
private static final CouchbaseLogger LOGGER = CouchbaseLoggerFactory.getInstance(CouchbaseAsyncBucket.class);
public static final int COUNTER_NOT_EXISTS_EXPIRY = 0xffffffff;
private static final int MAX_CAS_RETRIES_DATASTRUCTURES = Integer.parseInt(System.getProperty("com.couchbase.datastructureCASRetryLimit", "10"));
public static final String CURRENT_BUCKET_IDENTIFIER = "#CURRENT_BUCKET#";
public static final JsonTranscoder JSON_OBJECT_TRANSCODER = new JsonTranscoder();
public static final JsonArrayTranscoder JSON_ARRAY_TRANSCODER = new JsonArrayTranscoder();
public static final JsonBooleanTranscoder JSON_BOOLEAN_TRANSCODER = new JsonBooleanTranscoder();
public static final JsonDoubleTranscoder JSON_DOUBLE_TRANSCODER = new JsonDoubleTranscoder();
public static final JsonLongTranscoder JSON_LONG_TRANSCODER = new JsonLongTranscoder();
public static final JsonStringTranscoder JSON_STRING_TRANSCODER = new JsonStringTranscoder();
public static final RawJsonTranscoder RAW_JSON_TRANSCODER = new RawJsonTranscoder();
public static final ByteArrayTranscoder BYTE_ARRAY_TRANSCODER = new ByteArrayTranscoder();
public static final LegacyTranscoder LEGACY_TRANSCODER = new LegacyTranscoder();
public static final BinaryTranscoder BINARY_TRANSCODER = new BinaryTranscoder();
public static final StringTranscoder STRING_TRANSCODER = new StringTranscoder();
public static final SerializableTranscoder SERIALIZABLE_TRANSCODER = new SerializableTranscoder();
private final String bucket;
private final String username;
private final String password;
private final ClusterFacade core;
private final Map, Transcoder extends Document, ?>> transcoders;
//TODO this could be opened for customization like with transcoders
private final FragmentTranscoder subdocumentTranscoder = new JacksonFragmentTranscoder(JacksonTransformers.MAPPER);
private final AsyncBucketManager bucketManager;
private final CouchbaseEnvironment environment;
/** the bucket's {@link N1qlQueryExecutor}. Prefer using {@link #n1qlQueryExecutor()} since it allows mocking and testing */
private final N1qlQueryExecutor n1qlQueryExecutor;
private final AnalyticsQueryExecutor analyticsQueryExecutor;
private final SearchQueryExecutor searchQueryExecutor;
private volatile boolean closed;
public CouchbaseAsyncBucket(final ClusterFacade core, final CouchbaseEnvironment environment, final String name,
final String password, final List> customTranscoders) {
this(core, environment, name, name, password, customTranscoders);
}
public CouchbaseAsyncBucket(final ClusterFacade core, final CouchbaseEnvironment environment, final String name,
final String username, final String password, final List> customTranscoders) {
bucket = name;
this.username = username;
this.password = password;
this.core = core;
this.environment = environment;
this.closed = false;
transcoders = new ConcurrentHashMap, Transcoder extends Document, ?>>();
if (environment != null && environment.cryptoManager() != null) {
JsonCryptoTranscoder transcoder = new JsonCryptoTranscoder(environment.cryptoManager());
transcoders.put(transcoder.documentType(), transcoder);
} else {
transcoders.put(JSON_OBJECT_TRANSCODER.documentType(), JSON_OBJECT_TRANSCODER);
}
transcoders.put(JSON_ARRAY_TRANSCODER.documentType(), JSON_ARRAY_TRANSCODER);
transcoders.put(JSON_BOOLEAN_TRANSCODER.documentType(), JSON_BOOLEAN_TRANSCODER);
transcoders.put(JSON_DOUBLE_TRANSCODER.documentType(), JSON_DOUBLE_TRANSCODER);
transcoders.put(JSON_LONG_TRANSCODER.documentType(), JSON_LONG_TRANSCODER);
transcoders.put(JSON_STRING_TRANSCODER.documentType(), JSON_STRING_TRANSCODER);
transcoders.put(RAW_JSON_TRANSCODER.documentType(), RAW_JSON_TRANSCODER);
transcoders.put(LEGACY_TRANSCODER.documentType(), LEGACY_TRANSCODER);
transcoders.put(BINARY_TRANSCODER.documentType(), BINARY_TRANSCODER);
transcoders.put(STRING_TRANSCODER.documentType(), STRING_TRANSCODER);
transcoders.put(SERIALIZABLE_TRANSCODER.documentType(), SERIALIZABLE_TRANSCODER);
transcoders.put(BYTE_ARRAY_TRANSCODER.documentType(), BYTE_ARRAY_TRANSCODER);
for (Transcoder extends Document, ?> custom : customTranscoders) {
transcoders.put(custom.documentType(), custom);
}
bucketManager = DefaultAsyncBucketManager.create(bucket, username, password, core, environment);
boolean n1qlPreparedEncodedPlanEnabled = "true".equalsIgnoreCase(System.getProperty(N1qlQueryExecutor.ENCODED_PLAN_ENABLED_PROPERTY, "true")); //active by default
n1qlQueryExecutor = new N1qlQueryExecutor(core, bucket, username, password, n1qlPreparedEncodedPlanEnabled);
analyticsQueryExecutor = new AnalyticsQueryExecutor(core, bucket, username, password);
searchQueryExecutor = new SearchQueryExecutor(environment, core, bucket, username, password);
}
@Override
public String name() {
return bucket;
}
@Override
public Observable core() {
return Observable.just(core);
}
@Override
public FragmentTranscoder subdocumentTranscoder() {
return subdocumentTranscoder;
}
/**
* Returns the underlying {@link N1qlQueryExecutor} used to perform N1QL queries.
*
* Handle with care since all additional checks that are normally performed by this library may be skipped (hence
* the protected visibility).
*/
protected N1qlQueryExecutor n1qlQueryExecutor() {
return this.n1qlQueryExecutor;
}
@Override
public CouchbaseEnvironment environment() {
return environment;
}
@Override
public Observable repository() {
return Observable.just((AsyncRepository) new CouchbaseAsyncRepository(this));
}
@Override
public Observable get(final String id) {
return get(id, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public > Observable get(D document) {
return (Observable) get(document.id(), document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public > Observable get(final String id, final Class target) {
return Get.get(id, target, environment, bucket, core, transcoders, 0, null);
}
@Override
@SuppressWarnings("unchecked")
public > Observable get(final String id, final Class target, long timeout, TimeUnit timeUnit) {
return Get.get(id, target, environment, bucket, core, transcoders, timeout, timeUnit);
}
@Override
public Observable get(String id, long timeout, TimeUnit timeUnit) {
return get(id, JsonDocument.class, timeout, timeUnit);
}
@Override
@SuppressWarnings("unchecked")
public > Observable get(D document, long timeout, TimeUnit timeUnit) {
return (Observable) Get.get(document.id(), document.getClass(), environment, bucket, core, transcoders, timeout, timeUnit);
}
@Override
public Observable exists(String id, long timeout, TimeUnit timeUnit) {
return Exists.exists(id, environment, core, bucket, timeout, timeUnit);
}
@Override
public > Observable exists(D document, long timeout, TimeUnit timeUnit) {
return exists(document.id(), timeout, timeUnit);
}
@Override
public Observable exists(final String id) {
return Exists.exists(id, environment, core, bucket, 0, null);
}
@Override
public > Observable exists(D document) {
return exists(document.id());
}
@Override
public Observable getAndLock(String id, int lockTime) {
return getAndLock(id, lockTime, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public > Observable getAndLock(D document, int lockTime) {
return (Observable) getAndLock(document.id(), lockTime, document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public > Observable getAndLock(final String id, final int lockTime, final Class target) {
return Get.getAndLock(id, target, environment, bucket, core, transcoders, lockTime, 0, null);
}
@Override
public Observable getAndTouch(String id, int expiry) {
return getAndTouch(id, expiry, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public > Observable getAndTouch(D document) {
return (Observable) getAndTouch(document.id(), document.expiry(), document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public > Observable getAndTouch(final String id, final int expiry, final Class target) {
return Get.getAndTouch(id, target, environment, bucket, core, transcoders, expiry, 0, null);
}
@Override
public Observable getFromReplica(final String id, final ReplicaMode type) {
return getFromReplica(id, type, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public > Observable getFromReplica(final D document, final ReplicaMode type) {
return (Observable) getFromReplica(document.id(), type, document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public > Observable getFromReplica(final String id, final ReplicaMode type,
final Class target) {
return getFromReplica(id, type, target, 0, null);
}
@Override
public Observable getFromReplica(String id, ReplicaMode type, long timeout, TimeUnit timeUnit) {
return getFromReplica(id, type, JsonDocument.class, timeout, timeUnit);
}
@Override
public > Observable getFromReplica(D document, ReplicaMode type, long timeout, TimeUnit timeUnit) {
return (Observable) getFromReplica(document.id(), type, document.getClass(), timeout, timeUnit);
}
@Override
public > Observable getFromReplica(String id, ReplicaMode type, Class target, long timeout, TimeUnit timeUnit) {
return ReplicaReader.read(core, id, type, bucket, transcoders, target, environment, timeout, timeUnit);
}
@Override
public Observable getAndLock(String id, int lockTime, long timeout, TimeUnit timeUnit) {
return getAndLock(id, lockTime, JsonDocument.class, timeout, timeUnit);
}
@Override
public > Observable getAndLock(D document, int lockTime, long timeout, TimeUnit timeUnit) {
return (Observable) getAndLock(document.id(), lockTime, document.getClass(), timeout, timeUnit);
}
@Override
public > Observable getAndLock(String id, int lockTime, Class target, long timeout, TimeUnit timeUnit) {
return Get.getAndLock(id, target, environment, bucket, core, transcoders, lockTime, timeout, timeUnit);
}
@Override
public Observable getAndTouch(String id, int expiry, long timeout, TimeUnit timeUnit) {
return getAndTouch(id, expiry, JsonDocument.class, timeout, timeUnit);
}
@Override
public > Observable getAndTouch(D document, long timeout, TimeUnit timeUnit) {
return (Observable) getAndTouch(document.id(), document.expiry(), document.getClass(), timeout, timeUnit);
}
@Override
public > Observable getAndTouch(String id, int expiry, Class target, long timeout, TimeUnit timeUnit) {
return Get.getAndTouch(id, target, environment, bucket, core, transcoders, expiry, timeout, timeUnit);
}
@Override
@SuppressWarnings("unchecked")
public > Observable insert(final D document) {
return insert(document, 0, null);
}
@Override
public > Observable insert(final D document, final PersistTo persistTo,
final ReplicateTo replicateTo, final long timeout, final TimeUnit timeUnit) {
if (persistTo == PersistTo.NONE && replicateTo == ReplicateTo.NONE) {
return insert(document, timeout, timeUnit);
}
final Span parent = startTracing("insert_with_durability");
return insert(document, parent, timeout, timeUnit).flatMap(new Func1>() {
@Override
public Observable call(final D doc) {
Observable or = Observe
.call(core, bucket, doc.id(), doc.cas(), false, doc.mutationToken(),
persistTo.value(), replicateTo.value(),
environment.observeIntervalDelay(), environment.retryStrategy(), parent)
.map(new Func1() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
}).onErrorResumeNext(new Func1>() {
@Override
public Observable extends D> call(Throwable throwable) {
return Observable.error(new DurabilityException(
"Durability requirement failed: " + throwable.getMessage(),
throwable));
}
});
// we need a timeout here since observe doesn't have one yet
return timeout > 0 ? or.timeout(timeout, timeUnit, environment.scheduler()) : or;
}
}).doOnTerminate(stopTracing(parent));
}
@Override
@SuppressWarnings("unchecked")
public > Observable upsert(final D document) {
return upsert(document, 0, null);
}
@Override
public > Observable upsert(final D document, final PersistTo persistTo,
final ReplicateTo replicateTo, final long timeout, final TimeUnit timeUnit) {
if (persistTo == PersistTo.NONE && replicateTo == ReplicateTo.NONE) {
return upsert(document, timeout, timeUnit);
}
final Span parent = startTracing("upsert_with_durability");
return upsert(document, parent, timeout, timeUnit)
.flatMap(new Func1>() {
@Override
public Observable call(final D doc) {
Observable or = Observe
.call(core, bucket, doc.id(), doc.cas(), false, doc.mutationToken(),
persistTo.value(), replicateTo.value(),
environment.observeIntervalDelay(), environment.retryStrategy(), parent)
.map(new Func1() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
})
.onErrorResumeNext(new Func1>() {
@Override
public Observable extends D> call(Throwable throwable) {
return Observable.error(new DurabilityException(
"Durability requirement failed: " + throwable.getMessage(),
throwable));
}
});
// we need a timeout here since observe doesn't have one yet
return timeout > 0 ? or.timeout(timeout, timeUnit, environment.scheduler()) : or;
}
})
.doOnTerminate(stopTracing(parent));
}
@Override
@SuppressWarnings("unchecked")
public > Observable replace(final D document) {
return replace(document, 0, null);
}
@Override
public > Observable insert(D document, long timeout, TimeUnit timeUnit) {
return insert(document, (Span) null, timeout, timeUnit);
}
@SuppressWarnings({"unchecked"})
private > Observable insert(D document, Span parent, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder =
(Transcoder, Object>) transcoders.get(document.getClass());
return Mutate.insert(document, environment, transcoder, core, bucket, timeout, timeUnit, parent);
}
@Override
public > Observable insert(D document, PersistTo persistTo, ReplicateTo replicateTo) {
return insert(document, persistTo, replicateTo, 0, null);
}
@Override
public > Observable insert(D document, PersistTo persistTo, long timeout, TimeUnit timeUnit) {
return insert(document, persistTo, ReplicateTo.NONE, timeout, timeUnit);
}
@Override
public > Observable insert(D document, ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return insert(document, PersistTo.NONE, replicateTo, timeout, timeUnit);
}
@Override
public > Observable upsert(D document, long timeout, TimeUnit timeUnit) {
return upsert(document, (Span) null, timeout, timeUnit);
}
@SuppressWarnings({"unchecked"})
private > Observable upsert(D document, Span parent, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder =
(Transcoder, Object>) transcoders.get(document.getClass());
return Mutate.upsert(document, environment, transcoder, core, bucket, timeout, timeUnit, parent);
}
@Override
public > Observable upsert(D document, PersistTo persistTo, ReplicateTo replicateTo) {
return upsert(document, persistTo, replicateTo, 0, null);
}
@Override
public > Observable upsert(D document, PersistTo persistTo, long timeout, TimeUnit timeUnit) {
return upsert(document, persistTo, ReplicateTo.NONE, timeout, timeUnit);
}
@Override
public > Observable upsert(D document, ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return upsert(document, PersistTo.NONE, replicateTo, timeout, timeUnit);
}
@Override
public > Observable replace(D document, long timeout, TimeUnit timeUnit) {
return replace(document, (Span) null, timeout, timeUnit);
}
@SuppressWarnings({"unchecked"})
private > Observable replace(D document, Span parent, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder =
(Transcoder, Object>) transcoders.get(document.getClass());
return Mutate.replace(document, environment, transcoder, core, bucket, timeout, timeUnit, parent);
}
@Override
public > Observable replace(D document, PersistTo persistTo, ReplicateTo replicateTo) {
return replace(document, persistTo, replicateTo, 0, null);
}
@Override
public > Observable replace(D document, PersistTo persistTo, long timeout, TimeUnit timeUnit) {
return replace(document, persistTo, ReplicateTo.NONE, timeout, timeUnit);
}
@Override
public > Observable replace(D document, ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return replace(document, PersistTo.NONE, replicateTo, timeout, timeUnit);
}
@Override
public > Observable replace(final D document, final PersistTo persistTo,
final ReplicateTo replicateTo, final long timeout, final TimeUnit timeUnit) {
if (persistTo == PersistTo.NONE && replicateTo == ReplicateTo.NONE) {
return replace(document, timeout, timeUnit);
}
final Span parent = startTracing("replace_with_durability");
return replace(document, parent, timeout, timeUnit).flatMap(new Func1>() {
@Override
public Observable call(final D doc) {
Observable or = Observe
.call(core, bucket, doc.id(), doc.cas(), false, doc.mutationToken(), persistTo.value(),
replicateTo.value(), environment.observeIntervalDelay(), environment.retryStrategy(), parent)
.map(new Func1() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
}).onErrorResumeNext(new Func1>() {
@Override
public Observable extends D> call(Throwable throwable) {
return Observable.error(new DurabilityException(
"Durability requirement failed: " + throwable.getMessage(),
throwable));
}
});
// we need a timeout here since observe doesn't have one yet
return timeout > 0 ? or.timeout(timeout, timeUnit, environment.scheduler()) : or;
}
}).doOnTerminate(stopTracing(parent));
}
@Override
@SuppressWarnings("unchecked")
public > Observable remove(final D document, long timeout, TimeUnit timeUnit) {
return remove(document, (Span) null, timeout, timeUnit);
}
@SuppressWarnings({"unchecked"})
private > Observable remove(final D document, Span parent, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder =
(Transcoder, Object>) transcoders.get(document.getClass());
return Mutate.remove(document, environment, transcoder, core, bucket, timeout, timeUnit, parent);
}
@Override
public Observable remove(final String id) {
return remove(id, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public > Observable remove(final String id, final Class target) {
final Transcoder, Object> transcoder = (Transcoder, Object>) transcoders.get(target);
return remove((D) transcoder.newDocument(id, 0, null, 0, null));
}
@Override
@SuppressWarnings("unchecked")
public > Observable remove(D document, final PersistTo persistTo, final ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return observeRemove(document, persistTo, replicateTo, timeout, timeUnit);
}
@Override
public Observable remove(String id, PersistTo persistTo, ReplicateTo replicateTo) {
return remove(id, persistTo, replicateTo, JsonDocument.class);
}
@Override
@SuppressWarnings({"unchecked"})
public > Observable remove(String id, final PersistTo persistTo,
final ReplicateTo replicateTo, Class target, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder = (Transcoder, Object>) transcoders.get(target);
return observeRemove((D) transcoder.newDocument(id, 0, null, 0, null), persistTo, replicateTo, timeout, timeUnit);
}
@Override
public > Observable remove(D document) {
return remove(document, 0, null);
}
@Override
public > Observable remove(D document, PersistTo persistTo, ReplicateTo replicateTo) {
return remove(document, persistTo, replicateTo, 0, null);
}
@Override
public > Observable remove(D document, PersistTo persistTo, long timeout, TimeUnit timeUnit) {
return remove(document, persistTo, ReplicateTo.NONE, timeout, timeUnit);
}
@Override
public > Observable remove(D document, ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return remove(document, PersistTo.NONE, replicateTo, timeout, timeUnit);
}
@Override
public Observable remove(String id, long timeout, TimeUnit timeUnit) {
return remove(id, JsonDocument.class, timeout, timeUnit);
}
@Override
public Observable remove(String id, PersistTo persistTo, ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return remove(id, persistTo, replicateTo, JsonDocument.class, timeout, timeUnit);
}
@Override
public Observable remove(String id, PersistTo persistTo, long timeout, TimeUnit timeUnit) {
return remove(id, persistTo, ReplicateTo.NONE, JsonDocument.class, timeout, timeUnit);
}
@Override
public Observable remove(String id, ReplicateTo replicateTo, long timeout, TimeUnit timeUnit) {
return remove(id, PersistTo.NONE, replicateTo, JsonDocument.class, timeout, timeUnit);
}
@Override
public > Observable remove(String id, Class target, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder = (Transcoder, Object>) transcoders.get(target);
return remove((D) transcoder.newDocument(id, 0, null, 0, null), timeout, timeUnit);
}
@Override
public > Observable remove(String id, PersistTo persistTo, ReplicateTo replicateTo, Class target) {
return remove(id, persistTo, replicateTo, target, 0, null);
}
@Override
public > Observable remove(String id, PersistTo persistTo, Class target, long timeout, TimeUnit timeUnit) {
return remove(id, persistTo, ReplicateTo.NONE, target, timeout, timeUnit);
}
@Override
public > Observable remove(String id, ReplicateTo replicateTo, Class target, long timeout, TimeUnit timeUnit) {
return remove(id, PersistTo.NONE, replicateTo, target, timeout, timeUnit);
}
/**
* Helper method to observe the result of a remove operation with the given durability
* requirements.
*
* @param document the document that needs to be removed.
* @param persistTo the persistence requirement given.
* @param replicateTo the replication requirement given.
* @return an observable reporting success or error of the observe operation.
*/
private > Observable observeRemove(D document,
final PersistTo persistTo, final ReplicateTo replicateTo, final long timeout, final TimeUnit timeUnit) {
if (persistTo == PersistTo.NONE && replicateTo == ReplicateTo.NONE) {
return remove(document, timeout, timeUnit);
}
final Span parent = startTracing("remove_with_durability");
return remove(document, parent, timeout, timeUnit).flatMap(new Func1>() {
@Override
public Observable call(final D doc) {
Observable or = Observe
.call(core, bucket, doc.id(), doc.cas(), true, doc.mutationToken(),
persistTo.value(), replicateTo.value(),
environment.observeIntervalDelay(), environment.retryStrategy(), parent)
.map(new Func1() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
}).onErrorResumeNext(new Func1>() {
@Override
public Observable extends D> call(Throwable throwable) {
return Observable.error(new DurabilityException(
"Durability requirement failed: " + throwable.getMessage(),
throwable));
}
});
// we need a timeout here since observe doesn't have one yet
return timeout > 0 ? or.timeout(timeout, timeUnit, environment.scheduler()) : or;
}
}).doOnTerminate(stopTracing(parent));
}
@Override
public Observable query(final ViewQuery query) {
return query(query, environment.viewTimeout(), TimeUnit.MILLISECONDS);
}
@Override
public Observable query(final ViewQuery query, final long timeout, final TimeUnit timeUnit) {
final Observable source = deferAndWatch(
new Func1>() {
@Override
public Observable extends ViewQueryResponse> call(final Subscriber subscriber) {
final ViewQueryRequest request = new ViewQueryRequest(query.getDesign(), query.getView(),
query.isDevelopment(), query.toQueryString(), query.getKeys(), bucket, username, password);
Utils.addRequestSpan(environment, request, "view");
request.subscriber(subscriber);
return applyTimeout(core.send(request), request, environment, timeout, timeUnit);
}
});
return ViewRetryHandler
.retryOnCondition(source)
.flatMap(new Func1>() {
@Override
public Observable call(final ViewQueryResponse response) {
return ViewQueryResponseMapper.mapToViewResult(CouchbaseAsyncBucket.this, query, response);
}
});
}
@Override
public Observable query(SearchQuery query) {
return query(query, environment.searchTimeout(), TimeUnit.MILLISECONDS);
}
@Override
public Observable query(final SearchQuery query, final long timeout, final TimeUnit timeUnit) {
//always set a server side timeout. if not explicit, set it to the client side timeout
if (query.getServerSideTimeout() == null) {
query.serverSideTimeout(environment().searchTimeout(), TimeUnit.MILLISECONDS);
}
return searchQueryExecutor.execute(query, timeout, timeUnit);
}
@Override
public Observable query(final SpatialViewQuery query) {
return query(query, environment.viewTimeout(), TimeUnit.MILLISECONDS);
}
@Override
public Observable query(final SpatialViewQuery query, final long timeout, final TimeUnit timeUnit) {
final Observable source = deferAndWatch(
new Func1>() {
@Override
public Observable extends ViewQueryResponse> call(Subscriber subscriber) {
final ViewQueryRequest request = new ViewQueryRequest(query.getDesign(), query.getView(),
query.isDevelopment(), true, query.toString(), null, bucket, username, password);
addRequestSpan(environment, request, "spatial_view");
request.subscriber(subscriber);
return applyTimeout(core.send(request), request, environment, timeout, timeUnit);
}
});
return ViewRetryHandler
.retryOnCondition(source)
.flatMap(new Func1>() {
@Override
public Observable call(final ViewQueryResponse response) {
return ViewQueryResponseMapper.mapToSpatialViewResult(CouchbaseAsyncBucket.this, query, response);
}
});
}
@Override
public Observable query(final Statement statement) {
return query(N1qlQuery.simple(statement));
}
@Override
public Observable query(final N1qlQuery query) {
return query(query, environment.queryTimeout(), TimeUnit.MILLISECONDS);
}
@Override
public Observable query(N1qlQuery query, long timeout, TimeUnit timeUnit) {
if (!query.params().hasServerSideTimeout()) {
query.params().serverSideTimeout(timeout, timeUnit);
}
if (query.params().clientContextId() == null || query.params().clientContextId().isEmpty()) {
query.params().withContextId(UUID.randomUUID().toString());
}
return n1qlQueryExecutor.execute(query, environment, timeout, timeUnit);
}
@Override
public Observable query(final AnalyticsQuery query) {
return query(query, environment.analyticsTimeout(), TimeUnit.MILLISECONDS);
}
@Override
public Observable query(final AnalyticsQuery query, long timeout, TimeUnit timeUnit) {
if (!query.params().hasServerSideTimeout()) {
query.params().serverSideTimeout(timeout, timeUnit);
}
if (query.params().clientContextId() == null || query.params().clientContextId().isEmpty()) {
query.params().withContextId(UUID.randomUUID().toString());
}
return analyticsQueryExecutor.execute(query, environment, timeout, timeUnit);
}
@Override
public Observable counter(String id, long delta, long timeout, TimeUnit timeUnit) {
return counter(id, delta, 0, COUNTER_NOT_EXISTS_EXPIRY, timeout, timeUnit);
}
@Override
public Observable counter(String id, long delta, long initial, long timeout, TimeUnit timeUnit) {
return counter(id, delta, initial, 0, timeout, timeUnit);
}
@Override
public Observable counter(final String id, final long delta, final long initial, final int expiry, long timeout, TimeUnit timeUnit) {
return counter(id, delta, initial, expiry, (Span) null, timeout, timeUnit);
}
private Observable counter(final String id, final long delta, final long initial, final int expiry, Span parent, long timeout, TimeUnit timeUnit) {
return Mutate.counter(id, delta, initial, expiry, environment, core, bucket, timeout, timeUnit, parent);
}
@Override
public Observable unlock(final String id, final long cas, long timeout, TimeUnit timeUnit) {
return Mutate.unlock(id, cas, environment, core, bucket, timeout, timeUnit);
}
@Override
public > Observable unlock(D document, long timeout, TimeUnit timeUnit) {
return unlock(document.id(), document.cas(), timeout, timeUnit);
}
@Override
public Observable unlock(String id, long cas) {
return unlock(id, cas, 0, null);
}
@Override
public > Observable unlock(D document) {
return unlock(document, 0, null);
}
@Override
public Observable touch(final String id, final int expiry, long timeout, TimeUnit timeUnit) {
return Mutate.touch(id, expiry, environment, core, bucket, timeout, timeUnit);
}
@Override
public > Observable touch(D document, long timeout, TimeUnit timeUnit) {
return touch(document.id(), document.expiry(), timeout, timeUnit);
}
@Override
public Observable touch(String id, int expiry) {
return touch(id, expiry, 0, null);
}
@Override
public > Observable touch(D document) {
return touch(document, 0, null);
}
@Override
@SuppressWarnings("unchecked")
public > Observable append(final D document, long timeout, TimeUnit timeUnit) {
return append(document, (Span) null, timeout, timeUnit);
}
@SuppressWarnings("unchecked")
private > Observable append(final D document, Span parent, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder = (Transcoder, Object>) transcoders.get(document.getClass());
return Mutate.append(document, environment, transcoder, core, bucket, timeout, timeUnit, parent);
}
@Override
@SuppressWarnings("unchecked")
public > Observable prepend(final D document, long timeout, TimeUnit timeUnit) {
return prepend(document, (Span) null, timeout, timeUnit);
}
@SuppressWarnings("unchecked")
private > Observable prepend(final D document, Span parent, long timeout, TimeUnit timeUnit) {
final Transcoder, Object> transcoder = (Transcoder, Object>) transcoders.get(document.getClass());
return Mutate.prepend(document, environment, transcoder, core, bucket, timeout, timeUnit, parent);
}
@Override
public Observable bucketManager() {
return Observable.just(bucketManager);
}
@Override
public > Observable insert(D document, PersistTo persistTo) {
return insert(document, persistTo, ReplicateTo.NONE);
}
@Override
public > Observable insert(D document, ReplicateTo replicateTo) {
return insert(document, PersistTo.NONE, replicateTo);
}
@Override
public > Observable upsert(D document, PersistTo persistTo) {
return upsert(document, persistTo, ReplicateTo.NONE);
}
@Override
public > Observable upsert(D document, ReplicateTo replicateTo) {
return upsert(document, PersistTo.NONE, replicateTo);
}
@Override
public > Observable replace(D document, PersistTo persistTo) {
return replace(document, persistTo, ReplicateTo.NONE);
}
@Override
public > Observable replace(D document, ReplicateTo replicateTo) {
return replace(document, PersistTo.NONE, replicateTo);
}
@Override
public > Observable remove(D document, PersistTo persistTo) {
return remove(document, persistTo, ReplicateTo.NONE);
}
@Override
public > Observable remove(D document, ReplicateTo replicateTo) {
return remove(document, PersistTo.NONE, replicateTo);
}
@Override
public Observable