Skip to content

Commit

Permalink
encapsulated redis exceptions into a ... well a redis exception; simp…
Browse files Browse the repository at this point in the history
…le redis cluster introduced and tested (minimally)
  • Loading branch information
turu committed Jan 22, 2015
1 parent c4368ff commit 10e72b9
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 23 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
<version>2.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
Expand Down
32 changes: 23 additions & 9 deletions src/main/java/redis/embedded/AbstractRedisInstance.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package redis.embedded;

import redis.embedded.exceptions.EmbeddedRedisException;

import java.io.*;
import java.util.Collections;
import java.util.List;
Expand All @@ -9,7 +11,7 @@
/**
* Created by piotrturek on 22/01/15.
*/
abstract class AbstractRedisInstance implements RedisInstance {
abstract class AbstractRedisInstance implements Redis {
protected List<String> args = Collections.emptyList();
private volatile boolean active = false;
private Process redisProcess;
Expand All @@ -22,14 +24,18 @@ public boolean isActive() {
}

@Override
public synchronized void start() throws IOException {
public synchronized void start() throws EmbeddedRedisException {
if (active) {
throw new RuntimeException("This redis server instance is already running...");
throw new EmbeddedRedisException("This redis server instance is already running...");
}
try {
redisProcess = createRedisProcessBuilder().start();
logErrors();
awaitRedisServerReady();
active = true;
} catch (IOException e) {
throw new EmbeddedRedisException("Failed to start Reddis instance", e);
}
redisProcess = createRedisProcessBuilder().start();
logErrors();
awaitRedisServerReady();
active = true;
}

private void logErrors() {
Expand Down Expand Up @@ -70,11 +76,19 @@ private ProcessBuilder createRedisProcessBuilder() {
}

@Override
public synchronized void stop() throws InterruptedException {
public synchronized void stop() throws EmbeddedRedisException {
if (active) {
redisProcess.destroy();
redisProcess.waitFor();
tryWaitFor();
active = false;
}
}

private void tryWaitFor() {
try {
redisProcess.waitFor();
} catch (InterruptedException e) {
throw new EmbeddedRedisException("Failed to stop redis instance", e);
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/redis/embedded/Redis.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package redis.embedded;

import redis.embedded.exceptions.EmbeddedRedisException;

/**
* Created by piotrturek on 22/01/15.
*/
public interface Redis {
boolean isActive();

void start() throws EmbeddedRedisException;

void stop() throws EmbeddedRedisException;
}
36 changes: 36 additions & 0 deletions src/main/java/redis/embedded/RedisCluster.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package redis.embedded;

import redis.embedded.exceptions.EmbeddedRedisException;

import java.util.LinkedList;
import java.util.List;

/**
* Created by piotrturek on 22/01/15.
*/
public class RedisCluster implements Redis {
private final List<Redis> sentinels = new LinkedList<>();
private final List<Redis> servers = new LinkedList<>();

public RedisCluster(List<Redis> sentinels, List<Redis> servers) {
this.servers.addAll(servers);
this.sentinels.addAll(sentinels);
}

@Override
public boolean isActive() {
return sentinels.stream().allMatch(Redis::isActive) && servers.stream().allMatch(Redis::isActive);
}

@Override
public void start() throws EmbeddedRedisException {
sentinels.parallelStream().forEach(Redis::start);
servers.parallelStream().forEach(Redis::start);
}

@Override
public void stop() throws EmbeddedRedisException {
servers.parallelStream().forEach(Redis::stop);
sentinels.parallelStream().forEach(Redis::stop);
}
}
14 changes: 0 additions & 14 deletions src/main/java/redis/embedded/RedisInstance.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package redis.embedded.exceptions;

/**
* Created by piotrturek on 22/01/15.
*/
public class EmbeddedRedisException extends RuntimeException {
public EmbeddedRedisException(String message, Throwable cause) {
super(message, cause);
}

public EmbeddedRedisException(String message) {
super(message);
}
}
78 changes: 78 additions & 0 deletions src/test/java/redis/embedded/RedisClusterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package redis.embedded;

import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class RedisClusterTest {
private Redis sentinel1;
private Redis sentinel2;
private Redis master1;
private Redis master2;

private RedisCluster instance;

@Before
public void setUp() throws Exception {
sentinel1 = mock(Redis.class);
sentinel2 = mock(Redis.class);
master1 = mock(Redis.class);
master2 = mock(Redis.class);
}


@Test
public void stopShouldStopEntireCluster() throws Exception {
//given
final List<Redis> sentinels = Arrays.asList(sentinel1, sentinel2);
final List<Redis> servers = Arrays.asList(master1, master2);
instance = new RedisCluster(sentinels, servers);

//when
instance.stop();

//then
sentinels.stream().forEach(s -> verify(s).stop());
servers.stream().forEach(m -> verify(m).stop());
}

@Test
public void startShouldStartEntireCluster() throws Exception {
//given
final List<Redis> sentinels = Arrays.asList(sentinel1, sentinel2);
final List<Redis> servers = Arrays.asList(master1, master2);
instance = new RedisCluster(sentinels, servers);

//when
instance.start();

//then
sentinels.stream().forEach(s -> verify(s).start());
servers.stream().forEach(m -> verify(m).start());
}

@Test
public void isActiveShouldCheckEntireClusterIfAllActive() throws Exception {
//given
given(sentinel1.isActive()).willReturn(true);
given(sentinel2.isActive()).willReturn(true);
given(master1.isActive()).willReturn(true);
given(master2.isActive()).willReturn(true);
final List<Redis> sentinels = Arrays.asList(sentinel1, sentinel2);
final List<Redis> servers = Arrays.asList(master1, master2);
instance = new RedisCluster(sentinels, servers);

//when
instance.isActive();

//then
sentinels.stream().forEach(s -> verify(s).isActive());
servers.stream().forEach(m -> verify(m).isActive());
}
}

0 comments on commit 10e72b9

Please sign in to comment.