mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 08:56:15 +00:00
893 lines
43 KiB
Java
Executable File
893 lines
43 KiB
Java
Executable File
/*
|
|
* Autopsy Forensic Browser
|
|
*
|
|
* Copyright 2011-2017 Basis Technology Corp.
|
|
* Contact: carrier <at> sleuthkit <dot> org
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package org.sleuthkit.autopsy.experimental.autoingest;
|
|
|
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
import java.awt.Cursor;
|
|
import java.awt.EventQueue;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.time.Instant;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Observable;
|
|
import java.util.Observer;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.logging.Level;
|
|
import javax.swing.DefaultListSelectionModel;
|
|
import java.awt.Color;
|
|
import java.beans.PropertyChangeEvent;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JTable;
|
|
import javax.swing.SwingWorker;
|
|
import javax.swing.UIManager;
|
|
import javax.swing.event.ListSelectionEvent;
|
|
import javax.swing.table.DefaultTableModel;
|
|
import javax.swing.table.TableColumn;
|
|
import org.openide.util.NbBundle;
|
|
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestMonitor.JobsSnapshot;
|
|
|
|
/**
|
|
* A dashboard for monitoring an automated ingest cluster.
|
|
*/
|
|
public final class AutoIngestDashboard extends JPanel implements Observer {
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
private static final int GENERIC_COL_MIN_WIDTH = 30;
|
|
private static final int GENERIC_COL_MAX_WIDTH = 2000;
|
|
private static final int PENDING_TABLE_COL_PREFERRED_WIDTH = 280;
|
|
private static final int RUNNING_TABLE_COL_PREFERRED_WIDTH = 175;
|
|
private static final int ACTIVITY_TIME_COL_MIN_WIDTH = 250;
|
|
private static final int ACTIVITY_TIME_COL_MAX_WIDTH = 450;
|
|
private static final int TIME_COL_MIN_WIDTH = 30;
|
|
private static final int TIME_COL_MAX_WIDTH = 250;
|
|
private static final int TIME_COL_PREFERRED_WIDTH = 140;
|
|
private static final int NAME_COL_MIN_WIDTH = 100;
|
|
private static final int NAME_COL_MAX_WIDTH = 250;
|
|
private static final int NAME_COL_PREFERRED_WIDTH = 140;
|
|
private static final int ACTIVITY_COL_MIN_WIDTH = 70;
|
|
private static final int ACTIVITY_COL_MAX_WIDTH = 2000;
|
|
private static final int ACTIVITY_COL_PREFERRED_WIDTH = 300;
|
|
private static final int STATUS_COL_MIN_WIDTH = 55;
|
|
private static final int STATUS_COL_MAX_WIDTH = 250;
|
|
private static final int STATUS_COL_PREFERRED_WIDTH = 55;
|
|
private static final int COMPLETED_TIME_COL_MIN_WIDTH = 30;
|
|
private static final int COMPLETED_TIME_COL_MAX_WIDTH = 2000;
|
|
private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280;
|
|
private static final String UPDATE_TASKS_THREAD_NAME = "AID-update-tasks-%d";
|
|
private static final Logger logger = Logger.getLogger(AutoIngestDashboard.class.getName());
|
|
private final DefaultTableModel pendingTableModel;
|
|
private final DefaultTableModel runningTableModel;
|
|
private final DefaultTableModel completedTableModel;
|
|
private AutoIngestMonitor autoIngestMonitor;
|
|
private ExecutorService updateExecutor;
|
|
|
|
// DLG: The Viking code needs to be updated, too. See VikingStartupWindow,
|
|
// which should be using the AutoIngestControlPanel, not the AutoIngestDashboard.
|
|
/**
|
|
* Creates a dashboard for monitoring an automated ingest cluster.
|
|
*
|
|
* @return The dashboard.
|
|
*
|
|
* @throws AutoIngestDashboardException If there is a problem creating the
|
|
* dashboard.
|
|
*/
|
|
public static AutoIngestDashboard createDashboard() throws AutoIngestDashboardException {
|
|
AutoIngestDashboard dashBoard = new AutoIngestDashboard();
|
|
try {
|
|
dashBoard.startUp();
|
|
} catch (AutoIngestMonitor.AutoIngestMonitorException ex) {
|
|
throw new AutoIngestDashboardException("Error starting up auto ingest dashboard", ex);
|
|
}
|
|
return dashBoard;
|
|
}
|
|
|
|
/**
|
|
* Constructs a panel for monitoring an automated ingest cluster.
|
|
*/
|
|
private AutoIngestDashboard() {
|
|
pendingTableModel = new DefaultTableModel(JobsTableModelColumns.headers, 0) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public boolean isCellEditable(int row, int column) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
runningTableModel = new DefaultTableModel(JobsTableModelColumns.headers, 0) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public boolean isCellEditable(int row, int column) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
completedTableModel = new DefaultTableModel(JobsTableModelColumns.headers, 0) {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
@Override
|
|
public boolean isCellEditable(int row, int column) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
initComponents();
|
|
setServicesStatusMessage();
|
|
initPendingJobsTable();
|
|
initRunningJobsTable();
|
|
initCompletedJobsTable();
|
|
|
|
/*
|
|
* Must set this flag, otherwise pop up menus don't close properly.
|
|
*/
|
|
UIManager.put("PopupMenu.consumeEventOnClose", false);
|
|
}
|
|
|
|
/**
|
|
* Queries the services monitor and sets the text for the services status
|
|
* text box.
|
|
*/
|
|
private void setServicesStatusMessage() {
|
|
new SwingWorker<Void, Void>() {
|
|
String caseDatabaseServerStatus = ServicesMonitor.ServiceStatus.DOWN.toString();
|
|
String keywordSearchServiceStatus = ServicesMonitor.ServiceStatus.DOWN.toString();
|
|
String messagingStatus = ServicesMonitor.ServiceStatus.DOWN.toString();
|
|
|
|
@Override
|
|
protected Void doInBackground() throws Exception {
|
|
caseDatabaseServerStatus = getServiceStatus(ServicesMonitor.Service.REMOTE_CASE_DATABASE);
|
|
keywordSearchServiceStatus = getServiceStatus(ServicesMonitor.Service.REMOTE_KEYWORD_SEARCH);
|
|
messagingStatus = getServiceStatus(ServicesMonitor.Service.MESSAGING);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Gets a status string for a given service.
|
|
*
|
|
* @param service The service to test.
|
|
*
|
|
* @return The status string.
|
|
*/
|
|
private String getServiceStatus(ServicesMonitor.Service service) {
|
|
String serviceStatus = NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown");
|
|
try {
|
|
ServicesMonitor servicesMonitor = ServicesMonitor.getInstance();
|
|
serviceStatus = servicesMonitor.getServiceStatus(service.toString());
|
|
if (serviceStatus.compareTo(ServicesMonitor.ServiceStatus.UP.toString()) == 0) {
|
|
serviceStatus = NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message.Up");
|
|
} else {
|
|
serviceStatus = NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message.Down");
|
|
}
|
|
} catch (ServicesMonitor.ServicesMonitorException ex) {
|
|
logger.log(Level.SEVERE, String.format("Dashboard error getting service status for %s", service), ex);
|
|
}
|
|
return serviceStatus;
|
|
}
|
|
|
|
@Override
|
|
protected void done() {
|
|
tbServicesStatusMessage.setText(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message", caseDatabaseServerStatus, keywordSearchServiceStatus, keywordSearchServiceStatus, messagingStatus));
|
|
String upStatus = NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message.Up");
|
|
if (caseDatabaseServerStatus.compareTo(upStatus) != 0
|
|
|| keywordSearchServiceStatus.compareTo(upStatus) != 0
|
|
|| messagingStatus.compareTo(upStatus) != 0) {
|
|
tbServicesStatusMessage.setForeground(Color.RED);
|
|
} else {
|
|
tbServicesStatusMessage.setForeground(Color.BLACK);
|
|
}
|
|
}
|
|
|
|
}.execute();
|
|
}
|
|
|
|
/**
|
|
* Sets up the JTable that presents a view of the pending jobs queue for an
|
|
* auto ingest cluster.
|
|
*/
|
|
private void initPendingJobsTable() {
|
|
/*
|
|
* Remove some of the jobs table model columns from the JTable. This
|
|
* does not remove the columns from the model, just from this table.
|
|
*/
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STARTED_TIME.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.COMPLETED_TIME.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STAGE.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STAGE_TIME.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
|
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
|
|
|
|
/*
|
|
* Set up a column to display the cases associated with the jobs.
|
|
*/
|
|
TableColumn column;
|
|
column = pendingTable.getColumn(JobsTableModelColumns.CASE.getColumnHeader());
|
|
column.setMinWidth(GENERIC_COL_MIN_WIDTH);
|
|
column.setMaxWidth(GENERIC_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(PENDING_TABLE_COL_PREFERRED_WIDTH);
|
|
column.setWidth(PENDING_TABLE_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the data sources associated with the jobs.
|
|
*/
|
|
column = pendingTable.getColumn(JobsTableModelColumns.DATA_SOURCE.getColumnHeader());
|
|
column.setMaxWidth(GENERIC_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(PENDING_TABLE_COL_PREFERRED_WIDTH);
|
|
column.setWidth(PENDING_TABLE_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the create times of the jobs.
|
|
*/
|
|
column = pendingTable.getColumn(JobsTableModelColumns.CREATED_TIME.getColumnHeader());
|
|
column.setCellRenderer(new LongDateCellRenderer());
|
|
column.setMinWidth(TIME_COL_MIN_WIDTH);
|
|
column.setMaxWidth(TIME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(TIME_COL_PREFERRED_WIDTH);
|
|
column.setWidth(TIME_COL_PREFERRED_WIDTH);
|
|
|
|
/**
|
|
* Prevent sorting when a column header is clicked.
|
|
*/
|
|
pendingTable.setAutoCreateRowSorter(false);
|
|
|
|
/*
|
|
* Create a row selection listener to enable/disable the prioritize
|
|
* folder and prioritize case buttons.
|
|
*/
|
|
pendingTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
|
|
if (e.getValueIsAdjusting()) {
|
|
return;
|
|
}
|
|
int row = pendingTable.getSelectedRow();
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Sets up the JTable that presents a view of the running jobs list for an
|
|
* auto ingest cluster.
|
|
*/
|
|
private void initRunningJobsTable() {
|
|
/*
|
|
* Remove some of the jobs table model columns from the JTable. This
|
|
* does not remove the columns from the model, just from this table.
|
|
*/
|
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CREATED_TIME.getColumnHeader()));
|
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STARTED_TIME.getColumnHeader()));
|
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.COMPLETED_TIME.getColumnHeader()));
|
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
|
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
|
|
|
|
/*
|
|
* Set up a column to display the cases associated with the jobs.
|
|
*/
|
|
TableColumn column;
|
|
column = runningTable.getColumn(JobsTableModelColumns.CASE.getColumnHeader());
|
|
column.setMinWidth(GENERIC_COL_MIN_WIDTH);
|
|
column.setMaxWidth(GENERIC_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(RUNNING_TABLE_COL_PREFERRED_WIDTH);
|
|
column.setWidth(RUNNING_TABLE_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the image folders associated with the
|
|
* jobs.
|
|
*/
|
|
column = runningTable.getColumn(JobsTableModelColumns.DATA_SOURCE.getColumnHeader());
|
|
column.setMinWidth(GENERIC_COL_MIN_WIDTH);
|
|
column.setMaxWidth(GENERIC_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(RUNNING_TABLE_COL_PREFERRED_WIDTH);
|
|
column.setWidth(RUNNING_TABLE_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the host names of the cluster nodes
|
|
* processing the jobs.
|
|
*/
|
|
column = runningTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader());
|
|
column.setMinWidth(NAME_COL_MIN_WIDTH);
|
|
column.setMaxWidth(NAME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(NAME_COL_PREFERRED_WIDTH);
|
|
column.setWidth(NAME_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the ingest activities associated with the
|
|
* jobs.
|
|
*/
|
|
column = runningTable.getColumn(JobsTableModelColumns.STAGE.getColumnHeader());
|
|
column.setMinWidth(ACTIVITY_COL_MIN_WIDTH);
|
|
column.setMaxWidth(ACTIVITY_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(ACTIVITY_COL_PREFERRED_WIDTH);
|
|
column.setWidth(ACTIVITY_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the ingest activity times associated with
|
|
* the jobs.
|
|
*/
|
|
column = runningTable.getColumn(JobsTableModelColumns.STAGE_TIME.getColumnHeader());
|
|
column.setCellRenderer(new DurationCellRenderer());
|
|
column.setMinWidth(GENERIC_COL_MIN_WIDTH);
|
|
column.setMaxWidth(ACTIVITY_TIME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(ACTIVITY_TIME_COL_MIN_WIDTH);
|
|
column.setWidth(ACTIVITY_TIME_COL_MIN_WIDTH);
|
|
|
|
/*
|
|
* Prevent sorting when a column header is clicked.
|
|
*/
|
|
runningTable.setAutoCreateRowSorter(false);
|
|
}
|
|
|
|
/**
|
|
* Sets up the JTable that presents a view of the completed jobs list for an
|
|
* auto ingest cluster.
|
|
*/
|
|
private void initCompletedJobsTable() {
|
|
/*
|
|
* Remove some of the jobs table model columns from the JTable. This
|
|
* does not remove the columns from the model, just from this table.
|
|
*/
|
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.STARTED_TIME.getColumnHeader()));
|
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.STAGE.getColumnHeader()));
|
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.STAGE_TIME.getColumnHeader()));
|
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader()));
|
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
|
|
|
|
/*
|
|
* Set up a column to display the cases associated with the jobs.
|
|
*/
|
|
TableColumn column;
|
|
column = completedTable.getColumn(JobsTableModelColumns.CASE.getColumnHeader());
|
|
column.setMinWidth(COMPLETED_TIME_COL_MIN_WIDTH);
|
|
column.setMaxWidth(COMPLETED_TIME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(COMPLETED_TIME_COL_PREFERRED_WIDTH);
|
|
column.setWidth(COMPLETED_TIME_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the image folders associated with the
|
|
* jobs.
|
|
*/
|
|
column = completedTable.getColumn(JobsTableModelColumns.DATA_SOURCE.getColumnHeader());
|
|
column.setMinWidth(COMPLETED_TIME_COL_MIN_WIDTH);
|
|
column.setMaxWidth(COMPLETED_TIME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(COMPLETED_TIME_COL_PREFERRED_WIDTH);
|
|
column.setWidth(COMPLETED_TIME_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the create times of the jobs.
|
|
*/
|
|
column = completedTable.getColumn(JobsTableModelColumns.CREATED_TIME.getColumnHeader());
|
|
column.setCellRenderer(new LongDateCellRenderer());
|
|
column.setMinWidth(TIME_COL_MIN_WIDTH);
|
|
column.setMaxWidth(TIME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(TIME_COL_PREFERRED_WIDTH);
|
|
column.setWidth(TIME_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the completed times of the jobs.
|
|
*/
|
|
column = completedTable.getColumn(JobsTableModelColumns.COMPLETED_TIME.getColumnHeader());
|
|
column.setCellRenderer(new LongDateCellRenderer());
|
|
column.setMinWidth(TIME_COL_MIN_WIDTH);
|
|
column.setMaxWidth(TIME_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(TIME_COL_PREFERRED_WIDTH);
|
|
column.setWidth(TIME_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Set up a column to display the statuses of the jobs, with a cell
|
|
* renderer that will choose an icon to represent the job status.
|
|
*/
|
|
column = completedTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader());
|
|
column.setCellRenderer(new CaseStatusIconCellRenderer());
|
|
column.setMinWidth(STATUS_COL_MIN_WIDTH);
|
|
column.setMaxWidth(STATUS_COL_MAX_WIDTH);
|
|
column.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH);
|
|
column.setWidth(STATUS_COL_PREFERRED_WIDTH);
|
|
|
|
/*
|
|
* Prevent sorting when a column header is clicked.
|
|
*/
|
|
completedTable.setAutoCreateRowSorter(false);
|
|
|
|
/*
|
|
* Create a row selection listener to enable/disable the delete case and
|
|
* show log buttons.
|
|
*/
|
|
completedTable.getSelectionModel()
|
|
.addListSelectionListener((ListSelectionEvent e) -> {
|
|
if (e.getValueIsAdjusting()) {
|
|
return;
|
|
}
|
|
int row = completedTable.getSelectedRow();
|
|
boolean enabled = row >= 0 && row < completedTable.getRowCount();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Starts up the auto ingest monitor and adds this panel as an observer,
|
|
* subscribes to services monitor events and starts a task to populate the
|
|
* auto ingest job tables.
|
|
*/
|
|
private void startUp() throws AutoIngestMonitor.AutoIngestMonitorException {
|
|
autoIngestMonitor = AutoIngestMonitor.createMonitor();
|
|
autoIngestMonitor.addObserver(this);
|
|
updateExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(UPDATE_TASKS_THREAD_NAME).build());
|
|
updateExecutor.submit(new GetJobsSnapshotTask());
|
|
ServicesMonitor.getInstance().addSubscriber((PropertyChangeEvent evt) -> {
|
|
setServicesStatusMessage();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void update(Observable observable, Object argument) {
|
|
updateExecutor.submit(new GetJobsSnapshotTask());
|
|
}
|
|
|
|
/**
|
|
* Reloads the table models using a jobs snapshot and refreshes the JTables
|
|
* that use the models.
|
|
*
|
|
* @param jobsSnapshot The jobs snapshot.
|
|
*/
|
|
private void refreshTables(JobsSnapshot jobsSnapshot) {
|
|
List<AutoIngestJob> pendingJobs = jobsSnapshot.getPendingJobs();
|
|
List<AutoIngestJob> runningJobs = jobsSnapshot.getRunningJobs();
|
|
List<AutoIngestJob> completedJobs = jobsSnapshot.getCompletedJobs();
|
|
// DLG: Do the appropriate sorts.
|
|
refreshTable(pendingJobs, pendingTable, pendingTableModel);
|
|
refreshTable(runningJobs, runningTable, runningTableModel);
|
|
refreshTable(completedJobs, completedTable, completedTableModel);
|
|
}
|
|
|
|
/**
|
|
* Reloads the table model for an auto ingest jobs table and refreshes the
|
|
* JTable that uses the model.
|
|
*
|
|
* @param jobs The list of auto ingest jobs.
|
|
* @param tableModel The table model.
|
|
* @param comparator An optional comparator (may be null) for sorting the
|
|
* table model.
|
|
*/
|
|
private void refreshTable(List<AutoIngestJob> jobs, JTable table, DefaultTableModel tableModel) {
|
|
try {
|
|
Path currentRow = getSelectedEntry(table, tableModel);
|
|
tableModel.setRowCount(0);
|
|
for (AutoIngestJob job : jobs) {
|
|
if (job.getNodeData().getVersion() < 2) {
|
|
// Ignore version '1' nodes since they don't carry enough
|
|
// data to populate the table.
|
|
continue;
|
|
}
|
|
AutoIngestJob.StageDetails status = job.getStageDetails();
|
|
ManifestNodeData nodeData = job.getNodeData();
|
|
tableModel.addRow(new Object[]{
|
|
nodeData.getCaseName(), // CASE
|
|
nodeData.getDataSourcePath().getFileName(), // DATA_SOURCE
|
|
job.getNodeName(), // HOST_NAME
|
|
nodeData.getManifestFileDate(), // CREATED_TIME
|
|
job.getStageStartDate(), // STARTED_TIME
|
|
nodeData.getCompletedDate(), // COMPLETED_TIME
|
|
status.getDescription(), // ACTIVITY
|
|
nodeData.getErrorsOccurred(), // STATUS
|
|
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME
|
|
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
|
|
nodeData.getManifestFilePath()}); // MANIFEST_FILE_PATH
|
|
}
|
|
setSelectedEntry(table, tableModel, currentRow);
|
|
} catch (Exception ex) {
|
|
logger.log(Level.SEVERE, "Error refreshing table " + table.toString(), ex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets a path representing the current selection in a table.
|
|
*
|
|
* @param table The table.
|
|
* @param tableModel The table model of the table.
|
|
*
|
|
* @return A path representing the current selection, or null if there is no
|
|
* selection.
|
|
*/
|
|
Path getSelectedEntry(JTable table, DefaultTableModel tableModel) {
|
|
try {
|
|
int currentlySelectedRow = table.getSelectedRow();
|
|
if (currentlySelectedRow >= 0 && currentlySelectedRow < table.getRowCount()) {
|
|
return Paths.get(tableModel.getValueAt(currentlySelectedRow, JobsTableModelColumns.CASE.ordinal()).toString(),
|
|
tableModel.getValueAt(currentlySelectedRow, JobsTableModelColumns.DATA_SOURCE.ordinal()).toString());
|
|
}
|
|
} catch (Exception ignored) {
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the selection of the table to the passed-in path's item, if that
|
|
* item exists in the table. If it does not, clears the table selection.
|
|
*
|
|
* @param table The table.
|
|
* @param tableModel The table model of the table.
|
|
* @param path The path of the item to set
|
|
*/
|
|
void setSelectedEntry(JTable table, DefaultTableModel tableModel, Path path) {
|
|
if (path != null) {
|
|
try {
|
|
for (int row = 0; row < table.getRowCount(); ++row) {
|
|
Path temp = Paths.get(tableModel.getValueAt(row, JobsTableModelColumns.CASE.ordinal()).toString(),
|
|
tableModel.getValueAt(row, JobsTableModelColumns.DATA_SOURCE.ordinal()).toString());
|
|
if (temp.compareTo(path) == 0) { // found it
|
|
table.setRowSelectionInterval(row, row);
|
|
return;
|
|
}
|
|
}
|
|
} catch (Exception ignored) {
|
|
table.clearSelection();
|
|
}
|
|
}
|
|
table.clearSelection();
|
|
}
|
|
|
|
/*
|
|
* The enum is used in conjunction with the DefaultTableModel class to
|
|
* provide table models for the JTables used to display a view of the
|
|
* pending jobs queue, running jobs list, and completed jobs list for an
|
|
* auto ingest cluster. The enum allows the columns of the table model to be
|
|
* described by either an enum ordinal or a column header string.
|
|
*/
|
|
private enum JobsTableModelColumns {
|
|
|
|
// DLG: Go through the bundles.properties file and delete and unused key-value pairs.
|
|
CASE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Case")),
|
|
DATA_SOURCE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ImageFolder")),
|
|
HOST_NAME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.HostName")),
|
|
CREATED_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CreatedTime")),
|
|
STARTED_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.StartedTime")),
|
|
COMPLETED_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CompletedTime")),
|
|
STAGE(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Stage")),
|
|
STAGE_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime")),
|
|
STATUS(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Status")),
|
|
CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder")),
|
|
MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath"));
|
|
|
|
private final String header;
|
|
|
|
private JobsTableModelColumns(String header) {
|
|
this.header = header;
|
|
}
|
|
|
|
private String getColumnHeader() {
|
|
return header;
|
|
}
|
|
|
|
private static final String[] headers = {
|
|
CASE.getColumnHeader(),
|
|
DATA_SOURCE.getColumnHeader(),
|
|
HOST_NAME.getColumnHeader(),
|
|
CREATED_TIME.getColumnHeader(),
|
|
STARTED_TIME.getColumnHeader(),
|
|
COMPLETED_TIME.getColumnHeader(),
|
|
STAGE.getColumnHeader(),
|
|
STATUS.getColumnHeader(),
|
|
STAGE_TIME.getColumnHeader(),
|
|
CASE_DIRECTORY_PATH.getColumnHeader(),
|
|
MANIFEST_FILE_PATH.getColumnHeader()};
|
|
}
|
|
|
|
/**
|
|
* A task that gets the current snapshot of the pending, running and
|
|
* completed auto ingest jobs lists for an auto ingest cluster from the auto
|
|
* ingest monitor, sorts them, and queues a UI components refresh task for
|
|
* execution in the EDT.
|
|
*/
|
|
private class GetJobsSnapshotTask implements Runnable {
|
|
|
|
@Override
|
|
public void run() {
|
|
AutoIngestMonitor.JobsSnapshot jobsSnapshot = autoIngestMonitor.getJobsSnapshot();
|
|
List<AutoIngestJob> pendingJobs = jobsSnapshot.getPendingJobs();
|
|
List<AutoIngestJob> runningJobs = jobsSnapshot.getRunningJobs();
|
|
List<AutoIngestJob> completedJobs = jobsSnapshot.getCompletedJobs();
|
|
// DLG: Do the appropriate sorts in this background task.
|
|
EventQueue.invokeLater(new RefreshComponentsTask(pendingJobs, runningJobs, completedJobs));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A task that refreshes the UI components on this panel to reflect a
|
|
* snapshot of the pending, running and completed auto ingest jobs lists of
|
|
* an auto ingest cluster.
|
|
*/
|
|
private class RefreshComponentsTask implements Runnable {
|
|
|
|
private final List<AutoIngestJob> pendingJobs;
|
|
private final List<AutoIngestJob> runningJobs;
|
|
private final List<AutoIngestJob> completedJobs;
|
|
|
|
/**
|
|
* Constructs a task that refreshes the UI components on this panel to
|
|
* reflect a snapshot of the pending, running and completed auto ingest
|
|
* jobs lists of an auto ingest cluster.
|
|
*
|
|
* @param pendingJobs The pending jobs list.
|
|
* @param runningJobs The running jobs list.
|
|
* @param completedJobs The completed jobs list.
|
|
*/
|
|
RefreshComponentsTask(List<AutoIngestJob> pendingJobs, List<AutoIngestJob> runningJobs, List<AutoIngestJob> completedJobs) {
|
|
this.pendingJobs = pendingJobs;
|
|
this.runningJobs = runningJobs;
|
|
this.completedJobs = completedJobs;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
refreshTable(pendingJobs, pendingTable, pendingTableModel);
|
|
refreshTable(runningJobs, runningTable, runningTableModel);
|
|
refreshTable(completedJobs, completedTable, completedTableModel);
|
|
refreshButton.setEnabled(true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Exception type thrown when there is an error completing an auto ingest
|
|
* dashboard operation.
|
|
*/
|
|
static final class AutoIngestDashboardException extends Exception {
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
/**
|
|
* Constructs an instance of the exception type thrown when there is an
|
|
* error completing an auto ingest dashboard operation.
|
|
*
|
|
* @param message The exception message.
|
|
*/
|
|
private AutoIngestDashboardException(String message) {
|
|
super(message);
|
|
}
|
|
|
|
/**
|
|
* Constructs an instance of the exception type thrown when there is an
|
|
* error completing an auto ingest dashboard operation.
|
|
*
|
|
* @param message The exception message.
|
|
* @param cause A Throwable cause for the error.
|
|
*/
|
|
private AutoIngestDashboardException(String message, Throwable cause) {
|
|
super(message, cause);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* This method is called from within the constructor to initialize the form.
|
|
* WARNING: Do NOT modify this code. The content of this method is always
|
|
* regenerated by the Form Editor.
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
|
private void initComponents() {
|
|
|
|
pendingScrollPane = new javax.swing.JScrollPane();
|
|
pendingTable = new javax.swing.JTable();
|
|
runningScrollPane = new javax.swing.JScrollPane();
|
|
runningTable = new javax.swing.JTable();
|
|
completedScrollPane = new javax.swing.JScrollPane();
|
|
completedTable = new javax.swing.JTable();
|
|
lbPending = new javax.swing.JLabel();
|
|
lbRunning = new javax.swing.JLabel();
|
|
lbCompleted = new javax.swing.JLabel();
|
|
refreshButton = new javax.swing.JButton();
|
|
lbServicesStatus = new javax.swing.JLabel();
|
|
tbServicesStatusMessage = new javax.swing.JTextField();
|
|
prioritizeButton = new javax.swing.JButton();
|
|
|
|
pendingTable.setModel(pendingTableModel);
|
|
pendingTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.pendingTable.toolTipText")); // NOI18N
|
|
pendingTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS);
|
|
pendingTable.setRowHeight(20);
|
|
pendingTable.setSelectionModel(new DefaultListSelectionModel() {
|
|
private static final long serialVersionUID = 1L;
|
|
@Override
|
|
public void setSelectionInterval(int index0, int index1) {
|
|
if (index0 == pendingTable.getSelectedRow()) {
|
|
pendingTable.clearSelection();
|
|
} else {
|
|
super.setSelectionInterval(index0, index1);
|
|
}
|
|
}
|
|
});
|
|
pendingTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
|
pendingScrollPane.setViewportView(pendingTable);
|
|
|
|
runningTable.setModel(runningTableModel);
|
|
runningTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.runningTable.toolTipText")); // NOI18N
|
|
runningTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS);
|
|
runningTable.setRowHeight(20);
|
|
runningTable.setSelectionModel(new DefaultListSelectionModel() {
|
|
private static final long serialVersionUID = 1L;
|
|
@Override
|
|
public void setSelectionInterval(int index0, int index1) {
|
|
if (index0 == runningTable.getSelectedRow()) {
|
|
runningTable.clearSelection();
|
|
} else {
|
|
super.setSelectionInterval(index0, index1);
|
|
}
|
|
}
|
|
});
|
|
runningTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
|
runningScrollPane.setViewportView(runningTable);
|
|
|
|
completedTable.setModel(completedTableModel);
|
|
completedTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.completedTable.toolTipText")); // NOI18N
|
|
completedTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS);
|
|
completedTable.setRowHeight(20);
|
|
completedTable.setSelectionModel(new DefaultListSelectionModel() {
|
|
private static final long serialVersionUID = 1L;
|
|
@Override
|
|
public void setSelectionInterval(int index0, int index1) {
|
|
if (index0 == completedTable.getSelectedRow()) {
|
|
completedTable.clearSelection();
|
|
} else {
|
|
super.setSelectionInterval(index0, index1);
|
|
}
|
|
}
|
|
});
|
|
completedTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
|
completedScrollPane.setViewportView(completedTable);
|
|
|
|
lbPending.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
|
|
org.openide.awt.Mnemonics.setLocalizedText(lbPending, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.lbPending.text")); // NOI18N
|
|
|
|
lbRunning.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
|
|
org.openide.awt.Mnemonics.setLocalizedText(lbRunning, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.lbRunning.text")); // NOI18N
|
|
|
|
lbCompleted.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
|
|
org.openide.awt.Mnemonics.setLocalizedText(lbCompleted, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.lbCompleted.text")); // NOI18N
|
|
|
|
org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.refreshButton.text")); // NOI18N
|
|
refreshButton.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.refreshButton.toolTipText")); // NOI18N
|
|
refreshButton.setEnabled(false);
|
|
refreshButton.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
refreshButtonActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
lbServicesStatus.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
|
|
org.openide.awt.Mnemonics.setLocalizedText(lbServicesStatus, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.lbServicesStatus.text")); // NOI18N
|
|
|
|
tbServicesStatusMessage.setEditable(false);
|
|
tbServicesStatusMessage.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
|
|
tbServicesStatusMessage.setText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.text")); // NOI18N
|
|
tbServicesStatusMessage.setBorder(null);
|
|
|
|
org.openide.awt.Mnemonics.setLocalizedText(prioritizeButton, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.prioritizeButton.text")); // NOI18N
|
|
prioritizeButton.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.prioritizeButton.toolTipText")); // NOI18N
|
|
prioritizeButton.setEnabled(false);
|
|
prioritizeButton.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
prioritizeButtonActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
|
this.setLayout(layout);
|
|
layout.setHorizontalGroup(
|
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(lbPending)
|
|
.addComponent(lbCompleted)
|
|
.addComponent(lbRunning)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addComponent(lbServicesStatus)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
.addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(prioritizeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
|
.addGap(0, 0, Short.MAX_VALUE))
|
|
.addComponent(pendingScrollPane, javax.swing.GroupLayout.Alignment.TRAILING)
|
|
.addComponent(runningScrollPane)
|
|
.addComponent(completedScrollPane))
|
|
.addContainerGap())
|
|
);
|
|
layout.setVerticalGroup(
|
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
.addComponent(lbServicesStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(lbPending, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(pendingScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(lbRunning)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(lbCompleted)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addComponent(completedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
.addComponent(refreshButton)
|
|
.addComponent(prioritizeButton))
|
|
.addContainerGap())
|
|
);
|
|
}// </editor-fold>//GEN-END:initComponents
|
|
|
|
/**
|
|
* Handles a click on the Refresh button. Requests a refreshed jobs snapshot
|
|
* from the auto ingest monitor and uses it to refresh the UI components of
|
|
* the panel.
|
|
*
|
|
* @param evt The button click event.
|
|
*/
|
|
private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
|
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
|
JobsSnapshot jobsSnapshot = autoIngestMonitor.refreshJobsSnapshot();
|
|
refreshTables(jobsSnapshot);
|
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
}//GEN-LAST:event_refreshButtonActionPerformed
|
|
|
|
private void prioritizeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prioritizeButtonActionPerformed
|
|
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
|
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
|
Path manifestFilePath = (Path) (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal()));
|
|
JobsSnapshot jobsSnapshot;
|
|
try {
|
|
jobsSnapshot = autoIngestMonitor.prioritizeJob(manifestFilePath);
|
|
refreshTables(jobsSnapshot);
|
|
} catch (AutoIngestMonitor.AutoIngestMonitorException ex) {
|
|
// DLG: Log the exception and do a popup with a user-friendly
|
|
// message explaining that the operation failed
|
|
}
|
|
setCursor(Cursor.getDefaultCursor());
|
|
}
|
|
}//GEN-LAST:event_prioritizeButtonActionPerformed
|
|
|
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
|
private javax.swing.JScrollPane completedScrollPane;
|
|
private javax.swing.JTable completedTable;
|
|
private javax.swing.JLabel lbCompleted;
|
|
private javax.swing.JLabel lbPending;
|
|
private javax.swing.JLabel lbRunning;
|
|
private javax.swing.JLabel lbServicesStatus;
|
|
private javax.swing.JScrollPane pendingScrollPane;
|
|
private javax.swing.JTable pendingTable;
|
|
private javax.swing.JButton prioritizeButton;
|
|
private javax.swing.JButton refreshButton;
|
|
private javax.swing.JScrollPane runningScrollPane;
|
|
private javax.swing.JTable runningTable;
|
|
private javax.swing.JTextField tbServicesStatusMessage;
|
|
// End of variables declaration//GEN-END:variables
|
|
|
|
} |