Merge pull request #8125 from eugenp/revert-8119-BAEL-3275-2

Revert "BAEL-3275: Using blocking queue for pub-sub"
This commit is contained in:
Eric Martin
2019-10-31 20:43:47 -05:00
committed by GitHub
parent db85c8f275
commit 3225470df5
20543 changed files with 1642750 additions and 0 deletions
@@ -0,0 +1,229 @@
package com.baeldung;
import java.io.IOException;
import java.net.ServerSocket;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
import redis.embedded.RedisServer;
public class JedisIntegrationTest {
private static Jedis jedis;
private static RedisServer redisServer;
private static int port;
@BeforeClass
public static void setUp() throws IOException {
// Take an available port
ServerSocket s = new ServerSocket(0);
port = s.getLocalPort();
s.close();
redisServer = new RedisServer(port);
redisServer.start();
// Configure JEDIS
jedis = new Jedis("localhost", port);
}
@AfterClass
public static void destroy() {
redisServer.stop();
}
@After
public void flush() {
jedis.flushAll();
}
@Test
public void givenAString_thenSaveItAsRedisStrings() {
String key = "key";
String value = "value";
jedis.set(key, value);
String value2 = jedis.get(key);
Assert.assertEquals(value, value2);
}
@Test
public void givenListElements_thenSaveThemInRedisList() {
String queue = "queue#tasks";
String taskOne = "firstTask";
String taskTwo = "secondTask";
String taskThree = "thirdTask";
jedis.lpush(queue, taskOne, taskTwo);
String taskReturnedOne = jedis.rpop(queue);
jedis.lpush(queue, taskThree);
Assert.assertEquals(taskOne, taskReturnedOne);
String taskReturnedTwo = jedis.rpop(queue);
String taskReturnedThree = jedis.rpop(queue);
Assert.assertEquals(taskTwo, taskReturnedTwo);
Assert.assertEquals(taskThree, taskReturnedThree);
String taskReturnedFour = jedis.rpop(queue);
Assert.assertNull(taskReturnedFour);
}
@Test
public void givenSetElements_thenSaveThemInRedisSet() {
String countries = "countries";
String countryOne = "Spain";
String countryTwo = "Ireland";
String countryThree = "Ireland";
jedis.sadd(countries, countryOne);
Set<String> countriesSet = jedis.smembers(countries);
Assert.assertEquals(1, countriesSet.size());
jedis.sadd(countries, countryTwo);
countriesSet = jedis.smembers(countries);
Assert.assertEquals(2, countriesSet.size());
jedis.sadd(countries, countryThree);
countriesSet = jedis.smembers(countries);
Assert.assertEquals(2, countriesSet.size());
boolean exists = jedis.sismember(countries, countryThree);
Assert.assertTrue(exists);
}
@Test
public void givenObjectFields_thenSaveThemInRedisHash() {
String key = "user#1";
String field = "name";
String value = "William";
String field2 = "job";
String value2 = "politician";
jedis.hset(key, field, value);
jedis.hset(key, field2, value2);
String value3 = jedis.hget(key, field);
Assert.assertEquals(value, value3);
Map<String, String> fields = jedis.hgetAll(key);
String value4 = fields.get(field2);
Assert.assertEquals(value2, value4);
}
@Test
public void givenARanking_thenSaveItInRedisSortedSet() {
String key = "ranking";
Map<String, Double> scores = new HashMap<>();
scores.put("PlayerOne", 3000.0);
scores.put("PlayerTwo", 1500.0);
scores.put("PlayerThree", 8200.0);
scores.entrySet().forEach(playerScore -> {
jedis.zadd(key, playerScore.getValue(), playerScore.getKey());
});
Set<String> players = jedis.zrevrange(key, 0, 1);
Assert.assertEquals("PlayerThree", players.iterator().next());
long rank = jedis.zrevrank(key, "PlayerOne");
Assert.assertEquals(1, rank);
}
@Test
public void givenMultipleOperationsThatNeedToBeExecutedAtomically_thenWrapThemInATransaction() {
String friendsPrefix = "friends#";
String userOneId = "4352523";
String userTwoId = "5552321";
Transaction t = jedis.multi();
t.sadd(friendsPrefix + userOneId, userTwoId);
t.sadd(friendsPrefix + userTwoId, userOneId);
t.exec();
boolean exists = jedis.sismember(friendsPrefix + userOneId, userTwoId);
Assert.assertTrue(exists);
exists = jedis.sismember(friendsPrefix + userTwoId, userOneId);
Assert.assertTrue(exists);
}
@Test
public void givenMultipleIndependentOperations_whenNetworkOptimizationIsImportant_thenWrapThemInAPipeline() {
String userOneId = "4352523";
String userTwoId = "4849888";
Pipeline p = jedis.pipelined();
p.sadd("searched#" + userOneId, "paris");
p.zadd("ranking", 126, userOneId);
p.zadd("ranking", 325, userTwoId);
Response<Boolean> pipeExists = p.sismember("searched#" + userOneId, "paris");
Response<Set<String>> pipeRanking = p.zrange("ranking", 0, -1);
p.sync();
Assert.assertTrue(pipeExists.get());
Assert.assertEquals(2, pipeRanking.get().size());
}
@Test
public void givenAPoolConfiguration_thenCreateAJedisPool() {
final JedisPoolConfig poolConfig = buildPoolConfig();
try (JedisPool jedisPool = new JedisPool(poolConfig, "localhost", port); Jedis jedis = jedisPool.getResource()) {
// do simple operation to verify that the Jedis resource is working
// properly
String key = "key";
String value = "value";
jedis.set(key, value);
String value2 = jedis.get(key);
Assert.assertEquals(value, value2);
// flush Redis
jedis.flushAll();
}
}
private JedisPoolConfig buildPoolConfig() {
final JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
poolConfig.setMaxIdle(128);
poolConfig.setMinIdle(16);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis());
poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis());
poolConfig.setNumTestsPerEvictionRun(3);
poolConfig.setBlockWhenExhausted(true);
return poolConfig;
}
}
@@ -0,0 +1,312 @@
package com.baeldung;
import io.lettuce.core.LettuceFutures;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.TransactionResult;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.pubsub.RedisPubSubListener;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
import io.lettuce.core.pubsub.api.async.RedisPubSubAsyncCommands;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertTrue;
public class LettuceIntegrationLiveTest {
private static Logger log = LoggerFactory.getLogger(LettuceIntegrationLiveTest.class);
private static StatefulRedisConnection<String, String> redisConnection;
private static RedisClient redisClient;
@BeforeClass
public static void setUp() {
// Docker defaults to mapping redis port to 32768
redisClient = RedisClient.create("redis://localhost:32768/");
redisConnection = redisClient.connect();
}
@AfterClass
public static void destroy() {
redisConnection.close();
}
@Test
public void givenAString_thenSaveItAsRedisStringsSync() {
RedisCommands<String, String> syncCommands = redisConnection.sync();
String key = "key";
String value = "value";
syncCommands.set(key, value);
String response = syncCommands.get(key);
Assert.assertEquals(value, response);
}
@Test
public void givenValues_thenSaveAsRedisHashSync() {
RedisCommands<String, String> syncCommands = redisConnection.sync();
String recordName = "record1";
String name = "FirstName";
String value = "John";
String surname = "LastName";
String value1 = "Smith";
syncCommands.hset(recordName, name, value);
syncCommands.hset(recordName, surname, value1);
Map<String, String> record = syncCommands.hgetall(recordName);
Assert.assertEquals(record.get(name), value);
Assert.assertEquals(record.get(surname), value1);
}
@Test
public void givenAString_thenSaveItAsRedisStringsAsync() throws Exception {
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
String key = "key";
String value = "value";
asyncCommands.set(key, value);
RedisFuture<String> redisFuture = asyncCommands.get(key);
String response = redisFuture.get();
Assert.assertEquals(value, response);
}
@Test
public void givenValues_thenSaveAsRedisHashAsync() throws Exception {
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
String recordName = "record1";
String name = "FirstName";
String value = "John";
String surname = "LastName";
String value1 = "Smith";
asyncCommands.hset(recordName, name, value);
asyncCommands.hset(recordName, surname, value1);
RedisFuture<Map<String, String>> redisFuture = asyncCommands.hgetall(recordName);
Map<String, String> record = redisFuture.get();
Assert.assertEquals(record.get(name), value);
Assert.assertEquals(record.get(surname), value1);
}
@Test
public void givenValues_thenSaveAsRedisListAsync() throws Exception {
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
String listName = "tasks";
String firstTask = "firstTask";
String secondTask = "secondTask";
asyncCommands.del(listName);
asyncCommands.lpush(listName, firstTask);
asyncCommands.lpush(listName, secondTask);
RedisFuture<String> redisFuture = asyncCommands.rpop(listName);
String nextTask = redisFuture.get();
Assert.assertEquals(firstTask, nextTask);
asyncCommands.del(listName);
asyncCommands.lpush(listName, firstTask);
asyncCommands.lpush(listName, secondTask);
redisFuture = asyncCommands.lpop(listName);
nextTask = redisFuture.get();
Assert.assertEquals(secondTask, nextTask);
}
@Test
public void givenSetElements_thenSaveThemInRedisSetAsync() throws Exception {
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
String countries = "countries";
String countryOne = "Spain";
String countryTwo = "Ireland";
String countryThree = "Ireland";
asyncCommands.sadd(countries, countryOne);
RedisFuture<Set<String>> countriesSetFuture = asyncCommands.smembers(countries);
Assert.assertEquals(2, countriesSetFuture.get().size());
asyncCommands.sadd(countries, countryTwo);
countriesSetFuture = asyncCommands.smembers(countries);
Assert.assertEquals(2, countriesSetFuture.get().size());
asyncCommands.sadd(countries, countryThree);
countriesSetFuture = asyncCommands.smembers(countries);
Assert.assertEquals(2, countriesSetFuture.get().size());
RedisFuture<Boolean> exists = asyncCommands.sismember(countries, countryThree);
assertTrue(exists.get());
}
@Test
public void givenARanking_thenSaveItInRedisSortedSetAsync() throws Exception {
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
String key = "sortedset";
asyncCommands.zadd(key, 1, "one");
asyncCommands.zadd(key, 4, "zero");
asyncCommands.zadd(key, 2, "two");
RedisFuture<List<String>> values = asyncCommands.zrevrange(key, 0, 3);
Assert.assertEquals("zero", values.get().get(0));
values = asyncCommands.zrange(key, 0, 3);
Assert.assertEquals("one", values.get().get(0));
}
@Test
public void givenMultipleOperationsThatNeedToBeExecutedAtomically_thenWrapThemInATransaction() throws Exception {
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
// Start a transaction
asyncCommands.multi();
// Add three sets to it, and save the future responses
RedisFuture<String> result1 = asyncCommands.set("key1", "value1");
RedisFuture<String> result2 = asyncCommands.set("key2", "value2");
RedisFuture<String> result3 = asyncCommands.set("key3", "value3");
// Execute it
RedisFuture<TransactionResult> execResult = asyncCommands.exec();
TransactionResult transactionResult = execResult.get();
// Get the three results in the transaction return
String firstResult = transactionResult.get(0);
String secondResult = transactionResult.get(0);
String thirdResult = transactionResult.get(0);
// Our results are in both!
assertTrue(firstResult.equals("OK"));
assertTrue(secondResult.equals("OK"));
assertTrue(thirdResult.equals("OK"));
assertTrue(result1.get().equals("OK"));
assertTrue(result2.get().equals("OK"));
assertTrue(result3.get().equals("OK"));
}
@Test
public void givenMultipleIndependentOperations_whenNetworkOptimizationIsImportant_thenFlushManually() throws Exception {
int iterations = 50;
RedisAsyncCommands<String, String> asyncCommands = redisConnection.async();
asyncCommands.setAutoFlushCommands(false);
List<RedisFuture<?>> futures = new ArrayList<>();
for (int i = 0; i < iterations; i++) {
futures.add(asyncCommands.set("key" + i, "value" + i));
}
asyncCommands.flushCommands();
// Wait until all futures complete
boolean result = LettuceFutures.awaitAll(5, TimeUnit.SECONDS, futures.toArray(new RedisFuture[futures.size()]));
asyncCommands.setAutoFlushCommands(true);
}
@Test
public void givenPubSubChannel_whenMessage_thenMessageReceived() throws Exception {
Listener listener = new Listener();
StatefulRedisPubSubConnection<String, String> connection = redisClient.connectPubSub();
StatefulRedisPubSubConnection<String, String> pubconnection = redisClient.connectPubSub();
connection.addListener(listener);
RedisPubSubAsyncCommands<String, String> async = connection.async();
async.subscribe("channel");
RedisPubSubAsyncCommands<String, String> pubasync = pubconnection.async();
RedisFuture<Long> result = pubasync.publish("channel", "hithere");
// Need a long wait for publish to complete, depending on system.
result.get(15, TimeUnit.SECONDS);
assertTrue(listener.getMessage().equals("hithere"));
}
private static class Listener implements RedisPubSubListener<String, String> {
private String message;
String getMessage() {
return message;
}
@Override
public void message(String channel, String message) {
log.debug("Got {} on {}", message, channel);
this.message = message;
}
@Override
public void message(String pattern, String channel, String message) {
}
@Override
public void subscribed(String channel, long count) {
log.debug("Subscribed to {}", channel);
}
@Override
public void psubscribed(String pattern, long count) {
}
@Override
public void unsubscribed(String channel, long count) {
}
@Override
public void punsubscribed(String pattern, long count) {
}
}
}
@@ -0,0 +1,81 @@
package com.baeldung;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.charset.Charset;
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 com.google.common.io.Files;
import redis.embedded.RedisServer;
/**
* Created by johnson on 3/9/17.
*/
public class RedissonConfigurationIntegrationTest {
private static RedisServer redisServer;
private static RedissonClient client;
private static int port;
@BeforeClass
public static void setUp() throws IOException {
// Take an available port
ServerSocket s = new ServerSocket(0);
port = s.getLocalPort();
s.close();
redisServer = new RedisServer(port);
redisServer.start();
}
@AfterClass
public static void destroy() {
redisServer.stop();
if (client != null) {
client.shutdown();
}
}
@Test
public void givenJavaConfig_thenRedissonConnectToRedis() {
Config config = new Config();
config.useSingleServer()
.setAddress(String.format("127.0.0.1:%s", port));
client = Redisson.create(config);
assert(client != null && client.getKeys().count() >= 0);
}
@Test
public void givenJSONFileConfig_thenRedissonConnectToRedis() throws IOException {
File configFile = new File(getClass().getClassLoader().getResource("singleNodeConfig.json").getFile());
String configContent = Files.toString(configFile, Charset.defaultCharset()).replace("6379", String.valueOf(port));
Config config = Config.fromJSON(configContent);
client = Redisson.create(config);
assert(client != null && client.getKeys().count() >= 0);
}
@Test
public void givenYAMLFileConfig_thenRedissonConnectToRedis() throws IOException {
File configFile = new File(getClass().getClassLoader().getResource("singleNodeConfig.yaml").getFile());
String configContent = Files.toString(configFile, Charset.defaultCharset()).replace("6379", String.valueOf(port));
Config config = Config.fromYAML(configContent);
client = Redisson.create(config);
assert(client != null && client.getKeys().count() >= 0);
}
}
@@ -0,0 +1,234 @@
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.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;
import static org.junit.Assert.assertTrue;
public class RedissonIntegrationTest {
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();
if (client != null) {
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();
assertTrue(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<String> keysWithPattern
= keys.getKeysByPattern("key*");
List keyWithPatternList
= StreamSupport.stream(
keysWithPattern.spliterator(),
false).collect(Collectors.toList());
assertTrue(keyWithPatternList.size() == 3);
}
@Test
public void givenAnObject_thenSaveToRedis() {
RBucket<Ledger> bucket = client.getBucket("ledger");
Ledger ledger = new Ledger();
ledger.setName("ledger1");
bucket.set(ledger);
Ledger returnedLedger = bucket.get();
assertTrue(
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();
assertTrue(returnValue == 6L);
}
@Test
public void givenTopicSubscribedToAChannel_thenReceiveMessageFromChannel() throws ExecutionException, InterruptedException {
CompletableFuture<String> future = new CompletableFuture<>();
RTopic<CustomMessage> subscribeTopic = client.getTopic("baeldung");
subscribeTopic.addListener((channel, customMessage) -> future.complete(customMessage.getMessage()));
RTopic<CustomMessage> publishTopic = client.getTopic("baeldung");
long clientsReceivedMessage
= publishTopic.publish(new CustomMessage("This is a message"));
assertEquals("This is a message", future.get());
}
@Test
public void givenAMap_thenSaveMapToRedis(){
RMap<String, Ledger> map = client.getMap("ledger");
map.put("123", new Ledger("ledger"));
assertTrue(map.get("123").getName().equals("ledger"));
}
@Test
public void givenASet_thenSaveSetToRedis(){
RSet<Ledger> ledgerSet = client.getSet("ledgerSet");
ledgerSet.add(new Ledger("ledger"));
assertTrue(ledgerSet.contains(new Ledger("ledger")));
}
@Test
public void givenAList_thenSaveListToRedis(){
RList<Ledger> ledgerList = client.getList("ledgerList");
ledgerList.add(new Ledger("ledger"));
assertTrue(ledgerList.contains(new Ledger("ledger")));
}
@Test
public void givenLockSet_thenEnsureCanUnlock(){
RLock lock = client.getLock("lock");
lock.lock();
assertTrue(lock.isLocked());
lock.unlock();
assertTrue(!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();
assertTrue(lock1.isLocked() && lock2.isLocked() && lock3.isLocked());
lock.unlock();
assertTrue(!(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<String> entries = ledgerService.getEntries(10);
assertTrue(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");
assertTrue(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<String, String> map = client.getMap("ledgerMap");
assertTrue(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);
assertTrue(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();
assertTrue(testValue.equals("0"));
}
}