Package org.fcrepo.server.messaging

Source Code of org.fcrepo.server.messaging.MessagingModule

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.messaging;

import java.io.File;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.naming.Context;

import javax.jms.Session;

import org.fcrepo.common.Constants;
import org.fcrepo.server.DatastoreConfig;
import org.fcrepo.server.Module;
import org.fcrepo.server.Server;
import org.fcrepo.server.errors.MessagingException;
import org.fcrepo.server.errors.ModuleInitializationException;
import org.fcrepo.server.errors.ModuleShutdownException;
import org.fcrepo.server.messaging.JMSManager.DestinationType;
import org.fcrepo.server.utilities.ServerUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Fedora's <code>Messaging</code> as a configurable module.
*
* @author Edwin Shin
* @version $Id$
*/
public class MessagingModule
        extends Module
        implements Messaging {

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

    private Messaging msg;

    private JMSManager jmsMgr;

    private static final String ACTIVEMQ_PREFIX =
            "org.apache.activemq.default.directory.prefix";

    public MessagingModule(Map<String, String> moduleParameters,
                           Server server,
                           String role)
            throws ModuleInitializationException {
        super(moduleParameters, server, role);
    }

    @Override
    public void initModule() throws ModuleInitializationException {

        if (!enabled()) {
            logger.info("Messaging Module is disabled.");
            return;
        }

        // Sets the location of the activemq-data directory
        // Property is ignored if the messaging provider is not ActiveMQ
        if (System.getProperty(ACTIVEMQ_PREFIX) == null) {
            System.setProperty(ACTIVEMQ_PREFIX,
                               new File(Constants.FEDORA_HOME, "data").getPath()
                               + File.separator);
        }

        Properties jndiProps = getJNDISettings();

        try {
            jmsMgr = new JMSManager(jndiProps);
        } catch (Exception e) {
            throw new ModuleInitializationException(e.getMessage(), getRole());
        }

        try {
            String fedoraBaseUrl = ServerUtility.getBaseURL("http");
            msg =
                    new MessagingImpl(fedoraBaseUrl,
                                      createDestinations(),
                                      jmsMgr);
        } catch (Exception e) {
            throw new ModuleInitializationException("Error connecting to JMS ",
                                                    getRole(),
                                                    e);
        }
    }

    @Override
    public void postInitModule() throws ModuleInitializationException {

    }

    @Override
    public void shutdownModule() throws ModuleShutdownException {
        if(enabled()) {
            try {
                close();
            } catch (MessagingException e) {
                throw new ModuleShutdownException(e.getMessage(), getRole(), e);
            }
        }
    }

    public void send(String destName, FedoraMessage message)
            throws MessagingException {
        msg.send(destName, message);
    }

    public void send(FedoraMethod method) throws MessagingException {
        msg.send(method);
    }

    private Properties getJNDISettings() {

        String contextFactory = getParameter(Context.INITIAL_CONTEXT_FACTORY);
        String providerURL = getParameter(Context.PROVIDER_URL);
        String connectionFactory =
                getParameter(JMSManager.CONNECTION_FACTORY_NAME);

        if (providerURL == null || providerURL.length() == 0) {
            providerURL = "vm:(broker:(tcp://localhost:61616))";
            if (logger.isDebugEnabled()) {
                logger.debug("Using default provider url: " + providerURL);
            }
        }

        if (connectionFactory == null || connectionFactory.length() == 0) {
            connectionFactory = "ConnectionFactory";
            if (logger.isDebugEnabled()) {
                logger.debug("Using default connection factory name: " + connectionFactory);
            }
        }

        if (contextFactory == null || contextFactory.length() == 0) {
            contextFactory =
                    "org.apache.activemq.jndi.ActiveMQInitialContextFactory";
            if (logger.isDebugEnabled()) {
                logger.debug("Using default initial context factory: " + contextFactory);
            }
        } else if (contextFactory.equalsIgnoreCase("container")) {
            // assume jndi information is provided via the container
            return null;
        }

        Properties props = new Properties();
        props.setProperty(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
        props.setProperty(Context.PROVIDER_URL, providerURL);
        props
                .setProperty(JMSManager.CONNECTION_FACTORY_NAME,
                             connectionFactory);

        return props;
    }

    /**
     * @return a <code>Map</code>ping of message type to destinations
     * @throws ModuleInitializationException
     */
    private Map<String, List<String>> createDestinations()
            throws ModuleInitializationException {
        Map<String, List<String>> mdMap = new HashMap<String, List<String>>();
        for (MessageType type : MessageType.values()) {
            mdMap.put(type.toString(), new ArrayList<String>());
        }

        Iterator<String> parameters = parameterNames();
        String param;
        while (parameters.hasNext()) {
            param = parameters.next();
            if (param.startsWith("datastore")) {
                DatastoreConfig dsConfig = getDatastore(param);
                String[] msgTypes =
                        dsConfig.getParameter("messageTypes").split(" ");
                for (String msgType : msgTypes) {
                    if (!mdMap.containsKey(msgType)) {
                        throw new ModuleInitializationException(msgType
                                + " is not a supported MessageType.", getRole());
                    }
                }

                String destName = dsConfig.getParameter("name");
                String type = dsConfig.getParameter("type");
                boolean transacted =
                        Boolean.parseBoolean(dsConfig
                                .getParameter("transacted"));
                String ackMode = dsConfig.getParameter("ackMode");

                DestinationType destType = DestinationType.Topic;
                if (type.equalsIgnoreCase("queue")) {
                    destType = DestinationType.Queue;
                }

                int destAckMode = Session.AUTO_ACKNOWLEDGE;

                if (ackMode != null && ackMode.length() > 0) {
                    try {
                        destAckMode = Integer.parseInt(ackMode);
                    } catch (NumberFormatException e) {
                        throw new ModuleInitializationException("ackMode must be a number",
                                                                getRole());
                    }
                }

                try {
                    if (logger.isDebugEnabled()) {
                        logger.debug(String
                                .format("createDestination(%s, %s, %s, %s)",
                                        destName,
                                        destType,
                                        transacted,
                                        destAckMode));
                    }
                    jmsMgr.createDestination(destName,
                                             destType,
                                             transacted,
                                             destAckMode);
                } catch (Exception e) {
                    throw new ModuleInitializationException(e.getMessage(),
                                                            getRole());
                }

                for (String msgType : msgTypes) {
                    mdMap.get(msgType).add(destName);
                }
            }
        }
        return mdMap;
    }

    private DatastoreConfig getDatastore(String name)
            throws ModuleInitializationException {
        String value = getParameter(name);
        if (value == null || value.length() == 0) {
            throw new ModuleInitializationException(name + " parameter "
                    + "is required", getRole());
        }
        DatastoreConfig dsConfig = getServer().getDatastoreConfig(value);
        if (dsConfig == null) {
            throw new ModuleInitializationException(value + " datastore "
                    + "configuration is missing.", getRole());
        }
        return dsConfig;
    }

    // Check to see if messaging is enabled
    private boolean enabled() {
        String enabled = getParameter("enabled");
        return (enabled != null && enabled.equalsIgnoreCase("true"));
    }


    public void close() throws MessagingException {
        if (msg != null) {
            msg.close();
            msg = null;
        }
    }
}
TOP

Related Classes of org.fcrepo.server.messaging.MessagingModule

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.