/* * Copyright 2014-2016 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 static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Arrays; import java.util.List; import org.hamcrest.Matchers; 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.data.redis.connection.RedisConnection; import org.springframework.integration.handler.ReplyRequiredException; 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.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.PollableChannel; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Artem Bilan * @author Gary Russell * @since 4.0 */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) public class RedisOutboundGatewayTests extends RedisAvailableTests { @Autowired private BeanFactory beanFactory; @Autowired private PollableChannel replyChannel; @Autowired private MessageChannel pingChannel; @Autowired private MessageChannel leftPushRightPopChannel; @Autowired private MessageChannel incrementAtomicIntegerChannel; @Autowired private MessageChannel setDelCommandChannel; @Autowired private MessageChannel getCommandChannel; @Autowired private MessageChannel mgetCommandChannel; @Test @RedisAvailable public void testPingPongCommand() { this.pingChannel.send(MessageBuilder.withPayload("foo").setHeader(RedisHeaders.COMMAND, "PING").build()); Message<?> receive = this.replyChannel.receive(1000); assertNotNull(receive); assertTrue(Arrays.equals("PONG".getBytes(), (byte[]) receive.getPayload())); } @Test @RedisAvailable public void testPushAndPopCommands() { final String queueName = "si.test.testRedisOutboundGateway"; String payload = "testing"; this.leftPushRightPopChannel.send(MessageBuilder.withPayload(payload) .setHeader(RedisHeaders.COMMAND, "LPUSH") .setHeader("queue", queueName) .build()); Message<?> receive = this.replyChannel.receive(1000); assertNotNull(receive); this.leftPushRightPopChannel.send(MessageBuilder.withPayload(payload) .setHeader(RedisHeaders.COMMAND, "RPOP") .setHeader("queue", queueName) .build()); receive = this.replyChannel.receive(1000); assertNotNull(receive); assertTrue(Arrays.equals(payload.getBytes(), (byte[]) receive.getPayload())); } @Test @RedisAvailable public void testIncrementAtomicCommand() { // Since 'atomicInteger' is lazy-init to avoid early Redis connection, // we have to initialize it before send the INCR command. this.beanFactory.getBean("atomicInteger"); this.incrementAtomicIntegerChannel.send(MessageBuilder.withPayload("INCR").build()); Message<?> receive = this.replyChannel.receive(1000); assertNotNull(receive); assertEquals(11L, receive.getPayload()); this.getCommandChannel.send(MessageBuilder.withPayload("si.test.RedisAtomicInteger").build()); receive = this.replyChannel.receive(1000); assertNotNull(receive); assertEquals("11", new String((byte[]) receive.getPayload())); this.createStringRedisTemplate(this.getConnectionFactoryForTest()).delete("si.test.RedisAtomicInteger"); } @Test @RedisAvailable public void testGetCommand() { this.setDelCommandChannel.send(MessageBuilder.withPayload(new String[] { "foo", "bar" }) .setHeader(RedisHeaders.COMMAND, "SET").build()); Message<?> receive = this.replyChannel.receive(1000); assertNotNull(receive); assertTrue(Arrays.equals("OK".getBytes(), (byte[]) receive.getPayload())); this.getCommandChannel.send(MessageBuilder.withPayload("foo").build()); receive = this.replyChannel.receive(1000); assertNotNull(receive); assertTrue(Arrays.equals("bar".getBytes(), (byte[]) receive.getPayload())); this.setDelCommandChannel.send(MessageBuilder.withPayload("foo").setHeader(RedisHeaders.COMMAND, "DEL").build()); receive = this.replyChannel.receive(1000); assertNotNull(receive); assertEquals(1L, receive.getPayload()); try { this.getCommandChannel.send(MessageBuilder.withPayload("foo").build()); fail("ReplyRequiredException expected"); } catch (Exception e) { assertThat(e, Matchers.instanceOf(ReplyRequiredException.class)); } } @SuppressWarnings("unchecked") @Test @RedisAvailable public void testMGetCommand() { RedisConnection connection = this.getConnectionFactoryForTest().getConnection(); byte[] value1 = "bar1".getBytes(); byte[] value2 = "bar2".getBytes(); connection.set("foo1".getBytes(), value1); connection.set("foo2".getBytes(), value2); this.mgetCommandChannel.send(MessageBuilder.withPayload(new String[] { "foo1", "foo2" }).build()); Message<?> receive = this.replyChannel.receive(1000); assertNotNull(receive); assertThat((List<byte[]>) receive.getPayload(), Matchers.contains(value1, value2)); connection.del("foo1".getBytes(), "foo2".getBytes()); } }