org.qucosa.indexfeeder.Main.java Source code

Java tutorial

Introduction

Here is the source code for org.qucosa.indexfeeder.Main.java

Source

/*
 * Copyright (C) 2014 SLUB Dresden
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.qucosa.indexfeeder;

import com.yourmediashelf.fedora.client.FedoraClient;
import com.yourmediashelf.fedora.client.FedoraClientException;
import com.yourmediashelf.fedora.client.FedoraCredentials;
import com.yourmediashelf.fedora.client.messaging.JMSManager;
import com.yourmediashelf.fedora.client.messaging.MessagingClient;
import com.yourmediashelf.fedora.client.messaging.MessagingException;
import com.yourmediashelf.fedora.client.request.DescribeRepository;
import com.yourmediashelf.fedora.client.response.DescribeRepositoryResponse;
import com.yourmediashelf.fedora.generated.access.FedoraRepository;
import org.apache.activemq.jndi.ActiveMQInitialContextFactory;
import org.apache.commons.io.IOUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.qucosa.indexfeeder.jms.FedoraMessageBroadcaster;
import org.qucosa.indexfeeder.job.Job;
import org.qucosa.indexfeeder.job.JobDispatcher;
import org.qucosa.indexfeeder.queue.UniqueDelayQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.Context;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Properties;

public class Main {

    public static final String ACTIVEMQ_CONTEXT_FACTORY_NAME = ActiveMQInitialContextFactory.class
            .getCanonicalName();
    public static final String DEFAULT_ES_CLUSTER_NAME = "elasticsearch";
    public static final String DEFAULT_PROVIDER_URL = "tcp://localhost:61616";
    public static final String DEFAULT_TOPIC_FILTER = "fedora.apim.*";
    private static final String FEDORA_PARAM_BASE_URL = "fedora.url";
    private static final String FEDORA_PARAM_USER = "fedora.user";
    private static final String FEDORA_PARAM_PASSWORD = "fedora.password";
    private static final String ELASTICSEARCH_PARAM_HOST = "es.host";
    private static final UniqueDelayQueue<Job> indexJobQueue = new UniqueDelayQueue<>();
    private static Logger log = LoggerFactory.getLogger(Main.class);
    private static Properties properties;
    private static FedoraMessageBroadcaster messageBroadcaster;
    private static MessagingClient fedoraMessagingClient;
    private static JobDispatcher jobDispatcher;
    private static Client elasticSearchClient;
    private static FedoraClient fedoraClient;
    private static boolean messagingEnabled = true;

    public static void main(String[] args) throws Exception {
        initializeProperties();

        if (messagingEnabled) {
            initializeFedoraMessageBroadcasting();
            initializeMessagingClient();
        }
        initializeFedoraClient();
        initializeElasticSearchClient();
        initializeQucosaDocumentsIndex();

        initializeJobDispatcher();
        initializeIndexJobWorker();

        registerShutdownHooks();

        if (messagingEnabled) {
            startFedoraMessagingClient();
        }
        startFedoraClient();
        startIndexJobDispatcher();
    }

    private static void initializeQucosaDocumentsIndex() throws IOException {
        if (!elasticSearchClient.admin().indices().prepareExists("qucosa").execute().actionGet().isExists()) {
            elasticSearchClient.admin().indices().prepareCreate("qucosa").execute().actionGet();
            elasticSearchClient.admin().indices().preparePutMapping("qucosa").setType("documents")
                    .setSource(IOUtils.toString(Main.class.getResourceAsStream("/index_mappings.json"))).execute()
                    .actionGet();
        }
    }

    private static void startIndexJobDispatcher() {
        jobDispatcher.start();
    }

    private static void startFedoraClient() throws FedoraClientException {
        describeRepository(fedoraClient);
    }

    private static void startFedoraMessagingClient() throws MessagingException {
        fedoraMessagingClient.start(true);
    }

    private static void initializeJobDispatcher() {
        jobDispatcher = new JobDispatcher(indexJobQueue);
    }

    private static void initializeElasticSearchClient() {
        String hostname = properties.getProperty(ELASTICSEARCH_PARAM_HOST);
        Settings esSettings = ImmutableSettings.settingsBuilder().put("cluster.name", DEFAULT_ES_CLUSTER_NAME)
                .put("client.transport.sniff", true).build();
        elasticSearchClient = new TransportClient(esSettings)
                .addTransportAddress(new InetSocketTransportAddress(hostname, 9300));
    }

    private static void initializeMessagingClient() throws MessagingException {
        String messageSelector = "methodName LIKE 'modify%'" + " OR methodName LIKE 'add%'"
                + " OR methodName LIKE 'purge%'" + " OR methodName = 'ingest'";
        fedoraMessagingClient = new MessagingClient("indexfeeder", messageBroadcaster, properties, messageSelector,
                false);
        log.debug("JMS Message selector: " + messageSelector);
    }

    private static void initializeFedoraMessageBroadcasting() throws Exception {
        messageBroadcaster = new FedoraMessageBroadcaster();
        messageBroadcaster.addMessageHandler(new RelationshipMessageHandler(indexJobQueue));
        messageBroadcaster.addMessageHandler(new ObjectMessageHandler(indexJobQueue));
        messageBroadcaster.addMessageHandler(new DatastreamMessageHandler(indexJobQueue));
    }

    private static void initializeIndexJobWorker() throws MalformedURLException, FedoraClientException {
        jobDispatcher.registerWorker("ingest", new IngestWorker(elasticSearchClient, fedoraClient));
        jobDispatcher.registerWorker("modify", new IngestWorker(elasticSearchClient, fedoraClient));
        jobDispatcher.registerWorker("purgeObject", new PurgeObjectWorker(elasticSearchClient));
    }

    private static void initializeFedoraClient() throws MalformedURLException, FedoraClientException {
        FedoraCredentials fedoraCredentials = new FedoraCredentials(properties.getProperty(FEDORA_PARAM_BASE_URL),
                properties.getProperty(FEDORA_PARAM_USER), properties.getProperty(FEDORA_PARAM_PASSWORD));
        fedoraClient = new FedoraClient(fedoraCredentials);
    }

    private static void initializeProperties() {
        properties = new Properties();
        properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, ACTIVEMQ_CONTEXT_FACTORY_NAME);
        properties.setProperty(JMSManager.CONNECTION_FACTORY_NAME, "ConnectionFactory");
        properties.setProperty(Context.PROVIDER_URL,
                System.getProperty(Context.PROVIDER_URL, DEFAULT_PROVIDER_URL));
        properties.setProperty("topic.fedora", System.getProperty("topic.fedora", DEFAULT_TOPIC_FILTER));
        properties.setProperty(FEDORA_PARAM_BASE_URL,
                System.getProperty(FEDORA_PARAM_BASE_URL, "http://localhost:8080/fedora"));
        properties.setProperty(FEDORA_PARAM_USER, System.getProperty(FEDORA_PARAM_USER, "fedoraAdmin"));
        properties.setProperty(FEDORA_PARAM_PASSWORD, System.getProperty(FEDORA_PARAM_PASSWORD, "fedoraAdmin"));
        properties.setProperty(ELASTICSEARCH_PARAM_HOST,
                System.getProperty(ELASTICSEARCH_PARAM_HOST, "http://localhost:9300"));
        log.info("ActiveMQ URL:       " + properties.getProperty(Context.PROVIDER_URL));
        log.info("ActiveMQ Topic:     " + properties.getProperty("topic.fedora"));
        log.info("Fedora URL:         " + properties.getProperty(FEDORA_PARAM_BASE_URL));
        log.info("Fedora User:        " + properties.getProperty(FEDORA_PARAM_USER));
        log.info("ElasticSearch Host: " + properties.getProperty(ELASTICSEARCH_PARAM_HOST));
    }

    private static void registerShutdownHooks() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    log.info("Terminate Index Job Dispatcher...");
                    jobDispatcher.terminate();
                } catch (Exception e) {
                    log.error("Problem while terminating Index Job Dispatcher: " + e.getMessage());
                }
                try {
                    log.info("Terminate ElasticSearch Connection...");
                    elasticSearchClient.close();
                } catch (Exception e) {
                    log.error("Problem while terminating ElasticSearch Connection: " + e.getMessage());
                }
                try {
                    log.info("Terminating ActiveMQ client...");
                    fedoraMessagingClient.stop(false);
                } catch (Exception e) {
                    log.error("Problem while terminating ActiveMQ client: " + e.getMessage());
                }
            }
        });
    }

    private static void describeRepository(FedoraClient fcClient) throws FedoraClientException {
        DescribeRepository describeRequest = new DescribeRepository();
        DescribeRepositoryResponse describeResponse = describeRequest.execute(fcClient);
        FedoraRepository repoInfo = describeResponse.getRepositoryInfo();
        log.info("Repository Version : " + repoInfo.getRepositoryVersion());
        log.info("Repository Base URL: " + repoInfo.getRepositoryBaseURL());
        log.info("Repository PID     : " + repoInfo.getRepositoryPID());
    }

}