All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.automationrockstars.gunter.rabbit.Consumer Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2015, 2016 Automation RockStars Ltd.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License v2.0
 * which accompanies this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Contributors:
 *     Automation RockStars - initial API and implementation
 *******************************************************************************/
package com.automationrockstars.gunter.rabbit;

import com.automationrockstars.base.ConfigLoader;
import com.automationrockstars.gunter.events.Event;
import com.automationrockstars.gunter.events.EventFactory;
import com.automationrockstars.gunter.events.EventListener;
import com.google.common.collect.Lists;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.Thread.State;
import java.util.List;

public class Consumer {


    private static final long WAIT_FOR_MESSAGE = ConfigLoader.config().getLong("rabbitmq.message.timeout", 100);
    private final static Logger LOG = LoggerFactory.getLogger(Consumer.class);
    private final List listeners = Lists.newArrayList();
    private final Object semaphore = new Object();
    QueueingConsumer consumer;
    private String queue;
    private boolean continoue = true;
    private Thread listenerThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (continoue && listeners.size() > 0) {//&& consumer.getChannel().isOpen()) {
                QueueingConsumer.Delivery delivery;
                try {

                    delivery = consumer.nextDelivery(WAIT_FOR_MESSAGE);
                    if (delivery != null) {
                        String message = new String(delivery.getBody());
                        LOG.debug("Received '{}'", message);
//						RabbitEventBroker.getChannel().basicAck(delivery.getEnvelope().getDeliveryTag(), false);

                        Event ev = EventFactory.fromJson(message);

                        for (EventListener listener : listeners) {
                            try {
                                listener.onEvent(ev);
                            } catch (Throwable t) {
                                LOG.debug("Error in listener {} on event {}. {}", listener, ev, t.toString());
                            }
                        }

                    }
                } catch (ShutdownSignalException e) {
                    LOG.info("Shutting down");
                    stop();
                } catch (Exception e) {
                    LOG.error("Consuming is interrupted due to {}", e.getMessage());
                    LOG.trace("Details", e);
//				} catch ( IOException ack ){
//					LOG.error("Failed to ACK message due to {}",ack.getMessage());
//					LOG.trace("Details",ack);
                }

            }
            LOG.info("Exiting as {} {} {}", continoue, listeners.size() > 0, consumer.getChannel().isOpen());
            LOG.debug("Finishing listener thread");
        }

    }, "gunter-rabbit-listener");
    private Event lastEvent;

    protected Consumer(String exchange, String routingKey) {
        Channel channel = RabbitEventBroker.getChannel();
        try {
            queue = channel.queueDeclare().getQueue();
            RabbitEventBroker.declareExchange(exchange);
            channel.queueBind(queue, exchange, routingKey);
        } catch (IOException e) {
            LOG.error("Cannot bind to exchange {}", exchange, e);
        }
        consumer = new QueueingConsumer(channel);
        try {
            String tag = channel.basicConsume(queue, true, consumer);
            LOG.info("Consumer tag {}", tag);
        } catch (IOException e) {
            LOG.error("Cannot start consumer {}", e);
        }
    }

    public void stop() {
        continoue = false;
    }

    public void start() {
        continoue = true;
    }

    public void registerListener(EventListener listener) {
        listeners.add(listener);
        if (!continoue) {
            continoue = true;
        }
        listen();

    }

    public void removeListener(EventListener listener) {
        listeners.remove(listener);
    }

    private void listen() {
        LOG.info("Listener th {} {}", listenerThread, listenerThread.getState());
        if (listenerThread.getState() == State.NEW || listenerThread.getState() == State.RUNNABLE || listenerThread.getState() == State.TERMINATED) {
            listenerThread.setDaemon(true);
            listenerThread.start();
            LOG.debug("Started listener thread {}", listenerThread);
        } else {
            LOG.debug("Listener thread {} is already running", listenerThread);
        }

    }

    private EventListener singleMessageListener() {
        return new EventListener() {
            @Override
            public void onEvent(Event event) {
                synchronized (semaphore) {
                    lastEvent = event;
                    semaphore.notifyAll();
                }
            }
        };
    }

    public Event consume() {
        EventListener single = singleMessageListener();
        this.registerListener(single);
        try {
            synchronized (semaphore) {
                semaphore.wait();
            }
        } catch (InterruptedException e) {
            LOG.error("Consuming interrupted", e);
        }
        this.removeListener(single);
        return lastEvent;
    }

    public void close() {

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy