diff --git a/redis/pom.xml b/redis/pom.xml
index e3affdd7ef..9025294d59 100644
--- a/redis/pom.xml
+++ b/redis/pom.xml
@@ -23,6 +23,12 @@
${embedded-redis.version}
+
+ org.redisson
+ redisson
+ 3.3.0
+
+
junit
junit
diff --git a/redis/src/main/java/com/baeldung/CustomMessage.java b/redis/src/main/java/com/baeldung/CustomMessage.java
new file mode 100644
index 0000000000..1d6a7e4e13
--- /dev/null
+++ b/redis/src/main/java/com/baeldung/CustomMessage.java
@@ -0,0 +1,19 @@
+package com.baeldung;
+
+/**
+ * Created by johnson on 3/9/17.
+ */
+public class CustomMessage {
+ private String message;
+
+ public CustomMessage() {
+ }
+
+ public CustomMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/redis/src/main/java/com/baeldung/Ledger.java b/redis/src/main/java/com/baeldung/Ledger.java
new file mode 100644
index 0000000000..da72791f7e
--- /dev/null
+++ b/redis/src/main/java/com/baeldung/Ledger.java
@@ -0,0 +1,21 @@
+package com.baeldung;
+
+public class Ledger {
+
+ public Ledger() {
+ }
+
+ public Ledger(String name) {
+ this.name = name;
+ }
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/redis/src/main/java/com/baeldung/LedgerLiveObject.java b/redis/src/main/java/com/baeldung/LedgerLiveObject.java
new file mode 100644
index 0000000000..395498968e
--- /dev/null
+++ b/redis/src/main/java/com/baeldung/LedgerLiveObject.java
@@ -0,0 +1,21 @@
+package com.baeldung;
+
+import org.redisson.api.annotation.REntity;
+import org.redisson.api.annotation.RId;
+
+/**
+ * Created by johnson on 3/9/17.
+ */
+@REntity
+public class LedgerLiveObject {
+ @RId
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/redis/src/main/java/com/baeldung/LedgerServiceImpl.java b/redis/src/main/java/com/baeldung/LedgerServiceImpl.java
new file mode 100644
index 0000000000..207efbcdef
--- /dev/null
+++ b/redis/src/main/java/com/baeldung/LedgerServiceImpl.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by johnson on 3/9/17.
+ */
+public class LedgerServiceImpl implements LedgerServiceInterface {
+
+ String[] returnArray = {"entry1","entry2","entry3"};
+
+ @Override
+ public List getEntries(int count) {
+ return Arrays.asList(returnArray);
+ }
+}
diff --git a/redis/src/main/java/com/baeldung/LedgerServiceInterface.java b/redis/src/main/java/com/baeldung/LedgerServiceInterface.java
new file mode 100644
index 0000000000..918623ef7b
--- /dev/null
+++ b/redis/src/main/java/com/baeldung/LedgerServiceInterface.java
@@ -0,0 +1,10 @@
+package com.baeldung;
+
+import java.util.List;
+
+/**
+ * Created by johnson on 3/9/17.
+ */
+public interface LedgerServiceInterface {
+ List getEntries(int count);
+}
diff --git a/redis/src/main/resources/singleNodeConfig.json b/redis/src/main/resources/singleNodeConfig.json
new file mode 100644
index 0000000000..f56e13dcfc
--- /dev/null
+++ b/redis/src/main/resources/singleNodeConfig.json
@@ -0,0 +1,27 @@
+{
+ "singleServerConfig": {
+ "idleConnectionTimeout": 10000,
+ "pingTimeout": 1000,
+ "connectTimeout": 10000,
+ "timeout": 3000,
+ "retryAttempts": 3,
+ "retryInterval": 1500,
+ "reconnectionTimeout": 3000,
+ "failedAttempts": 3,
+ "password": null,
+ "subscriptionsPerConnection": 5,
+ "clientName": null,
+ "address": "redis://127.0.0.1:6379",
+ "subscriptionConnectionMinimumIdleSize": 1,
+ "subscriptionConnectionPoolSize": 50,
+ "connectionMinimumIdleSize": 10,
+ "connectionPoolSize": 64,
+ "database": 0,
+ "dnsMonitoring": false,
+ "dnsMonitoringInterval": 5000
+ },
+ "threads": 0,
+ "nettyThreads": 0,
+ "codec": null,
+ "useLinuxNativeEpoll": false
+}
\ No newline at end of file
diff --git a/redis/src/main/resources/singleNodeConfig.yaml b/redis/src/main/resources/singleNodeConfig.yaml
new file mode 100644
index 0000000000..1b05c46be2
--- /dev/null
+++ b/redis/src/main/resources/singleNodeConfig.yaml
@@ -0,0 +1,24 @@
+singleServerConfig:
+ idleConnectionTimeout: 10000
+ pingTimeout: 1000
+ connectTimeout: 10000
+ timeout: 3000
+ retryAttempts: 3
+ retryInterval: 1500
+ reconnectionTimeout: 3000
+ failedAttempts: 3
+ password: null
+ subscriptionsPerConnection: 5
+ clientName: null
+ address: "redis://127.0.0.1:6379"
+ subscriptionConnectionMinimumIdleSize: 1
+ subscriptionConnectionPoolSize: 50
+ connectionMinimumIdleSize: 10
+ connectionPoolSize: 64
+ database: 0
+ dnsMonitoring: false
+ dnsMonitoringInterval: 5000
+threads: 0
+nettyThreads: 0
+codec: ! {}
+useLinuxNativeEpoll: false
\ No newline at end of file
diff --git a/redis/src/test/java/com/baeldung/RedissonConfigurationTest.java b/redis/src/test/java/com/baeldung/RedissonConfigurationTest.java
new file mode 100644
index 0000000000..ba6d2eb54a
--- /dev/null
+++ b/redis/src/test/java/com/baeldung/RedissonConfigurationTest.java
@@ -0,0 +1,65 @@
+package com.baeldung;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import redis.embedded.RedisServer;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Created by johnson on 3/9/17.
+ */
+public class RedissonConfigurationTest {
+ private static RedisServer redisServer;
+ private static RedissonClient client;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ redisServer = new RedisServer(6379);
+ redisServer.start();
+ }
+
+ @AfterClass
+ public static void destroy() {
+ redisServer.stop();
+ client.shutdown();
+ }
+
+ @Test
+ public void givenJavaConfig_thenRedissonConnectToRedis() {
+ Config config = new Config();
+ config.useSingleServer()
+ .setAddress("127.0.0.1:6379");
+
+ client = Redisson.create(config);
+
+ assert(client != null && client.getKeys().count() >= 0);
+ }
+
+ @Test
+ public void givenJSONFileConfig_thenRedissonConnectToRedis() throws IOException {
+ Config config = Config.fromJSON(
+ new File(getClass().getClassLoader().getResource(
+ "singleNodeConfig.json").getFile()));
+
+ client = Redisson.create(config);
+
+ assert(client != null && client.getKeys().count() >= 0);
+ }
+
+ @Test
+ public void givenYAMLFileConfig_thenRedissonConnectToRedis() throws IOException {
+ Config config = Config.fromYAML(
+ new File(getClass().getClassLoader().getResource(
+ "singleNodeConfig.yaml").getFile()));
+
+ client = Redisson.create(config);
+
+ assert(client != null && client.getKeys().count() >= 0);
+ }
+}
\ No newline at end of file
diff --git a/redis/src/test/java/com/baeldung/RedissonTest.java b/redis/src/test/java/com/baeldung/RedissonTest.java
new file mode 100644
index 0000000000..59d8a1ebc9
--- /dev/null
+++ b/redis/src/test/java/com/baeldung/RedissonTest.java
@@ -0,0 +1,237 @@
+package com.baeldung;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.redisson.Redisson;
+import org.redisson.RedissonMultiLock;
+import org.redisson.api.*;
+import org.redisson.api.listener.MessageListener;
+import org.redisson.client.RedisClient;
+import org.redisson.client.RedisConnection;
+import org.redisson.client.codec.StringCodec;
+import org.redisson.client.protocol.RedisCommands;
+import redis.embedded.RedisServer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.junit.Assert.assertEquals;
+
+public class RedissonTest {
+
+ private static RedisServer redisServer;
+ private static RedissonClient client;
+
+ @BeforeClass
+ public static void setUp() throws IOException {
+ redisServer = new RedisServer(6379);
+ redisServer.start();
+ client = Redisson.create();
+ }
+
+ @AfterClass
+ public static void destroy() {
+ redisServer.stop();
+ client.shutdown();
+ }
+
+ @Test
+ public void givenMultipleKeysInRedis_thenGetAllKeys() {
+ client.getBucket("key1").set("key1");
+ client.getBucket("key2").set("key2");
+ client.getBucket("key3").set("key3");
+
+ RKeys keys = client.getKeys();
+
+ assert(keys.count() >= 3);
+ }
+
+ @Test
+ public void givenKeysWithPatternInRedis_thenGetPatternKeys() {
+ client.getBucket("key1").set("key1");
+ client.getBucket("key2").set("key2");
+ client.getBucket("key3").set("key3");
+ client.getBucket("id4").set("id4");
+
+ RKeys keys = client.getKeys();
+
+ Iterable keysWithPattern
+ = keys.getKeysByPattern("key*");
+
+ List keyWithPatternList
+ = StreamSupport.stream(
+ keysWithPattern.spliterator(),
+ false).collect(Collectors.toList());
+
+ assert(keyWithPatternList.size() == 3);
+ }
+
+ @Test
+ public void givenAnObject_thenSaveToRedis() {
+ RBucket bucket = client.getBucket("ledger");
+ Ledger ledger = new Ledger();
+ ledger.setName("ledger1");
+ bucket.set(ledger);
+
+ Ledger returnedLedger = bucket.get();
+
+ assert(
+ returnedLedger != null
+ && returnedLedger.getName().equals("ledger1"));
+ }
+
+ @Test
+ public void givenALong_thenSaveLongToRedisAndAtomicallyIncrement(){
+ Long value = 5L;
+
+ RAtomicLong atomicLong
+ = client.getAtomicLong("myAtomicLong");
+ atomicLong.set(value);
+ Long returnValue = atomicLong.incrementAndGet();
+
+ assert(returnValue == 6L);
+ }
+
+ @Test
+ public void givenTopicSubscribedToAChannel_thenReceiveMessageFromChannel() throws ExecutionException, InterruptedException {
+ CompletableFuture future = new CompletableFuture<>();
+
+ RTopic subscribeTopic = client.getTopic("baeldung");
+ subscribeTopic.addListener(new MessageListener() {
+ @Override
+ public void onMessage(String channel, CustomMessage customMessage) {
+ future.complete(customMessage.getMessage());
+ }
+ });
+
+ RTopic recieveTopic = client.getTopic("baeldung");
+ long clientsReceivedMessage
+ = recieveTopic.publish(new CustomMessage("This is a message"));
+
+ assertEquals("This is a message", future.get());
+
+ }
+
+ @Test
+ public void givenAMap_thenSaveMapToRedis(){
+ RMap map = client.getMap("ledger");
+ map.put("123", new Ledger("ledger"));
+
+ assert(map.get("123").getName().equals("ledger"));
+ }
+
+ @Test
+ public void givenASet_thenSaveSetToRedis(){
+ RSet ledgerSet = client.getSet("ledgerSet");
+ ledgerSet.add(new Ledger("ledger"));
+
+ assert(ledgerSet.contains(new Ledger("ledger")));
+ }
+
+ @Test
+ public void givenAList_thenSaveListToRedis(){
+ RList ledgerList = client.getList("ledgerList");
+ ledgerList.add(new Ledger("ledger"));
+
+ assert(ledgerList.contains(new Ledger("ledger")));
+ }
+
+ @Test
+ public void givenLockSet_thenEnsureCanUnlock(){
+ RLock lock = client.getLock("lock");
+ lock.lock();
+ assert(lock.isLocked());
+
+ lock.unlock();
+ assert(!lock.isLocked());
+ }
+
+ @Test
+ public void givenMultipleLocksSet_thenEnsureAllCanUnlock(){
+ RedissonClient clientInstance1 = Redisson.create();
+ RedissonClient clientInstance2 = Redisson.create();
+ RedissonClient clientInstance3 = Redisson.create();
+
+ RLock lock1 = clientInstance1.getLock("lock1");
+ RLock lock2 = clientInstance2.getLock("lock2");
+ RLock lock3 = clientInstance3.getLock("lock3");
+
+ RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
+ lock.lock();
+ assert(lock1.isLocked() && lock2.isLocked() && lock3.isLocked());
+
+ lock.unlock();
+ assert(!(lock1.isLocked() || lock2.isLocked() || lock3.isLocked()));
+ }
+
+ @Test
+ public void givenRemoteServiceMethodRegistered_thenInvokeMethod(){
+ RRemoteService remoteService = client.getRemoteService();
+ LedgerServiceImpl ledgerServiceImpl = new LedgerServiceImpl();
+
+ remoteService.register(LedgerServiceInterface.class, ledgerServiceImpl);
+
+
+ LedgerServiceInterface ledgerService
+ = remoteService.get(LedgerServiceInterface.class);
+
+ List entries = ledgerService.getEntries(10);
+
+ assert(entries.size() == 3 && entries.contains("entry1"));
+ }
+
+ @Test
+ public void givenLiveObjectPersisted_thenGetLiveObject(){
+ RLiveObjectService service = client.getLiveObjectService();
+
+ LedgerLiveObject ledger = new LedgerLiveObject();
+ ledger.setName("ledger1");
+
+ ledger = service.persist(ledger);
+
+ LedgerLiveObject returnLedger
+ = service.get(LedgerLiveObject.class, "ledger1");
+
+ assert(ledger.getName().equals(returnLedger.getName()));
+ }
+
+ @Test
+ public void givenMultipleOperations_thenDoAllAtomically(){
+ RBatch batch = client.createBatch();
+ batch.getMap("ledgerMap").fastPutAsync("1", "2");
+ batch.getMap("ledgerMap").putAsync("2", "5");
+
+ List> result = batch.execute();
+
+ RMap map = client.getMap("ledgerMap");
+ assert(result.size() > 0 && map.get("1").equals("2"));
+ }
+
+ @Test
+ public void givenLUAScript_thenExecuteScriptOnRedis(){
+ client.getBucket("foo").set("bar");
+ String result = client.getScript().eval(RScript.Mode.READ_ONLY,
+ "return redis.call('get', 'foo')", RScript.ReturnType.VALUE);
+
+ assert(result.equals("bar"));
+ }
+
+ @Test
+ public void givenLowLevelRedisCommands_thenExecuteLowLevelCommandsOnRedis(){
+ RedisClient client = new RedisClient("localhost", 6379);
+ RedisConnection conn = client.connect();
+ conn.sync(StringCodec.INSTANCE, RedisCommands.SET, "test", 0);
+
+ String testValue = conn.sync(StringCodec.INSTANCE, RedisCommands.GET, "test");
+
+ conn.closeAsync();
+ client.shutdown();
+
+ assert(testValue.equals("0"));
+ }
+}