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..6f5a6f5 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; + 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/RedisConfigurationValidator.java b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java new file mode 100644 index 0000000..b6bbfe3 --- /dev/null +++ b/src/main/java/org/prebid/cache/repository/redis/RedisConfigurationValidator.java @@ -0,0 +1,66 @@ +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 instanceResult.isDefined() || clusterResult.isDefined(); + } + + 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 = timeOut && host && port; + + 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 22cf591..58e6f2b 100644 --- a/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java +++ b/src/main/java/org/prebid/cache/repository/redis/RedisPropertyConfiguration.java @@ -16,6 +16,7 @@ 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 java.time.Duration; @@ -29,7 +30,7 @@ @NoArgsConstructor @AllArgsConstructor @Configuration -@ConditionalOnProperty(prefix = "spring.redis", name = {"timeout"}) +@Conditional(RedisConfigurationValidator.class) @ConfigurationProperties(prefix = "spring.redis") public class RedisPropertyConfiguration { @@ -64,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() { @@ -79,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")