/*
 * Copyright (c) 2010-2015. Axon Framework
 *
 * 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.axonframework.amqp.eventhandling.spring;

import com.rabbitmq.client.Channel;
import org.axonframework.amqp.eventhandling.AMQPMessageConverter;
import org.axonframework.common.Registration;
import org.axonframework.eventhandling.EventMessage;
import org.axonframework.messaging.SubscribableMessageSource;
import org.axonframework.serialization.UnknownSerializedTypeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;

/**
 * MessageListener implementation that deserializes incoming messages and forwards them to one or more event processors.
 * <p>
 * The SpringAMQPMessageSource must be registered with a Spring MessageListenerContainer and forwards each message
 * to all subscribed processors.
 * <p>
 * Note that the Processors must be subscribed before the MessageListenerContainer is started. Otherwise, messages will
 * be consumed from the AMQP Queue without any processor processing them.
 *
 * @author Allard Buijze
 * @since 3.0
 */
public class SpringAMQPMessageSource implements ChannelAwareMessageListener,
                                                SubscribableMessageSource<EventMessage<?>> {

    private static final Logger logger = LoggerFactory.getLogger(SpringAMQPMessageSource.class);

    private final List<Consumer<List<? extends EventMessage<?>>>> eventProcessors = new CopyOnWriteArrayList<>();
    private final AMQPMessageConverter messageConverter;

    /**
     * Initializes an SpringAMQPMessageSource with given {@code messageConverter} to convert the incoming AMQP
     * message into an EventMessage.
     *
     * @param messageConverter The message converter to use to convert AMQP Messages to Event Messages
     */
    public SpringAMQPMessageSource(AMQPMessageConverter messageConverter) {
        this.messageConverter = messageConverter;
    }

    @Override
    public Registration subscribe(Consumer<List<? extends EventMessage<?>>> messageProcessor) {
        eventProcessors.add(messageProcessor);
        return () -> eventProcessors.remove(messageProcessor);
    }

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        if (!eventProcessors.isEmpty()) {
            try {
                EventMessage<?> event = messageConverter
                        .readAMQPMessage(message.getBody(), message.getMessageProperties().getHeaders());
                if (event != null) {
                    eventProcessors.forEach(ep -> ep.accept(Collections.singletonList(event)));
                }
            } catch (UnknownSerializedTypeException e) {
                logger.warn("Unable to deserialize an incoming message. Ignoring it. {}", e.toString());
            }
        }
    }

}

@@ -754,24 +754,97 @@
 eConverter;%0A
+import org.axonframework.amqp.eventhandling.DefaultAMQPMessageConverter;%0A
 import org.a
@@ -992,16 +992,67 @@
 Source;%0A
+import org.axonframework.serialization.Serializer;%0A
 import o
@@ -2399,16 +2399,369 @@
 erter;%0A%0A
+%0A    /**%0A     * Initializes an SpringAMQPMessageSource with %7B@link DefaultAMQPMessageConverter%7D using given %7B@code serializer%7D.%0A     *%0A     * @param serializer The serializer to serialize payload and metadata of events%0A     */%0A    public SpringAMQPMessageSource(Serializer serializer) %7B%0A        this(new DefaultAMQPMessageConverter(serializer));%0A    %7D%0A%0A
     /**%0A

Add simpler constructor to SpringAMQPMessageSource