Package com.zanox.rabbiteasy.cdi

Source Code of com.zanox.rabbiteasy.cdi.EventPublisher$PublisherConfiguration

package com.zanox.rabbiteasy.cdi;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.ConnectionFactory;
import com.zanox.rabbiteasy.Message;
import com.zanox.rabbiteasy.publisher.DeliveryOptions;
import com.zanox.rabbiteasy.publisher.GenericPublisher;
import com.zanox.rabbiteasy.publisher.MessagePublisher;
import com.zanox.rabbiteasy.publisher.PublisherReliability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* Publishes events to exchanges of a broker.
*
* @author christian.bick
*/
@Singleton
public class EventPublisher {

    private static Logger LOGGER = LoggerFactory.getLogger(EventPublisher.class);

    ConnectionFactory connectionFactory;

    Map<Class<?>, PublisherConfiguration> publisherConfigurations =
            new HashMap<Class<?>, PublisherConfiguration>();

    ThreadLocal<Map<Class<?>, MessagePublisher>> publishers = new ThreadLocal<Map<Class<?>, MessagePublisher>>();

    @Inject
    public EventPublisher(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    /**
     * Adds events of the given type to the CDI events to which the event publisher listens in order to
     * publish them. The publisher configuration is used to decide where to and how to publish messages.
     *
     * @param eventType The event type
     * @param configuration The configuration used when publishing and event
     * @param <T> The event type
     */
    public <T> void addEvent(Class<T> eventType, PublisherConfiguration configuration) {
        publisherConfigurations.put(eventType, configuration);
    }

    /**
     * Observes CDI events for remote events and publishes those events if their event type
     * was added before.
     *
     * @param event The event to publish
     * @throws IOException if the event failed to be published
     */
    public void publishEvent(@Observes Object event) throws IOException {
        Class<?> eventType = event.getClass();
        LOGGER.debug("Receiving event of type {}", eventType.getSimpleName());
        if (! publisherConfigurations.containsKey(eventType)) {
            LOGGER.debug("No publisher configured for event of type {}", eventType.getSimpleName());
            return;
        }
        PublisherConfiguration publisherConfiguration = publisherConfigurations.get(eventType);
        MessagePublisher publisher = providePublisher(publisherConfiguration.reliability, eventType);
        Message message = buildMessage(publisherConfiguration, event);
        try {
            LOGGER.info("Publishing event of type {}", eventType.getSimpleName());
            publisher.publish(message, publisherConfiguration.deliveryOptions);
            LOGGER.info("Successfully published event of type {}", eventType.getSimpleName());
        } catch (IOException e) {
            LOGGER.error("Failed to publish event {}", eventType.getSimpleName(), e);
            throw e;
        }
    }

    /**
     * Provides a publisher with the specified reliability. Within the same thread, the same
     * producer instance is provided for the given event type.
     *
     * @param reliability The desired publisher reliability
     * @param eventType The event type
     * @return The provided publisher
     */
    MessagePublisher providePublisher(PublisherReliability reliability, Class<?> eventType) {
        Map<Class<?>, MessagePublisher> localPublishers = publishers.get();
        if (localPublishers == null) {
            localPublishers = new HashMap<Class<?>, MessagePublisher>();
            publishers.set(localPublishers);
        }
        MessagePublisher publisher = localPublishers.get(eventType);
        if (publisher == null) {
            publisher = new GenericPublisher(connectionFactory, reliability);
            localPublishers.put(eventType, publisher);
        }
        return publisher;
    }

    /**
     * A publisher configuration stores all important settings and options used for publishing and event.
     *
     * @author christian.bick
     */
    public static class PublisherConfiguration {
        public PublisherConfiguration(String exchange, String routingKey, Boolean persistent,
                                      PublisherReliability reliability, DeliveryOptions deliveryOptions,
                                      AMQP.BasicProperties basicProperties) {
            this.exchange = exchange;
            this.routingKey = routingKey;
            this.persistent = persistent;
            this.reliability = reliability;
            this.deliveryOptions = deliveryOptions;
            this.basicProperties = basicProperties;
        }

        String exchange;
        String routingKey;
        Boolean persistent;
        PublisherReliability reliability;
        DeliveryOptions deliveryOptions;
        AMQP.BasicProperties basicProperties;
    }

    /**
     * Builds a message based on a CDI event and its publisher configuration.
     *
     * @param publisherConfiguration The publisher configuration
     * @param event The CDI event
     * @return The message
     */
    static Message buildMessage(PublisherConfiguration publisherConfiguration, Object event) {
        Message message = new Message(publisherConfiguration.basicProperties)
                .exchange(publisherConfiguration.exchange)
                .routingKey(publisherConfiguration.routingKey);
        if (publisherConfiguration.persistent) {
            message.persistent();
        }
        if (event instanceof ContainsData) {
            message.body(((ContainsData) event).getData());
        } else if (event instanceof ContainsContent) {
            message.body(((ContainsContent) event).getContent());
        } else if (event instanceof ContainsId) {
            message.body(((ContainsId) event).getId());
        }
        return message;
    }
}
TOP

Related Classes of com.zanox.rabbiteasy.cdi.EventPublisher$PublisherConfiguration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.