diff --git a/docs/failover.md b/docs/failover.md index 24e654076f..1c0c365829 100644 --- a/docs/failover.md +++ b/docs/failover.md @@ -209,9 +209,9 @@ The health check system operates independently of your application traffic, runn #### Available Health Check Types -##### 1. EchoStrategy (Default) +##### 1. PingStrategy (Default) -The `EchoStrategy` is the default health check implementation that uses Redis's `ECHO` command to verify both connectivity and write capability. +The `PingStrategy` is the default health check implementation that uses Redis's `PING` command to verify both connectivity and write capability. **Use Cases:** - General-purpose health checking for most Redis deployments @@ -219,8 +219,8 @@ The `EchoStrategy` is the default health check implementation that uses Redis's - Simple connectivity validation **How it works:** -- Sends `ECHO "HealthCheck"` command to the Redis server -- Expects exact response `"HealthCheck"` to consider the server healthy +- Sends `PING` command to the Redis server +- Expects exact response `"PONG"` to consider the server healthy - Any exception or unexpected response marks the server as unhealthy ##### 2. LagAwareStrategy [PREVIEW] (Redis Enterprise) diff --git a/src/main/java/redis/clients/jedis/MultiDbConfig.java b/src/main/java/redis/clients/jedis/MultiDbConfig.java index 867abae7d1..3c46d2c72b 100644 --- a/src/main/java/redis/clients/jedis/MultiDbConfig.java +++ b/src/main/java/redis/clients/jedis/MultiDbConfig.java @@ -11,7 +11,7 @@ import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisValidationException; import redis.clients.jedis.mcf.ConnectionFailoverException; -import redis.clients.jedis.mcf.EchoStrategy; +import redis.clients.jedis.mcf.PingStrategy; import redis.clients.jedis.mcf.HealthCheckStrategy; /** @@ -71,7 +71,7 @@ *

