/**
* Copyright (C) 2014 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/
package com.couchbase.client.java;
import com.couchbase.client.core.ClusterFacade;
import com.couchbase.client.core.config.CouchbaseBucketConfig;
import com.couchbase.client.core.lang.Tuple2;
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.cluster.GetClusterConfigRequest;
import com.couchbase.client.core.message.cluster.GetClusterConfigResponse;
import com.couchbase.client.core.message.kv.*;
import com.couchbase.client.core.message.query.GenericQueryRequest;
import com.couchbase.client.core.message.query.GenericQueryResponse;
import com.couchbase.client.core.message.view.ViewQueryRequest;
import com.couchbase.client.core.message.view.ViewQueryResponse;
import com.couchbase.client.core.message.observe.Observe;
import com.couchbase.client.deps.io.netty.buffer.ByteBuf;
import com.couchbase.client.java.bucket.AsyncBucketManager;
import com.couchbase.client.java.bucket.DefaultAsyncBucketManager;
import com.couchbase.client.java.document.Document;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.JsonLongDocument;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.error.*;
import com.couchbase.client.java.query.*;
import com.couchbase.client.java.transcoder.*;
import com.couchbase.client.java.view.*;
import rx.Observable;
import rx.functions.Func1;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CouchbaseAsyncBucket implements AsyncBucket {
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 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 password;
private final ClusterFacade core;
private final Map<Class<? extends Document>, Transcoder<? extends Document, ?>> transcoders;
private final AsyncBucketManager bucketManager;
public CouchbaseAsyncBucket(final ClusterFacade core, final String name, final String password,
final List<Transcoder<? extends Document, ?>> customTranscoders) {
bucket = name;
this.password = password;
this.core = core;
transcoders = new ConcurrentHashMap<Class<? extends Document>, Transcoder<? extends Document, ?>>();
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);
for (Transcoder<? extends Document, ?> custom : customTranscoders) {
transcoders.put(custom.documentType(), custom);
}
bucketManager = DefaultAsyncBucketManager.create(bucket, password, core);
}
@Override
public String name() {
return bucket;
}
@Override
public Observable<JsonDocument> get(final String id) {
return get(id, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> get(D document) {
return (Observable<D>) get(document.id(), document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> get(final String id, final Class<D> target) {
return core
.<GetResponse>send(new GetRequest(id, bucket))
.filter(new Func1<GetResponse, Boolean>() {
@Override
public Boolean call(GetResponse getResponse) {
return getResponse.status() == ResponseStatus.SUCCESS;
}
})
.map(new Func1<GetResponse, D>() {
@Override
public D call(final GetResponse response) {
Transcoder<?, Object> transcoder = (Transcoder<?, Object>) transcoders.get(target);
return (D) transcoder.decode(id, response.content(), response.cas(), 0, response.flags(), response.status());
}
});
}
@Override
public Observable<JsonDocument> getAndLock(String id, int lockTime) {
return getAndLock(id, lockTime, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> getAndLock(D document, int lockTime) {
return (Observable<D>) getAndLock(document.id(), lockTime, document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> getAndLock(final String id, final int lockTime, final Class<D> target) {
return core.<GetResponse>send(new GetRequest(id, bucket, true, false, lockTime))
.filter(new Func1<GetResponse, Boolean>() {
@Override
public Boolean call(GetResponse getResponse) {
return getResponse.status() == ResponseStatus.SUCCESS;
}
})
.map(new Func1<GetResponse, D>() {
@Override
public D call(final GetResponse response) {
Transcoder<?, Object> transcoder = (Transcoder<?, Object>) transcoders.get(target);
return (D) transcoder.decode(id, response.content(), response.cas(), 0, response.flags(), response.status());
}
});
}
@Override
public Observable<JsonDocument> getAndTouch(String id, int expiry) {
return getAndTouch(id, expiry, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> getAndTouch(D document) {
return (Observable<D>) getAndTouch(document.id(), document.expiry(), document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> getAndTouch(final String id, final int expiry, final Class<D> target) {
return core.<GetResponse>send(new GetRequest(id, bucket, false, true, expiry))
.filter(new Func1<GetResponse, Boolean>() {
@Override
public Boolean call(GetResponse getResponse) {
return getResponse.status() == ResponseStatus.SUCCESS;
}
})
.map(new Func1<GetResponse, D>() {
@Override
public D call(final GetResponse response) {
Transcoder<?, Object> transcoder = (Transcoder<?, Object>) transcoders.get(target);
return (D) transcoder.decode(id, response.content(), response.cas(), 0, response.flags(), response.status());
}
});
}
@Override
public Observable<JsonDocument> getFromReplica(final String id, final ReplicaMode type) {
return getFromReplica(id, type, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> getFromReplica(final D document, final ReplicaMode type) {
return (Observable<D>) getFromReplica(document.id(), type, document.getClass());
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> getFromReplica(final String id, final ReplicaMode type,
final Class<D> target) {
Observable<GetResponse> incoming;
if (type == ReplicaMode.ALL) {
incoming = core
.<GetClusterConfigResponse>send(new GetClusterConfigRequest())
.map(new Func1<GetClusterConfigResponse, Integer>() {
@Override
public Integer call(GetClusterConfigResponse response) {
CouchbaseBucketConfig conf = (CouchbaseBucketConfig) response.config().bucketConfig(bucket);
return conf.numberOfReplicas();
}
}).flatMap(new Func1<Integer, Observable<BinaryRequest>>() {
@Override
public Observable<BinaryRequest> call(Integer max) {
List<BinaryRequest> requests = new ArrayList<BinaryRequest>();
requests.add(new GetRequest(id, bucket));
for (int i = 0; i < max; i++) {
requests.add(new ReplicaGetRequest(id, bucket, (short)(i+1)));
}
return Observable.from(requests);
}
}).flatMap(new Func1<BinaryRequest, Observable<GetResponse>>() {
@Override
public Observable<GetResponse> call(BinaryRequest req) {
return core.send(req);
}
});
} else {
incoming = core.send(new ReplicaGetRequest(id, bucket, (short) type.ordinal()));
}
return incoming
.filter(new Func1<GetResponse, Boolean>() {
@Override
public Boolean call(GetResponse getResponse) {
return getResponse.status() == ResponseStatus.SUCCESS;
}
})
.map(new Func1<GetResponse, D>() {
@Override
public D call(final GetResponse response) {
Transcoder<?, Object> transcoder = (Transcoder<?, Object>) transcoders.get(target);
return (D) transcoder.decode(id, response.content(), response.cas(), 0, response.flags(), response.status());
}
});
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> insert(final D document) {
final Transcoder<Document<Object>, Object> transcoder = (Transcoder<Document<Object>, Object>) transcoders.get(document.getClass());
Tuple2<ByteBuf, Integer> encoded = transcoder.encode((Document<Object>) document);
return core
.<InsertResponse>send(new InsertRequest(document.id(), encoded.value1(), document.expiry(), encoded.value2(), bucket))
.flatMap(new Func1<InsertResponse, Observable<? extends D>>() {
@Override
public Observable<? extends D> call(InsertResponse response) {
if (response.status() == ResponseStatus.EXISTS) {
return Observable.error(new DocumentAlreadyExistsException());
}
return Observable.just((D) transcoder.newDocument(document.id(), document.expiry(), document.content(), response.cas()));
}
});
}
@Override
public <D extends Document<?>> Observable<D> insert(final D document, final PersistTo persistTo,
final ReplicateTo replicateTo) {
return insert(document).flatMap(new Func1<D, Observable<D>>() {
@Override
public Observable<D> call(final D doc) {
return Observe
.call(core, bucket, doc.id(), doc.cas(), false, persistTo.value(), replicateTo.value())
.map(new Func1<Boolean, D>() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
}).onErrorResumeNext(new Func1<Throwable, Observable<? extends D>>() {
@Override
public Observable<? extends D> call(Throwable throwable) {
return Observable.error(new DurabilityException("Durability constraint failed.", throwable));
}
});
}
});
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> upsert(final D document) {
final Transcoder<Document<Object>, Object> transcoder = (Transcoder<Document<Object>, Object>) transcoders.get(document.getClass());
Tuple2<ByteBuf, Integer> encoded = transcoder.encode((Document<Object>) document);
return core
.<UpsertResponse>send(new UpsertRequest(document.id(), encoded.value1(), document.expiry(), encoded.value2(), bucket))
.flatMap(new Func1<UpsertResponse, Observable<D>>() {
@Override
public Observable<D> call(UpsertResponse response) {
if (response.status() == ResponseStatus.EXISTS) {
return Observable.error(new CASMismatchException());
}
return Observable.just((D) transcoder.newDocument(document.id(), document.expiry(), document.content(), response.cas()));
}
});
}
@Override
public <D extends Document<?>> Observable<D> upsert(final D document, final PersistTo persistTo, final ReplicateTo replicateTo) {
return upsert(document).flatMap(new Func1<D, Observable<D>>() {
@Override
public Observable<D> call(final D doc) {
return Observe
.call(core, bucket, doc.id(), doc.cas(), false, persistTo.value(), replicateTo.value())
.map(new Func1<Boolean, D>() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
});
}
});
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> replace(final D document) {
final Transcoder<Document<Object>, Object> transcoder = (Transcoder<Document<Object>, Object>) transcoders.get(document.getClass());
Tuple2<ByteBuf, Integer> encoded = transcoder.encode((Document<Object>) document);
return core.<ReplaceResponse>send(new ReplaceRequest(document.id(), encoded.value1(), document.cas(), document.expiry(), encoded.value2(), bucket))
.flatMap(new Func1<ReplaceResponse, Observable<D>>() {
@Override
public Observable<D> call(ReplaceResponse response) {
if (response.status() == ResponseStatus.NOT_EXISTS) {
return Observable.error(new DocumentDoesNotExistException());
}
if (response.status() == ResponseStatus.EXISTS) {
return Observable.error(new CASMismatchException());
}
return Observable.just((D) transcoder.newDocument(document.id(), document.expiry(), document.content(), response.cas()));
}
});
}
@Override
public <D extends Document<?>> Observable<D> replace(final D document, final PersistTo persistTo, final ReplicateTo replicateTo) {
return replace(document).flatMap(new Func1<D, Observable<D>>() {
@Override
public Observable<D> call(final D doc) {
return Observe
.call(core, bucket, doc.id(), doc.cas(), false, persistTo.value(), replicateTo.value())
.map(new Func1<Boolean, D>() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
});
}
});
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> remove(final D document) {
final Transcoder<Document<Object>, Object> transcoder =
(Transcoder<Document<Object>, Object>) transcoders.get(document.getClass());
RemoveRequest request = new RemoveRequest(document.id(), document.cas(),
bucket);
return core
.<RemoveResponse>send(request)
.map(new Func1<RemoveResponse, D>() {
@Override
public D call(final RemoveResponse response) {
if (response.status() == ResponseStatus.EXISTS) {
throw new CASMismatchException();
}
return (D) transcoder.newDocument(document.id(), 0, null, response.cas());
}
});
}
@Override
public Observable<JsonDocument> remove(final String id) {
return remove(id, JsonDocument.class);
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> remove(final String id, final Class<D> target) {
final Transcoder<Document<Object>, Object> transcoder = (Transcoder<Document<Object>, Object>) transcoders.get(target);
return remove((D) transcoder.newDocument(id, 0, null, 0));
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> remove(D document, PersistTo persistTo, ReplicateTo replicateTo) {
return (Observable<D>) remove(document.id(), persistTo, replicateTo, document.getClass());
}
@Override
public Observable<JsonDocument> remove(String id, PersistTo persistTo, ReplicateTo replicateTo) {
return remove(id, persistTo, replicateTo, JsonDocument.class);
}
@Override
public <D extends Document<?>> Observable<D> remove(String id, final PersistTo persistTo,
final ReplicateTo replicateTo, Class<D> target) {
return remove(id, target).flatMap(new Func1<D, Observable<D>>() {
@Override
public Observable<D> call(final D doc) {
return Observe
.call(core, bucket, doc.id(), doc.cas(), true, persistTo.value(), replicateTo.value())
.map(new Func1<Boolean, D>() {
@Override
public D call(Boolean aBoolean) {
return doc;
}
});
}
});
}
@Override
public Observable<AsyncViewResult> query(final ViewQuery query) {
final ViewQueryRequest request = new ViewQueryRequest(query.getDesign(), query.getView(), query.isDevelopment(),
query.toString(), bucket, password);
return core.<ViewQueryResponse>send(request)
.flatMap(new Func1<ViewQueryResponse, Observable<AsyncViewResult>>() {
@Override
public Observable<AsyncViewResult> call(final ViewQueryResponse response) {
return ViewQueryResponseMapper.mapToViewResult(CouchbaseAsyncBucket.this, query, response);
}
});
}
@Override
public Observable<AsyncQueryResult> query(final Query query) {
return query(query.toString());
}
@Override
public Observable<AsyncQueryResult> query(final String query) {
GenericQueryRequest request = new GenericQueryRequest(query, bucket, password);
return core
.<GenericQueryResponse>send(request)
.flatMap(new Func1<GenericQueryResponse, Observable<AsyncQueryResult>>() {
@Override
public Observable<AsyncQueryResult> call(final GenericQueryResponse response) {
final Observable<AsyncQueryRow> rows = response.rows().map(new Func1<ByteBuf, AsyncQueryRow>() {
@Override
public AsyncQueryRow call(ByteBuf byteBuf) {
try {
JsonObject value = JSON_OBJECT_TRANSCODER.byteBufToJsonObject(byteBuf);
return new DefaultAsyncQueryRow(value);
} catch (Exception e) {
throw new TranscodingException("Could not decode View Info.", e);
}
}
});
final Observable<JsonObject> info = response.info().map(new Func1<ByteBuf, JsonObject>() {
@Override
public JsonObject call(ByteBuf byteBuf) {
try {
return JSON_OBJECT_TRANSCODER.byteBufToJsonObject(byteBuf);
} catch (Exception e) {
throw new TranscodingException("Could not decode View Info.", e);
}
}
});
if (response.status().isSuccess()) {
return Observable.just((AsyncQueryResult) new DefaultAsyncQueryResult(rows, info, null,
response.status().isSuccess()));
} else {
return response.info().map(new Func1<ByteBuf, AsyncQueryResult>() {
@Override
public AsyncQueryResult call(ByteBuf byteBuf) {
try {
JsonObject error = JSON_OBJECT_TRANSCODER.byteBufToJsonObject(byteBuf);
return new DefaultAsyncQueryResult(rows, info, error, response.status().isSuccess());
} catch (Exception e) {
throw new TranscodingException("Could not decode View Info.", e);
}
}
});
}
}
});
}
@Override
public Observable<JsonLongDocument> counter(String id, long delta) {
return counter(id, delta, delta);
}
@Override
public Observable<JsonLongDocument> counter(String id, long delta, long initial) {
return counter(id, delta, initial, 0);
}
@Override
public Observable<JsonLongDocument> counter(final String id, final long delta, final long initial, final int expiry) {
return core
.<CounterResponse>send(new CounterRequest(id, initial, delta, expiry, bucket))
.map(new Func1<CounterResponse, JsonLongDocument>() {
@Override
public JsonLongDocument call(CounterResponse response) {
return JsonLongDocument.create(id, expiry, response.value(), response.cas());
}
});
}
@Override
public Observable<Boolean> unlock(String id, long cas) {
return core
.<UnlockResponse>send(new UnlockRequest(id, cas, bucket))
.map(new Func1<UnlockResponse, Boolean>() {
@Override
public Boolean call(UnlockResponse response) {
if (response.status() == ResponseStatus.NOT_EXISTS) {
throw new DocumentDoesNotExistException();
}
if (response.status() == ResponseStatus.FAILURE) {
throw new CASMismatchException();
}
return response.status().isSuccess();
}
});
}
@Override
public <D extends Document<?>> Observable<Boolean> unlock(D document) {
return unlock(document.id(), document.cas());
}
@Override
public Observable<Boolean> touch(String id, int expiry) {
return core.<TouchResponse>send(new TouchRequest(id, expiry, bucket)).map(new Func1<TouchResponse, Boolean>() {
@Override
public Boolean call(TouchResponse touchResponse) {
return touchResponse.status().isSuccess();
}
});
}
@Override
public <D extends Document<?>> Observable<Boolean> touch(D document) {
return touch(document.id(), document.expiry());
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> append(final D document) {
final Transcoder<Document<Object>, Object> transcoder = (Transcoder<Document<Object>, Object>) transcoders.get(document.getClass());
Tuple2<ByteBuf, Integer> encoded = transcoder.encode((Document<Object>) document);
return core
.<AppendResponse>send(new AppendRequest(document.id(), document.cas(), encoded.value1(), bucket))
.map(new Func1<AppendResponse, D>() {
@Override
public D call(final AppendResponse response) {
if (response.status() == ResponseStatus.FAILURE) {
throw new DocumentDoesNotExistException();
}
return (D) transcoder.newDocument(document.id(), 0, null, response.cas());
}
});
}
@Override
@SuppressWarnings("unchecked")
public <D extends Document<?>> Observable<D> prepend(final D document) {
final Transcoder<Document<Object>, Object> transcoder = (Transcoder<Document<Object>, Object>) transcoders.get(document.getClass());
Tuple2<ByteBuf, Integer> encoded = transcoder.encode((Document<Object>) document);
return core
.<PrependResponse>send(new PrependRequest(document.id(), document.cas(), encoded.value1(), bucket))
.map(new Func1<PrependResponse, D>() {
@Override
public D call(final PrependResponse response) {
if (response.status() == ResponseStatus.FAILURE) {
throw new DocumentDoesNotExistException();
}
return (D) transcoder.newDocument(document.id(), 0, null, response.cas());
}
});
}
@Override
public Observable<AsyncBucketManager> bucketManager() {
return Observable.just(bucketManager);
}
@Override
public <D extends Document<?>> Observable<D> insert(D document, PersistTo persistTo) {
return insert(document, persistTo, ReplicateTo.NONE);
}
@Override
public <D extends Document<?>> Observable<D> insert(D document, ReplicateTo replicateTo) {
return insert(document, PersistTo.NONE, replicateTo);
}
@Override
public <D extends Document<?>> Observable<D> upsert(D document, PersistTo persistTo) {
return upsert(document, persistTo, ReplicateTo.NONE);
}
@Override
public <D extends Document<?>> Observable<D> upsert(D document, ReplicateTo replicateTo) {
return upsert(document, PersistTo.NONE, replicateTo);
}
@Override
public <D extends Document<?>> Observable<D> replace(D document, PersistTo persistTo) {
return replace(document, persistTo, ReplicateTo.NONE);
}
@Override
public <D extends Document<?>> Observable<D> replace(D document, ReplicateTo replicateTo) {
return replace(document, PersistTo.NONE, replicateTo);
}
@Override
public <D extends Document<?>> Observable<D> remove(D document, PersistTo persistTo) {
return remove(document, persistTo, ReplicateTo.NONE);
}
@Override
public <D extends Document<?>> Observable<D> remove(D document, ReplicateTo replicateTo) {
return remove(document, PersistTo.NONE, replicateTo);
}
@Override
public Observable<JsonDocument> remove(String id, PersistTo persistTo) {
return remove(id, persistTo, ReplicateTo.NONE);
}
@Override
public Observable<JsonDocument> remove(String id, ReplicateTo replicateTo) {
return remove(id, PersistTo.NONE, replicateTo);
}
@Override
public <D extends Document<?>> Observable<D> remove(String id, PersistTo persistTo, Class<D> target) {
return remove(id, persistTo, ReplicateTo.NONE, target);
}
@Override
public <D extends Document<?>> Observable<D> remove(String id, ReplicateTo replicateTo, Class<D> target) {
return remove(id, PersistTo.NONE, replicateTo, target);
}
@Override
public Observable<Boolean> close() {
return core.<CloseBucketResponse>send(new CloseBucketRequest(bucket))
.map(new Func1<CloseBucketResponse, Boolean>() {
@Override
public Boolean call(CloseBucketResponse response) {
return response.status().isSuccess();
}
});
}
}