/*
* Copyright 2007-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.redis.outbound;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.support.collections.DefaultRedisList;
import org.springframework.data.redis.support.collections.DefaultRedisMap;
import org.springframework.data.redis.support.collections.DefaultRedisSet;
import org.springframework.data.redis.support.collections.DefaultRedisZSet;
import org.springframework.data.redis.support.collections.RedisList;
import org.springframework.data.redis.support.collections.RedisMap;
import org.springframework.data.redis.support.collections.RedisProperties;
import org.springframework.data.redis.support.collections.RedisSet;
import org.springframework.data.redis.support.collections.RedisZSet;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.integration.redis.rules.RedisAvailable;
import org.springframework.integration.redis.rules.RedisAvailableTests;
import org.springframework.integration.redis.support.RedisHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.2
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class RedisStoreOutboundChannelAdapterIntegrationTests extends RedisAvailableTests {
private final StringRedisTemplate redisTemplate = new StringRedisTemplate();
@Autowired
private BeanFactory beanFactory;
@Autowired
@Qualifier("listWithKeyAsHeader")
private MessageChannel listWithKeyAsHeaderChannel;
@Autowired
@Qualifier("listWithKeyProvided")
private MessageChannel listWithKeyProvidedChannel;
@Autowired
@Qualifier("zset")
private MessageChannel zsetChannel;
@Autowired
@Qualifier("mapToZset")
private MessageChannel mapToZsetChannel;
@Autowired
@Qualifier("mapToMapA")
private MessageChannel mapToMapAChannel;
@Autowired
@Qualifier("mapToMapB")
private MessageChannel mapToMapBChannel;
@Autowired
@Qualifier("simpleMap")
private MessageChannel simpleMapChannel;
@Autowired
@Qualifier("set")
private MessageChannel setChannel;
@Autowired
@Qualifier("setNotParsed")
private MessageChannel setNotParsedChannel;
@Autowired
@Qualifier("pojoIntoSet")
private MessageChannel pojoIntoSetChannel;
@Autowired
@Qualifier("property")
private MessageChannel propertyChannel;
@Autowired
@Qualifier("simpleProperty")
private MessageChannel simplePropertyChannel;
@Before
@After
public void setup() {
RedisConnectionFactory jcf = getConnectionFactoryForTest();
this.redisTemplate.setConnectionFactory(jcf);
this.redisTemplate.afterPropertiesSet();
this.redisTemplate.delete("pepboys");
this.redisTemplate.delete("foo");
this.redisTemplate.delete("bar");
this.redisTemplate.delete("presidents");
}
@Test
@RedisAvailable
public void testListWithKeyAsHeader() {
RedisList<String> redisList = new DefaultRedisList<String>("pepboys", this.redisTemplate);
assertEquals(0, redisList.size());
List<String> pepboys = new ArrayList<String>();
pepboys.add("Manny");
pepboys.add("Moe");
pepboys.add("Jack");
Message<List<String>> message = MessageBuilder.withPayload(pepboys).setHeader(RedisHeaders.KEY, "pepboys").build();
this.listWithKeyAsHeaderChannel.send(message);
assertEquals(3, redisList.size());
}
@Test
@RedisAvailable
public void testListWithKeyAsHeaderSimple() {
redisTemplate.delete("foo");
RedisList<String> redisList = new DefaultRedisList<String>("foo", this.redisTemplate);
assertEquals(0, redisList.size());
Message<String> message = MessageBuilder.withPayload("bar").setHeader("redis_key", "foo").build();
this.listWithKeyAsHeaderChannel.send(message);
assertEquals(1, redisList.size());
}
@Test
@RedisAvailable
public void testListWithProvidedKey() {
RedisList<String> redisList = new DefaultRedisList<String>("pepboys", this.redisTemplate);
assertEquals(0, redisList.size());
List<String> pepboys = new ArrayList<String>();
pepboys.add("Manny");
pepboys.add("Moe");
pepboys.add("Jack");
Message<List<String>> message = MessageBuilder.withPayload(pepboys).build();
this.listWithKeyProvidedChannel.send(message);
assertEquals(3, redisList.size());
}
@Test
@RedisAvailable
public void testZsetSimplePayloadIncrement() {
RedisZSet<String> redisZSet = new DefaultRedisZSet<String>("foo", this.redisTemplate);
assertEquals(0, redisZSet.size());
Message<String> message = MessageBuilder.withPayload("bar")
.setHeader(RedisHeaders.KEY, "foo")
.setHeader(RedisHeaders.ZSET_INCREMENT_SCORE, true)
.build();
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(1), redisZSet.score("bar"));
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(2), redisZSet.score("bar"));
}
@Test
@RedisAvailable
public void testZsetSimplePayloadOverwrite() {
RedisZSet<String> redisZSet = new DefaultRedisZSet<String>("foo", this.redisTemplate);
assertEquals(0, redisZSet.size());
Message<String> message = MessageBuilder.withPayload("bar")
.setHeader(RedisHeaders.KEY, "foo")
.build();
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(1), redisZSet.score("bar"));
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(1), redisZSet.score("bar"));
}
@Test
@RedisAvailable
public void testZsetSimplePayloadIncrementBy2() {
RedisZSet<String> redisZSet = new DefaultRedisZSet<String>("foo", this.redisTemplate);
assertEquals(0, redisZSet.size());
Message<String> message = MessageBuilder.withPayload("bar")
.setHeader(RedisHeaders.KEY, "foo")
.setHeader(RedisHeaders.ZSET_SCORE, 2)
.setHeader(RedisHeaders.ZSET_INCREMENT_SCORE, true)
.build();
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(2), redisZSet.score("bar"));
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(4), redisZSet.score("bar"));
}
@Test
@RedisAvailable
public void testZsetSimplePayloadOverwriteWithHeaderScore() {
RedisZSet<String> redisZSet = new DefaultRedisZSet<String>("foo", this.redisTemplate);
assertEquals(0, redisZSet.size());
Message<String> message = MessageBuilder.withPayload("bar")
.setHeader(RedisHeaders.KEY, "foo")
.setHeader(RedisHeaders.ZSET_INCREMENT_SCORE, false)
.setHeader(RedisHeaders.ZSET_SCORE, 2)
.build();
this.zsetChannel.send(message);
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(2), redisZSet.score("bar"));
this.zsetChannel.send(MessageBuilder.fromMessage(message).setHeader(RedisHeaders.ZSET_SCORE, 15).build());
assertEquals(1, redisZSet.size());
assertEquals(Double.valueOf(15), redisZSet.score("bar"));
}
@Test
@RedisAvailable
public void testMapToZsetWithProvidedKey() {
RedisZSet<String> redisZset = new DefaultRedisZSet<String>("presidents", this.redisTemplate);
assertEquals(0, redisZset.size());
Map<String, Integer> presidents = new HashMap<String, Integer>();
presidents.put("John Adams", 18);
presidents.put("Barack Obama", 21);
presidents.put("Thomas Jefferson", 19);
presidents.put("John Quincy Adams", 19);
presidents.put("Zachary Taylor", 19);
Message<Map<String, Integer>> message = MessageBuilder.withPayload(presidents)
.setHeader(RedisHeaders.ZSET_INCREMENT_SCORE, true)
.build();
this.mapToZsetChannel.send(message);
assertEquals(5, redisZset.size());
assertEquals(1, redisZset.rangeByScore(18, 18).size());
assertEquals(4, redisZset.rangeByScore(18, 19).size());
assertEquals(1, redisZset.rangeByScore(21, 21).size());
RedisStoreWritingMessageHandler handler =
this.beanFactory.getBean("mapToZset.handler", RedisStoreWritingMessageHandler.class);
assertEquals("'presidents'", TestUtils.getPropertyValue(handler, "keyExpression.expression"));
this.mapToZsetChannel.send(message);
assertEquals(5, redisZset.size());
assertEquals(1, redisZset.rangeByScore(36, 36).size());
assertEquals(4, redisZset.rangeByScore(36, 38).size());
assertEquals(1, redisZset.rangeByScore(42, 42).size());
// test overwrite score behavior
presidents.put("Barack Obama", 31);
this.mapToZsetChannel.send(MessageBuilder.fromMessage(message)
.setHeader(RedisHeaders.ZSET_INCREMENT_SCORE, false)
.build());
assertEquals(5, redisZset.size());
assertEquals(1, redisZset.rangeByScore(18, 18).size());
assertEquals(4, redisZset.rangeByScore(18, 19).size());
assertEquals(1, redisZset.rangeByScore(31, 31).size());
}
@Test
@RedisAvailable
public void testMapToMapWithProvidedKey() {
RedisMap<String, String> redisMap = new DefaultRedisMap<String, String>("pepboys", this.redisTemplate);
assertEquals(0, redisMap.size());
Map<String, String> pepboys = new HashMap<String, String>();
pepboys.put("1", "Manny");
pepboys.put("2", "Moe");
pepboys.put("3", "Jack");
Message<Map<String, String>> message = MessageBuilder.withPayload(pepboys).build();
this.mapToMapAChannel.send(message);
assertEquals("Manny", redisMap.get("1"));
assertEquals("Moe", redisMap.get("2"));
assertEquals("Jack", redisMap.get("3"));
RedisStoreWritingMessageHandler handler = this.beanFactory.getBean("mapToMapA.handler",
RedisStoreWritingMessageHandler.class);
assertEquals("pepboys",
TestUtils.getPropertyValue(handler, "keyExpression", LiteralExpression.class).getExpressionString());
assertEquals("'foo'",
TestUtils.getPropertyValue(handler, "mapKeyExpression", SpelExpression.class).getExpressionString());
}
@Test(expected = MessageHandlingException.class) // map key is not provided
@RedisAvailable
public void testMapToMapAsSingleEntryWithKeyAsHeaderFail() {
RedisMap<String, Map<String, String>> redisMap =
new DefaultRedisMap<String, Map<String, String>>("pepboys", this.redisTemplate);
assertEquals(0, redisMap.size());
Map<String, String> pepboys = new HashMap<String, String>();
pepboys.put("1", "Manny");
pepboys.put("2", "Moe");
pepboys.put("3", "Jack");
Message<Map<String, String>> message = MessageBuilder.withPayload(pepboys).
setHeader(RedisHeaders.KEY, "pepboys").build();
this.mapToMapBChannel.send(message);
}
@Test(expected = MessageHandlingException.class) // key is not provided
@RedisAvailable
public void testMapToMapNoKey() {
RedisTemplate<String, Map<String, Map<String, String>>> redisTemplate = new RedisTemplate<String, Map<String, Map<String, String>>>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(getConnectionFactoryForTest());
redisTemplate.afterPropertiesSet();
RedisMap<String, Map<String, String>> redisMap =
new DefaultRedisMap<String, Map<String, String>>("pepboys", redisTemplate);
assertEquals(0, redisMap.size());
Map<String, String> pepboys = new HashMap<String, String>();
pepboys.put("1", "Manny");
pepboys.put("2", "Moe");
pepboys.put("3", "Jack");
Message<Map<String, String>> message = MessageBuilder.withPayload(pepboys).build();
this.mapToMapBChannel.send(message);
}
@Test
@RedisAvailable
public void testMapToMapAsSingleEntryWithKeyAsHeader() {
RedisTemplate<String, Map<String, Map<String, String>>> redisTemplate = new RedisTemplate<String, Map<String, Map<String, String>>>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(getConnectionFactoryForTest());
redisTemplate.afterPropertiesSet();
RedisMap<String, Map<String, String>> redisMap =
new DefaultRedisMap<String, Map<String, String>>("pepboys", redisTemplate);
assertEquals(0, redisMap.size());
Map<String, String> pepboys = new HashMap<String, String>();
pepboys.put("1", "Manny");
pepboys.put("2", "Moe");
pepboys.put("3", "Jack");
Message<Map<String, String>> message = MessageBuilder.withPayload(pepboys).
setHeader(RedisHeaders.KEY, "pepboys").setHeader(RedisHeaders.MAP_KEY, "foo").build();
this.mapToMapBChannel.send(message);
Map<String, String> pepboyz = redisMap.get("foo");
assertEquals("Manny", pepboyz.get("1"));
assertEquals("Moe", pepboyz.get("2"));
assertEquals("Jack", pepboyz.get("3"));
}
@Test
@RedisAvailable
public void testStoreSimpleStringInMap() {
RedisMap<String, String> redisMap = new DefaultRedisMap<String, String>("bar", this.redisTemplate);
assertEquals(0, redisMap.size());
Message<String> message = MessageBuilder.withPayload("hello, world!").
setHeader(RedisHeaders.KEY, "bar").setHeader(RedisHeaders.MAP_KEY, "foo").build();
this.simpleMapChannel.send(message);
String hello = redisMap.get("foo");
assertEquals("hello, world!", hello);
}
@Test
@RedisAvailable
public void testSetWithKeyAsHeader() {
RedisSet<String> redisSet = new DefaultRedisSet<String>("pepboys", this.redisTemplate);
assertEquals(0, redisSet.size());
Set<String> pepboys = new HashSet<String>();
pepboys.add("Manny");
pepboys.add("Moe");
pepboys.add("Jack");
Message<Set<String>> message = MessageBuilder.withPayload(pepboys).setHeader("redis_key", "pepboys").build();
this.setChannel.send(message);
assertEquals(3, redisSet.size());
}
@Test
@RedisAvailable
public void testSetWithKeyAsHeaderSimple() {
RedisSet<String> redisSet = new DefaultRedisSet<String>("foo", this.redisTemplate);
assertEquals(0, redisSet.size());
Message<String> message = MessageBuilder.withPayload("foo")
.setHeader(RedisHeaders.KEY, "foo").build();
this.setChannel.send(message);
assertEquals(1, redisSet.size());
}
@Test
@RedisAvailable
public void testSetWithKeyAsHeaderNotParsed() {
RedisSet<String> redisSet = new DefaultRedisSet<String>("pepboys", this.redisTemplate);
assertEquals(0, redisSet.size());
Set<String> pepboys = new HashSet<String>();
pepboys.add("Manny");
pepboys.add("Moe");
pepboys.add("Jack");
Message<Set<String>> message = MessageBuilder.withPayload(pepboys).setHeader("redis_key", "pepboys").build();
this.setNotParsedChannel.send(message);
assertEquals(1, redisSet.size());
}
@Test
@RedisAvailable
public void testPojoIntoSet() {
RedisSet<String> redisSet = new DefaultRedisSet<String>("pepboys", this.redisTemplate);
assertEquals(0, redisSet.size());
String pepboy = "Manny";
Message<String> message = MessageBuilder.withPayload(pepboy).setHeader("redis_key", "pepboys").build();
this.pojoIntoSetChannel.send(message);
assertEquals(1, redisSet.size());
}
@Test
@RedisAvailable
public void testProperties() {
RedisProperties redisProperties = new RedisProperties("pepboys", this.redisTemplate);
assertEquals(0, redisProperties.size());
Properties pepboys = new Properties();
pepboys.put("1", "Manny");
pepboys.put("2", "Moe");
pepboys.put("3", "Jack");
Message<Properties> message = MessageBuilder.withPayload(pepboys).build();
this.propertyChannel.send(message);
assertEquals("Manny", redisProperties.get("1"));
assertEquals("Moe", redisProperties.get("2"));
assertEquals("Jack", redisProperties.get("3"));
}
@Test
@RedisAvailable
public void testPropertiesSimple() {
RedisProperties redisProperties = new RedisProperties("foo", this.redisTemplate);
assertEquals(0, redisProperties.size());
Message<String> message = MessageBuilder.withPayload("bar")
.setHeader(RedisHeaders.KEY, "foo")
.setHeader("baz", "qux")
.build();
this.simplePropertyChannel.send(message);
assertEquals("bar", redisProperties.get("qux"));
}
}