org.springframework.integration.redis.inbound.RedisInboundChannelAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.integration.redis.inbound.RedisInboundChannelAdapter.java

Source

/*
 * Copyright 2007-2019 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
 *
 *      https://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.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;

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.redis.support.RedisHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.converter.SimpleMessageConverter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * @author Mark Fisher
 * @author Oleg Zhurakousky
 * @author Gary Russell
 * @author Artem Bilan
 * @author Venil Noronha
 *
 * @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) {
        Assert.notEmpty(topics, "at least one topic is required");
        this.topics = Arrays.copyOf(topics, topics.length);
    }

    public void setTopicPatterns(String... topicPatterns) {
        Assert.notEmpty(topicPatterns, "at least one topic pattern is required");
        this.topicPatterns = Arrays.copyOf(topicPatterns, topicPatterns.length);
    }

    public void setMessageConverter(MessageConverter messageConverter) {
        Assert.notNull(messageConverter, "messageConverter must not be null");
        this.messageConverter = messageConverter;
    }

    /**
     * Specify an {@link Executor} used for running the message listeners when messages are received.
     * @param taskExecutor the Executor to use for listener container.
     * @since 4.3.13
     * @see RedisMessageListenerContainer#setTaskExecutor(Executor)
     */
    public void setTaskExecutor(Executor taskExecutor) {
        this.container.setTaskExecutor(taskExecutor);
    }

    @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(getBeanFactory());
        }
        MessageListenerDelegate delegate = new MessageListenerDelegate();
        MessageListenerAdapter adapter = new MessageListenerAdapter(delegate);
        adapter.setSerializer(this.serializer);
        List<Topic> topicList = new ArrayList<>();
        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, String source) {
        MessageHeaders messageHeaders = null;
        if (StringUtils.hasText(source)) {
            messageHeaders = new MessageHeaders(Collections.singletonMap(RedisHeaders.MESSAGE_SOURCE, source));
        }

        return this.messageConverter.toMessage(object, messageHeaders);
    }

    private class MessageListenerDelegate {

        MessageListenerDelegate() {
            super();
        }

        @SuppressWarnings("unused")
        public void handleMessage(Object message, String source) {
            sendMessage(convertMessage(message, source));
        }

    }

}