Search in sources :

Example 1 with NodeInfo

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);
    }
}
Also used : NodeInfo(com.couchbase.client.core.config.NodeInfo)

Example 2 with NodeInfo

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);
}
Also used : CoreContext(com.couchbase.client.core.CoreContext) CouchbaseBucketConfig(com.couchbase.client.core.config.CouchbaseBucketConfig) CoreEnvironment(com.couchbase.client.core.env.CoreEnvironment) ArrayList(java.util.ArrayList) NodeInfo(com.couchbase.client.core.config.NodeInfo) GetRequest(com.couchbase.client.core.msg.kv.GetRequest) RequestContext(com.couchbase.client.core.msg.RequestContext) Authenticator(com.couchbase.client.core.env.Authenticator) ClusterConfig(com.couchbase.client.core.config.ClusterConfig) Core(com.couchbase.client.core.Core) Test(org.junit.jupiter.api.Test)

Example 3 with NodeInfo

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);
}
Also used : CouchbaseBucketConfig(com.couchbase.client.core.config.CouchbaseBucketConfig) NodeInfo(com.couchbase.client.core.config.NodeInfo) GetRequest(com.couchbase.client.core.msg.kv.GetRequest) ArrayList(java.util.ArrayList) RequestContext(com.couchbase.client.core.msg.RequestContext) ClusterConfig(com.couchbase.client.core.config.ClusterConfig) Test(org.junit.jupiter.api.Test)

Example 4 with NodeInfo

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);
}
Also used : CouchbaseBucketConfig(com.couchbase.client.core.config.CouchbaseBucketConfig) NodeInfo(com.couchbase.client.core.config.NodeInfo) GetRequest(com.couchbase.client.core.msg.kv.GetRequest) ArrayList(java.util.ArrayList) RequestContext(com.couchbase.client.core.msg.RequestContext) ClusterConfig(com.couchbase.client.core.config.ClusterConfig) Test(org.junit.jupiter.api.Test)

Example 5 with NodeInfo

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);
    });
}
Also used : Disposable(reactor.core.Disposable) ArrayList(java.util.ArrayList) EventBus(com.couchbase.client.core.cnc.EventBus) ServiceType(com.couchbase.client.core.service.ServiceType) CoreContext(com.couchbase.client.core.CoreContext) Duration(java.time.Duration) Map(java.util.Map) Stability(com.couchbase.client.core.annotation.Stability) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) BucketConfig(com.couchbase.client.core.config.BucketConfig) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) Reactor(com.couchbase.client.core.Reactor) UTF_8(java.nio.charset.StandardCharsets.UTF_8) NodeInfo(com.couchbase.client.core.config.NodeInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Mono(reactor.core.publisher.Mono) FailFastRetryStrategy(com.couchbase.client.core.retry.FailFastRetryStrategy) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Optional(java.util.Optional) CollectionIdentifier(com.couchbase.client.core.io.CollectionIdentifier) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) CarrierBucketConfigRequest(com.couchbase.client.core.msg.kv.CarrierBucketConfigRequest) Core(com.couchbase.client.core.Core) NodeInfo(com.couchbase.client.core.config.NodeInfo) ArrayList(java.util.ArrayList) BucketConfigRefreshFailedEvent(com.couchbase.client.core.cnc.events.config.BucketConfigRefreshFailedEvent) BucketConfig(com.couchbase.client.core.config.BucketConfig)

Aggregations

NodeInfo (com.couchbase.client.core.config.NodeInfo)8 ArrayList (java.util.ArrayList)7 CouchbaseBucketConfig (com.couchbase.client.core.config.CouchbaseBucketConfig)5 Core (com.couchbase.client.core.Core)4 ClusterConfig (com.couchbase.client.core.config.ClusterConfig)4 RequestContext (com.couchbase.client.core.msg.RequestContext)4 GetRequest (com.couchbase.client.core.msg.kv.GetRequest)4 CoreContext (com.couchbase.client.core.CoreContext)3 Reactor (com.couchbase.client.core.Reactor)3 Stability (com.couchbase.client.core.annotation.Stability)3 BucketConfig (com.couchbase.client.core.config.BucketConfig)3 CollectionIdentifier (com.couchbase.client.core.io.CollectionIdentifier)3 Duration (java.time.Duration)3 List (java.util.List)3 Map (java.util.Map)3 Optional (java.util.Optional)3 Test (org.junit.jupiter.api.Test)3 Flux (reactor.core.publisher.Flux)3 Mono (reactor.core.publisher.Mono)3 EventBus (com.couchbase.client.core.cnc.EventBus)2