/*
* Copyright 2007-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.inbound;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
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.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.support.converter.SimpleMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.util.Assert;
/**
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gary Russell
* @author Artem Bilan
* @since 2.1
*/
public class RedisInboundChannelAdapter extends MessageProducerSupport {
private final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
private volatile MessageConverter messageConverter = new SimpleMessageConverter();
private volatile String[] topics;
private volatile String[] topicPatterns;
private volatile RedisSerializer<?> serializer = new StringRedisSerializer();
public RedisInboundChannelAdapter(RedisConnectionFactory connectionFactory) {
Assert.notNull(connectionFactory, "connectionFactory must not be null");
this.container.setConnectionFactory(connectionFactory);
}
public void setSerializer(RedisSerializer<?> serializer) {
this.serializer = serializer;
}
public void setTopics(String... topics) {
this.topics = topics;
}
public void setTopicPatterns(String... topicPatterns) {
this.topicPatterns = topicPatterns;
}
public void setMessageConverter(MessageConverter messageConverter) {
Assert.notNull(messageConverter, "messageConverter must not be null");
this.messageConverter = messageConverter;
}
@Override
public String getComponentType() {
return "redis:inbound-channel-adapter";
}
@Override
protected void onInit() {
super.onInit();
boolean hasTopics = false;
if (this.topics != null) {
Assert.noNullElements(this.topics, "'topics' may not contain null elements.");
hasTopics = true;
}
boolean hasPatterns = false;
if (this.topicPatterns != null) {
Assert.noNullElements(this.topicPatterns, "'topicPatterns' may not contain null elements.");
hasPatterns = true;
}
Assert.state(hasTopics || hasPatterns, "at least one topic or topic pattern is required for subscription.");
if (this.messageConverter instanceof BeanFactoryAware) {
((BeanFactoryAware) this.messageConverter).setBeanFactory(this.getBeanFactory());
}
MessageListenerDelegate delegate = new MessageListenerDelegate();
MessageListenerAdapter adapter = new MessageListenerAdapter(delegate);
adapter.setSerializer(this.serializer);
List<Topic> topicList = new ArrayList<Topic>();
if (hasTopics) {
for (String topic : this.topics) {
topicList.add(new ChannelTopic(topic));
}
}
if (hasPatterns) {
for (String pattern : this.topicPatterns) {
topicList.add(new PatternTopic(pattern));
}
}
adapter.afterPropertiesSet();
this.container.addMessageListener(adapter, topicList);
this.container.afterPropertiesSet();
}
@Override
protected void doStart() {
super.doStart();
this.container.start();
}
@Override
protected void doStop() {
super.doStop();
this.container.stop();
}
private Message<?> convertMessage(Object object) {
return this.messageConverter.toMessage(object, null);
}
private class MessageListenerDelegate {
MessageListenerDelegate() {
super();
}
@SuppressWarnings("unused")
public void handleMessage(Object object) {
sendMessage(convertMessage(object));
}
}
}