From bad18b916bc9c30aa58edb4676c6d6c8f571ab63 Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:48:17 +0600 Subject: [PATCH] Add Experimental, Internal and VisibleForTesting annotations (#3790) * Add Experimental, Internal and VisibleForTesting annotations * Use VisibleForTesting annotation * Use Internal annotation * Use Experimental annotation --- .../clients/jedis/JedisClusterInfoCache.java | 6 +++++- .../clients/jedis/MultiClusterClientConfig.java | 2 ++ .../java/redis/clients/jedis/UnifiedJedis.java | 2 ++ .../clients/jedis/annots/Experimental.java | 17 +++++++++++++++++ .../redis/clients/jedis/annots/Internal.java | 17 +++++++++++++++++ .../clients/jedis/annots/VisibleForTesting.java | 12 ++++++++++++ .../jedis/executors/ClusterCommandExecutor.java | 3 +++ .../executors/RetryableCommandExecutor.java | 3 +++ .../mcf/CircuitBreakerCommandExecutor.java | 2 ++ .../jedis/mcf/CircuitBreakerFailoverBase.java | 2 ++ ...ircuitBreakerFailoverConnectionProvider.java | 2 ++ .../clients/jedis/mcf/MultiClusterPipeline.java | 2 ++ .../jedis/mcf/MultiClusterTransaction.java | 2 ++ .../MultiClusterPooledConnectionProvider.java | 2 ++ 14 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/main/java/redis/clients/jedis/annots/Experimental.java create mode 100644 src/main/java/redis/clients/jedis/annots/Internal.java create mode 100644 src/main/java/redis/clients/jedis/annots/VisibleForTesting.java diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index bea4982fd4..da88462ef4 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -11,22 +11,26 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; + import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import redis.clients.jedis.annots.Internal; import redis.clients.jedis.exceptions.JedisClusterOperationException; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.util.SafeEncoder; import static redis.clients.jedis.JedisCluster.INIT_NO_ERROR_PROPERTY; +@Internal public class JedisClusterInfoCache { private static final Logger logger = LoggerFactory.getLogger(JedisClusterInfoCache.class); diff --git a/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java b/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java index 15956ebed4..10dff9ef64 100644 --- a/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java +++ b/src/main/java/redis/clients/jedis/MultiClusterClientConfig.java @@ -7,6 +7,7 @@ import java.util.Arrays; import java.util.List; +import redis.clients.jedis.annots.Experimental; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisValidationException; @@ -25,6 +26,7 @@ *
*/ // TODO: move +@Experimental public final class MultiClusterClientConfig { private static final int RETRY_MAX_ATTEMPTS_DEFAULT = 3; diff --git a/src/main/java/redis/clients/jedis/UnifiedJedis.java b/src/main/java/redis/clients/jedis/UnifiedJedis.java index 138300c451..b8137d3536 100644 --- a/src/main/java/redis/clients/jedis/UnifiedJedis.java +++ b/src/main/java/redis/clients/jedis/UnifiedJedis.java @@ -9,6 +9,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.json.JSONArray; +import redis.clients.jedis.annots.Experimental; import redis.clients.jedis.args.*; import redis.clients.jedis.bloom.*; import redis.clients.jedis.commands.JedisCommands; @@ -192,6 +193,7 @@ public UnifiedJedis(ConnectionProvider provider, int maxAttempts, Duration maxTo * by using simple configuration which is passed through from Resilience4j - https://resilience4j.readme.io/docs *
*/ + @Experimental public UnifiedJedis(MultiClusterPooledConnectionProvider provider) { this(new CircuitBreakerCommandExecutor(provider), provider); } diff --git a/src/main/java/redis/clients/jedis/annots/Experimental.java b/src/main/java/redis/clients/jedis/annots/Experimental.java new file mode 100644 index 0000000000..e0c642e630 --- /dev/null +++ b/src/main/java/redis/clients/jedis/annots/Experimental.java @@ -0,0 +1,17 @@ +package redis.clients.jedis.annots; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * Annotation to mark classes for experimental development. + *
+ * Classes with this annotation may be renamed, changed or even removed in a future version. This + * annotation doesn't mean that the implementation has an 'experimental' quality. + *
+ * If a type is marked with this annotation, all its members are considered experimental. + */ +@Documented +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR}) +public @interface Experimental { } diff --git a/src/main/java/redis/clients/jedis/annots/Internal.java b/src/main/java/redis/clients/jedis/annots/Internal.java new file mode 100644 index 0000000000..551460e834 --- /dev/null +++ b/src/main/java/redis/clients/jedis/annots/Internal.java @@ -0,0 +1,17 @@ +package redis.clients.jedis.annots; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * Annotation to mark classes or methods as an internal development API. It indicates that the + * annotated element must not be considered as a public API. + *
+ * Classes or methods with this annotation may change across releases. + *
+ * If a type is marked with this annotation, all its members are considered internal.
+ */
+@Documented
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
+public @interface Internal { }
\ No newline at end of file
diff --git a/src/main/java/redis/clients/jedis/annots/VisibleForTesting.java b/src/main/java/redis/clients/jedis/annots/VisibleForTesting.java
new file mode 100644
index 0000000000..e9aac5c7b3
--- /dev/null
+++ b/src/main/java/redis/clients/jedis/annots/VisibleForTesting.java
@@ -0,0 +1,12 @@
+package redis.clients.jedis.annots;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * A member or type annotated with {@link VisibleForTesting} declares that it is only visible for testing purposes.
+ */
+@Documented
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.TYPE})
+public @interface VisibleForTesting { }
diff --git a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
index 4cc25c42a9..375db99e14 100644
--- a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
+++ b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
@@ -13,6 +13,7 @@
import redis.clients.jedis.ConnectionPool;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Protocol;
+import redis.clients.jedis.annots.VisibleForTesting;
import redis.clients.jedis.exceptions.*;
import redis.clients.jedis.providers.ClusterConnectionProvider;
import redis.clients.jedis.util.IOUtils;
@@ -135,6 +136,7 @@ public final
*/
+@Experimental
public class CircuitBreakerCommandExecutor extends CircuitBreakerFailoverBase implements CommandExecutor {
public CircuitBreakerCommandExecutor(MultiClusterPooledConnectionProvider provider) {
diff --git a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java
index b06d7b9604..4ef383e649 100644
--- a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java
+++ b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverBase.java
@@ -1,6 +1,7 @@
package redis.clients.jedis.mcf;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
+import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider;
import redis.clients.jedis.util.IOUtils;
@@ -14,6 +15,7 @@
* Resilience4j - https://resilience4j.readme.io/docs
*
*/
+@Experimental
public class CircuitBreakerFailoverBase implements AutoCloseable {
protected final MultiClusterPooledConnectionProvider provider;
diff --git a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java
index 10a0823973..cd0e91015a 100644
--- a/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java
+++ b/src/main/java/redis/clients/jedis/mcf/CircuitBreakerFailoverConnectionProvider.java
@@ -5,6 +5,7 @@
import io.github.resilience4j.decorators.Decorators.DecorateSupplier;
import redis.clients.jedis.Connection;
+import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider;
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider.Cluster;
@@ -13,6 +14,7 @@
* With this executor 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 class CircuitBreakerFailoverConnectionProvider extends CircuitBreakerFailoverBase {
public CircuitBreakerFailoverConnectionProvider(MultiClusterPooledConnectionProvider provider) {
diff --git a/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java b/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java
index 00c0ba1d91..d7f1416e34 100644
--- a/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java
+++ b/src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java
@@ -7,6 +7,7 @@
import java.util.Queue;
import redis.clients.jedis.*;
+import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.graph.ResultSet;
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider;
import redis.clients.jedis.util.KeyValue;
@@ -15,6 +16,7 @@
* This is high memory dependent solution as all the appending commands will be hold in memory until
* {@link MultiClusterPipeline#sync() SYNC} (or {@link MultiClusterPipeline#close() CLOSE}) gets called.
*/
+@Experimental
public class MultiClusterPipeline extends PipelineBase implements Closeable {
private final CircuitBreakerFailoverConnectionProvider failoverProvider;
diff --git a/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java b/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java
index d759ce1da0..f39cdf36b6 100644
--- a/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java
+++ b/src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java
@@ -14,6 +14,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import redis.clients.jedis.*;
+import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.graph.ResultSet;
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider;
@@ -22,6 +23,7 @@
/**
* This is high memory dependent solution as all the appending commands will be hold in memory.
*/
+@Experimental
public class MultiClusterTransaction extends TransactionBase {
private static final Builder> NO_OP_BUILDER = BuilderFactory.RAW_OBJECT;
diff --git a/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java b/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java
index e6013a2c58..f26716086e 100644
--- a/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java
+++ b/src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java
@@ -19,6 +19,7 @@
import redis.clients.jedis.*;
import redis.clients.jedis.MultiClusterClientConfig.ClusterConfig;
+import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisValidationException;
import redis.clients.jedis.util.Pool;
@@ -35,6 +36,7 @@
*
*/
// TODO: move?
+@Experimental
public class MultiClusterPooledConnectionProvider implements ConnectionProvider {
private final Logger log = LoggerFactory.getLogger(getClass());