use of com.couchbase.client.core.msg.kv.GetRequest in project couchbase-jvm-clients by couchbase.
the class ReactiveCollection method get.
/**
* Fetches a Document from a collection with custom options.
*
* @param id the document id which is used to uniquely identify it.
* @param options custom options to change the default behavior.
* @return a {@link Mono} indicating once loaded or failed
*/
public Mono<GetResult> get(final String id, final GetOptions options) {
return Mono.defer(() -> {
GetOptions.Built opts = options.build();
final Transcoder transcoder = opts.transcoder() == null ? environment().transcoder() : opts.transcoder();
if (opts.projections().isEmpty() && !opts.withExpiry()) {
GetRequest request = asyncCollection.fullGetRequest(id, opts);
return Reactor.wrap(request, GetAccessor.get(core, request, transcoder), true);
} else {
SubdocGetRequest request = asyncCollection.subdocGetRequest(id, opts);
return Reactor.wrap(request, GetAccessor.subdocGet(core, request, transcoder), true);
}
});
}
use of com.couchbase.client.core.msg.kv.GetRequest in project couchbase-jvm-clients by couchbase.
the class KeyValueLocatorTest method pickCurrentIfNoFFMapAndNmvbSeen.
@Test
@SuppressWarnings("unchecked")
void pickCurrentIfNoFFMapAndNmvbSeen() {
Locator locator = new KeyValueLocator();
// Setup 2 nodes
NodeInfo nodeInfo1 = new NodeInfo("http://foo:1234", "192.168.56.101:8091", Collections.EMPTY_MAP, null);
NodeInfo nodeInfo2 = new NodeInfo("http://foo:1234", "192.168.56.102:8091", Collections.EMPTY_MAP, null);
Node node1Mock = mock(Node.class);
when(node1Mock.identifier()).thenReturn(new NodeIdentifier("192.168.56.101", 8091));
Node node2Mock = mock(Node.class);
when(node2Mock.identifier()).thenReturn(new NodeIdentifier("192.168.56.102", 8091));
List<Node> nodes = new ArrayList<>(Arrays.asList(node1Mock, node2Mock));
// Configure Cluster and Bucket config
ClusterConfig configMock = mock(ClusterConfig.class);
CouchbaseBucketConfig bucketMock = mock(CouchbaseBucketConfig.class);
when(configMock.bucketConfig("bucket")).thenReturn(bucketMock);
when(bucketMock.nodes()).thenReturn(Arrays.asList(nodeInfo1, nodeInfo2));
when(bucketMock.numberOfPartitions()).thenReturn(1024);
when(bucketMock.nodeAtIndex(0)).thenReturn(nodeInfo1);
when(bucketMock.nodeAtIndex(1)).thenReturn(nodeInfo2);
when(bucketMock.hasFastForwardMap()).thenReturn(false);
// Fake a vbucket move in ffwd map from node 0 to node 1
when(bucketMock.nodeIndexForActive(656, false)).thenReturn((short) 0);
when(bucketMock.nodeIndexForActive(656, true)).thenReturn((short) 1);
// Create Request
GetRequest getRequest = mock(GetRequest.class);
when(getRequest.bucket()).thenReturn("bucket");
when(getRequest.key()).thenReturn("key".getBytes(UTF_8));
RequestContext requestCtx = mock(RequestContext.class);
when(getRequest.context()).thenReturn(requestCtx);
when(getRequest.rejectedWithNotMyVbucket()).thenReturn(9);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(1)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
when(getRequest.rejectedWithNotMyVbucket()).thenReturn(1);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(2)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
}
use of com.couchbase.client.core.msg.kv.GetRequest in project couchbase-jvm-clients by couchbase.
the class ReplicaHelper method getAllReplicasRequests.
/**
* Helper method to assemble a stream of requests to the active and all replicas
*
* @param core the core to execute the request
* @param collectionIdentifier the collection containing the document
* @param documentId the ID of the document
* @param clientContext (nullable) client context info
* @param retryStrategy the retry strategy to use
* @param timeout the timeout until we need to stop the get all replicas
* @param parent the "get all/any replicas" request span
* @return a stream of requests.
*/
public static CompletableFuture<Stream<GetRequest>> getAllReplicasRequests(final Core core, final CollectionIdentifier collectionIdentifier, final String documentId, final Map<String, Object> clientContext, final RetryStrategy retryStrategy, final Duration timeout, final RequestSpan parent) {
notNullOrEmpty(documentId, "Id");
final CoreContext coreContext = core.context();
final CoreEnvironment environment = coreContext.environment();
final BucketConfig config = core.clusterConfig().bucketConfig(collectionIdentifier.bucket());
if (config instanceof CouchbaseBucketConfig) {
int numReplicas = ((CouchbaseBucketConfig) config).numberOfReplicas();
List<GetRequest> requests = new ArrayList<>(numReplicas + 1);
RequestSpan span = environment.requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_GET, parent);
GetRequest activeRequest = new GetRequest(documentId, timeout, coreContext, collectionIdentifier, retryStrategy, span);
activeRequest.context().clientContext(clientContext);
requests.add(activeRequest);
for (short replica = 1; replica <= numReplicas; replica++) {
RequestSpan replicaSpan = environment.requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_GET_REPLICA, parent);
ReplicaGetRequest replicaRequest = new ReplicaGetRequest(documentId, timeout, coreContext, collectionIdentifier, retryStrategy, replica, replicaSpan);
replicaRequest.context().clientContext(clientContext);
requests.add(replicaRequest);
}
return CompletableFuture.completedFuture(requests.stream());
} else if (config == null) {
// no bucket config found, it might be in-flight being opened so we need to reschedule the operation until
// the timeout fires!
final Duration retryDelay = Duration.ofMillis(100);
final CompletableFuture<Stream<GetRequest>> future = new CompletableFuture<>();
coreContext.environment().timer().schedule(() -> {
getAllReplicasRequests(core, collectionIdentifier, documentId, clientContext, retryStrategy, timeout.minus(retryDelay), parent).whenComplete((getRequestStream, throwable) -> {
if (throwable != null) {
future.completeExceptionally(throwable);
} else {
future.complete(getRequestStream);
}
});
}, retryDelay);
return future;
} else {
final CompletableFuture<Stream<GetRequest>> future = new CompletableFuture<>();
future.completeExceptionally(CommonExceptions.getFromReplicaNotCouchbaseBucket());
return future;
}
}
use of com.couchbase.client.core.msg.kv.GetRequest in project couchbase-jvm-clients by couchbase.
the class KeyValueMessageHandlerTest method retriesCertainResponseStatusCodes.
/**
* Certain status codes are identified that should be passed to the retry orchestrator rathen than complete
* the response right away.
*/
@Test
void retriesCertainResponseStatusCodes() {
List<MemcacheProtocol.Status> retryOnThese = Arrays.asList(MemcacheProtocol.Status.LOCKED, MemcacheProtocol.Status.TEMPORARY_FAILURE, MemcacheProtocol.Status.SYNC_WRITE_IN_PROGRESS, MemcacheProtocol.Status.SYNC_WRITE_RE_COMMIT_IN_PROGRESS);
List<RetryReason> retryReasons = Arrays.asList(RetryReason.KV_LOCKED, RetryReason.KV_TEMPORARY_FAILURE, RetryReason.KV_SYNC_WRITE_IN_PROGRESS, RetryReason.KV_SYNC_WRITE_RE_COMMIT_IN_PROGRESS);
int i = 0;
for (MemcacheProtocol.Status status : retryOnThese) {
EmbeddedChannel channel = new EmbeddedChannel(new KeyValueMessageHandler(null, CTX, Optional.of(BUCKET)));
try {
GetRequest request = new GetRequest("key", Duration.ofSeconds(1), CTX, CID, FailFastRetryStrategy.INSTANCE, null);
channel.writeOutbound(request);
ByteBuf getResponse = MemcacheProtocol.response(channel.alloc(), MemcacheProtocol.Opcode.GET, (byte) 0, status.status(), request.opaque(), 0, Unpooled.EMPTY_BUFFER, Unpooled.EMPTY_BUFFER, Unpooled.EMPTY_BUFFER);
channel.writeInbound(getResponse);
assertEquals(CancellationReason.noMoreRetries(retryReasons.get(i)), request.cancellationReason());
assertEquals(0, getResponse.refCnt());
i++;
} finally {
channel.finishAndReleaseAll();
}
}
}
use of com.couchbase.client.core.msg.kv.GetRequest in project couchbase-jvm-clients by couchbase.
the class KeyValueMessageHandlerTest method opaqueIsIncreasing.
/**
* This test sends two get requests and makes sure the latter one has a higher opaque then the
* former one.
*/
@Test
void opaqueIsIncreasing() {
EmbeddedChannel channel = new EmbeddedChannel(new KeyValueMessageHandler(null, CTX, Optional.of(BUCKET)));
try {
channel.writeOutbound(new GetRequest("key", Duration.ofSeconds(1), CTX, CID, null, null));
channel.flushOutbound();
ByteBuf request = channel.readOutbound();
int firstOpaque = MemcacheProtocol.opaque(request);
assertTrue(firstOpaque > 0);
ReferenceCountUtil.release(request);
channel.writeOutbound(new GetRequest("key", Duration.ofSeconds(1), CTX, CID, null, null));
channel.flushOutbound();
request = channel.readOutbound();
int secondOpaque = MemcacheProtocol.opaque(request);
assertTrue(secondOpaque > firstOpaque);
ReferenceCountUtil.release(request);
} finally {
channel.finishAndReleaseAll();
}
}
Aggregations