From 98c124fb270975e4fcf6f909b08a9578738dd409 Mon Sep 17 00:00:00 2001 From: "piot.turek" Date: Thu, 22 Jan 2015 17:02:36 +0100 Subject: [PATCH] RedisSentinelBuilder, RedisSentinel adder --- .../redis/embedded/AbstractRedisInstance.java | 11 +- .../java/redis/embedded/RedisSentinel.java | 15 ++ .../redis/embedded/RedisSentinelBuilder.java | 143 ++++++++++++++++++ src/main/java/redis/embedded/RedisServer.java | 7 +- .../redis/embedded/RedisServerBuilder.java | 10 +- 5 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 src/main/java/redis/embedded/RedisSentinel.java create mode 100644 src/main/java/redis/embedded/RedisSentinelBuilder.java diff --git a/src/main/java/redis/embedded/AbstractRedisInstance.java b/src/main/java/redis/embedded/AbstractRedisInstance.java index 4796479c..18764d4b 100644 --- a/src/main/java/redis/embedded/AbstractRedisInstance.java +++ b/src/main/java/redis/embedded/AbstractRedisInstance.java @@ -16,10 +16,6 @@ abstract class AbstractRedisInstance implements RedisInstance { private volatile boolean active = false; private Process redisProcess; - public static RedisServerBuilder builder() { - return new RedisServerBuilder(); - } - @Override public boolean isActive() { return active; @@ -36,9 +32,8 @@ public synchronized void start() throws IOException { } private void awaitRedisServerReady() throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(redisProcess.getInputStream())); - try { - String outputLine = null; + try (BufferedReader reader = new BufferedReader(new InputStreamReader(redisProcess.getInputStream()))) { + String outputLine; do { outputLine = reader.readLine(); @@ -47,8 +42,6 @@ private void awaitRedisServerReady() throws IOException { throw new RuntimeException("Can't start redis server. Check logs for details."); } } while (!outputLine.matches(REDIS_READY_PATTERN)); - } finally { - reader.close(); } } diff --git a/src/main/java/redis/embedded/RedisSentinel.java b/src/main/java/redis/embedded/RedisSentinel.java new file mode 100644 index 00000000..07e640d5 --- /dev/null +++ b/src/main/java/redis/embedded/RedisSentinel.java @@ -0,0 +1,15 @@ +package redis.embedded; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by piotrturek on 22/01/15. + */ +public class RedisSentinel extends AbstractRedisInstance { + public RedisSentinel(List args) { + this.args = new ArrayList<>(args); + } + + public static RedisSentinelBuilder builder() { return new RedisSentinelBuilder(); } +} diff --git a/src/main/java/redis/embedded/RedisSentinelBuilder.java b/src/main/java/redis/embedded/RedisSentinelBuilder.java new file mode 100644 index 00000000..21306d55 --- /dev/null +++ b/src/main/java/redis/embedded/RedisSentinelBuilder.java @@ -0,0 +1,143 @@ +package redis.embedded; + +import com.google.common.base.Preconditions; +import com.google.common.io.Files; +import redis.embedded.util.JarUtil; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by piotrturek on 22/01/15. + */ +public class RedisSentinelBuilder { + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + private static final String CONF_FILENAME = "embedded-redis-sentinel"; + private static final String MASTER_MONITOR_LINE = "sentinel monitor %s 127.0.0.1 %d 1"; + private static final String DOWN_AFTER_LINE = "sentinel down-after-milliseconds %s %d"; + private static final String FAILOVER_LINE = "sentinel failover-timeout %s %d"; + private static final String PARALLEL_SYNCS_LINE = "parallel-syncs %s %d"; + + private File executable; + private Integer port; + private int masterPort = 6379; + private String masterName = "mymaster"; + private long downAfterMilliseconds = 60000L; + private long failoverTimeout = 180000L; + private int parallelSyncs = 1; + private String sentinelConf; + + private StringBuilder redisConfigBuilder; + + public RedisSentinelBuilder executable(File executable) { + this.executable = executable; + return this; + } + + public RedisSentinelBuilder executable(String executable) { + this.executable = new File(executable); + return this; + } + + public RedisSentinelBuilder port(Integer port) { + this.port = port; + return this; + } + + public RedisSentinelBuilder masterPort(Integer masterPort) { + this.masterPort = masterPort; + return this; + } + + public RedisSentinelBuilder masterName(String masterName) { + this.masterName = masterName; + return this; + } + + public RedisSentinelBuilder downAfterMilliseconds(Long downAfterMilliseconds) { + this.downAfterMilliseconds = downAfterMilliseconds; + return this; + } + + public RedisSentinelBuilder failoverTimeout(Long failoverTimeout) { + this.failoverTimeout = failoverTimeout; + return this; + } + + public RedisSentinelBuilder parallelSyncs(int parallelSyncs) { + this.parallelSyncs = parallelSyncs; + return this; + } + + public RedisSentinelBuilder configFile(String redisConf) { + if (redisConfigBuilder != null) { + throw new RuntimeException("Redis configuration is already partially build using setting(String) method!"); + } + this.sentinelConf = redisConf; + return this; + } + + public RedisSentinelBuilder setting(String configLine) { + if (sentinelConf != null) { + throw new RuntimeException("Redis configuration is already set using redis conf file!"); + } + + if (redisConfigBuilder == null) { + redisConfigBuilder = new StringBuilder(); + } + + redisConfigBuilder.append(configLine); + redisConfigBuilder.append(LINE_SEPARATOR); + return this; + } + + public RedisSentinel build() throws IOException { + if (sentinelConf == null) { + resolveSentinelConf(); + } + if (executable == null) { + executable = JarUtil.extractExecutableFromJar(RedisRunScriptEnum.getRedisRunScript()); + } + + List args = buildCommandArgs(); + return new RedisSentinel(args); + } + + private void resolveSentinelConf() throws IOException { + if (redisConfigBuilder == null) { + useDefaultConfig(); + } + final String configString = redisConfigBuilder.toString(); + + File redisConfigFile = File.createTempFile(CONF_FILENAME, ".conf"); + redisConfigFile.deleteOnExit(); + Files.write(configString, redisConfigFile, Charset.forName("UTF-8")); + sentinelConf = redisConfigFile.getAbsolutePath(); + } + + private void useDefaultConfig() { + setting(String.format(MASTER_MONITOR_LINE, masterName, masterPort)); + setting(String.format(DOWN_AFTER_LINE, masterName, downAfterMilliseconds)); + setting(String.format(FAILOVER_LINE, masterName, failoverTimeout)); + setting(String.format(PARALLEL_SYNCS_LINE, masterName, parallelSyncs)); + } + + private List buildCommandArgs() { + Preconditions.checkNotNull(sentinelConf); + + List args = new ArrayList<>(); + args.add(sentinelConf); + args.add("--sentinel"); + args.add(executable.getAbsolutePath()); + + if (port != null) { + args.add("--port"); + args.add(Integer.toString(port)); + } + + return args; + } +} diff --git a/src/main/java/redis/embedded/RedisServer.java b/src/main/java/redis/embedded/RedisServer.java index 563c33b3..ff7e4f07 100644 --- a/src/main/java/redis/embedded/RedisServer.java +++ b/src/main/java/redis/embedded/RedisServer.java @@ -9,7 +9,7 @@ import java.util.List; public class RedisServer extends AbstractRedisInstance { - RedisServer(Integer port) throws IOException { + public RedisServer(Integer port) throws IOException { File executable = JarUtil.extractExecutableFromJar(RedisRunScriptEnum.getRedisRunScript()); this.args = Arrays.asList( executable.getAbsolutePath(), @@ -17,7 +17,7 @@ public class RedisServer extends AbstractRedisInstance { ); } - RedisServer(File executable, Integer port) { + public RedisServer(File executable, Integer port) { this.args = Arrays.asList( executable.getAbsolutePath(), "--port", Integer.toString(port) @@ -28,4 +28,7 @@ public class RedisServer extends AbstractRedisInstance { this.args = new ArrayList<>(args); } + public static RedisServerBuilder builder() { + return new RedisServerBuilder(); + } } diff --git a/src/main/java/redis/embedded/RedisServerBuilder.java b/src/main/java/redis/embedded/RedisServerBuilder.java index 64268a35..e1ae6a55 100644 --- a/src/main/java/redis/embedded/RedisServerBuilder.java +++ b/src/main/java/redis/embedded/RedisServerBuilder.java @@ -16,6 +16,7 @@ */ public class RedisServerBuilder { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + private static final String CONF_FILENAME = "embedded-redis-server"; private File executable; private Integer port; @@ -73,7 +74,7 @@ public RedisServerBuilder setting(String configLine) { public RedisServer build() throws IOException { if (redisConf == null && redisConfigBuilder != null) { - File redisConfigFile = File.createTempFile("embedded-redis", ".conf"); + File redisConfigFile = File.createTempFile(CONF_FILENAME, ".conf"); redisConfigFile.deleteOnExit(); Files.write(redisConfigBuilder.toString(), redisConfigFile, Charset.forName("UTF-8")); redisConf = redisConfigFile.getAbsolutePath(); @@ -87,8 +88,11 @@ public RedisServer build() throws IOException { return new RedisServer(args); } - private List buildCommandArgs() { - List args = new ArrayList(); + private List buildCommandArgs() throws IOException { + List args = new ArrayList<>(); + if (executable == null) { + executable = JarUtil.extractExecutableFromJar(RedisRunScriptEnum.getRedisRunScript()); + } args.add(executable.getAbsolutePath()); if (!Strings.isNullOrEmpty(redisConf)) {