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")); + } +}