AgentIndexRunner.java revision 1190
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER START
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Common Development and Distribution License (the "License").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You may not use this file except in compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See LICENSE.txt included in this distribution for the specific
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * language governing permissions and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * file and include the License file at LICENSE.txt.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below this CDDL HEADER, with the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * information: Portions Copyright [yyyy] [name of copyright owner]
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER END
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpackage org.opensolaris.opengrok.management;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
9740fa737ef2ed9453ab46d145777dbbbf6a747bMark de Reeperimport java.io.File;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Arrays;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.HashSet;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Iterator;
80849398a45dca1fb917716907d6ec99be6222c2Peter Majorimport java.util.List;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Set;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.logging.Level;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.logging.Logger;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.ListenerNotFoundException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.MBeanNotificationInfo;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.MBeanRegistration;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.MBeanServer;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.Notification;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.NotificationEmitter;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.NotificationFilter;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.NotificationListener;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.management.ObjectName;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.opensolaris.opengrok.configuration.RuntimeEnvironment;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.opensolaris.opengrok.history.HistoryGuru;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.opensolaris.opengrok.index.IndexChangedListener;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.opensolaris.opengrok.index.Indexer;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * AgentIndexRunner.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @author Jan S Berg
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic final class AgentIndexRunner implements AgentIndexRunnerMBean, NotificationListener,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MBeanRegistration, Runnable, IndexChangedListener, NotificationEmitter {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private transient static AgentIndexRunner indexerInstance = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final static String NOTIFICATIONACTIONTYPE = "ogaaction";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final static String NOTIFICATIONEXCEPTIONTYPE = "ogaexception";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final static String NOTIFICATIONINFOSTRINGTYPE = "ogainfostring";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final static String NOTIFICATIONINFOLONGTYPE = "ogainfolong";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private boolean enabled;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private transient Thread indexThread = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final static Logger log = Logger.getLogger("org.opensolaris.opengrok");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private RuntimeEnvironment env = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private long lastIndexStart = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private long lastIndexFinish = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private long lastIndexUsedTime = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private Exception lastException = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final Set<NotificationHolder> notifListeners =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster new HashSet<NotificationHolder>();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static long sequenceNo = 0;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final StringBuilder notifications = new StringBuilder();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private final static int MAXMESSAGELENGTH = 50000;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest /**
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * The only constructor is private, so other classes will only get an
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * instance through the static factory method getInstance().
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest */
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest private AgentIndexRunner(boolean enabledParam) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest enabled = enabledParam;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest /**
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * Static factory method to get an instance of AgentIndexRunner.
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param enabledParam if true, the initial instance should be running or not
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest */
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel")
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static synchronized AgentIndexRunner getInstance(boolean enabledParam) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (indexerInstance == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster indexerInstance = new AgentIndexRunner(enabledParam);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return indexerInstance;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public ObjectName preRegister(MBeanServer serverParam, ObjectName name) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return name;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void postRegister(Boolean registrationDone) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // not used
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest @Override
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public void preDeregister() {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest // not used
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest @Override
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public void postDeregister() {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest // not used
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest @Override
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public void run() {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest try {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest //Indexer ind = new Indexer();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.info("Running...");
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest lastIndexStart = System.currentTimeMillis();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest lastException = null;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doNotify(NOTIFICATIONINFOLONGTYPE, "StartIndexing", Long.valueOf(lastIndexStart));
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest String configfile = Management.getInstance().getConfigurationFile();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if (configfile == null) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doNotify(NOTIFICATIONEXCEPTIONTYPE, "Missing Configuration file", "");
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest File cfgFile = new File(configfile);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if (cfgFile.exists()) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest env = RuntimeEnvironment.getInstance();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.log(Level.INFO, "Running indexer with configuration {0}", configfile);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest env.readConfiguration(cfgFile);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest Indexer index = Indexer.getInstance();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest int noThreads = Management.getInstance().getNumberOfThreads().intValue();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest boolean update = Management.getInstance().getUpdateIndexDatabase().booleanValue();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest String[] sublist = Management.getInstance().getSubFiles();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.info("Update source repositories");
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest HistoryGuru.getInstance().updateRepositories();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest List<String> subFiles = Arrays.asList(sublist);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.log(Level.INFO, "Starting index, update {0} noThreads {1} subfiles {2}", new Object[]{String.valueOf(update), String.valueOf(noThreads), String.valueOf(subFiles.size())});
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest index.doIndexerExecution(update, noThreads, subFiles, this);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.info("Finished indexing");
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest lastIndexFinish = System.currentTimeMillis();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest sendNotifications();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doNotify(NOTIFICATIONINFOLONGTYPE, "FinishedIndexing", Long.valueOf(lastIndexFinish));
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest lastIndexUsedTime = lastIndexFinish - lastIndexStart;
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest String publishhost = Management.getInstance().getPublishServerURL();
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest if ((publishhost == null) || (publishhost.equals(""))) {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.warning("No publishhost given, not sending updates");
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } else {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest index.sendToConfigHost(env, publishhost);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doNotify(NOTIFICATIONINFOSTRINGTYPE, "Published index", publishhost);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest }
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } else {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest log.log(Level.WARNING, "Cannot Run indexing without proper configuration file {0}", configfile);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doNotify(NOTIFICATIONEXCEPTIONTYPE, "Configuration file not valid", configfile);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.SEVERE,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Exception running indexing ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster lastException = e;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Disables indexer
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void disable() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster enabled = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Enables the indexer
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void enable() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster enabled = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Handle timer notifications to the purgatory.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Will start the purger if it is enabled and return immediately.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void handleNotification(Notification n, Object hb) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (n.getType().equals("timer.notification")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.finer("Received timer notification");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (enabled) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster index(false);
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk } else {
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk log.info("Indexing is disabled, doing nothing");
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk }
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.WARNING, "Received unknown notification type: {0}", n.getType());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The index method starts a thread that will
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * start indexing part of the opengrok agent.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param waitForFinished if false the command returns immediately, if true
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * it will return when the indexing is done.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void index(boolean waitForFinished) {
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk log.info("Starting indexing.");
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk /*
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk * Synchronize here to make sure that you never get more than one
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * indexing thread trying to start at the same time.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (this) {
4a48635cccc646ac479830fd4df0ee8e10c5bd8djeff.schenk if (indexThread != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (indexThread.isAlive()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.warning("Previous indexer is still alive, will not start another.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.fine("Previous indexer is no longer alive, starting a new one.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster indexThread = new Thread(this);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster indexThread.start();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!waitForFinished) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.fine("Waiting for indexer to finish...");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster indexThread.join();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.fine("indexer finished.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.SEVERE,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Caught Exception while waiting for indexing to finish.", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void fileAdd(String path, String analyzer) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.INFO, "Add {0} analyzer {1}", new Object[]{path, analyzer});
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void fileRemove(String path) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.INFO, "File remove {0}", path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void fileUpdate(String path) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.INFO, "File updated {0}", path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster addFileAction("U:", path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void fileAdded(String path, String analyzer) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.INFO, "Added {0} analyzer {1}", new Object[]{path, analyzer});
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster addFileAction("A:", path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void fileRemoved(String path) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.INFO, "File removed {0}", path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster addFileAction("R:", path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void addFileAction(String type, String path) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notifications.append('\n');
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notifications.append(type);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notifications.append(path);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (notifications.length() > MAXMESSAGELENGTH) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sendNotifications();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void sendNotifications() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (notifications.length() > 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster doNotify(NOTIFICATIONACTIONTYPE, "FilesInfo", notifications.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notifications.delete(0, notifications.length());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long lastIndexTimeFinished() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return lastIndexFinish;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long lastIndexTimeStarted() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return lastIndexStart;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public long lastIndexTimeUsed() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return lastIndexUsedTime;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Exception getExceptions() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return lastException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void addNotificationListener(NotificationListener notiflistener, NotificationFilter notfilt, Object obj) throws IllegalArgumentException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.CONFIG, "Adds a notiflistner, with obj {0}", obj.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (notiflistener == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new IllegalArgumentException("Must have legal NotificationListener");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (notifListeners) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notifListeners.add(new NotificationHolder(notiflistener, notfilt, obj));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void removeNotificationListener(NotificationListener notiflistener) throws ListenerNotFoundException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.info("removes a notiflistener, no obj");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean removed = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (notifListeners) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator<NotificationHolder> it = notifListeners.iterator();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (it.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NotificationHolder mnf = it.next();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (mnf.getNL().equals(notiflistener)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster it.remove();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster removed = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!removed) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new ListenerNotFoundException("Didn't remove the given NotificationListener");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void removeNotificationListener(NotificationListener notiflistener, NotificationFilter filt, Object obj) throws ListenerNotFoundException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.CONFIG, "removes a notiflistener obj {0}", obj);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean removed = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (notifListeners) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator<NotificationHolder> it = notifListeners.iterator();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major while (it.hasNext()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major NotificationHolder mnf = it.next();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (mnf.getNL().equals(notiflistener)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && ((mnf.getFilter() == null) || mnf.getFilter().equals(filt))
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && ((mnf.getFilter() == null) || mnf.getObj().equals(obj))) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major it.remove();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major removed = true;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!removed) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new ListenerNotFoundException("Didn't remove the given NotificationListener");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Method that the subclass can override, but doesn't have to
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return MBeanNotificationInfo array of notification (and types) this class can emitt.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster @Override
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public MBeanNotificationInfo[] getNotificationInfo() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MBeanNotificationInfo[] info = new MBeanNotificationInfo[1];
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] supptypes = {NOTIFICATIONACTIONTYPE, NOTIFICATIONINFOLONGTYPE, NOTIFICATIONINFOSTRINGTYPE};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String name = "AgentIndexRunner";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String descr = "OpenGrok Indexer Notifications";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MBeanNotificationInfo minfo = new MBeanNotificationInfo(supptypes, name,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster descr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster info[0] = minfo;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return info;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void doNotify(String type, String msg, Object userdata) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.CONFIG, "start notifying {0} listeners", notifListeners.size());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster long ts = System.currentTimeMillis();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sequenceNo++;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Notification notif = new Notification(type, this, sequenceNo, ts, msg);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notif.setUserData(userdata);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (notifListeners) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (NotificationHolder nl : notifListeners) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.FINE, "having one with obj {0}", nl.getObj());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((nl.getFilter() == null) ||
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster nl.getFilter().isNotificationEnabled(notif)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster nl.getNL().handleNotification(notif, nl.getObj());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception exnot) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.WARNING, "Ex " + exnot, exnot);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception ex) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log.log(Level.SEVERE,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Exception during notification sending: " + ex.getMessage(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster