Search in sources :

Example 6 with HostAndPort

use of io.lettuce.core.internal.HostAndPort in project lettuce-core by lettuce-io.

the class ClusterDistributionChannelWriter method doWrite.

private <K, V, T> RedisCommand<K, V, T> doWrite(RedisCommand<K, V, T> command) {
    if (command instanceof ClusterCommand && !command.isDone()) {
        ClusterCommand<K, V, T> clusterCommand = (ClusterCommand<K, V, T>) command;
        if (clusterCommand.isMoved() || clusterCommand.isAsk()) {
            HostAndPort target;
            boolean asking;
            ByteBuffer firstEncodedKey = clusterCommand.getArgs().getFirstEncodedKey();
            String keyAsString = null;
            int slot = -1;
            if (firstEncodedKey != null) {
                firstEncodedKey.mark();
                keyAsString = StringCodec.UTF8.decodeKey(firstEncodedKey);
                firstEncodedKey.reset();
                slot = getSlot(firstEncodedKey);
            }
            if (clusterCommand.isMoved()) {
                target = getMoveTarget(clusterCommand.getError());
                clusterEventListener.onMovedRedirection();
                asking = false;
                publish(new MovedRedirectionEvent(clusterCommand.getType().name(), keyAsString, slot, clusterCommand.getError()));
            } else {
                target = getAskTarget(clusterCommand.getError());
                asking = true;
                clusterEventListener.onAskRedirection();
                publish(new AskRedirectionEvent(clusterCommand.getType().name(), keyAsString, slot, clusterCommand.getError()));
            }
            command.getOutput().setError((String) null);
            CompletableFuture<StatefulRedisConnection<K, V>> connectFuture = asyncClusterConnectionProvider.getConnectionAsync(Intent.WRITE, target.getHostText(), target.getPort());
            if (isSuccessfullyCompleted(connectFuture)) {
                writeCommand(command, asking, connectFuture.join(), null);
            } else {
                connectFuture.whenComplete((connection, throwable) -> writeCommand(command, asking, connection, throwable));
            }
            return command;
        }
    }
    ClusterCommand<K, V, T> commandToSend = getCommandToSend(command);
    CommandArgs<K, V> args = command.getArgs();
    // exclude CLIENT commands from cluster routing
    if (args != null && !CommandType.CLIENT.equals(commandToSend.getType())) {
        ByteBuffer encodedKey = args.getFirstEncodedKey();
        if (encodedKey != null) {
            int hash = getSlot(encodedKey);
            Intent intent = getIntent(command.getType());
            CompletableFuture<StatefulRedisConnection<K, V>> connectFuture = ((AsyncClusterConnectionProvider) clusterConnectionProvider).getConnectionAsync(intent, hash);
            if (isSuccessfullyCompleted(connectFuture)) {
                writeCommand(commandToSend, false, connectFuture.join(), null);
            } else {
                connectFuture.whenComplete((connection, throwable) -> writeCommand(commandToSend, false, connection, throwable));
            }
            return commandToSend;
        }
    }
    writeCommand(commandToSend, defaultWriter);
    return commandToSend;
}
Also used : Intent(io.lettuce.core.cluster.ClusterConnectionProvider.Intent) ByteBuffer(java.nio.ByteBuffer) DefaultEndpoint(io.lettuce.core.protocol.DefaultEndpoint) StatefulRedisConnection(io.lettuce.core.api.StatefulRedisConnection) MovedRedirectionEvent(io.lettuce.core.cluster.event.MovedRedirectionEvent) HostAndPort(io.lettuce.core.internal.HostAndPort) AskRedirectionEvent(io.lettuce.core.cluster.event.AskRedirectionEvent)

Example 7 with HostAndPort

use of io.lettuce.core.internal.HostAndPort in project lettuce-core by lettuce-io.

the class RedisClusterURIUtil method toRedisURIs.

/**
 * Parse a Redis Cluster URI with potentially multiple hosts into a {@link List} of {@link RedisURI}.
 *
 * An URI follows the syntax: {@code redis://[password@]host[:port][,host2[:port2]]}
 *
 * @param uri must not be empty or {@code null}.
 * @return {@link List} of {@link RedisURI}.
 */
public static List<RedisURI> toRedisURIs(URI uri) {
    RedisURI redisURI = RedisURI.create(uri);
    String[] parts = redisURI.getHost().split("\\,");
    List<RedisURI> redisURIs = new ArrayList<>(parts.length);
    for (String part : parts) {
        HostAndPort hostAndPort = HostAndPort.parse(part);
        RedisURI nodeUri = RedisURI.create(hostAndPort.getHostText(), hostAndPort.hasPort() ? hostAndPort.getPort() : redisURI.getPort());
        applyUriConnectionSettings(redisURI, nodeUri);
        redisURIs.add(nodeUri);
    }
    return redisURIs;
}
Also used : HostAndPort(io.lettuce.core.internal.HostAndPort) RedisURI(io.lettuce.core.RedisURI) ArrayList(java.util.ArrayList)

