From c19932ed01b48e02c89cdfdf14ea747dd0ff3a92 Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 11 Jul 2022 13:58:43 +0300 Subject: [PATCH 1/8] Re-impl validation for cache config --- .../ValidateRedisPropertyConditional.java | 26 +++++++++++++++++++ .../AerospikePropertyConfiguration.java | 9 +++++++ .../redis/RedisPropertyConfiguration.java | 8 ++++-- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java diff --git a/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java b/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java new file mode 100644 index 0000000..e81b31c --- /dev/null +++ b/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java @@ -0,0 +1,26 @@ +package org.prebid.cache.helpers; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.env.Environment; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public class ValidateRedisPropertyConditional implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + final Environment contextEnvironment = context.getEnvironment(); + final boolean timeOut = contextEnvironment.containsProperty("spring.redis.timeout"); + final boolean host = contextEnvironment.containsProperty("spring.redis.host"); + final boolean password = contextEnvironment.containsProperty("spring.redis.password"); + final boolean port = contextEnvironment.containsProperty("spring.redis.port"); + final boolean cluster = contextEnvironment.containsProperty("spring.redis.cluster"); + final boolean clusterNodes = contextEnvironment.containsProperty("spring.redis.cluster.nodes"); + + if (timeOut & host & port & password & cluster) { + return false; + } else if (timeOut & host & port & password) { + return true; + } else return timeOut & cluster & clusterNodes; + } +} diff --git a/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java index 180874e..da02dca 100644 --- a/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java @@ -31,14 +31,23 @@ @ConditionalOnProperty(prefix = "spring.aerospike", name = {"host"}) @ConfigurationProperties(prefix = "spring.aerospike") public class AerospikePropertyConfiguration { + @NotNull private String host; + @NotNull private Integer port; + @NotNull private String password; + @NotNull private Integer cores; + @NotNull private Long firstBackoff; + @NotNull private Long maxBackoff; + @NotNull private int maxRetry; + @NotNull private String namespace; + @NotNull private boolean preventUUIDDuplication; private static final int DEFAULT_PORT = 3000; diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java index 22cf591..4c91053 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java @@ -13,11 +13,14 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.Singular; +import org.prebid.cache.helpers.ValidateRedisPropertyConditional; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import javax.validation.constraints.NotNull; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.List; @@ -29,8 +32,7 @@ @NoArgsConstructor @AllArgsConstructor @Configuration -@ConditionalOnProperty(prefix = "spring.redis", name = {"timeout"}) -@ConfigurationProperties(prefix = "spring.redis") +@Conditional(ValidateRedisPropertyConditional.class) public class RedisPropertyConfiguration { private String host; @@ -40,9 +42,11 @@ public class RedisPropertyConfiguration { private Cluster cluster; @Data + @ConditionalOnProperty(prefix = "spring.redis", name = {"cluster"}) public static class Cluster { @Singular + @NotNull List nodes; boolean enableTopologyRefresh; From 6cedd4b6b39a64f56de642a348ed49114b4ec2cb Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 11 Jul 2022 14:03:25 +0300 Subject: [PATCH 2/8] Remove unused imports --- .../cache/repository/redis/RedisPropertyConfiguration.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java index 4c91053..b8c69d0 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java @@ -15,7 +15,6 @@ import lombok.Singular; import org.prebid.cache.helpers.ValidateRedisPropertyConditional; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; From 2d5384d8808b8d2471c5e769726d610d1f95b144 Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 11 Jul 2022 15:14:05 +0300 Subject: [PATCH 3/8] Minor fix --- .../repository/aerospike/AerospikePropertyConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java index da02dca..aafa80e 100644 --- a/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java @@ -47,7 +47,7 @@ public class AerospikePropertyConfiguration { private int maxRetry; @NotNull private String namespace; - @NotNull + private boolean preventUUIDDuplication; private static final int DEFAULT_PORT = 3000; From 5cd51c0affd05a4b1badd673a974835431168494 Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 11 Jul 2022 16:29:42 +0300 Subject: [PATCH 4/8] Fixed --- .../cache/helpers/ValidateRedisPropertyConditional.java | 9 ++------- .../aerospike/AerospikePropertyConfiguration.java | 4 ++-- .../repository/redis/RedisPropertyConfiguration.java | 5 ++--- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java b/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java index e81b31c..104624b 100644 --- a/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java +++ b/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java @@ -12,15 +12,10 @@ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) final Environment contextEnvironment = context.getEnvironment(); final boolean timeOut = contextEnvironment.containsProperty("spring.redis.timeout"); final boolean host = contextEnvironment.containsProperty("spring.redis.host"); - final boolean password = contextEnvironment.containsProperty("spring.redis.password"); final boolean port = contextEnvironment.containsProperty("spring.redis.port"); final boolean cluster = contextEnvironment.containsProperty("spring.redis.cluster"); - final boolean clusterNodes = contextEnvironment.containsProperty("spring.redis.cluster.nodes"); + final boolean nodes = contextEnvironment.containsProperty("spring.redis.cluster.nodes"); - if (timeOut & host & port & password & cluster) { - return false; - } else if (timeOut & host & port & password) { - return true; - } else return timeOut & cluster & clusterNodes; + return timeOut & host & port || timeOut & cluster & nodes; } } diff --git a/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java index aafa80e..6f5a6f5 100644 --- a/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/aerospike/AerospikePropertyConfiguration.java @@ -35,7 +35,7 @@ public class AerospikePropertyConfiguration { private String host; @NotNull private Integer port; - @NotNull + private String password; @NotNull private Integer cores; @@ -47,7 +47,7 @@ public class AerospikePropertyConfiguration { private int maxRetry; @NotNull private String namespace; - + @NotNull private boolean preventUUIDDuplication; private static final int DEFAULT_PORT = 3000; diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java index b8c69d0..c4ea1e0 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java @@ -15,11 +15,11 @@ import lombok.Singular; import org.prebid.cache.helpers.ValidateRedisPropertyConditional; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; -import javax.validation.constraints.NotNull; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.List; @@ -32,6 +32,7 @@ @AllArgsConstructor @Configuration @Conditional(ValidateRedisPropertyConditional.class) +@ConfigurationProperties(prefix = "spring.redis") public class RedisPropertyConfiguration { private String host; @@ -41,11 +42,9 @@ public class RedisPropertyConfiguration { private Cluster cluster; @Data - @ConditionalOnProperty(prefix = "spring.redis", name = {"cluster"}) public static class Cluster { @Singular - @NotNull List nodes; boolean enableTopologyRefresh; From 2d306da79c86b72998f7e1bed733ce7f598607a0 Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Mon, 11 Jul 2022 16:57:21 +0300 Subject: [PATCH 5/8] Enhance errors on invalid redis configuration --- .../ValidateRedisPropertyConditional.java | 21 ------ .../redis/RedisConfigurationValidator.java | 65 +++++++++++++++++++ .../redis/RedisPropertyConfiguration.java | 15 ++--- 3 files changed, 72 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java create mode 100644 src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java diff --git a/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java b/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java deleted file mode 100644 index 104624b..0000000 --- a/src/main/java/org/prebid/cache/helpers/ValidateRedisPropertyConditional.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.prebid.cache.helpers; - -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.core.env.Environment; -import org.springframework.core.type.AnnotatedTypeMetadata; - -public class ValidateRedisPropertyConditional implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - final Environment contextEnvironment = context.getEnvironment(); - final boolean timeOut = contextEnvironment.containsProperty("spring.redis.timeout"); - final boolean host = contextEnvironment.containsProperty("spring.redis.host"); - final boolean port = contextEnvironment.containsProperty("spring.redis.port"); - final boolean cluster = contextEnvironment.containsProperty("spring.redis.cluster"); - final boolean nodes = contextEnvironment.containsProperty("spring.redis.cluster.nodes"); - - return timeOut & host & port || timeOut & cluster & nodes; - } -} diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java new file mode 100644 index 0000000..459d7ab --- /dev/null +++ b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java @@ -0,0 +1,65 @@ +package org.prebid.cache.repository.redis; + +import lombok.Value; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.env.Environment; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public class RedisConfigurationValidator implements Condition { + + private static final String CLUSTER_PREFIX = "spring.redis.cluster."; + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + final Environment environment = context.getEnvironment(); + final ValidationResult clusterResult = validateClusterConfiguration(environment); + final ValidationResult instanceResult = validateInstanceConfiguration(environment); + + if (clusterResult.isDefined() && instanceResult.isDefined()) { + throw new IllegalArgumentException("Defining both instance and cluster redis is prohibited"); + } else if (clusterResult.isDefined() && !clusterResult.isValid()) { + throw new IllegalArgumentException("Cluster redis configuration is invalid"); + } else if (instanceResult.isDefined() && !instanceResult.isValid()) { + throw new IllegalArgumentException("Redis instance configuration is invalid"); + } + + return true; + } + + private static ValidationResult validateInstanceConfiguration(Environment environment) { + final boolean host = environment.containsProperty("spring.redis.host"); + final boolean password = environment.containsProperty("spring.redis.password"); + final boolean port = environment.containsProperty("spring.redis.port"); + + final boolean instanceDefined = host || port || password; + final boolean instanceValid = host && port && password; + + return ValidationResult.of(instanceDefined, instanceValid); + } + + private static ValidationResult validateClusterConfiguration(Environment environment) { + final boolean timeOut = environment.containsProperty("spring.redis.timeout"); + + final boolean clusterNodes = environment.containsProperty(CLUSTER_PREFIX + "nodes"); + final boolean clusterRefresh = environment.containsProperty(CLUSTER_PREFIX + "enable-topology-refresh"); + final boolean clusterTopology = environment.containsProperty(CLUSTER_PREFIX + + "topology-periodic-refresh-period"); + + boolean refreshAbsent = !clusterRefresh && !clusterTopology; + boolean refreshValid = clusterRefresh && clusterTopology; + + boolean clusterDefined = clusterNodes || clusterRefresh || clusterTopology; + boolean clusterValid = timeOut && clusterNodes && (refreshValid || refreshAbsent); + + return ValidationResult.of(clusterDefined, clusterValid); + } + + @Value(staticConstructor = "of") + private static class ValidationResult { + + boolean defined; + + boolean valid; + } +} diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java index c4ea1e0..58e6f2b 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java @@ -13,7 +13,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.Singular; -import org.prebid.cache.helpers.ValidateRedisPropertyConditional; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -31,7 +30,7 @@ @NoArgsConstructor @AllArgsConstructor @Configuration -@Conditional(ValidateRedisPropertyConditional.class) +@Conditional(RedisConfigurationValidator.class) @ConfigurationProperties(prefix = "spring.redis") public class RedisPropertyConfiguration { @@ -66,9 +65,9 @@ private RedisURI createRedisURI(String host, int port) { private List createRedisClusterURIs() { return cluster.getNodes().stream() - .map(node -> node.split(":")) - .map(host -> createRedisURI(host[0], Integer.parseInt(host[1]))) - .collect(Collectors.toList()); + .map(node -> node.split(":")) + .map(host -> createRedisURI(host[0], Integer.parseInt(host[1]))) + .collect(Collectors.toList()); } private ClusterClientOptions createRedisClusterOptions() { @@ -81,9 +80,9 @@ private ClusterClientOptions createRedisClusterOptions() { : null; return ClusterClientOptions.builder() - .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS) - .topologyRefreshOptions(topologyRefreshOptions) - .build(); + .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS) + .topologyRefreshOptions(topologyRefreshOptions) + .build(); } @Bean(destroyMethod = "shutdown") From 6ff84752dcfe15411688c163909d4e53885611f8 Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Mon, 11 Jul 2022 17:15:56 +0300 Subject: [PATCH 6/8] Remove password validation --- .../cache/repository/redis/RedisConfigurationValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java index 459d7ab..1222def 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java @@ -33,7 +33,7 @@ private static ValidationResult validateInstanceConfiguration(Environment enviro final boolean port = environment.containsProperty("spring.redis.port"); final boolean instanceDefined = host || port || password; - final boolean instanceValid = host && port && password; + final boolean instanceValid = host && port; return ValidationResult.of(instanceDefined, instanceValid); } From 65bea583a06735e4c79926d600d8ea88949de1fd Mon Sep 17 00:00:00 2001 From: markiian Date: Mon, 11 Jul 2022 17:28:57 +0300 Subject: [PATCH 7/8] Fixed --- .../cache/repository/redis/RedisConfigurationValidator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java index 1222def..a5bb272 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java @@ -28,12 +28,13 @@ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) } private static ValidationResult validateInstanceConfiguration(Environment environment) { + final boolean timeOut = environment.containsProperty("spring.redis.timeout"); final boolean host = environment.containsProperty("spring.redis.host"); final boolean password = environment.containsProperty("spring.redis.password"); final boolean port = environment.containsProperty("spring.redis.port"); final boolean instanceDefined = host || port || password; - final boolean instanceValid = host && port; + final boolean instanceValid = timeOut && host && port; return ValidationResult.of(instanceDefined, instanceValid); } From 36487b8c304a2558bb9eae82b323f02297757eca Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Tue, 12 Jul 2022 15:54:43 +0300 Subject: [PATCH 8/8] Fixed redis configuration matcher --- .../cache/repository/redis/RedisConfigurationValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java index a5bb272..b6bbfe3 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java @@ -24,7 +24,7 @@ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) throw new IllegalArgumentException("Redis instance configuration is invalid"); } - return true; + return instanceResult.isDefined() || clusterResult.isDefined(); } private static ValidationResult validateInstanceConfiguration(Environment environment) {