/* * Copyright 2014 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.xd.shell.command; import static org.junit.Assert.assertEquals; import java.util.Collections; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.Topic; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.xd.shell.command.fixtures.HttpSource; import org.springframework.xd.test.redis.RedisTestSupport; /** * Integration tests for Redis sink. * * @author Ilayaperumal Gopinathan */ public class AbstractRedisSinkTests extends AbstractStreamIntegrationTest { @Rule public RedisTestSupport redisAvailableRule = new RedisTestSupport(); private RedisTemplate<String, Object> redisTemplate; private RedisMessageListenerContainer container; @Before public void setup() { createTemplate(); } @Test public void testRedisTopicExpressionSink() throws InterruptedException { String topicName = "testTopicExpression"; CountDownLatch latch = new CountDownLatch(1); setupMessageListener(latch, topicName); final HttpSource httpSource = newHttpSource(); stream().create(generateStreamName(), "%s | redis --topicExpression='''%s'''", httpSource, topicName); Thread.sleep(1000); final String stringToPost = "test"; httpSource.ensureReady().postData(stringToPost); latch.await(3, TimeUnit.SECONDS); assertEquals(0, latch.getCount()); container.stop(); } @Test public void testRedisTopicSink() throws InterruptedException { String topicName = "testTopic"; CountDownLatch latch = new CountDownLatch(1); setupMessageListener(latch, topicName); final HttpSource httpSource = newHttpSource(); stream().create(generateStreamName(), "%s | redis --topic=%s", httpSource, topicName); Thread.sleep(1000); final String stringToPost = "test"; httpSource.ensureReady().postData(stringToPost); latch.await(3, TimeUnit.SECONDS); assertEquals(0, latch.getCount()); container.stop(); } @Test public void testRedisQueueExpressionSink() throws InterruptedException { final String listName = "testListExpression"; final String stringToPost = "test"; final HttpSource httpSource = newHttpSource(); stream().create(generateStreamName(), "%s | redis --queueExpression='''%s'''", httpSource, listName); Thread.sleep(1000); httpSource.ensureReady().postData(stringToPost); byte[] leftPop = (byte[]) createTemplate().boundListOps(listName).leftPop(5, TimeUnit.SECONDS); Assert.assertEquals(stringToPost, new String(leftPop)); } @Test public void testRedisQueueSink() throws InterruptedException { final String listName = "testList"; final String stringToPost = "test"; final HttpSource httpSource = newHttpSource(); stream().create(generateStreamName(), "%s | redis --queue=%s", httpSource, listName); Thread.sleep(1000); httpSource.ensureReady().postData(stringToPost); byte[] leftPop = (byte[]) createTemplate().boundListOps(listName).leftPop(5, TimeUnit.SECONDS); Assert.assertEquals(stringToPost, new String(leftPop)); } @Test public void testRedisStoreExpressionSink() throws InterruptedException { final String setName = "testSetExpression"; final String stringToPost = "test"; final HttpSource httpSource = newHttpSource(); stream().create(generateStreamName(), "%s | redis --keyExpression='''%s''' --collectionType='SET'", httpSource, setName); Thread.sleep(1000); httpSource.ensureReady().postData(stringToPost); byte[] popped = (byte[]) createTemplate().boundSetOps(setName).pop(); Assert.assertEquals(stringToPost, new String(popped)); } @Test public void testRedisStoreSink() throws InterruptedException { final String setName = "testSet"; final String stringToPost = "test"; final HttpSource httpSource = newHttpSource(); stream().create(generateStreamName(), "%s | redis --key=%s --collectionType='SET'", httpSource, setName); Thread.sleep(1000); httpSource.ensureReady().postData(stringToPost); byte[] popped = (byte[]) createTemplate().boundSetOps(setName).pop(); Assert.assertEquals(stringToPost, new String(popped)); } private RedisTemplate<String, Object> createTemplate() { if (this.redisTemplate != null) { return this.redisTemplate; } RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(this.redisAvailableRule.getResource()); template.setKeySerializer(new StringRedisSerializer()); template.setEnableDefaultSerializer(false); template.afterPropertiesSet(); this.redisTemplate = template; return template; } private void setupMessageListener(CountDownLatch latch, String topic) throws InterruptedException { MessageListenerAdapter listener = new MessageListenerAdapter(); listener.setDelegate(new Listener(latch)); listener.afterPropertiesSet(); this.container = new RedisMessageListenerContainer(); container.setConnectionFactory(this.redisAvailableRule.getResource()); container.afterPropertiesSet(); container.addMessageListener(listener, Collections.<Topic> singletonList(new ChannelTopic(topic))); container.start(); Thread.sleep(1000); } private static class Listener { private final CountDownLatch latch; private Listener(CountDownLatch latch) { this.latch = latch; } @SuppressWarnings("unused") public void handleMessage(Object s) { this.latch.countDown(); } } }