use of com.couchbase.client.core.config.CouchbaseBucketConfig in project couchbase-jvm-clients by couchbase.
the class KeyValueLocator method dispatch.
@Override
public void dispatch(final Request<? extends Response> request, final List<Node> nodes, final ClusterConfig config, final CoreContext ctx) {
if (request.target() != null) {
dispatchTargeted(request, nodes, ctx);
} else {
KeyValueRequest r = (KeyValueRequest) request;
String bucket = r.bucket();
BucketConfig bucketConfig = config.bucketConfig(bucket);
if (bucketConfig == null) {
// Since a bucket is opened lazily, it might not be available yet (or for some
// other reason the config is gone) - send it into retry!
RetryOrchestrator.maybeRetry(ctx, request, ctx.core().configurationProvider().bucketConfigLoadInProgress() ? RetryReason.BUCKET_OPEN_IN_PROGRESS : RetryReason.BUCKET_NOT_AVAILABLE);
return;
}
if (bucketConfig instanceof CouchbaseBucketConfig) {
couchbaseBucket(r, nodes, (CouchbaseBucketConfig) bucketConfig, ctx);
} else if (bucketConfig instanceof MemcachedBucketConfig) {
memcacheBucket(r, nodes, (MemcachedBucketConfig) bucketConfig, ctx);
} else {
throw new IllegalStateException("Unsupported Bucket Type: " + bucketConfig + " for request " + request);
}
}
}
use of com.couchbase.client.core.config.CouchbaseBucketConfig in project couchbase-jvm-clients by couchbase.
the class KeyValueLocatorTest method locateGetRequestForCouchbaseBucket.
@Test
@SuppressWarnings("unchecked")
void locateGetRequestForCouchbaseBucket() {
Locator locator = new KeyValueLocator();
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);
GetRequest getRequestMock = mock(GetRequest.class);
ClusterConfig configMock = mock(ClusterConfig.class);
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));
CouchbaseBucketConfig bucketMock = mock(CouchbaseBucketConfig.class);
when(getRequestMock.bucket()).thenReturn("bucket");
when(getRequestMock.key()).thenReturn("key".getBytes(UTF_8));
CoreContext coreContext = new CoreContext(mock(Core.class), 1, mock(CoreEnvironment.class), mock(Authenticator.class));
when(getRequestMock.context()).thenReturn(new RequestContext(coreContext, getRequestMock));
when(configMock.bucketConfig("bucket")).thenReturn(bucketMock);
when(bucketMock.nodes()).thenReturn(Arrays.asList(nodeInfo1, nodeInfo2));
when(bucketMock.numberOfPartitions()).thenReturn(1024);
when(bucketMock.nodeIndexForActive(656, false)).thenReturn((short) 0);
when(bucketMock.nodeAtIndex(0)).thenReturn(nodeInfo1);
locator.dispatch(getRequestMock, nodes, configMock, null);
verify(node1Mock, times(1)).send(getRequestMock);
verify(node2Mock, never()).send(getRequestMock);
}
use of com.couchbase.client.core.config.CouchbaseBucketConfig in project couchbase-jvm-clients by couchbase.
the class KeyValueLocatorTest method pickFastForwardIfAvailableAndNmvbSeen.
@Test
@SuppressWarnings("unchecked")
void pickFastForwardIfAvailableAndNmvbSeen() {
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(true);
// 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);
// Dispatch with retry 0
when(requestCtx.retryAttempts()).thenReturn(0);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(1)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
// Dispatch with retry 1 but no nmvb seen, still go to the active
when(requestCtx.retryAttempts()).thenReturn(1);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(2)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
// Dispatch with retry 2, now we see a NMVB
when(requestCtx.retryAttempts()).thenReturn(2);
when(getRequest.rejectedWithNotMyVbucket()).thenReturn(1);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(2)).send(getRequest);
verify(node2Mock, times(1)).send(getRequest);
}
use of com.couchbase.client.core.config.CouchbaseBucketConfig in project couchbase-jvm-clients by couchbase.
the class KeyValueLocatorTest method pickCurrentIfNoFFMapAndRetry.
@Test
@SuppressWarnings("unchecked")
void pickCurrentIfNoFFMapAndRetry() {
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);
// Dispatch with retry 0
when(requestCtx.retryAttempts()).thenReturn(0);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(1)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
// Dispatch with retry 1
when(requestCtx.retryAttempts()).thenReturn(1);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(2)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
// Dispatch with retry 5
when(requestCtx.retryAttempts()).thenReturn(5);
locator.dispatch(getRequest, nodes, configMock, null);
verify(node1Mock, times(3)).send(getRequest);
verify(node2Mock, never()).send(getRequest);
}
use of com.couchbase.client.core.config.CouchbaseBucketConfig in project couchbase-jvm-clients by couchbase.
the class ReactiveBatchHelper method existsBytes.
/**
* Performs the bulk logic of fetching a config and splitting up the observe requests.
*
* @param collection the collection on which the query should be performed.
* @param ids the list of ids which should be checked.
* @return a flux of all
*/
private static Flux<byte[]> existsBytes(final Collection collection, final java.util.Collection<String> ids) {
final Core core = collection.core();
final CoreEnvironment env = core.context().environment();
BucketConfig config = core.clusterConfig().bucketConfig(collection.bucketName());
if (core.configurationProvider().bucketConfigLoadInProgress() || config == null) {
// and then try again. In a steady state this should not happen.
return Mono.delay(Duration.ofMillis(100), env.scheduler()).flatMapMany(ign -> existsBytes(collection, ids));
}
long start = System.nanoTime();
if (!(config instanceof CouchbaseBucketConfig)) {
throw new IllegalStateException("Only couchbase (and ephemeral) buckets are supported at this point!");
}
Map<NodeIdentifier, Map<byte[], Short>> nodeEntries = new HashMap<>(config.nodes().size());
for (NodeInfo node : config.nodes()) {
nodeEntries.put(node.identifier(), new HashMap<>(ids.size() / config.nodes().size()));
}
CouchbaseBucketConfig cbc = (CouchbaseBucketConfig) config;
CollectionIdentifier ci = new CollectionIdentifier(collection.bucketName(), Optional.of(collection.scopeName()), Optional.of(collection.name()));
for (String id : ids) {
byte[] encodedId = id.getBytes(StandardCharsets.UTF_8);
int partitionId = KeyValueLocator.partitionForKey(encodedId, cbc.numberOfPartitions());
int nodeId = cbc.nodeIndexForActive(partitionId, false);
NodeInfo nodeInfo = cbc.nodeAtIndex(nodeId);
nodeEntries.get(nodeInfo.identifier()).put(encodedId, (short) partitionId);
}
List<Mono<MultiObserveViaCasResponse>> responses = new ArrayList<>(nodeEntries.size());
List<MultiObserveViaCasRequest> requests = new ArrayList<>(nodeEntries.size());
for (Map.Entry<NodeIdentifier, Map<byte[], Short>> node : nodeEntries.entrySet()) {
if (node.getValue().isEmpty()) {
// service enabled and 2) have keys that we need to fetch
continue;
}
MultiObserveViaCasRequest request = new MultiObserveViaCasRequest(env.timeoutConfig().kvTimeout(), core.context(), env.retryStrategy(), ci, node.getKey(), node.getValue(), PMGET_PREDICATE);
core.send(request);
requests.add(request);
responses.add(Reactor.wrap(request, request.response(), true));
}
return Flux.merge(responses).flatMap(response -> Flux.fromIterable(response.observed().keySet())).onErrorMap(throwable -> {
BatchErrorContext ctx = new BatchErrorContext(Collections.unmodifiableList(requests));
return new BatchHelperFailureException("Failed to perform BatchHelper bulk operation", throwable, ctx);
}).doOnComplete(() -> core.context().environment().eventBus().publish(new BatchHelperExistsCompletedEvent(Duration.ofNanos(System.nanoTime() - start), new BatchErrorContext(Collections.unmodifiableList(requests)))));
}
Aggregations