use of com.couchbase.client.core.config.NodeInfo in project couchbase-jvm-clients by couchbase.
the class KeyValueLocator method couchbaseBucket.
private static void couchbaseBucket(final KeyValueRequest<?> request, final List<Node> nodes, final CouchbaseBucketConfig config, CoreContext ctx) {
if (!precheckCouchbaseBucket(request, config)) {
return;
}
int partitionId = partitionForKey(request.key(), config.numberOfPartitions());
request.partition((short) partitionId);
int nodeId = calculateNodeId(partitionId, request, config);
if (nodeId < 0) {
RetryOrchestrator.maybeRetry(ctx, request, RetryReason.NODE_NOT_AVAILABLE);
return;
}
NodeInfo nodeInfo = config.nodeAtIndex(nodeId);
for (Node node : nodes) {
if (node.identifier().equals(nodeInfo.identifier())) {
node.send(request);
return;
}
}
if (handleNotEqualNodeSizes(config.nodes().size(), nodes.size(), ctx)) {
RetryOrchestrator.maybeRetry(ctx, request, RetryReason.NODE_NOT_AVAILABLE);
return;
}
if (ctx.core().configurationProvider().bucketConfigLoadInProgress()) {
RetryOrchestrator.maybeRetry(ctx, request, RetryReason.BUCKET_OPEN_IN_PROGRESS);
} else {
throw new IllegalStateException("Node not found for request" + request);
}
}
use of com.couchbase.client.core.config.NodeInfo 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.NodeInfo 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.NodeInfo 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.NodeInfo in project couchbase-jvm-clients by couchbase.
the class KeyValueBucketRefresher method filterEligibleNodes.
/**
* Helper method to generate a stream of KV nodes that can be used to fetch a config.
*
* <p>To be more resilient to failures, this method (similar to 1.x) shifts the node
* list on each invocation by one to make sure we hit all of them eventually.</p>
*
* @param name the bucket name.
* @return a flux of nodes that have the KV service enabled.
*/
private Flux<NodeInfo> filterEligibleNodes(final String name) {
return Flux.defer(() -> {
BucketConfig config = provider.config().bucketConfig(name);
if (config == null) {
eventBus.publish(new BucketConfigRefreshFailedEvent(core.context(), BucketConfigRefreshFailedEvent.RefresherType.KV, BucketConfigRefreshFailedEvent.Reason.NO_BUCKET_FOUND, Optional.empty()));
return Flux.empty();
}
List<NodeInfo> nodes = new ArrayList<>(config.nodes());
shiftNodeList(nodes);
return Flux.fromIterable(nodes).filter(n -> n.services().containsKey(ServiceType.KV) || n.sslServices().containsKey(ServiceType.KV)).take(MAX_PARALLEL_FETCH);
});
}
Aggregations