Skip to content

Commit

Permalink
Register library name and library version on Redis 7.2 or greater #2483
Browse files Browse the repository at this point in the history
RedisURI now accepts library name and library version and sets those after the handshake.
  • Loading branch information
mp911de committed Aug 15, 2023
1 parent 8afffae commit 556474e
Show file tree
Hide file tree
Showing 14 changed files with 484 additions and 46 deletions.
22 changes: 22 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,12 @@
<version>1.3.0</version>
</plugin>

<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.9.10</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
Expand Down Expand Up @@ -658,6 +664,19 @@
</pluginManagement>

<plugins>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
<phase>initialize</phase>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand Down Expand Up @@ -796,6 +815,9 @@
</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Implementation-Version>
${project.version}/${git.commit.id.abbrev}
</Implementation-Version>
<Automatic-Module-Name>lettuce.core</Automatic-Module-Name>
</manifestEntries>
</archive>
Expand Down
74 changes: 74 additions & 0 deletions src/main/java/io/lettuce/core/ConnectionMetadata.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2023 the original author or authors.
*
* 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;

/**
* @author Mark Paluch
*/
class ConnectionMetadata {

private volatile String clientName;

private volatile String libraryName;

private volatile String libraryVersion;

public ConnectionMetadata() {
}

public ConnectionMetadata(RedisURI uri) {
apply(uri);
}

public void apply(RedisURI redisURI) {

setClientName(redisURI.getClientName());
setLibraryName(redisURI.getLibraryName());
setLibraryVersion(redisURI.getLibraryVersion());
}

public void apply(ConnectionMetadata metadata) {

setClientName(metadata.getClientName());
setLibraryName(metadata.getLibraryName());
setLibraryVersion(metadata.getLibraryVersion());
}

protected void setClientName(String clientName) {
this.clientName = clientName;
}

String getClientName() {
return clientName;
}

void setLibraryName(String libraryName) {
this.libraryName = libraryName;
}

String getLibraryName() {
return libraryName;
}

void setLibraryVersion(String libraryVersion) {
this.libraryVersion = libraryVersion;
}

String getLibraryVersion() {
return libraryVersion;
}

}
16 changes: 12 additions & 4 deletions src/main/java/io/lettuce/core/ConnectionState.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ConnectionState {

private volatile boolean readOnly;

private volatile String clientName;
private volatile ConnectionMetadata connectionMetadata = new ConnectionMetadata();

/**
* Applies settings from {@link RedisURI}.
Expand All @@ -46,10 +46,18 @@ public class ConnectionState {
*/
public void apply(RedisURI redisURI) {

setClientName(redisURI.getClientName());
connectionMetadata.apply(redisURI);
setCredentialsProvider(redisURI.getCredentialsProvider());
}

void apply(ConnectionMetadata metadata) {
this.connectionMetadata.apply(metadata);
}

ConnectionMetadata getConnectionMetadata() {
return connectionMetadata;
}

/**
* Returns the negotiated {@link ProtocolVersion}.
*
Expand Down Expand Up @@ -142,11 +150,11 @@ boolean isReadOnly() {
}

protected void setClientName(String clientName) {
this.clientName = clientName;
this.connectionMetadata.setClientName(clientName);
}

String getClientName() {
return clientName;
return connectionMetadata.getClientName();
}

/**
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/io/lettuce/core/LettuceVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2023 the original author or authors.
*
* 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;

/**
* Class that exposes the Lettuce version. Fetches the "Implementation-Version" manifest attribute from the jar file.
* <p>
* Note that some ClassLoaders do not expose the package metadata, hence this class might not be able to determine the Lettuce
* version in all environments. Consider using a reflection-based check instead &mdash; for example, checking for the presence
* of a specific Lettuce method that you intend to call.
*
* @author Mark Paluch
* @since 6.3
*/
public final class LettuceVersion {

private LettuceVersion() {
}

/**
* Return the library name.
*/
public static String getName() {
return "Lettuce";
}

/**
* Return the full version string of the present Lettuce codebase, or {@code null} if it cannot be determined.
*
* @see Package#getImplementationVersion()
*/
public static String getVersion() {
Package pkg = LettuceVersion.class.getPackage();
return (pkg != null ? pkg.getImplementationVersion() : null);
}

}
13 changes: 5 additions & 8 deletions src/main/java/io/lettuce/core/RedisClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Supplier;

import reactor.core.publisher.Mono;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.codec.StringCodec;
import io.lettuce.core.internal.ExceptionFactory;
import io.lettuce.core.internal.Futures;
import io.lettuce.core.internal.LettuceAssert;
import io.lettuce.core.internal.LettuceStrings;
import io.lettuce.core.masterreplica.MasterReplica;
import io.lettuce.core.protocol.CommandExpiryWriter;
import io.lettuce.core.protocol.CommandHandler;
Expand All @@ -51,6 +49,7 @@
import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import reactor.core.publisher.Mono;

/**
* A scalable and thread-safe <a href="https://redis.io/">Redis</a> client supporting synchronous, asynchronous and reactive
Expand Down Expand Up @@ -510,7 +509,7 @@ private <K, V> CompletableFuture<StatefulRedisSentinelConnection<K, V>> connectS
logger.debug("Trying to get a Redis Sentinel connection for one of: " + redisURI.getSentinels());

if (redisURI.getSentinels().isEmpty() && (isNotEmpty(redisURI.getHost()) || !isEmpty(redisURI.getSocket()))) {
return doConnectSentinelAsync(codec, redisURI, timeout, redisURI.getClientName()).toCompletableFuture();
return doConnectSentinelAsync(codec, redisURI, timeout, new ConnectionMetadata(redisURI)).toCompletableFuture();
}

List<RedisURI> sentinels = redisURI.getSentinels();
Expand All @@ -522,7 +521,7 @@ private <K, V> CompletableFuture<StatefulRedisSentinelConnection<K, V>> connectS
for (RedisURI uri : sentinels) {

Mono<StatefulRedisSentinelConnection<K, V>> connectionMono = Mono
.fromCompletionStage(() -> doConnectSentinelAsync(codec, uri, timeout, redisURI.getClientName()))
.fromCompletionStage(() -> doConnectSentinelAsync(codec, uri, timeout, new ConnectionMetadata(redisURI)))
.onErrorMap(CompletionException.class, Throwable::getCause)
.onErrorMap(e -> new RedisConnectionException("Cannot connect Redis Sentinel at " + uri, e))
.doOnError(exceptionCollector::add);
Expand Down Expand Up @@ -557,7 +556,7 @@ private <K, V> CompletableFuture<StatefulRedisSentinelConnection<K, V>> connectS
}

private <K, V> ConnectionFuture<StatefulRedisSentinelConnection<K, V>> doConnectSentinelAsync(RedisCodec<K, V> codec,
RedisURI redisURI, Duration timeout, String clientName) {
RedisURI redisURI, Duration timeout, ConnectionMetadata metadata) {

ConnectionBuilder connectionBuilder;
if (redisURI.isSsl()) {
Expand Down Expand Up @@ -585,9 +584,7 @@ private <K, V> ConnectionFuture<StatefulRedisSentinelConnection<K, V>> doConnect
ConnectionState state = connection.getConnectionState();

state.apply(redisURI);
if (LettuceStrings.isEmpty(state.getClientName())) {
state.setClientName(clientName);
}
state.apply(metadata);

connectionBuilder.connectionInitializer(createHandshake(state));

Expand Down
Loading

0 comments on commit 556474e

Please sign in to comment.