* @see redis.clients.jedis.mcf.MultiDbConnectionProvider * @see redis.clients.jedis.mcf.HealthCheckStrategy - * @see redis.clients.jedis.mcf.EchoStrategy + * @see redis.clients.jedis.mcf.PingStrategy * @see redis.clients.jedis.mcf.LagAwareStrategy * @since 7.0 */ @@ -90,13 +90,13 @@ public final class MultiDbConfig { * Common Implementations: *

* * @see redis.clients.jedis.mcf.HealthCheckStrategy - * @see redis.clients.jedis.mcf.EchoStrategy + * @see redis.clients.jedis.mcf.PingStrategy * @see redis.clients.jedis.mcf.LagAwareStrategy */ public static interface StrategySupplier { @@ -839,7 +839,7 @@ public static class DatabaseConfig { /** * Strategy supplier for creating health check instances for this database. Default is - * EchoStrategy.DEFAULT. + * PingStrategy.DEFAULT. */ private StrategySupplier healthCheckStrategySupplier; @@ -847,7 +847,7 @@ public static class DatabaseConfig { * Constructs a DatabaseConfig with basic endpoint and client configuration. *

* This constructor creates a database configuration with default settings: weight of 1.0f and - * EchoStrategy for health checks. Use the {@link Builder} for more advanced configuration + * PingStrategy for health checks. Use the {@link Builder} for more advanced configuration * options. *

* @param endpoint the Redis endpoint (host and port) @@ -863,7 +863,7 @@ public DatabaseConfig(Endpoint endpoint, JedisClientConfig clientConfig) { * Constructs a DatabaseConfig with endpoint, client, and connection pool configuration. *

* This constructor allows specification of connection pool settings in addition to basic - * endpoint configuration. Default weight of 1.0f and EchoStrategy for health checks are used. + * endpoint configuration. Default weight of 1.0f and PingStrategy for health checks are used. *

* @param endpoint the Redis endpoint (host and port) * @param clientConfig the Jedis client configuration @@ -963,7 +963,7 @@ public StrategySupplier getHealthCheckStrategySupplier() { *

* */ @@ -980,8 +980,8 @@ public static class Builder { /** Weight for database selection priority. Default: 1.0f */ private float weight = 1.0f; - /** Health check strategy supplier. Default: EchoStrategy.DEFAULT */ - private StrategySupplier healthCheckStrategySupplier = EchoStrategy.DEFAULT; + /** Health check strategy supplier. Default: PingStrategy.DEFAULT */ + private StrategySupplier healthCheckStrategySupplier = PingStrategy.DEFAULT; /** * Constructs a new Builder with required endpoint and client configuration. @@ -1089,7 +1089,7 @@ public Builder healthCheckStrategy(HealthCheckStrategy healthCheckStrategy) { * *

* When health checks are enabled (true) and no strategy supplier was previously set, the - * default {@link redis.clients.jedis.mcf.EchoStrategy#DEFAULT} will be used. + * default {@link redis.clients.jedis.mcf.PingStrategy#DEFAULT} will be used. *

* @param healthCheckEnabled true to enable health checks, false to disable * @return this builder instance for method chaining @@ -1098,7 +1098,7 @@ public Builder healthCheckEnabled(boolean healthCheckEnabled) { if (!healthCheckEnabled) { this.healthCheckStrategySupplier = null; } else if (healthCheckStrategySupplier == null) { - this.healthCheckStrategySupplier = EchoStrategy.DEFAULT; + this.healthCheckStrategySupplier = PingStrategy.DEFAULT; } return this; } diff --git a/src/main/java/redis/clients/jedis/UnifiedJedis.java b/src/main/java/redis/clients/jedis/UnifiedJedis.java index a03dbc24ed..3839c38ea2 100644 --- a/src/main/java/redis/clients/jedis/UnifiedJedis.java +++ b/src/main/java/redis/clients/jedis/UnifiedJedis.java @@ -194,18 +194,6 @@ public UnifiedJedis(ConnectionProvider provider, int maxAttempts, Duration maxTo this(new RetryableCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration), provider); } - /** - * Constructor which supports multiple cluster/database endpoints each with their own isolated connection pool. - *

- * With this Constructor users can seamlessly failover to Disaster Recovery (DR), Backup, and Active-Active cluster(s) - * by using simple configuration which is passed through from Resilience4j - https://resilience4j.readme.io/docs - *

- */ - @Experimental - public UnifiedJedis(MultiDbConnectionProvider provider) { - this(new MultiDbCommandExecutor(provider), provider); - } - /** * The constructor to use a custom {@link CommandExecutor}. *

diff --git a/src/main/java/redis/clients/jedis/mcf/EchoStrategy.java b/src/main/java/redis/clients/jedis/mcf/PingStrategy.java similarity index 80% rename from src/main/java/redis/clients/jedis/mcf/EchoStrategy.java rename to src/main/java/redis/clients/jedis/mcf/PingStrategy.java index 6be05e2cfb..9f9a143596 100644 --- a/src/main/java/redis/clients/jedis/mcf/EchoStrategy.java +++ b/src/main/java/redis/clients/jedis/mcf/PingStrategy.java @@ -10,17 +10,17 @@ import redis.clients.jedis.UnifiedJedis; import redis.clients.jedis.MultiDbConfig.StrategySupplier; -public class EchoStrategy implements HealthCheckStrategy { +public class PingStrategy implements HealthCheckStrategy { private static final int MAX_HEALTH_CHECK_POOL_SIZE = 2; private final UnifiedJedis jedis; private final HealthCheckStrategy.Config config; - public EchoStrategy(HostAndPort hostAndPort, JedisClientConfig jedisClientConfig) { + public PingStrategy(HostAndPort hostAndPort, JedisClientConfig jedisClientConfig) { this(hostAndPort, jedisClientConfig, HealthCheckStrategy.Config.create()); } - public EchoStrategy(HostAndPort hostAndPort, JedisClientConfig jedisClientConfig, + public PingStrategy(HostAndPort hostAndPort, JedisClientConfig jedisClientConfig, HealthCheckStrategy.Config config) { GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig<>(); poolConfig.setMaxTotal(MAX_HEALTH_CHECK_POOL_SIZE); @@ -55,8 +55,7 @@ public int getDelayInBetweenProbes() { @Override public HealthStatus doHealthCheck(Endpoint endpoint) { - return "HealthCheck".equals(jedis.echo("HealthCheck")) ? HealthStatus.HEALTHY - : HealthStatus.UNHEALTHY; + return "PONG".equals(jedis.ping()) ? HealthStatus.HEALTHY : HealthStatus.UNHEALTHY; } @Override @@ -64,6 +63,6 @@ public void close() { jedis.close(); } - public static final StrategySupplier DEFAULT = EchoStrategy::new; + public static final StrategySupplier DEFAULT = PingStrategy::new; } diff --git a/src/test/java/redis/clients/jedis/failover/FailoverIntegrationTest.java b/src/test/java/redis/clients/jedis/failover/FailoverIntegrationTest.java index f0349a851e..d0e7e32811 100644 --- a/src/test/java/redis/clients/jedis/failover/FailoverIntegrationTest.java +++ b/src/test/java/redis/clients/jedis/failover/FailoverIntegrationTest.java @@ -16,6 +16,7 @@ import redis.clients.jedis.EndpointConfig; import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.JedisClientConfig; +import redis.clients.jedis.MultiDbClient; import redis.clients.jedis.MultiDbConfig; import redis.clients.jedis.UnifiedJedis; import redis.clients.jedis.exceptions.JedisConnectionException; @@ -58,7 +59,7 @@ public class FailoverIntegrationTest { private static String JEDIS1_ID = ""; private static String JEDIS2_ID = ""; private MultiDbConnectionProvider provider; - private UnifiedJedis failoverClient; + private MultiDbClient failoverClient; @BeforeAll public static void setupAdminClients() throws IOException { @@ -110,7 +111,7 @@ public void setup() throws IOException { // Create default provider and client for most tests provider = createProvider(); - failoverClient = new UnifiedJedis(provider); + failoverClient = MultiDbClient.builder().connectionProvider(provider).build(); } @AfterEach @@ -272,7 +273,7 @@ public void testCircuitBreakerCountsEachConnectionErrorSeparately() throws IOExc .build(); MultiDbConnectionProvider provider = new MultiDbConnectionProvider(failoverConfig); - try (UnifiedJedis client = new UnifiedJedis(provider)) { + try (MultiDbClient client = MultiDbClient.builder().connectionProvider(provider).build()) { // Verify initial connection to first endpoint assertThat(getNodeId(client.info("server")), equalTo(JEDIS1_ID)); @@ -321,7 +322,8 @@ public void testInflightCommandsAreRetriedAfterFailover() throws Exception { builder -> builder.retryOnFailover(true)); // Create a custom client with retryOnFailover enabled for this specific test - try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) { + try (MultiDbClient customClient = MultiDbClient.builder().connectionProvider(customProvider) + .build()) { assertThat(getNodeId(customClient.info("server")), equalTo(JEDIS1_ID)); Thread.sleep(1000); @@ -362,7 +364,8 @@ public void testInflightCommandsAreNotRetriedAfterFailover() throws Exception { MultiDbConnectionProvider customProvider = createProvider( builder -> builder.retryOnFailover(false)); - try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) { + try (MultiDbClient customClient = MultiDbClient.builder().connectionProvider(customProvider) + .build()) { assertThat(getNodeId(customClient.info("server")), equalTo(JEDIS1_ID)); Future> blpop = executor.submit(() -> customClient.blpop(500, "test-list-2")); diff --git a/src/test/java/redis/clients/jedis/mcf/ActiveActiveLocalFailoverTest.java b/src/test/java/redis/clients/jedis/mcf/ActiveActiveLocalFailoverTest.java index b103e6a3c0..c9835536aa 100644 --- a/src/test/java/redis/clients/jedis/mcf/ActiveActiveLocalFailoverTest.java +++ b/src/test/java/redis/clients/jedis/mcf/ActiveActiveLocalFailoverTest.java @@ -23,6 +23,7 @@ import redis.clients.jedis.scenario.RecommendedSettings; import redis.clients.jedis.scenario.FaultInjectionClient.TriggerActionResponse; import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.util.ClientTestUtil; import java.io.IOException; import java.time.Duration; @@ -152,13 +153,12 @@ public void accept(DatabaseSwitchEvent e) { ensureEndpointAvailability(endpoint1.getHostAndPort(), config); ensureEndpointAvailability(endpoint2.getHostAndPort(), config); - // Create the connection provider - MultiDbConnectionProvider provider = new MultiDbConnectionProvider(builder.build()); FailoverReporter reporter = new FailoverReporter(); - provider.setDatabaseSwitchListener(reporter); - provider.setActiveDatabase(endpoint1.getHostAndPort()); - UnifiedJedis client = new UnifiedJedis(provider); + MultiDbClient multiDbClient = MultiDbClient.builder().multiDbConfig(builder.build()) + .databaseSwitchListener(reporter).build(); + + multiDbClient.setActiveDatabase(endpoint1.getHostAndPort()); AtomicLong retryingThreadsCounter = new AtomicLong(0); AtomicLong failedCommandsAfterFailover = new AtomicLong(0); @@ -168,25 +168,24 @@ public void accept(DatabaseSwitchEvent e) { AtomicBoolean unexpectedErrors = new AtomicBoolean(false); AtomicReference lastException = new AtomicReference(); AtomicLong stopRunningAt = new AtomicLong(); - String database2Id = provider.getDatabase(endpoint2.getHostAndPort()).getCircuitBreaker() - .getName(); + Endpoint db2Endpoint = endpoint2.getHostAndPort(); - // Start thread that imitates an application that uses the client + // Start thread that imitates an application that uses the multiDbClient RateLimiterConfig rateLimiterConfig = RateLimiterConfig.custom().limitForPeriod(100) .limitRefreshPeriod(Duration.ofSeconds(1)).timeoutDuration(Duration.ofSeconds(1)).build(); - MultiThreadedFakeApp fakeApp = new MultiThreadedFakeApp(client, (UnifiedJedis c) -> { + MultiThreadedFakeApp fakeApp = new MultiThreadedFakeApp(multiDbClient, (UnifiedJedis c) -> { long threadId = Thread.currentThread().getId(); int attempt = 0; int maxTries = 500; int retryingDelay = 5; - String currentDatabaseId = null; + String currentDbKey = null; while (true) { try { if (System.currentTimeMillis() > stopRunningAt.get()) break; - currentDatabaseId = provider.getDatabase().getCircuitBreaker().getName(); + currentDbKey = dbKey(multiDbClient.getActiveDatabaseEndpoint()); Map executionInfo = new HashMap() { { put("threadId", String.valueOf(threadId)); @@ -194,7 +193,7 @@ public void accept(DatabaseSwitchEvent e) { } }; - client.xadd("execution_log", StreamEntryID.NEW_ENTRY, executionInfo); + multiDbClient.xadd("execution_log", StreamEntryID.NEW_ENTRY, executionInfo); if (attempt > 0) { log.info("Thread {} recovered after {} ms. Threads still not recovered: {}", threadId, @@ -203,7 +202,7 @@ public void accept(DatabaseSwitchEvent e) { break; } catch (JedisConnectionException e) { - if (database2Id.equals(currentDatabaseId)) { + if (dbKey(db2Endpoint).equals(currentDbKey)) { break; } lastException.set(e); @@ -231,7 +230,7 @@ public void accept(DatabaseSwitchEvent e) { } if (++attempt == maxTries) throw e; } catch (Exception e) { - if (database2Id.equals(currentDatabaseId)) { + if (dbKey(db2Endpoint).equals(currentDbKey)) { break; } lastException.set(e); @@ -275,6 +274,7 @@ public boolean isCompleted(Duration checkInterval, Duration delayAfter, Duration } log.info("Fake app completed"); + MultiDbConnectionProvider provider = ClientTestUtil.getConnectionProvider(multiDbClient); ConnectionPool pool = provider.getDatabase(endpoint1.getHostAndPort()).getConnectionPool(); log.info("First connection pool state: active: {}, idle: {}", pool.getNumActive(), @@ -305,7 +305,11 @@ public boolean isCompleted(Duration checkInterval, Duration delayAfter, Duration } assertFalse(unexpectedErrors.get()); - client.close(); + multiDbClient.close(); + } + + private String dbKey(Endpoint endpoint) { + return endpoint.getHost() + ":" + endpoint.getPort(); } private static void ensureEndpointAvailability(HostAndPort endpoint, JedisClientConfig config) { diff --git a/src/test/java/redis/clients/jedis/mcf/DefaultValuesTest.java b/src/test/java/redis/clients/jedis/mcf/DefaultValuesTest.java index 767fd60c90..6adb788577 100644 --- a/src/test/java/redis/clients/jedis/mcf/DefaultValuesTest.java +++ b/src/test/java/redis/clients/jedis/mcf/DefaultValuesTest.java @@ -33,8 +33,8 @@ void testDefaultValuesInConfig() { // check healthchecks enabled assertNotNull(databaseConfig.getHealthCheckStrategySupplier()); - // check default healthcheck strategy is echo - assertEquals(EchoStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); + // check default healthcheck strategy is PingStrategy + assertEquals(PingStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); // check number of probes assertEquals(3, diff --git a/src/test/java/redis/clients/jedis/mcf/HealthCheckIntegrationTest.java b/src/test/java/redis/clients/jedis/mcf/HealthCheckIntegrationTest.java index f19af41a6e..8e4a1a3200 100644 --- a/src/test/java/redis/clients/jedis/mcf/HealthCheckIntegrationTest.java +++ b/src/test/java/redis/clients/jedis/mcf/HealthCheckIntegrationTest.java @@ -15,10 +15,11 @@ import redis.clients.jedis.EndpointConfig; import redis.clients.jedis.HostAndPorts; import redis.clients.jedis.JedisClientConfig; +import redis.clients.jedis.MultiDbClient; import redis.clients.jedis.MultiDbConfig; -import redis.clients.jedis.UnifiedJedis; import redis.clients.jedis.MultiDbConfig.DatabaseConfig; import redis.clients.jedis.MultiDbConfig.StrategySupplier; +import redis.clients.jedis.UnifiedJedis; import redis.clients.jedis.mcf.ProbingPolicy.BuiltIn; import redis.clients.jedis.scenario.RecommendedSettings; @@ -32,8 +33,9 @@ public class HealthCheckIntegrationTest { @Test public void testDisableHealthCheck() { // No health check strategy supplier means health check is disabled - MultiDbConnectionProvider customProvider = getMCCF(null); - try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) { + MultiDbConfig multiDbConfig = getMCCF(null); + try ( + MultiDbClient customClient = MultiDbClient.builder().multiDbConfig(multiDbConfig).build()) { // Verify that the client can connect and execute commands String result = customClient.ping(); assertEquals("PONG", result); @@ -42,12 +44,13 @@ public void testDisableHealthCheck() { @Test public void testDefaultStrategySupplier() { - // Create a default strategy supplier that creates EchoStrategy instances + // Create a default strategy supplier that creates PingStrategy instances MultiDbConfig.StrategySupplier defaultSupplier = (hostAndPort, jedisClientConfig) -> { - return new EchoStrategy(hostAndPort, jedisClientConfig); + return new PingStrategy(hostAndPort, jedisClientConfig); }; - MultiDbConnectionProvider customProvider = getMCCF(defaultSupplier); - try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) { + MultiDbConfig multiDbConfig = getMCCF(defaultSupplier); + try ( + MultiDbClient customClient = MultiDbClient.builder().multiDbConfig(multiDbConfig).build()) { // Verify that the client can connect and execute commands String result = customClient.ping(); assertEquals("PONG", result); @@ -70,15 +73,16 @@ public void testCustomStrategySupplier() { }); }; - MultiDbConnectionProvider customProvider = getMCCF(strategySupplier); - try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) { + MultiDbConfig multiDbConfig = getMCCF(strategySupplier); + try ( + MultiDbClient customClient = MultiDbClient.builder().multiDbConfig(multiDbConfig).build()) { // Verify that the client can connect and execute commands String result = customClient.ping(); assertEquals("PONG", result); } } - private MultiDbConnectionProvider getMCCF(MultiDbConfig.StrategySupplier strategySupplier) { + private MultiDbConfig getMCCF(MultiDbConfig.StrategySupplier strategySupplier) { Function modifier = builder -> strategySupplier == null ? builder.healthCheckEnabled(false) : builder.healthCheckStrategySupplier(strategySupplier); @@ -88,13 +92,13 @@ private MultiDbConnectionProvider getMCCF(MultiDbConfig.StrategySupplier strateg .apply(MultiDbConfig.DatabaseConfig.builder(e.getHostAndPort(), clientConfig)).build()) .collect(Collectors.toList()); - MultiDbConfig mccf = new MultiDbConfig.Builder(databaseConfigs) + MultiDbConfig multiDbConfig = new MultiDbConfig.Builder(databaseConfigs) .commandRetry(MultiDbConfig.RetryConfig.builder().maxAttempts(1).waitDuration(1).build()) .failureDetector(MultiDbConfig.CircuitBreakerConfig.builder().slidingWindowSize(1) .failureRateThreshold(100).build()) .build(); - return new MultiDbConnectionProvider(mccf); + return multiDbConfig; } // ========== Probe Logic Integration Tests ========== @@ -113,8 +117,8 @@ public void testProbingLogic_RealHealthCheckWithProbes() throws InterruptedExcep } // Third attempt succeeds - do actual health check try (UnifiedJedis jedis = new UnifiedJedis(hostAndPort, jedisClientConfig)) { - String result = jedis.echo("HealthCheck"); - return "HealthCheck".equals(result) ? HealthStatus.HEALTHY : HealthStatus.UNHEALTHY; + String result = jedis.ping(); + return "PONG".equals(result) ? HealthStatus.HEALTHY : HealthStatus.UNHEALTHY; } catch (Exception e) { return HealthStatus.UNHEALTHY; } diff --git a/src/test/java/redis/clients/jedis/mcf/HealthCheckTest.java b/src/test/java/redis/clients/jedis/mcf/HealthCheckTest.java index 10090811c1..339f4ce1ed 100644 --- a/src/test/java/redis/clients/jedis/mcf/HealthCheckTest.java +++ b/src/test/java/redis/clients/jedis/mcf/HealthCheckTest.java @@ -321,11 +321,11 @@ void testHealthStatusManagerClose() { verify(closeableStrategy).close(); } - // ========== EchoStrategy Tests ========== + // ========== PingStrategy Tests ========== @Test - void testEchoStrategyCustomIntervalTimeout() { - try (EchoStrategy strategy = new EchoStrategy(testEndpoint, testConfig, + void testPingStrategyCustomIntervalTimeout() { + try (PingStrategy strategy = new PingStrategy(testEndpoint, testConfig, HealthCheckStrategy.Config.builder().interval(2000).timeout(1500).delayInBetweenProbes(50) .numProbes(11).policy(BuiltIn.ANY_SUCCESS).build())) { assertEquals(2000, strategy.getInterval()); @@ -337,11 +337,11 @@ void testEchoStrategyCustomIntervalTimeout() { } @Test - void testEchoStrategyDefaultSupplier() { - MultiDbConfig.StrategySupplier supplier = EchoStrategy.DEFAULT; + void testPingStrategyDefaultSupplier() { + MultiDbConfig.StrategySupplier supplier = PingStrategy.DEFAULT; HealthCheckStrategy strategy = supplier.get(testEndpoint, testConfig); - assertInstanceOf(EchoStrategy.class, strategy); + assertInstanceOf(PingStrategy.class, strategy); } // ========== Failover configuration Tests ========== @@ -368,7 +368,7 @@ void testDefaultValues() { .builder(testEndpoint, testConfig).build(); assertEquals(1.0f, databaseConfig.getWeight()); // Default weight - assertEquals(EchoStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); // Default + assertEquals(PingStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); // Default // is null // (no // health @@ -410,26 +410,26 @@ void testDatabaseConfigWithStrategySupplier() { } @Test - void testDatabaseConfigWithEchoStrategy() { - MultiDbConfig.StrategySupplier echoSupplier = (hostAndPort, jedisClientConfig) -> { - return new EchoStrategy(hostAndPort, jedisClientConfig); + void testDatabaseConfigWithPingStrategy() { + MultiDbConfig.StrategySupplier pingSupplier = (hostAndPort, jedisClientConfig) -> { + return new PingStrategy(hostAndPort, jedisClientConfig); }; MultiDbConfig.DatabaseConfig databaseConfig = MultiDbConfig.DatabaseConfig - .builder(testEndpoint, testConfig).healthCheckStrategySupplier(echoSupplier).build(); + .builder(testEndpoint, testConfig).healthCheckStrategySupplier(pingSupplier).build(); MultiDbConfig.StrategySupplier supplier = databaseConfig.getHealthCheckStrategySupplier(); assertNotNull(supplier); - assertInstanceOf(EchoStrategy.class, supplier.get(testEndpoint, testConfig)); + assertInstanceOf(PingStrategy.class, supplier.get(testEndpoint, testConfig)); } @Test void testDatabaseConfigWithDefaultHealthCheck() { MultiDbConfig.DatabaseConfig databaseConfig = MultiDbConfig.DatabaseConfig - .builder(testEndpoint, testConfig).build(); // Should use default EchoStrategy + .builder(testEndpoint, testConfig).build(); // Should use default PingStrategy assertNotNull(databaseConfig.getHealthCheckStrategySupplier()); - assertEquals(EchoStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); + assertEquals(PingStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); } @Test @@ -446,7 +446,7 @@ void testDatabaseConfigHealthCheckEnabledExplicitly() { .builder(testEndpoint, testConfig).healthCheckEnabled(true).build(); assertNotNull(databaseConfig.getHealthCheckStrategySupplier()); - assertEquals(EchoStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); + assertEquals(PingStrategy.DEFAULT, databaseConfig.getHealthCheckStrategySupplier()); } // ========== Integration Tests ========== @@ -516,10 +516,10 @@ void testStrategySupplierPolymorphism() { // Test that the polymorphic design works correctly MultiDbConfig.StrategySupplier supplier = (hostAndPort, jedisClientConfig) -> { if (jedisClientConfig != null) { - return new EchoStrategy(hostAndPort, jedisClientConfig, + return new PingStrategy(hostAndPort, jedisClientConfig, HealthCheckStrategy.Config.builder().interval(500).timeout(250).numProbes(1).build()); } else { - return new EchoStrategy(hostAndPort, DefaultJedisClientConfig.builder().build()); + return new PingStrategy(hostAndPort, DefaultJedisClientConfig.builder().build()); } }; diff --git a/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderInitializationTest.java b/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderInitializationTest.java index f134490112..122dcc6dae 100644 --- a/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderInitializationTest.java +++ b/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderInitializationTest.java @@ -56,7 +56,7 @@ void testInitializationWithMixedHealthCheckConfiguration() { .build(); DatabaseConfig db2 = DatabaseConfig.builder(endpoint2, clientConfig).weight(2.0f) - .healthCheckStrategySupplier(EchoStrategy.DEFAULT) // With + .healthCheckStrategySupplier(PingStrategy.DEFAULT) // With // health // check .build(); diff --git a/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderTest.java b/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderTest.java index d22c26f39c..8dcbce06cc 100644 --- a/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderTest.java +++ b/src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderTest.java @@ -121,7 +121,7 @@ public void testDatabaseSwitchListener() { isValidTest.set(true); }); - try (UnifiedJedis jedis = new UnifiedJedis(localProvider)) { + try (MultiDbClient jedis = MultiDbClient.builder().connectionProvider(localProvider).build()) { // This will fail due to unable to connect and open the circuit which will trigger the post // processor @@ -236,7 +236,7 @@ public void userCommand_firstTemporary_thenPermanent_inOrder() { .maxNumFailoverAttempts(2) .commandRetry(MultiDbConfig.RetryConfig.builder().maxAttempts(1).build()).build()); - try (UnifiedJedis jedis = new UnifiedJedis(testProvider)) { + try (MultiDbClient jedis = MultiDbClient.builder().connectionProvider(testProvider).build()) { jedis.get("foo"); // Disable both databases so any attempt to switch results in 'no healthy database' path @@ -278,7 +278,7 @@ public void userCommand_connectionExceptions_thenMultipleTemporary_thenPermanent .build()) { }; - try (UnifiedJedis jedis = new UnifiedJedis(testProvider)) { + try (MultiDbClient jedis = MultiDbClient.builder().connectionProvider(testProvider).build()) { jedis.get("foo"); // disable most weighted database so that it will fail on initial requests diff --git a/src/test/java/redis/clients/jedis/mcf/EchoStrategyIntegrationTest.java b/src/test/java/redis/clients/jedis/mcf/PingStrategyIntegrationTest.java similarity index 92% rename from src/test/java/redis/clients/jedis/mcf/EchoStrategyIntegrationTest.java rename to src/test/java/redis/clients/jedis/mcf/PingStrategyIntegrationTest.java index 56b04a9437..66f25a78ab 100644 --- a/src/test/java/redis/clients/jedis/mcf/EchoStrategyIntegrationTest.java +++ b/src/test/java/redis/clients/jedis/mcf/PingStrategyIntegrationTest.java @@ -20,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.*; @Tag("failover") -public class EchoStrategyIntegrationTest { +public class PingStrategyIntegrationTest { private static final EndpointConfig endpoint = HostAndPorts.getRedisEndpoint("redis-failover-1"); private static final HostAndPort proxyHostAndPort = endpoint.getHostAndPort(); @@ -55,10 +55,10 @@ public void resetProxy() throws IOException { } @Test - public void testEchoStrategyRecoversAfterDisconnect() throws Exception { + public void testPingStrategyRecoversAfterDisconnect() throws Exception { JedisClientConfig config = DefaultJedisClientConfig.builder().socketTimeoutMillis(1000) .connectionTimeoutMillis(1000).build(); - try (EchoStrategy strategy = new EchoStrategy(proxyHostAndPort, config, + try (PingStrategy strategy = new PingStrategy(proxyHostAndPort, config, HealthCheckStrategy.Config.create())) { // Initial health check should work @@ -81,11 +81,11 @@ public void testEchoStrategyRecoversAfterDisconnect() throws Exception { } @Test - public void testEchoStrategyWithConnectionTimeout() throws Exception { + public void testPingStrategyWithConnectionTimeout() throws Exception { JedisClientConfig config = DefaultJedisClientConfig.builder().socketTimeoutMillis(100) .connectionTimeoutMillis(100).build(); - try (EchoStrategy strategy = new EchoStrategy(proxyHostAndPort, config, + try (PingStrategy strategy = new PingStrategy(proxyHostAndPort, config, HealthCheckStrategy.Config.builder().interval(1000).timeout(500).numProbes(1).build())) { // Initial health check should work @@ -110,7 +110,7 @@ public void testEchoStrategyWithConnectionTimeout() throws Exception { @Test public void testConnectionDropDuringHealthCheck() throws Exception { JedisClientConfig config = DefaultJedisClientConfig.builder().socketTimeoutMillis(2000).build(); - try (EchoStrategy strategy = new EchoStrategy(proxyHostAndPort, config, + try (PingStrategy strategy = new PingStrategy(proxyHostAndPort, config, HealthCheckStrategy.Config.create())) { // Initial health check diff --git a/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java b/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java index 306cb7a998..c050fbf0c1 100644 --- a/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java +++ b/src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java @@ -73,7 +73,7 @@ public void pipelineWithSwitch() { getDatabaseConfigs(clientConfig, hostPortWithFailure, workingEndpoint.getHostAndPort())) .build()); - try (UnifiedJedis client = new UnifiedJedis(provider)) { + try (MultiDbClient client = MultiDbClient.builder().connectionProvider(provider).build()) { AbstractPipeline pipe = client.pipelined(); pipe.set("pstr", "foobar"); pipe.hset("phash", "foo", "bar"); @@ -93,7 +93,7 @@ public void transactionWithSwitch() { getDatabaseConfigs(clientConfig, hostPortWithFailure, workingEndpoint.getHostAndPort())) .build()); - try (UnifiedJedis client = new UnifiedJedis(provider)) { + try (MultiDbClient client = MultiDbClient.builder().connectionProvider(provider).build()) { AbstractTransaction tx = client.multi(); tx.set("tstr", "foobar"); tx.hset("thash", "foo", "bar"); @@ -125,7 +125,7 @@ public void commandFailoverUnresolvableHost() { builder.build()); connectionProvider.setDatabaseSwitchListener(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(connectionProvider); + MultiDbClient jedis = MultiDbClient.builder().connectionProvider(connectionProvider).build(); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis"); @@ -168,7 +168,7 @@ public void commandFailover() { builder.build()); connectionProvider.setDatabaseSwitchListener(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(connectionProvider); + MultiDbClient jedis = MultiDbClient.builder().connectionProvider(connectionProvider).build(); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis"); @@ -208,7 +208,7 @@ public void pipelineFailover() { builder.build()); cacheProvider.setDatabaseSwitchListener(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + MultiDbClient jedis = MultiDbClient.builder().connectionProvider(cacheProvider).build(); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis"); @@ -243,7 +243,7 @@ public void failoverFromAuthError() { builder.build()); cacheProvider.setDatabaseSwitchListener(failoverReporter); - UnifiedJedis jedis = new UnifiedJedis(cacheProvider); + MultiDbClient jedis = MultiDbClient.builder().connectionProvider(cacheProvider).build(); String key = "hash-" + System.nanoTime(); log.info("Starting calls to Redis");