Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,18 @@ public List<RedisCommandEvaluation> getEvaluatedRedisCommands() {
operations.stream()
.filter(command -> command.getType().shouldCalculateHeuristic())
.forEach(redisCommand -> {
RedisDistanceWithMetrics distanceWithMetrics = computeDistance(redisCommand, redisClient);
evaluatedRedisCommands.add(new RedisCommandEvaluation(redisCommand, distanceWithMetrics));
registerFailedCommand(redisCommand, distanceWithMetrics.getDistance());
try {
RedisDistanceWithMetrics distanceWithMetrics = computeDistance(redisCommand, redisClient);
evaluatedRedisCommands.add(new RedisCommandEvaluation(redisCommand, distanceWithMetrics));
registerFailedCommand(redisCommand, distanceWithMetrics.getDistance());
} catch (Exception e) {
// A single command must never take down the whole test evaluation: this is
// reported here (rather than left to computeDistance's own catch) because it
// also covers registerFailedCommand/createFailedCommand, which parse whatever
// query string the SUT happened to build, including malformed ones no grammar
// here accounts for.
SimpleLogger.warn("Could not evaluate Redis command " + redisCommand + ": " + e, e);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shuould we kept statistics? How do other handlers (Mongo, Sql, Neo4J, Cassandra) deal with this scenario?

}
});
operations.clear();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,24 @@ public class ReflectionBasedRedisClient {
* @param keyspace Logical database index. Default is 0.
*/
public ReflectionBasedRedisClient(String host, int port, int keyspace) {
this(host, port, keyspace, null);
}

/**
* Creates the Redis connection.
* @param host Redis database host.
* @param port Redis database port.
* @param keyspace Logical database index. Default is 0.
* @param password password to authenticate with, as set by {@code requirepass}. Null or empty
* if the server does not require authentication.
*/
public ReflectionBasedRedisClient(String host, int port, int keyspace, String password) {
try {
Class<?> redisClientClass = Class.forName("io.lettuce.core.RedisClient");
Class<?> redisURIClass = Class.forName("io.lettuce.core.RedisURI");

Method createUri = redisURIClass.getMethod(CREATE_METHOD, String.class);
Object uri = createUri.invoke(null, "redis://" + host + ":" + port + "/" + keyspace);
Object uri = createUri.invoke(null, buildRedisUrl(host, port, keyspace, password));

Method createClient = redisClientClass.getMethod(CREATE_METHOD, redisURIClass);
this.lettuceClient = createClient.invoke(null, uri);
Expand All @@ -76,21 +88,28 @@ public ReflectionBasedRedisClient(String host, int port, int keyspace) {
throw new RuntimeException("Failed to initialize Lettuce Redis client via reflection", e);
}

this.jedisClient = createJedisClient(host, port);
this.jedisClient = createJedisClient(host, port, password);
}

/**
* Builds a standard {@code redis://[:password@]host:port/keyspace} URL, understood by both
* Lettuce's {@code RedisURI.create} and Jedis's {@code UnifiedJedis(String)} constructor.
*/
private static String buildRedisUrl(String host, int port, int keyspace, String password) {
String auth = (password != null && !password.isEmpty()) ? ":" + password + "@" : "";
return "redis://" + auth + host + ":" + port + "/" + keyspace;
}

/**
* Best-effort creation of a Jedis-based connection, used only for RediSearch introspection.
* Unlike the Lettuce connection above, its absence does not prevent the rest of this client
* from working, since plain Redis heuristics have no need for it.
*/
private static Object createJedisClient(String host, int port) {
private static Object createJedisClient(String host, int port, String password) {
try {
Class<?> hostAndPortClass = Class.forName("redis.clients.jedis.HostAndPort");
Object hostAndPort = hostAndPortClass.getConstructor(String.class, int.class).newInstance(host, port);

Class<?> unifiedJedisClass = Class.forName("redis.clients.jedis.UnifiedJedis");
return unifiedJedisClass.getConstructor(hostAndPortClass).newInstance(hostAndPort);
return unifiedJedisClass.getConstructor(String.class)
.newInstance(buildRedisUrl(host, port, 0, password));
} catch (Exception e) {
return null;
}
Expand Down
Loading