001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.jms;
007
008import static org.slf4j.LoggerFactory.getLogger;
009
010import javax.annotation.PostConstruct;
011import javax.annotation.PreDestroy;
012import javax.inject.Inject;
013import javax.jms.Connection;
014import javax.jms.Destination;
015import javax.jms.JMSException;
016import javax.jms.Message;
017import javax.jms.MessageProducer;
018import javax.jms.Session;
019
020import com.google.common.eventbus.AllowConcurrentEvents;
021import org.apache.activemq.ActiveMQConnectionFactory;
022import org.fcrepo.kernel.api.observer.Event;
023import org.slf4j.Logger;
024
025import com.google.common.eventbus.EventBus;
026import com.google.common.eventbus.Subscribe;
027
028/**
029 * Machinery to publish JMS messages when an EventBus
030 * message is received.
031 *
032 * @author barmintor
033 * @author awoods
034 * @author acoburn
035 */
036public abstract class AbstractJMSPublisher {
037
038    @Inject
039    private EventBus eventBus;
040
041    @Inject
042    private ActiveMQConnectionFactory connectionFactory;
043
044    @Inject
045    private JMSEventMessageFactory eventFactory;
046
047    private Connection connection;
048
049    protected Session jmsSession;
050
051    private MessageProducer producer;
052
053    private static final Logger LOGGER = getLogger(AbstractJMSPublisher.class);
054
055    protected abstract Destination createDestination() throws JMSException;
056
057    /**
058     * When an EventBus message is received, map it to our JMS
059     * message payload and push it onto the queue.
060     *
061     * @param event the fedora event
062     * @throws JMSException if JMS exception occurred
063     */
064    @Subscribe
065    @AllowConcurrentEvents
066    public void publishJCREvent(final Event event) throws JMSException {
067        LOGGER.debug("Received an event from the internal bus. {}", event);
068        final Message tm =
069                eventFactory.getMessage(event, jmsSession);
070        LOGGER.trace("Transformed the event to a JMS message.");
071        producer.send(tm);
072
073        LOGGER.debug("Put event: {} onto JMS.", tm.getJMSMessageID());
074    }
075
076    /**
077     * Connect to JCR Repository and JMS queue
078     *
079     * @throws JMSException if JMS Exception occurred
080     */
081    @PostConstruct
082    public void acquireConnections() throws JMSException {
083        LOGGER.debug("Initializing: {}", this.getClass().getCanonicalName());
084
085        connection = connectionFactory.createConnection();
086        connection.start();
087        jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
088        producer = jmsSession.createProducer(createDestination());
089        eventBus.register(this);
090    }
091
092    /**
093     * Close external connections
094     *
095     * @throws JMSException if JMS exception occurred
096     */
097    @PreDestroy
098    public void releaseConnections() throws JMSException {
099        LOGGER.debug("Tearing down: {}", this.getClass().getCanonicalName());
100
101        producer.close();
102        jmsSession.close();
103        connection.close();
104        eventBus.unregister(this);
105    }
106}