Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
Advanced and thread-safe Java Redis client for synchronous, asynchronous, and
reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs
and much more.
/*
* Copyright 2019-Present, Redis Ltd. and Contributors
* All rights reserved.
*
* Licensed under the MIT License.
*
* This file contains contributions from third-party contributors
* licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.lettuce.core;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.lettuce.core.codec.StringCodec;
import io.lettuce.core.internal.Futures;
import io.lettuce.core.internal.LettuceAssert;
import io.lettuce.core.internal.LettuceStrings;
import io.lettuce.core.protocol.AsyncCommand;
import io.lettuce.core.protocol.Command;
import io.lettuce.core.protocol.ConnectionInitializer;
import io.lettuce.core.protocol.ProtocolVersion;
import io.netty.channel.Channel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
/**
* Redis RESP2/RESP3 handshake using the configured {@link ProtocolVersion} and other options for connection initialization and
* connection state restoration. This class is part of the internal API.
*
* @author Mark Paluch
* @author Tugdual Grall
* @since 6.0
*/
class RedisHandshake implements ConnectionInitializer {
private static final InternalLogger LOG = InternalLoggerFactory.getInstance(RedisHandshake.class);
private final RedisCommandBuilder commandBuilder = new RedisCommandBuilder<>(StringCodec.UTF8);
private final ProtocolVersion requestedProtocolVersion;
private final boolean pingOnConnect;
private final ConnectionState connectionState;
private volatile ProtocolVersion negotiatedProtocolVersion;
RedisHandshake(ProtocolVersion requestedProtocolVersion, boolean pingOnConnect, ConnectionState connectionState) {
this.requestedProtocolVersion = requestedProtocolVersion;
this.pingOnConnect = pingOnConnect;
this.connectionState = connectionState;
}
/**
* @return the requested {@link ProtocolVersion}. May be {@code null} if not configured.
*/
public ProtocolVersion getRequestedProtocolVersion() {
return requestedProtocolVersion;
}
/**
* @return the negotiated {@link ProtocolVersion} once the handshake is done.
*/
public ProtocolVersion getNegotiatedProtocolVersion() {
return negotiatedProtocolVersion;
}
@Override
public CompletionStage initialize(Channel channel) {
CompletionStage> handshake;
if (this.requestedProtocolVersion == ProtocolVersion.RESP2) {
handshake = initializeResp2(channel);
negotiatedProtocolVersion = ProtocolVersion.RESP2;
} else if (this.requestedProtocolVersion == ProtocolVersion.RESP3) {
handshake = initializeResp3(channel);
} else if (this.requestedProtocolVersion == null) {
handshake = tryHandshakeResp3(channel);
} else {
handshake = Futures.failed(
new RedisConnectionException("Protocol version" + this.requestedProtocolVersion + " not supported"));
}
return handshake
// post-handshake commands, whose execution failures would cause the connection to be considered
// unsuccessfully established
.thenCompose(ignore -> applyPostHandshake(channel))
// post-handshake commands, executed in a 'fire and forget' manner, to avoid having to react to different
// implementations or versions of the server runtime, and whose execution result (whether a success or a
// failure ) should not alter the outcome of the connection attempt
.thenCompose(ignore -> applyConnectionMetadataSafely(channel));
}
private CompletionStage> tryHandshakeResp3(Channel channel) {
CompletableFuture> handshake = new CompletableFuture<>();
CompletionStage