Example 8 with HostAndPort

use of io.lettuce.core.internal.HostAndPort in project lettuce-core by lettuce-io.

the class ClusterPartitionParser method parseNode.

private static RedisClusterNode parseNode(String nodeInformation) {
    Iterator<String> iterator = Arrays.asList(nodeInformation.split(" ")).iterator();
    String nodeId = iterator.next();
    boolean connected = false;
    RedisURI uri = null;
    String hostAndPortPart = iterator.next();
    if (hostAndPortPart.contains("@")) {
        hostAndPortPart = hostAndPortPart.substring(0, hostAndPortPart.indexOf('@'));
    }
    HostAndPort hostAndPort = HostAndPort.parseCompat(hostAndPortPart);
    if (LettuceStrings.isNotEmpty(hostAndPort.getHostText())) {
        uri = RedisURI.Builder.redis(hostAndPort.getHostText(), hostAndPort.getPort()).build();
    }
    String flags = iterator.next();
    List<String> flagStrings = LettuceLists.newList(flags.split("\\,"));
    Set<RedisClusterNode.NodeFlag> nodeFlags = readFlags(flagStrings);
    // (nodeId or -)
    String replicaOfString = iterator.next();
    String replicaOf = "-".equals(replicaOfString) ? null : replicaOfString;
    long pingSentTs = getLongFromIterator(iterator, 0);
    long pongReceivedTs = getLongFromIterator(iterator, 0);
    long configEpoch = getLongFromIterator(iterator, 0);
    // "connected" : "disconnected"
    String connectedFlags = iterator.next();
    if (CONNECTED.equals(connectedFlags)) {
        connected = true;
    }
    // slot, from-to [slot->-nodeID] [slot-<-nodeID]
    List<String> slotStrings = LettuceLists.newList(iterator);
    BitSet slots = readSlots(slotStrings);
    RedisClusterNode partition = new RedisClusterNode(uri, nodeId, connected, replicaOf, pingSentTs, pongReceivedTs, configEpoch, slots, nodeFlags);
    return partition;
}
Also used : HostAndPort(io.lettuce.core.internal.HostAndPort) RedisURI(io.lettuce.core.RedisURI)

Example 9 with HostAndPort

use of io.lettuce.core.internal.HostAndPort in project lettuce-core by lettuce-io.

the class ClusterDistributionChannelWriterUnitTests method shouldParseIPv6MovedTargetCorrectly.

@Test
void shouldParseIPv6MovedTargetCorrectly() {
    HostAndPort moveTarget = ClusterDistributionChannelWriter.getMoveTarget("MOVED 1234-2020 1:2:3:4::6:6381");
    assertThat(moveTarget.getHostText()).isEqualTo("1:2:3:4::6");
    assertThat(moveTarget.getPort()).isEqualTo(6381);
}
Also used : HostAndPort(io.lettuce.core.internal.HostAndPort) Test(org.junit.jupiter.api.Test)

Example 10 with HostAndPort

use of io.lettuce.core.internal.HostAndPort in project lettuce-core by lettuce-io.

the class ClusterDistributionChannelWriterUnitTests method shouldParseMovedTargetCorrectly.

@Test
void shouldParseMovedTargetCorrectly() {
    HostAndPort moveTarget = ClusterDistributionChannelWriter.getMoveTarget("MOVED 1234-2020 127.0.0.1:6381");
    assertThat(moveTarget.getHostText()).isEqualTo("127.0.0.1");
    assertThat(moveTarget.getPort()).isEqualTo(6381);
}
Also used : HostAndPort(io.lettuce.core.internal.HostAndPort) Test(org.junit.jupiter.api.Test)

Aggregations

HostAndPort (io.lettuce.core.internal.HostAndPort)11 Test (org.junit.jupiter.api.Test)4 RedisURI (io.lettuce.core.RedisURI)3 ArrayList (java.util.ArrayList)2 StatefulRedisConnection (io.lettuce.core.api.StatefulRedisConnection)1 Intent (io.lettuce.core.cluster.ClusterConnectionProvider.Intent)1 AskRedirectionEvent (io.lettuce.core.cluster.event.AskRedirectionEvent)1 MovedRedirectionEvent (io.lettuce.core.cluster.event.MovedRedirectionEvent)1 DefaultEndpoint (io.lettuce.core.protocol.DefaultEndpoint)1 InetSocketAddress (java.net.InetSocketAddress)1 UnknownHostException (java.net.UnknownHostException)1 ByteBuffer (java.nio.ByteBuffer)1 RedisSentinelConfiguration (org.springframework.data.redis.connection.RedisSentinelConfiguration)1 RedisStandaloneConfiguration (org.springframework.data.redis.connection.RedisStandaloneConfiguration)1 LettuceConnectionFactory (org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory)1