diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusDashboard.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusDashboard.java index 3cfe48da5d..270b3c3dc8 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusDashboard.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AinStatusDashboard.java @@ -18,11 +18,14 @@ */ package org.sleuthkit.autopsy.experimental.autoingest; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.awt.Cursor; import java.awt.EventQueue; import java.util.Observable; import java.util.Observer; -import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestMonitor.AutoIngestNodeState; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.sleuthkit.autopsy.healthmonitor.HealthMonitorDashboard; /** @@ -33,12 +36,18 @@ final class AinStatusDashboard extends javax.swing.JPanel implements Observer { private final AutoIngestMonitor autoIngestMonitor; private final AinStatusPanel nodesPanel; + private final static String AIN_REFRESH_THREAD_NAME = "AID-refresh-jobs-%d"; + private final static int AIN_REFRESH_INTERVAL_SECS = 30; + private final static int AIN_DELAY_BEFORE_FIRST_REFRESH = 0; + private final ScheduledThreadPoolExecutor scheduledRefreshThreadPoolExecutor; + private AtomicBoolean scheduledRefreshStarted = new AtomicBoolean(false); /** * Creates new form AutoIngestNodeStatus */ AinStatusDashboard(AutoIngestMonitor monitor) { initComponents(); + scheduledRefreshThreadPoolExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder().setNameFormat(AIN_REFRESH_THREAD_NAME).build()); autoIngestMonitor = monitor; nodesPanel = new AinStatusPanel(); nodesPanel.setSize(nodesPanel.getSize()); @@ -172,10 +181,12 @@ final class AinStatusDashboard extends javax.swing.JPanel implements Observer { @Override public void update(Observable o, Object arg) { - if (arg instanceof AutoIngestNodeState) { - EventQueue.invokeLater(() -> { - refreshTables(); - }); + if (!scheduledRefreshStarted.getAndSet(true)) { + scheduledRefreshThreadPoolExecutor.scheduleWithFixedDelay(() -> { + EventQueue.invokeLater(() -> { + refreshTables(); + }); + }, AIN_DELAY_BEFORE_FIRST_REFRESH, AIN_REFRESH_INTERVAL_SECS, TimeUnit.SECONDS); } } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java index 8d993f4dc9..754a9c3ad7 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java @@ -18,9 +18,8 @@ */ package org.sleuthkit.autopsy.experimental.autoingest; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.awt.Cursor; -import java.util.Observable; -import java.util.Observer; import java.util.logging.Level; import java.awt.Color; import java.awt.EventQueue; @@ -29,8 +28,13 @@ import java.beans.PropertyChangeListener; import java.io.File; import java.nio.file.Paths; import java.util.HashSet; +import java.util.Observable; +import java.util.Observer; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.JPanel; import javax.swing.SwingWorker; import javax.swing.UIManager; @@ -46,15 +50,20 @@ import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestNodeRefreshEvents */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class AutoIngestDashboard extends JPanel implements Observer { - + private final static String ADMIN_ACCESS_FILE_NAME = "_aiaa"; // NON-NLS private final static String ADMIN_ACCESS_FILE_PATH = Paths.get(PlatformUtil.getUserConfigDirectory(), ADMIN_ACCESS_FILE_NAME).toString(); + private final static String AID_REFRESH_THREAD_NAME = "AID-refresh-jobs-%d"; + private final static int AID_REFRESH_INTERVAL_SECS = 30; + private final static int AID_DELAY_BEFORE_FIRST_REFRESH = 0; private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(AutoIngestDashboard.class.getName()); private AutoIngestMonitor autoIngestMonitor; private AutoIngestJobsPanel pendingJobsPanel; private AutoIngestJobsPanel runningJobsPanel; private AutoIngestJobsPanel completedJobsPanel; + private final ScheduledThreadPoolExecutor scheduledRefreshThreadPoolExecutor; + private AtomicBoolean scheduledRefreshStarted = new AtomicBoolean(false); /** * Maintain a mapping of each service to it's last status update. @@ -88,7 +97,7 @@ final class AutoIngestDashboard extends JPanel implements Observer { private AutoIngestDashboard() { this.statusByService = new ConcurrentHashMap<>(); - + scheduledRefreshThreadPoolExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder().setNameFormat(AID_REFRESH_THREAD_NAME).build()); initComponents(); statusByService.put(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString(), NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message.Down")); statusByService.put(ServicesMonitor.Service.REMOTE_KEYWORD_SEARCH.toString(), NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message.Down")); @@ -240,6 +249,7 @@ final class AutoIngestDashboard extends JPanel implements Observer { new Thread(() -> { try { autoIngestMonitor.startUp(); + } catch (AutoIngestMonitor.AutoIngestMonitorException ex) { LOGGER.log(Level.SEVERE, "Unable to start up Auto Ingest Monitor", ex); } @@ -257,18 +267,19 @@ final class AutoIngestDashboard extends JPanel implements Observer { @Override public void update(Observable observable, Object arg) { - if (arg == null ) { - EventQueue.invokeLater(() -> { - refreshTables(); - }); + if (!scheduledRefreshStarted.getAndSet(true)) { + scheduledRefreshThreadPoolExecutor.scheduleWithFixedDelay(() -> { + EventQueue.invokeLater(() -> { + refreshTables(); + }); + }, AID_DELAY_BEFORE_FIRST_REFRESH, AID_REFRESH_INTERVAL_SECS, TimeUnit.SECONDS); } } /** - * Reloads the table models using a jobs snapshot and refreshes the JTables + * Reloads the table models using a RefreshChildrenEvent and refreshes the JTables * that use the models. * - * @param nodeStateSnapshot The jobs snapshot. */ void refreshTables() { pendingJobsPanel.refresh(new RefreshChildrenEvent(autoIngestMonitor)); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java index 18fb8171b2..6962057541 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobsPanel.java @@ -164,7 +164,7 @@ final class AutoIngestJobsPanel extends javax.swing.JPanel implements ExplorerMa * Update the contents of this AutoIngestJobsPanel while retaining currently * selected node. * - * @param jobsSnapshot - the JobsSnapshot which will provide the new + * @param refreshEvent - the AutoIngestRefreshEvent which will provide the new * contents */ void refresh(AutoIngestRefreshEvent refreshEvent) { diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index 84eaa5fcdf..8f7a9c0696 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -198,6 +198,7 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen runningJob.setModuleRuntimesSnapshot(job.getModuleRunTimes()); runningJob.setProcessingStage(job.getProcessingStage(), job.getProcessingStageStartDate()); runningJob.setProcessingStatus(job.getProcessingStatus()); + break; } } setChanged(); @@ -734,7 +735,7 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen stopWatch.start(); eventPublisher.publishRemotely(new AutoIngestCaseDeletedEvent(caseName, LOCAL_HOST_NAME, AutoIngestManager.getSystemUserNameProperty())); stopWatch.stop(); - LOGGER.log(Level.INFO, String.format("Used %d s to publish job deletion event for case %s at %s", stopWatch.getElapsedTimeSecs(), caseName,caseDirectoryPath)); + LOGGER.log(Level.INFO, String.format("Used %d s to publish job deletion event for case %s at %s", stopWatch.getElapsedTimeSecs(), caseName, caseDirectoryPath)); } return CaseDeletionResult.FULLY_DELETED;