mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
First cut at merging latest AIM
This commit is contained in:
parent
efed6a333b
commit
885aba8daf
@ -28,8 +28,6 @@ import java.util.logging.Level;
|
|||||||
* Utility for creating and checking for the existence of an automated ingest
|
* Utility for creating and checking for the existence of an automated ingest
|
||||||
* alert file. The purpose of the file is to put a marker in the case directory
|
* alert file. The purpose of the file is to put a marker in the case directory
|
||||||
* when an error or warning occurs in connection with an automated ingest job.
|
* when an error or warning occurs in connection with an automated ingest job.
|
||||||
* If there is an error creating an alert file, it is logged to the auto ingest
|
|
||||||
* system log.
|
|
||||||
*/
|
*/
|
||||||
final class AutoIngestAlertFile {
|
final class AutoIngestAlertFile {
|
||||||
|
|
||||||
@ -54,7 +52,7 @@ final class AutoIngestAlertFile {
|
|||||||
*
|
*
|
||||||
* @return True or false.
|
* @return True or false.
|
||||||
*/
|
*/
|
||||||
static void create(Path caseDirectoryPath) {
|
static void create(Path caseDirectoryPath) throws AutoIngestAlertFileException {
|
||||||
try {
|
try {
|
||||||
Files.createFile(caseDirectoryPath.resolve(ERROR_FILE_NAME));
|
Files.createFile(caseDirectoryPath.resolve(ERROR_FILE_NAME));
|
||||||
} catch (FileAlreadyExistsException ignored) {
|
} catch (FileAlreadyExistsException ignored) {
|
||||||
@ -67,15 +65,44 @@ final class AutoIngestAlertFile {
|
|||||||
* for that case.
|
* for that case.
|
||||||
*/
|
*/
|
||||||
if (!exists(caseDirectoryPath)) {
|
if (!exists(caseDirectoryPath)) {
|
||||||
AutoIngestSystemLogger.getLogger().log(Level.SEVERE, String.format("Error creating automated ingest alert file in %s", caseDirectoryPath), ex);
|
throw new AutoIngestAlertFileException(String.format("Error creating automated ingest alert file in %s", caseDirectoryPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when there is a problem creating an alert file.
|
||||||
|
*/
|
||||||
|
final static class AutoIngestAlertFileException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception to throw when there is a problem creating an
|
||||||
|
* alert file.
|
||||||
|
*
|
||||||
|
* @param message The exception message.
|
||||||
|
*/
|
||||||
|
private AutoIngestAlertFileException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception to throw when there is a problem creating an
|
||||||
|
* alert file.
|
||||||
|
*
|
||||||
|
* @param message The exception message.
|
||||||
|
* @param cause The cause of the exception, if it was an exception.
|
||||||
|
*/
|
||||||
|
private AutoIngestAlertFileException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents instantiation of this utility class.
|
* Prevents instantiation of this utility class.
|
||||||
*/
|
*/
|
||||||
private AutoIngestAlertFile() {
|
private AutoIngestAlertFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,23 +24,23 @@ import org.sleuthkit.autopsy.events.AutopsyEvent;
|
|||||||
/**
|
/**
|
||||||
* Event published when a case is deleted by the automated ingest manager.
|
* Event published when a case is deleted by the automated ingest manager.
|
||||||
*/
|
*/
|
||||||
public final class AutoIngestCaseDeletedEvent extends AutopsyEvent implements Serializable {
|
@Immutable
|
||||||
|
final class AutoIngestCaseDeletedEvent extends AutopsyEvent implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final AutoIngestManager.CaseDeletionResult result;
|
private final String caseName;
|
||||||
private final String nodeName;
|
private final String nodeName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an event that is published when a case is deleted by the
|
* Constructs an event that is published when a case is deleted by the
|
||||||
* automated ingest manager.
|
* automated ingest manager.
|
||||||
*
|
*
|
||||||
* @param result The deletion result // RJCTODO: Get rid of logical
|
* @param caseName The case name.
|
||||||
* deletion
|
|
||||||
* @param nodeName The host name of the node that deleted the case.
|
* @param nodeName The host name of the node that deleted the case.
|
||||||
*/
|
*/
|
||||||
public AutoIngestCaseDeletedEvent(AutoIngestManager.CaseDeletionResult result, String nodeName) {
|
AutoIngestCaseDeletedEvent(String caseName, String nodeName) {
|
||||||
super(AutoIngestManager.Event.CASE_DELETED.toString(), null, null);
|
super(AutoIngestManager.Event.CASE_DELETED.toString(), null, null);
|
||||||
this.result = result;
|
this.caseName = caseName;
|
||||||
this.nodeName = nodeName;
|
this.nodeName = nodeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +49,8 @@ public final class AutoIngestCaseDeletedEvent extends AutopsyEvent implements Se
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getNodeName() {
|
String getCaseName() {
|
||||||
return nodeName;
|
return caseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,8 +58,8 @@ public final class AutoIngestCaseDeletedEvent extends AutopsyEvent implements Se
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public AutoIngestManager.CaseDeletionResult getResult() {
|
String getNodeName() {
|
||||||
return result;
|
return nodeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.events.AutopsyEvent;
|
|||||||
* Event published when an automated ingest manager prioritizes all or part of a
|
* Event published when an automated ingest manager prioritizes all or part of a
|
||||||
* case.
|
* case.
|
||||||
*/
|
*/
|
||||||
public final class AutoIngestCasePrioritizedEvent extends AutopsyEvent implements Serializable {
|
public final class AutoIngestCasePrioritizedEvent extends AutopsyEvent implements Serializable { // RJCTODO: Rename to AutoIngestPrioritizationEvent
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final String caseName;
|
private final String caseName;
|
||||||
|
@ -19,67 +19,62 @@
|
|||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
|
<Component id="lbPending" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="pendingScrollPane" min="-2" pref="920" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="bnPrioritizeCase" max="32767" attributes="0"/>
|
||||||
|
<Component id="bnPrioritizeJob" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Component id="bnPause" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="lbPending" alignment="0" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
<Component id="pendingScrollPane" min="-2" pref="920" max="-2" attributes="0"/>
|
<Component id="bnRefresh" linkSize="1" min="-2" pref="100" max="-2" attributes="0"/>
|
||||||
</Group>
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<Component id="bnOptions" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
|
<Component id="bnOpenLogDir" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
|
<Component id="bnExit" linkSize="1" min="-2" pref="94" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="bnPrioritizeCase" min="-2" pref="117" max="-2" attributes="0"/>
|
<Component id="runningScrollPane" min="-2" pref="920" max="-2" attributes="0"/>
|
||||||
<Component id="bnPrioritizeFolder" min="-2" pref="117" max="-2" attributes="0"/>
|
<Component id="completedScrollPane" min="-2" pref="920" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
|
<Component id="bnCancelJob" linkSize="1" pref="117" max="32767" attributes="0"/>
|
||||||
|
<Component id="bnShowProgress" linkSize="1" pref="116" max="32767" attributes="0"/>
|
||||||
|
<Component id="bnCancelModule" linkSize="1" alignment="0" pref="117" max="32767" attributes="0"/>
|
||||||
|
<Component id="bnDeleteCase" linkSize="1" alignment="0" pref="117" max="32767" attributes="0"/>
|
||||||
|
<Component id="bnShowCaseLog" max="32767" attributes="0"/>
|
||||||
|
<Component id="bnReprocessJob" alignment="0" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Component id="lbStatus" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
<Component id="tbStatusMessage" min="-2" pref="861" max="-2" attributes="0"/>
|
||||||
<Component id="bnPause" linkSize="1" min="-2" max="-2" attributes="0"/>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
<Component id="lbCompleted" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="bnRefresh" linkSize="1" min="-2" pref="100" max="-2" attributes="0"/>
|
<Component id="lbRunning" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="bnOptions" linkSize="1" min="-2" max="-2" attributes="0"/>
|
<Component id="lbServicesStatus" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="bnOpenLogDir" linkSize="1" min="-2" max="-2" attributes="0"/>
|
<Component id="tbServicesStatusMessage" min="-2" pref="861" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
|
||||||
<Component id="bnExit" linkSize="1" min="-2" pref="94" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Component id="runningScrollPane" min="-2" pref="920" max="-2" attributes="0"/>
|
|
||||||
<Component id="completedScrollPane" min="-2" pref="920" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
|
||||||
<Component id="bnCancelJob" linkSize="1" pref="117" max="32767" attributes="0"/>
|
|
||||||
<Component id="bnShowProgress" linkSize="1" pref="116" max="32767" attributes="0"/>
|
|
||||||
<Component id="bnCancelModule" linkSize="1" alignment="0" pref="117" max="32767" attributes="0"/>
|
|
||||||
<Component id="bnDeleteCase" linkSize="1" alignment="0" pref="117" max="32767" attributes="0"/>
|
|
||||||
<Component id="bnShowCaseLog" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<Component id="lbStatus" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="tbStatusMessage" min="-2" pref="861" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Component id="lbCompleted" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="lbRunning" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
</Group>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<Component id="lbServicesStatus" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="tbServicesStatusMessage" min="-2" pref="861" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -106,7 +101,7 @@
|
|||||||
<EmptySpace min="-2" pref="82" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="82" max="-2" attributes="0"/>
|
||||||
<Component id="bnPrioritizeCase" min="-2" max="-2" attributes="0"/>
|
<Component id="bnPrioritizeCase" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="bnPrioritizeFolder" min="-2" max="-2" attributes="0"/>
|
<Component id="bnPrioritizeJob" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
@ -127,9 +122,11 @@
|
|||||||
</Group>
|
</Group>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="102" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="68" max="-2" attributes="0"/>
|
||||||
|
<Component id="bnReprocessJob" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="bnDeleteCase" linkSize="2" min="-2" max="-2" attributes="0"/>
|
<Component id="bnDeleteCase" linkSize="2" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="bnShowCaseLog" min="-2" max="-2" attributes="0"/>
|
<Component id="bnShowCaseLog" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
@ -461,5 +458,15 @@
|
|||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenLogDirActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenLogDirActionPerformed"/>
|
||||||
</Events>
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="bnReprocessJob">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestDashboard.bnReprocessJob.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnReprocessJobActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -54,10 +54,13 @@ import org.openide.LifecycleManager;
|
|||||||
import org.openide.NotifyDescriptor;
|
import org.openide.NotifyDescriptor;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
|
import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
|
||||||
|
import org.sleuthkit.autopsy.experimental.AutoIngestManager.CaseDeletionResult;
|
||||||
|
import org.sleuthkit.autopsy.experimental.AutoIngestManager.JobsSnapshot;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.OptionsDialog;
|
import org.sleuthkit.autopsy.experimental.configuration.OptionsDialog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,7 +94,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280;
|
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 String UPDATE_TASKS_THREAD_NAME = "AID-update-tasks-%d";
|
||||||
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
|
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
|
||||||
private static final Logger LOGGER = AutoIngestSystemLogger.getLogger();
|
private static final Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger();
|
||||||
private static AutoIngestDashboard instance;
|
private static AutoIngestDashboard instance;
|
||||||
private final DefaultTableModel pendingTableModel;
|
private final DefaultTableModel pendingTableModel;
|
||||||
private final DefaultTableModel runningTableModel;
|
private final DefaultTableModel runningTableModel;
|
||||||
@ -121,7 +124,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
STAGE_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime")),
|
STAGE_TIME(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.StageTime")),
|
||||||
STATUS(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Status")),
|
STATUS(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.Status")),
|
||||||
CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder")),
|
CASE_DIRECTORY_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.CaseFolder")),
|
||||||
IS_LOCAL_JOB(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.LocalJob"));
|
IS_LOCAL_JOB(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.LocalJob")),
|
||||||
|
MANIFEST_FILE_PATH(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath"));
|
||||||
|
|
||||||
private final String header;
|
private final String header;
|
||||||
|
|
||||||
@ -144,7 +148,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
STATUS.getColumnHeader(),
|
STATUS.getColumnHeader(),
|
||||||
STAGE_TIME.getColumnHeader(),
|
STAGE_TIME.getColumnHeader(),
|
||||||
CASE_DIRECTORY_PATH.getColumnHeader(),
|
CASE_DIRECTORY_PATH.getColumnHeader(),
|
||||||
IS_LOCAL_JOB.getColumnHeader()};
|
IS_LOCAL_JOB.getColumnHeader(),
|
||||||
|
MANIFEST_FILE_PATH.getColumnHeader()};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,6 +237,29 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
return null;
|
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) {
|
||||||
|
SYS_LOGGER.log(Level.SEVERE, String.format("Dashboard error getting service status for %s", service), ex);
|
||||||
|
}
|
||||||
|
return serviceStatus;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
tbServicesStatusMessage.setText(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message", caseDatabaseServerStatus, keywordSearchServiceStatus, keywordSearchServiceStatus, messagingStatus));
|
tbServicesStatusMessage.setText(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.tbServicesStatusMessage.Message", caseDatabaseServerStatus, keywordSearchServiceStatus, keywordSearchServiceStatus, messagingStatus));
|
||||||
@ -249,30 +277,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a status string for a given service.
|
* Sets up the JTable that presents a view of the system-wide pending jobs
|
||||||
*
|
* queue.
|
||||||
* @param service The service to test.
|
|
||||||
*
|
|
||||||
* @return up, down, or unknown
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the JTable that presents a view of the
|
|
||||||
*/
|
*/
|
||||||
private void initPendingJobsTable() {
|
private void initPendingJobsTable() {
|
||||||
/*
|
/*
|
||||||
@ -287,6 +293,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
||||||
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
|
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
|
||||||
pendingTable.removeColumn(pendingTable.getColumn(JobsTableModelColumns.STATUS.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.
|
* Set up a column to display the cases associated with the jobs.
|
||||||
@ -344,7 +351,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the header and columns for the running auto ingest jobs table.
|
* Sets up the JTable that presents a view of the system-wide running jobs
|
||||||
|
* list.
|
||||||
*/
|
*/
|
||||||
private void initRunningJobsTable() {
|
private void initRunningJobsTable() {
|
||||||
/*
|
/*
|
||||||
@ -357,6 +365,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader()));
|
||||||
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.getColumnHeader()));
|
||||||
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
|
||||||
|
runningTable.removeColumn(runningTable.getColumn(JobsTableModelColumns.MANIFEST_FILE_PATH.getColumnHeader()));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up a column to display the cases associated with the jobs.
|
* Set up a column to display the cases associated with the jobs.
|
||||||
@ -438,8 +447,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the header, columns, and selection listener for the completed
|
* Sets up the JTable that presents a view of the system-wide competed jobs
|
||||||
* auto ingest jobs table.
|
* list.
|
||||||
*/
|
*/
|
||||||
private void initCompletedJobsTable() {
|
private void initCompletedJobsTable() {
|
||||||
/*
|
/*
|
||||||
@ -452,6 +461,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.IS_LOCAL_JOB.getColumnHeader()));
|
||||||
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader()));
|
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.HOST_NAME.getColumnHeader()));
|
||||||
completedTable.removeColumn(completedTable.getColumn(JobsTableModelColumns.CASE_DIRECTORY_PATH.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.
|
* Set up a column to display the cases associated with the jobs.
|
||||||
@ -558,11 +568,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
* @param enable Enable/disable the buttons.
|
* @param enable Enable/disable the buttons.
|
||||||
*/
|
*/
|
||||||
private void enablePendingTableButtons(Boolean enable) {
|
private void enablePendingTableButtons(Boolean enable) {
|
||||||
// RJCTODO: Restore prioritization feature
|
bnPrioritizeCase.setEnabled(enable);
|
||||||
// bnPrioritizeCase.setEnabled(enable);
|
bnPrioritizeJob.setEnabled(enable);
|
||||||
// bnPrioritizeFolder.setEnabled(enable);
|
|
||||||
bnPrioritizeCase.setEnabled(false);
|
|
||||||
bnPrioritizeFolder.setEnabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -573,12 +580,12 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
private void startUp() {
|
private void startUp() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start up the auto ingest manager (AIM).
|
* Starts up the auto ingest manager (AIM).
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
manager.startUp();
|
manager.startUp();
|
||||||
} catch (AutoIngestManager.AutoIngestManagerStartupException ex) {
|
} catch (AutoIngestManager.AutoIngestManagerStartupException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Dashboard error starting up auto ingest", ex);
|
SYS_LOGGER.log(Level.SEVERE, "Dashboard error starting up auto ingest", ex);
|
||||||
tbStatusMessage.setText(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.AutoIngestStartupError"));
|
tbStatusMessage.setText(NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.AutoIngestStartupError"));
|
||||||
manager = null;
|
manager = null;
|
||||||
|
|
||||||
@ -594,20 +601,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Attempt to connect the AIM to any other auto ingest nodes (AINs) if
|
|
||||||
* this is a cluster.
|
|
||||||
*/
|
|
||||||
try {
|
|
||||||
manager.establishRemoteCommunications();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOGGER.log(Level.SEVERE, "Dashboard error establishing remote communications for auto ingest", ex);
|
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.AutoIngestStartupWarning.Message"),
|
|
||||||
NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.AutoIngestStartupWarning.Title"),
|
|
||||||
JOptionPane.WARNING_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Subscribe to services monitor events.
|
* Subscribe to services monitor events.
|
||||||
*/
|
*/
|
||||||
@ -621,18 +614,10 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
manager.addObserver(this);
|
manager.addObserver(this);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Populate the pending, running, and completed auto ingest tables.
|
* Populate the pending, running, and completed auto ingest job tables.
|
||||||
*/
|
*/
|
||||||
updateExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(UPDATE_TASKS_THREAD_NAME).build());
|
updateExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(UPDATE_TASKS_THREAD_NAME).build());
|
||||||
updateExecutor.submit(new UpdateAllJobsTablesTask());
|
updateExecutor.submit(new UpdateAllJobsTablesTask());
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO (RC): This does not seem right, given that the AIM does its
|
|
||||||
* first image folder scan on start up. I think it could actually delay
|
|
||||||
* the population of the auto ingest job tables, since the table refresh
|
|
||||||
* and the scan both acquire the job lists manager. Does the AIM send an
|
|
||||||
* event after a scan? Need to check this.
|
|
||||||
*/
|
|
||||||
manager.scanInputDirsNow();
|
manager.scanInputDirsNow();
|
||||||
|
|
||||||
bnPause.setEnabled(true);
|
bnPause.setEnabled(true);
|
||||||
@ -743,7 +728,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
isPaused = true;
|
isPaused = true;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case PAUSED_FOR_SYSTEM_ERROR: // RJCTODO: Consider making this more detailed again, probably not, too much maintenance and is iverkill
|
case PAUSED_FOR_SYSTEM_ERROR:
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(() -> {
|
||||||
tbStatusMessage.setText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.PauseDueToSystemError"));
|
tbStatusMessage.setText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.PauseDueToSystemError"));
|
||||||
bnOptions.setEnabled(true);
|
bnOptions.setEnabled(true);
|
||||||
@ -777,9 +762,9 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
* running, and that the auto ingest manager will not actually pause until
|
* running, and that the auto ingest manager will not actually pause until
|
||||||
* the current auto ingest job completes.
|
* the current auto ingest job completes.
|
||||||
*
|
*
|
||||||
* @param buttonClicked Is this pause requests in response to a user gesture
|
* @param buttonClicked Is this pause request in response to a user gesture
|
||||||
* or a nofification from the auto ingest manager
|
* or a nofification from the auto ingest manager
|
||||||
* (AMI)?
|
* (AIM)?
|
||||||
*/
|
*/
|
||||||
private void pause(boolean buttonClicked) {
|
private void pause(boolean buttonClicked) {
|
||||||
/**
|
/**
|
||||||
@ -1058,15 +1043,16 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
job.getNodeName(), // HOST_NAME
|
job.getNodeName(), // HOST_NAME
|
||||||
job.getManifest().getDateFileCreated(), // CREATED_TIME
|
job.getManifest().getDateFileCreated(), // CREATED_TIME
|
||||||
job.getStageStartDate(), // STARTED_TIME
|
job.getStageStartDate(), // STARTED_TIME
|
||||||
job.getStageStartDate(), // COMPLETED_TIME
|
job.getCompletedDate(), // COMPLETED_TIME
|
||||||
status.getDescription(), // ACTIVITY
|
status.getDescription(), // ACTIVITY
|
||||||
(null != job.getCaseDirectoryPath()) ? AutoIngestAlertFile.exists(job.getCaseDirectoryPath()) : false, // STATUS // RJCTODO: awkward?
|
job.hasErrors(), // STATUS
|
||||||
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME
|
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME
|
||||||
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH // RJCTODO: What about nulls?
|
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
|
||||||
job.getNodeName().equals(LOCAL_HOST_NAME)}); // IS_LOCAL_JOB // RJCTODO: move method that also does this
|
job.getNodeName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB
|
||||||
|
job.getManifest().getFilePath()}); // MANIFEST_FILE_PATH
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Dashboard error refreshing table", ex); // NON-NLS // RJCTODO: Consider AID log
|
SYS_LOGGER.log(Level.SEVERE, "Dashboard error refreshing table", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1100,10 +1086,11 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
bnShowCaseLog = new javax.swing.JButton();
|
bnShowCaseLog = new javax.swing.JButton();
|
||||||
tbStatusMessage = new javax.swing.JTextField();
|
tbStatusMessage = new javax.swing.JTextField();
|
||||||
lbStatus = new javax.swing.JLabel();
|
lbStatus = new javax.swing.JLabel();
|
||||||
bnPrioritizeFolder = new javax.swing.JButton();
|
bnPrioritizeJob = new javax.swing.JButton();
|
||||||
lbServicesStatus = new javax.swing.JLabel();
|
lbServicesStatus = new javax.swing.JLabel();
|
||||||
tbServicesStatusMessage = new javax.swing.JTextField();
|
tbServicesStatusMessage = new javax.swing.JTextField();
|
||||||
bnOpenLogDir = new javax.swing.JButton();
|
bnOpenLogDir = new javax.swing.JButton();
|
||||||
|
bnReprocessJob = new javax.swing.JButton();
|
||||||
|
|
||||||
pendingTable.setModel(pendingTableModel);
|
pendingTable.setModel(pendingTableModel);
|
||||||
pendingTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.pendingTable.toolTipText")); // NOI18N
|
pendingTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.pendingTable.toolTipText")); // NOI18N
|
||||||
@ -1257,11 +1244,11 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
lbStatus.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
|
lbStatus.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(lbStatus, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.lbStatus.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(lbStatus, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.lbStatus.text")); // NOI18N
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(bnPrioritizeFolder, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.bnPrioritizeFolder.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(bnPrioritizeJob, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.bnPrioritizeJob.text")); // NOI18N
|
||||||
bnPrioritizeFolder.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.bnPrioritizeFolder.toolTipText")); // NOI18N
|
bnPrioritizeJob.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.bnPrioritizeJob.toolTipText")); // NOI18N
|
||||||
bnPrioritizeFolder.addActionListener(new java.awt.event.ActionListener() {
|
bnPrioritizeJob.addActionListener(new java.awt.event.ActionListener() {
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
bnPrioritizeFolderActionPerformed(evt);
|
bnPrioritizeJobActionPerformed(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1280,6 +1267,13 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(bnReprocessJob, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.bnReprocessJob.text")); // NOI18N
|
||||||
|
bnReprocessJob.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
bnReprocessJobActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -1287,53 +1281,50 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
|
.addComponent(lbPending, javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(pendingScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(bnPrioritizeCase, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(bnPrioritizeJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addComponent(bnPause)
|
||||||
.addComponent(lbPending, javax.swing.GroupLayout.Alignment.LEADING)
|
.addGap(18, 18, 18)
|
||||||
.addComponent(pendingScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(bnRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addGap(18, 18, 18)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(bnOptions)
|
||||||
.addComponent(bnPrioritizeCase, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addGap(18, 18, 18)
|
||||||
.addComponent(bnPrioritizeFolder, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(bnOpenLogDir)
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addComponent(bnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGap(50, 50, 50)
|
.addComponent(completedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addComponent(bnPause)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addGap(50, 50, 50)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
.addComponent(bnRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(bnCancelJob, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
|
||||||
.addGap(50, 50, 50)
|
.addComponent(bnShowProgress, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
|
||||||
.addComponent(bnOptions)
|
.addComponent(bnCancelModule, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
|
||||||
.addGap(50, 50, 50)
|
.addComponent(bnDeleteCase, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
|
||||||
.addComponent(bnOpenLogDir)
|
.addComponent(bnShowCaseLog, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addGap(50, 50, 50)
|
.addComponent(bnReprocessJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||||
.addComponent(bnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addComponent(lbStatus)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(tbStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addComponent(completedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(lbCompleted)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addComponent(lbRunning)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(bnCancelJob, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
|
.addComponent(lbServicesStatus)
|
||||||
.addComponent(bnShowProgress, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(bnCancelModule, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
|
.addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
.addComponent(bnDeleteCase, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)
|
.addGap(0, 0, Short.MAX_VALUE)))
|
||||||
.addComponent(bnShowCaseLog, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
.addContainerGap())
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(lbStatus)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addComponent(tbStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
||||||
.addComponent(lbCompleted)
|
|
||||||
.addComponent(lbRunning))
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)))
|
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(lbServicesStatus)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnCancelJob, bnCancelModule, bnDeleteCase, bnExit, bnOpenLogDir, bnOptions, bnPause, bnRefresh, bnShowProgress});
|
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnCancelJob, bnCancelModule, bnDeleteCase, bnExit, bnOpenLogDir, bnOptions, bnPause, bnRefresh, bnShowProgress});
|
||||||
@ -1358,7 +1349,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
.addGap(82, 82, 82)
|
.addGap(82, 82, 82)
|
||||||
.addComponent(bnPrioritizeCase)
|
.addComponent(bnPrioritizeCase)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(bnPrioritizeFolder)))
|
.addComponent(bnPrioritizeJob)))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(lbRunning)
|
.addComponent(lbRunning)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -1374,9 +1365,11 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
.addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(102, 102, 102)
|
.addGap(68, 68, 68)
|
||||||
|
.addComponent(bnReprocessJob)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(bnDeleteCase)
|
.addComponent(bnDeleteCase)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(bnShowCaseLog))
|
.addComponent(bnShowCaseLog))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
@ -1419,55 +1412,47 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
* @param evt The button click event.
|
* @param evt The button click event.
|
||||||
*/
|
*/
|
||||||
private void bnDeleteCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDeleteCaseActionPerformed
|
private void bnDeleteCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDeleteCaseActionPerformed
|
||||||
// RJCTODO: Re-implement
|
if (completedTableModel.getRowCount() < 0 || completedTable.getSelectedRow() < 0) {
|
||||||
// if (completedTableModel.getRowCount() < 0 || completedTable.getSelectedRow() < 0) {
|
return;
|
||||||
// return;
|
}
|
||||||
// }
|
|
||||||
//
|
String caseName = (String) completedTable.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal());
|
||||||
// String caseName = (String) completedTable.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal());
|
Object[] options = {
|
||||||
// Object[] options = {
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.Delete"),
|
||||||
// org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.Delete"),
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.DoNotDelete")
|
||||||
// org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.DoNotDelete")
|
};
|
||||||
// };
|
Object[] msgContent = {org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.DeleteAreYouSure") + "\"" + caseName + "\"?"};
|
||||||
//
|
int reply = JOptionPane.showOptionDialog(this,
|
||||||
// // Add checkbox to allow user to delete images in input folder as well
|
msgContent,
|
||||||
// JCheckBox deleteInputChk = new JCheckBox("Delete input images for this case in shared input folder");
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.ConfirmDeletionHeader"),
|
||||||
// Object[] msgContent = {org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.DeleteAreYouSure") + "\"" + caseName + "\"?", deleteInputChk};
|
JOptionPane.DEFAULT_OPTION,
|
||||||
// int reply = JOptionPane.showOptionDialog(this,
|
JOptionPane.WARNING_MESSAGE,
|
||||||
// msgContent,
|
null,
|
||||||
// org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "ConfirmationDialog.ConfirmDeletionHeader"),
|
options,
|
||||||
// JOptionPane.DEFAULT_OPTION,
|
options[JOptionPane.NO_OPTION]);
|
||||||
// JOptionPane.WARNING_MESSAGE,
|
if (reply == JOptionPane.YES_OPTION) {
|
||||||
// null,
|
bnDeleteCase.setEnabled(false);
|
||||||
// options,
|
bnShowCaseLog.setEnabled(false);
|
||||||
// options[JOptionPane.NO_OPTION]);
|
if (completedTableModel.getRowCount() > 0 && completedTable.getSelectedRow() >= 0) {
|
||||||
// if (reply == JOptionPane.YES_OPTION) {
|
Path caseDirectoryPath = (Path) completedTableModel.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal());
|
||||||
// bnDeleteCase.setEnabled(false);
|
completedTable.clearSelection();
|
||||||
// bnShowCaseLog.setEnabled(false);
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
// if (completedTableModel.getRowCount() > 0 && completedTable.getSelectedRow() >= 0) {
|
CaseDeletionResult result = manager.deleteCase(caseName, caseDirectoryPath);
|
||||||
// String caseOutputFolderPath = completedTableModel.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE_FOLDER.ordinal()).toString();
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
// String caseAutFilePath = completedTableModel.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal()).toString() + CaseMetadata.getFileExtension();
|
if (CaseDeletionResult.FAILED == result) {
|
||||||
// completedTable.clearSelection();
|
JOptionPane.showMessageDialog(this,
|
||||||
// this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
String.format("Could not delete case %s. It may be in in use.", caseName),
|
||||||
// AutoIngestManager.CaseDeletionResult deletionResult = manager.deleteCase(Paths.get(caseOutputFolderPath), deleteInputChk.isSelected(), caseAutFilePath);
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.DeletionFailed"),
|
||||||
// this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
// if (deletionResult.getCaseDeletionStatus() == AutoIngestManager.CaseDeletionResult.Status.FAILED) {
|
} else if (CaseDeletionResult.PARTIALLY_DELETED == result) {
|
||||||
// JOptionPane.showMessageDialog(this, "Could not delete case " + caseName + " because it is in use",
|
JOptionPane.showMessageDialog(this,
|
||||||
// org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.DeletionFailed"), JOptionPane.INFORMATION_MESSAGE);
|
String.format("Could not delete case %s. See system log for details.", caseName),
|
||||||
// } else if (deletionResult.getCaseDeletionStatus() == AutoIngestManager.CaseDeletionResult.Status.PARTIALLY_COMPLETED) {
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.DeletionFailed"),
|
||||||
// String str = "Deleted case \"" + caseName + "\", but not all files could be deleted.\nTo delete these files, stop automated ingest and delete \n"
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
// + caseOutputFolderPath + "\nand \n" + deletionResult.getCaseImageFolderPath() + "\nif present.";
|
}
|
||||||
// JOptionPane.showMessageDialog(this, str,
|
updateExecutor.submit(new UpdateAllJobsTablesTask());
|
||||||
// org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.DeletionFailed"), JOptionPane.INFORMATION_MESSAGE);
|
}
|
||||||
// }
|
}
|
||||||
// /**
|
|
||||||
// * Need to update both the pending jobs table and the completed
|
|
||||||
// * jobs table since pending jobs for the deleted case are also
|
|
||||||
// * deleted.
|
|
||||||
// */
|
|
||||||
// updateExecutor.submit(new UpdateAllJobsTablesTask());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}//GEN-LAST:event_bnDeleteCaseActionPerformed
|
}//GEN-LAST:event_bnDeleteCaseActionPerformed
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1583,22 +1568,15 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
* @param evt The button click event.
|
* @param evt The button click event.
|
||||||
*/
|
*/
|
||||||
private void bnPrioritizeCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeCaseActionPerformed
|
private void bnPrioritizeCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeCaseActionPerformed
|
||||||
// RJCTODO: Re-implement
|
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
|
||||||
// if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
// this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
String caseName = (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal())).toString();
|
||||||
// String caseName = (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal())).toString();
|
List<AutoIngestJob> prioritizedQueue = manager.prioritizeCase(caseName);
|
||||||
// try {
|
refreshTable(prioritizedQueue, pendingTableModel, null);
|
||||||
// List<AutoIngestJob> prioritizedQueue = manager.prioritizeCase(caseName);
|
pendingTable.clearSelection();
|
||||||
// refreshTable(prioritizedQueue, pendingTableModel, null);
|
enablePendingTableButtons(false);
|
||||||
// } catch (IOException ex) {
|
AutoIngestDashboard.this.setCursor(Cursor.getDefaultCursor());
|
||||||
// logger.log(Level.SEVERE, String.format("Error while prioritizing case %s", caseName), ex);
|
}
|
||||||
// MessageNotifyUtil.Message.error("An error occurred while prioritizing the case.");
|
|
||||||
// } finally {
|
|
||||||
// pendingTable.clearSelection();
|
|
||||||
// enablePendingTableButtons(false);
|
|
||||||
// AutoIngestDashboard.this.setCursor(Cursor.getDefaultCursor());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}//GEN-LAST:event_bnPrioritizeCaseActionPerformed
|
}//GEN-LAST:event_bnPrioritizeCaseActionPerformed
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1612,16 +1590,20 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
int selectedRow = completedTable.getSelectedRow();
|
int selectedRow = completedTable.getSelectedRow();
|
||||||
if (selectedRow != -1) {
|
if (selectedRow != -1) {
|
||||||
Path caseDirectoryPath = (Path) completedTableModel.getValueAt(selectedRow, JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal());
|
Path caseDirectoryPath = (Path) completedTableModel.getValueAt(selectedRow, JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal());
|
||||||
Path pathToLog = AutoIngestJobLogger.getLogPath(caseDirectoryPath);
|
if (null != caseDirectoryPath) {
|
||||||
if (pathToLog.toFile().exists()) {
|
Path pathToLog = AutoIngestJobLogger.getLogPath(caseDirectoryPath);
|
||||||
Desktop.getDesktop().edit(pathToLog.toFile());
|
if (pathToLog.toFile().exists()) {
|
||||||
|
Desktop.getDesktop().edit(pathToLog.toFile());
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.ShowLogFailed.Message"),
|
||||||
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.ShowLogFailed.Title"), JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.ShowLogFailed.Message"),
|
MessageNotifyUtil.Message.warn("The case directory for this job has been deleted.");
|
||||||
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.ShowLogFailed.Title"), JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Dashboard error attempting to display case auto ingest log", ex);
|
SYS_LOGGER.log(Level.SEVERE, "Dashboard error attempting to display case auto ingest log", ex);
|
||||||
Object[] options = {org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "DisplayLogDialog.okay")};
|
Object[] options = {org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "DisplayLogDialog.okay")};
|
||||||
JOptionPane.showOptionDialog(this,
|
JOptionPane.showOptionDialog(this,
|
||||||
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "DisplayLogDialog.cannotFindLog"),
|
org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "DisplayLogDialog.cannotFindLog"),
|
||||||
@ -1634,25 +1616,17 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
}
|
}
|
||||||
}//GEN-LAST:event_bnShowCaseLogActionPerformed
|
}//GEN-LAST:event_bnShowCaseLogActionPerformed
|
||||||
|
|
||||||
private void bnPrioritizeFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeFolderActionPerformed
|
private void bnPrioritizeJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeJobActionPerformed
|
||||||
// RJCTODO: Re-implement
|
if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
|
||||||
// if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) {
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
// this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
Path manifestFilePath = (Path) (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal()));
|
||||||
// String caseName = (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal())).toString();
|
List<AutoIngestJob> prioritizedQueue = manager.prioritizeJob(manifestFilePath);
|
||||||
// String folderName = (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.DATA_SOURCE.ordinal())).toString();
|
refreshTable(prioritizedQueue, pendingTableModel, null);
|
||||||
// try {
|
pendingTable.clearSelection();
|
||||||
// List<AutoIngestJob> prioritizedQueue = manager.prioritizeJob(caseName, folderName);
|
enablePendingTableButtons(false);
|
||||||
// refreshTable(prioritizedQueue, pendingTableModel, null);
|
AutoIngestDashboard.this.setCursor(Cursor.getDefaultCursor());
|
||||||
// } catch (IOException ex) {
|
}
|
||||||
// logger.log(Level.SEVERE, String.format("Error while prioritizing folder %s", folderName), ex);
|
}//GEN-LAST:event_bnPrioritizeJobActionPerformed
|
||||||
// MessageNotifyUtil.Message.error("An error occurred while prioritizing the folder.");
|
|
||||||
// } finally {
|
|
||||||
// pendingTable.clearSelection();
|
|
||||||
// enablePendingTableButtons(false);
|
|
||||||
// AutoIngestDashboard.this.setCursor(Cursor.getDefaultCursor());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}//GEN-LAST:event_bnPrioritizeFolderActionPerformed
|
|
||||||
|
|
||||||
private void bnOpenLogDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenLogDirActionPerformed
|
private void bnOpenLogDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenLogDirActionPerformed
|
||||||
Path logDirPath = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath(), "var", "log");
|
Path logDirPath = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath(), "var", "log");
|
||||||
@ -1661,11 +1635,24 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
Desktop.getDesktop().open(logDir);
|
Desktop.getDesktop().open(logDir);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
|
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
|
||||||
String.format("Unable to open log directory %s:\n%s", logDirPath, ex.getLocalizedMessage()), // RJCTODO: Localize
|
String.format("Unable to open log directory %s:\n%s", logDirPath, ex.getLocalizedMessage()),
|
||||||
NotifyDescriptor.ERROR_MESSAGE));
|
NotifyDescriptor.ERROR_MESSAGE));
|
||||||
}
|
}
|
||||||
}//GEN-LAST:event_bnOpenLogDirActionPerformed
|
}//GEN-LAST:event_bnOpenLogDirActionPerformed
|
||||||
|
|
||||||
|
private void bnReprocessJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnReprocessJobActionPerformed
|
||||||
|
if (completedTableModel.getRowCount() < 0 || completedTable.getSelectedRow() < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
|
Path manifestPath = (Path) completedTableModel.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal());
|
||||||
|
JobsSnapshot jobsSnapshot = manager.reprocessJob(manifestPath);
|
||||||
|
refreshTable(jobsSnapshot.getCompletedJobs(), completedTableModel, null);
|
||||||
|
refreshTable(jobsSnapshot.getPendingJobs(), pendingTableModel, null);
|
||||||
|
refreshTable(jobsSnapshot.getRunningJobs(), runningTableModel, null);
|
||||||
|
AutoIngestDashboard.this.setCursor(Cursor.getDefaultCursor());
|
||||||
|
}//GEN-LAST:event_bnReprocessJobActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton bnCancelJob;
|
private javax.swing.JButton bnCancelJob;
|
||||||
private javax.swing.JButton bnCancelModule;
|
private javax.swing.JButton bnCancelModule;
|
||||||
@ -1675,8 +1662,9 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
|
|||||||
private javax.swing.JButton bnOptions;
|
private javax.swing.JButton bnOptions;
|
||||||
private javax.swing.JButton bnPause;
|
private javax.swing.JButton bnPause;
|
||||||
private javax.swing.JButton bnPrioritizeCase;
|
private javax.swing.JButton bnPrioritizeCase;
|
||||||
private javax.swing.JButton bnPrioritizeFolder;
|
private javax.swing.JButton bnPrioritizeJob;
|
||||||
private javax.swing.JButton bnRefresh;
|
private javax.swing.JButton bnRefresh;
|
||||||
|
private javax.swing.JButton bnReprocessJob;
|
||||||
private javax.swing.JButton bnShowCaseLog;
|
private javax.swing.JButton bnShowCaseLog;
|
||||||
private javax.swing.JButton bnShowProgress;
|
private javax.swing.JButton bnShowProgress;
|
||||||
private javax.swing.JScrollPane completedScrollPane;
|
private javax.swing.JScrollPane completedScrollPane;
|
||||||
|
@ -27,13 +27,13 @@ import java.util.Date;
|
|||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An automated ingest job auto ingest jobs associated with a manifest file. A
|
* An automated ingest job for a manifest. The manifest specifies a co-located
|
||||||
* manifest file specifies a co-located data source and a case to which the data
|
* data source and a case to which the data source is to be added.
|
||||||
* source is to be added.
|
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
||||||
@ -51,14 +51,38 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private Date stageStartDate;
|
private Date stageStartDate;
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
|
transient private DataSourceProcessor dataSourceProcessor;
|
||||||
|
@GuardedBy("this")
|
||||||
transient private IngestJob ingestJob;
|
transient private IngestJob ingestJob;
|
||||||
|
@GuardedBy("this")
|
||||||
|
transient private boolean cancelled; // RJCTODO: Document
|
||||||
|
@GuardedBy("this")
|
||||||
|
transient private boolean completed; // RJCTODO: Document
|
||||||
|
@GuardedBy("this")
|
||||||
|
private Date completedDate;
|
||||||
|
@GuardedBy("this")
|
||||||
|
private boolean errorsOccurred;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Constructs an automated ingest job for a manifest. The manifest specifies
|
||||||
|
* a co-located data source and a case to which the data source is to be
|
||||||
|
* added.
|
||||||
*
|
*
|
||||||
* @param manifest
|
* @param manifest The manifest
|
||||||
|
* @param caseDirectoryPath The path to the case directory for the job, may
|
||||||
|
* be null.
|
||||||
|
* @param priority The priority of the job. The higher the number,
|
||||||
|
* the higher the priority.
|
||||||
|
* @param nodeName If the job is in progress, the node doing the
|
||||||
|
* processing, otherwise the locla host.
|
||||||
|
* @param stage The processing stage for display purposes.
|
||||||
|
* @param completedDate The date when the job was completed. Use the
|
||||||
|
* epoch (January 1, 1970, 00:00:00 GMT) to
|
||||||
|
* indicate the the job is not completed, i.e., new
|
||||||
|
* Date(0L).
|
||||||
*/
|
*/
|
||||||
AutoIngestJob(Manifest manifest, Path caseDirectoryPath, int priority, String nodeName, Stage stage) {
|
// RJCTODO: The null case directory is error-prone and the nodeName is confusing.
|
||||||
|
AutoIngestJob(Manifest manifest, Path caseDirectoryPath, int priority, String nodeName, Stage stage, Date completedDate, boolean errorsOccurred) {
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
if (null != caseDirectoryPath) {
|
if (null != caseDirectoryPath) {
|
||||||
this.caseDirectoryPath = caseDirectoryPath.toString();
|
this.caseDirectoryPath = caseDirectoryPath.toString();
|
||||||
@ -69,12 +93,14 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
this.nodeName = nodeName;
|
this.nodeName = nodeName;
|
||||||
this.stage = stage;
|
this.stage = stage;
|
||||||
this.stageStartDate = manifest.getDateFileCreated();
|
this.stageStartDate = manifest.getDateFileCreated();
|
||||||
|
this.completedDate = completedDate;
|
||||||
|
this.errorsOccurred = errorsOccurred;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Gets the auto ingest jobmanifest.
|
||||||
*
|
*
|
||||||
* @return
|
* @return The manifest.
|
||||||
*/
|
*/
|
||||||
Manifest getManifest() {
|
Manifest getManifest() {
|
||||||
return this.manifest;
|
return this.manifest;
|
||||||
@ -86,6 +112,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
*
|
*
|
||||||
* @return True or false
|
* @return True or false
|
||||||
*/
|
*/
|
||||||
|
// RJCTODO: Use this or lose this
|
||||||
synchronized boolean hasCaseDirectoryPath() {
|
synchronized boolean hasCaseDirectoryPath() {
|
||||||
return (false == this.caseDirectoryPath.isEmpty());
|
return (false == this.caseDirectoryPath.isEmpty());
|
||||||
}
|
}
|
||||||
@ -114,14 +141,21 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the priority of the job. A higher number indicates a higher
|
||||||
|
* priority.
|
||||||
|
*
|
||||||
|
* @param priority The priority.
|
||||||
|
*/
|
||||||
synchronized void setPriority(Integer priority) {
|
synchronized void setPriority(Integer priority) {
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Gets the priority of the job. A higher number indicates a higher
|
||||||
|
* priority.
|
||||||
*
|
*
|
||||||
* @return
|
* @return The priority.
|
||||||
*/
|
*/
|
||||||
synchronized Integer getPriority() {
|
synchronized Integer getPriority() {
|
||||||
return this.priority;
|
return this.priority;
|
||||||
@ -143,11 +177,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
* @param stateStartedDate
|
* @param stateStartedDate
|
||||||
*/
|
*/
|
||||||
synchronized void setStage(Stage newState, Date stateStartedDate) {
|
synchronized void setStage(Stage newState, Date stateStartedDate) {
|
||||||
if (Stage.CANCELLED == this.stage && Stage.COMPLETED != newState) {
|
if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newState) {
|
||||||
/**
|
|
||||||
* Do not overwrite canceling status with anything other than
|
|
||||||
* completed status.
|
|
||||||
*/
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.stage = newState;
|
this.stage = newState;
|
||||||
@ -214,10 +244,12 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
return new StageDetails(description, startDate);
|
return new StageDetails(description, startDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized void setDataSourceProcessor(DataSourceProcessor dataSourceProcessor) {
|
||||||
|
this.dataSourceProcessor = dataSourceProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* RJCTODO
|
||||||
*
|
|
||||||
* @param ingestStatus
|
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Consider moving this class into AIM and making this private
|
// RJCTODO: Consider moving this class into AIM and making this private
|
||||||
synchronized void setIngestJob(IngestJob ingestJob) {
|
synchronized void setIngestJob(IngestJob ingestJob) {
|
||||||
@ -226,8 +258,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* RJCTODO
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Consider moving this class into AIM and making this private.
|
// RJCTODO: Consider moving this class into AIM and making this private.
|
||||||
// Or move the AID into a separate package. Or do not worry about it.
|
// Or move the AID into a separate package. Or do not worry about it.
|
||||||
@ -235,6 +265,83 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
return this.ingestJob;
|
return this.ingestJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RJCTODO
|
||||||
|
*/
|
||||||
|
synchronized void cancel() {
|
||||||
|
setStage(Stage.CANCELLING);
|
||||||
|
cancelled = true;
|
||||||
|
errorsOccurred = true;
|
||||||
|
if (null != dataSourceProcessor) {
|
||||||
|
dataSourceProcessor.cancel();
|
||||||
|
}
|
||||||
|
if (null != ingestJob) {
|
||||||
|
ingestJob.cancel(IngestJob.CancellationReason.USER_CANCELLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RJCTODO
|
||||||
|
*/
|
||||||
|
synchronized boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RJCTODO
|
||||||
|
*/
|
||||||
|
synchronized void setCompleted() {
|
||||||
|
setStage(Stage.COMPLETED);
|
||||||
|
completed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RJCTODO
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
synchronized boolean isCompleted() {
|
||||||
|
return completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the date the job was completed, with or without cancellation or
|
||||||
|
* errors.
|
||||||
|
*
|
||||||
|
* @param completedDate The completion date.
|
||||||
|
*/
|
||||||
|
synchronized void setCompletedDate(Date completedDate) {
|
||||||
|
this.completedDate = completedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the date the job was completed, with or without cancellation or
|
||||||
|
* errors.
|
||||||
|
*
|
||||||
|
* @return True or false.
|
||||||
|
*/
|
||||||
|
synchronized Date getCompletedDate() {
|
||||||
|
return completedDate; // RJCTODO: Consider returning null if == 0 (epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not erros occurred during the processing of the job.
|
||||||
|
*
|
||||||
|
* @param errorsOccurred True or false;
|
||||||
|
*/
|
||||||
|
synchronized void setErrorsOccurred(boolean errorsOccurred) {
|
||||||
|
this.errorsOccurred = errorsOccurred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries whether or not erros occurred during the processing of the job.
|
||||||
|
*
|
||||||
|
* @return True or false.
|
||||||
|
*/
|
||||||
|
synchronized boolean hasErrors() {
|
||||||
|
return this.errorsOccurred;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO Gets name of the node associated with the job, possibly a remote
|
* RJCTODO Gets name of the node associated with the job, possibly a remote
|
||||||
* hose if the job is in progress.
|
* hose if the job is in progress.
|
||||||
@ -309,30 +416,21 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom comparator that sorts the pending list with prioritized cases
|
* Comparator that sorts auto ingest jobs by priority in descending order.
|
||||||
* first, then nonprioritized cases. Prioritized cases are last in, first
|
|
||||||
* out. Nonprioritized cases are first in, first out. Prioritized times are
|
|
||||||
* from the creation time of the "prioritized" state file. Non prioritized
|
|
||||||
* are from the folder creation time.
|
|
||||||
*/
|
*/
|
||||||
public static class PriorityComparator implements Comparator<AutoIngestJob> {
|
public static class PriorityComparator implements Comparator<AutoIngestJob> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* RJCTODO
|
||||||
*
|
*
|
||||||
* @param o1
|
* @param job
|
||||||
* @param o2
|
* @param anotherJob
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
|
public int compare(AutoIngestJob job, AutoIngestJob anotherJob) {
|
||||||
Integer result = o1.getPriority().compareTo(o2.getPriority());
|
return -(job.getPriority().compareTo(anotherJob.getPriority()));
|
||||||
if (0 != result) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return o1.getManifest().getDateFileCreated().compareTo(o2.getManifest().getDateFileCreated());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -364,6 +462,10 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RJCTODO
|
||||||
|
*/
|
||||||
|
// RJCTODO: Combine this enum with StageDetails to make a single class.
|
||||||
enum Stage {
|
enum Stage {
|
||||||
|
|
||||||
PENDING("Pending"),
|
PENDING("Pending"),
|
||||||
@ -377,8 +479,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
ANALYZING_FILES("Analyzing files"),
|
ANALYZING_FILES("Analyzing files"),
|
||||||
EXPORTING_FILES("Exporting files"),
|
EXPORTING_FILES("Exporting files"),
|
||||||
CANCELLING_MODULE("Cancelling module"),
|
CANCELLING_MODULE("Cancelling module"),
|
||||||
CANCELLED("Cancelled"),
|
CANCELLING("Cancelling"),
|
||||||
INTERRUPTED("Cancelled"),
|
|
||||||
COMPLETED("Completed");
|
COMPLETED("Completed");
|
||||||
|
|
||||||
private final String displayText;
|
private final String displayText;
|
||||||
|
@ -28,7 +28,6 @@ import java.nio.file.Paths;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService;
|
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService;
|
||||||
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.Lock;
|
import org.sleuthkit.autopsy.experimental.coordinationservice.CoordinationService.Lock;
|
||||||
@ -59,6 +58,7 @@ final class AutoIngestJobLogger {
|
|||||||
private static final String DATE_FORMAT_STRING = "yyyy/MM/dd HH:mm:ss";
|
private static final String DATE_FORMAT_STRING = "yyyy/MM/dd HH:mm:ss";
|
||||||
private static final SimpleDateFormat logDateFormat = new SimpleDateFormat(DATE_FORMAT_STRING);
|
private static final SimpleDateFormat logDateFormat = new SimpleDateFormat(DATE_FORMAT_STRING);
|
||||||
private final Path manifestPath;
|
private final Path manifestPath;
|
||||||
|
private final String manifestFileName;
|
||||||
private final String dataSourceFileName;
|
private final String dataSourceFileName;
|
||||||
private final Path caseDirectoryPath;
|
private final Path caseDirectoryPath;
|
||||||
private final String hostName;
|
private final String hostName;
|
||||||
@ -73,7 +73,7 @@ final class AutoIngestJobLogger {
|
|||||||
*/
|
*/
|
||||||
INFO,
|
INFO,
|
||||||
/**
|
/**
|
||||||
* Qualifies a log message about an unexpected event or condition during
|
* Qualifies a log message about an unexpected event or condtion during
|
||||||
* automated ingest processing.
|
* automated ingest processing.
|
||||||
*/
|
*/
|
||||||
WARNING,
|
WARNING,
|
||||||
@ -111,6 +111,7 @@ final class AutoIngestJobLogger {
|
|||||||
*/
|
*/
|
||||||
AutoIngestJobLogger(Path manifestPath, String dataSourceFileName, Path caseDirectoryPath) {
|
AutoIngestJobLogger(Path manifestPath, String dataSourceFileName, Path caseDirectoryPath) {
|
||||||
this.manifestPath = manifestPath;
|
this.manifestPath = manifestPath;
|
||||||
|
manifestFileName = manifestPath.getFileName().toString();
|
||||||
this.dataSourceFileName = dataSourceFileName;
|
this.dataSourceFileName = dataSourceFileName;
|
||||||
this.caseDirectoryPath = caseDirectoryPath;
|
this.caseDirectoryPath = caseDirectoryPath;
|
||||||
hostName = NetworkUtils.getLocalHostName();
|
hostName = NetworkUtils.getLocalHostName();
|
||||||
@ -119,151 +120,146 @@ final class AutoIngestJobLogger {
|
|||||||
/**
|
/**
|
||||||
* Logs the cancellation of an auto ingest job during processing.
|
* Logs the cancellation of an auto ingest job during processing.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logJobCancelled() throws InterruptedException {
|
void logJobCancelled() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, "Auto ingest job cancelled during processing");
|
log(MessageCategory.WARNING, "Auto ingest job cancelled during processing");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the presence of a manifest file without a matching data source.
|
* Logs the presence of a manifest file without a matching data source.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logMissingDataSource() throws InterruptedException {
|
void logMissingDataSource() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, "Data source file not found"); // RJCTODO: Check for this
|
log(MessageCategory.ERROR, "Data source file not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs an error identifying the type of a data source.
|
* Logs a failure to extract an archived data source.
|
||||||
*
|
*
|
||||||
* @param dataSource The data source.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* @param errorMessage The error.
|
* message.
|
||||||
*
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* to acquire an exclusive lock on the
|
||||||
* acquire an exclusive lock on the log file
|
* log file.
|
||||||
* path.
|
|
||||||
*/
|
*/
|
||||||
void logDataSourceTypeIdError(String errorMessage) throws InterruptedException {
|
void logFailedToExtractDataSource() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, String.format("Error identifying data source type: %s", errorMessage));
|
log(MessageCategory.ERROR, "Failed to extract data source from archive");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Logs a failure to parse a Cellebrite logical report data source.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logFailedToIdentifyDataSource() throws InterruptedException {
|
void logFailedToParseLogicalReportDataSource() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, String.format("Failed to identifying data source type, cannot ingest"));
|
log(MessageCategory.ERROR, "Failed to parse Cellebrite logical report data source");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Logs a failure to identify an image data source as either a drive or
|
||||||
|
* phone image.
|
||||||
*
|
*
|
||||||
* @param dataSourceType
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
*
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceTypeId(String dataSourceType) throws InterruptedException {
|
void logFailedToIdentifyImageDataSource() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.INFO, String.format("Identified data source as %s", dataSourceType));
|
log(MessageCategory.ERROR, String.format("Failed to identifying data source as drive or phone image"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs cancellation of the addition of a data source to the case database.
|
* Logs cancellation of the addition of a data source to the case database.
|
||||||
*
|
*
|
||||||
* @param dataSourceType The data source type.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
*
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceProcessorCancelled(String dataSourceType) throws InterruptedException { // RJCTODO: Is this used now?
|
void logDataSourceProcessorCancelled() throws AutoIngestJobLoggerException, InterruptedException { // RJCTODO: Is this used now?
|
||||||
log(MessageCategory.WARNING, String.format("Cancelled adding data source to case as %s", dataSourceType));
|
log(MessageCategory.WARNING, "Cancelled adding data source to case");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the addition of a data source to the case database.
|
* Logs the addition of a data source to the case database.
|
||||||
*
|
*
|
||||||
* @param dataSourceType The data source type.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
*
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceAdded(String dataSourceType) throws InterruptedException {
|
void logDataSourceAdded() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.INFO, String.format("Added data source to case as %s", dataSourceType));
|
log(MessageCategory.INFO, "Added data source to case");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a critical error reported by a data source processor when adding a
|
* Logs an failure adding a data source to the case database.
|
||||||
* data source to the case database.
|
|
||||||
*
|
*
|
||||||
* @param dataSourceType The data source type.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* @param errorMessage The error message.
|
* message.
|
||||||
*
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* to acquire an exclusive lock on the
|
||||||
* acquire an exclusive lock on the log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceProcessorError(String dataSourceType, String errorMessage) throws InterruptedException {
|
void logFailedToAddDataSource() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, String.format("Critical error adding data source to case as %s: %s", dataSourceType, errorMessage));
|
log(MessageCategory.ERROR, "Failed to add data source to case");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a non-critical error reported by a data source processor when adding
|
* Logs failure of a data source to produce content.
|
||||||
* a data source to the case database.
|
|
||||||
*
|
*
|
||||||
* @param dataSourceType The data source type.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* @param errorMessage The error message.
|
* message.
|
||||||
*
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* to acquire an exclusive lock on the
|
||||||
* acquire an exclusive lock on the log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceProcessorWarning(String dataSourceType, String errorMessage) throws InterruptedException {
|
void logNoDataSourceContent() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, String.format("Critical error adding data source to case as %s: %s", dataSourceType, errorMessage));
|
log(MessageCategory.ERROR, "Data source failed to produce content");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs an error adding a data source to the case database.
|
* Logs failure to analyze a data source due to ingest job settings errors.
|
||||||
*
|
*
|
||||||
* @param dataSourceType The data source type.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* @param dataSource The data source.
|
* message.
|
||||||
*
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* to acquire an exclusive lock on the
|
||||||
* acquire an exclusive lock on the log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logFailedToAddDataSource(String dataSourceType) throws InterruptedException { // RJCTODO: Why this and logDataSourceProcessorError? Bd handling of critical vs. non-critical?
|
void logIngestJobSettingsErrors() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, String.format("Failed to add data source to case as %s", dataSourceType));
|
log(MessageCategory.ERROR, "Failed to analyze data source due to settings errors");
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO: Document and homogenize messages
|
|
||||||
*
|
|
||||||
* @param errors
|
|
||||||
*
|
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
|
||||||
* acquire an exclusive lock on the log file.
|
|
||||||
*/
|
|
||||||
void logIngestJobSettingsErrors(List<String> errors) throws InterruptedException {
|
|
||||||
for (String error : errors) {
|
|
||||||
log(MessageCategory.ERROR, String.format("Settings error, analysis of data source by ingest modules not started: %s", error));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs failure to analyze a data source due to ingest module startup
|
* Logs failure to analyze a data source due to ingest module startup
|
||||||
* errors.
|
* errors.
|
||||||
*
|
*
|
||||||
* @param errors The ingest module errors.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
*
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logIngestModuleStartupErrors(List<IngestModuleError> errors) throws InterruptedException {
|
void logIngestModuleStartupErrors() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
for (IngestModuleError error : errors) {
|
log(MessageCategory.ERROR, "Failed to analyze data source due to ingest module startup errors");
|
||||||
log(MessageCategory.ERROR, String.format("Analysis of data source by ingest modules not started, %s startup error: %s", error.getModuleDisplayName(), error.getThrowable().getLocalizedMessage()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,21 +268,27 @@ final class AutoIngestJobLogger {
|
|||||||
*
|
*
|
||||||
* @param ex The ingest manager exception.
|
* @param ex The ingest manager exception.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logAnalysisStartupError(IngestManagerException ex) throws InterruptedException {
|
void logAnalysisStartupError() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, String.format("Analysis of data source by ingest modules not started: %s", ex.getLocalizedMessage()));
|
log(MessageCategory.ERROR, "Failed to analyze data source due to ingest job startup error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the completion of analysis of a data source by the ingest modules.
|
* Logs the completion of analysis of a data source by the ingest modules.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logAnalysisCompleted() throws InterruptedException {
|
void logAnalysisCompleted() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.INFO, "Analysis of data source by ingest modules completed");
|
log(MessageCategory.INFO, "Analysis of data source completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -296,67 +298,79 @@ final class AutoIngestJobLogger {
|
|||||||
* @param cancelledModuleName The display name of the cancelled ingest
|
* @param cancelledModuleName The display name of the cancelled ingest
|
||||||
* module.
|
* module.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logIngestModuleCancelled(String cancelledModuleName) throws InterruptedException {
|
void logIngestModuleCancelled(String cancelledModuleName) throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, String.format("%s analysis of data source cancelled", cancelledModuleName));
|
log(MessageCategory.WARNING, String.format("%s analysis of data source cancelled", cancelledModuleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the cancellation of analysis of a data source by the ingest modules.
|
* Logs the cancellation of analysis of a data source by the ingest modules.
|
||||||
*
|
*
|
||||||
* @param reason The reason for cancellation.
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
*
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logAnalysisCancelled(String reason) throws InterruptedException {
|
void logAnalysisCancelled() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, String.format("Analysis of data source by ingest modules cancelled: %s", reason));
|
log(MessageCategory.WARNING, "Analysis of data source cancelled");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs that automated file export is not enabled.
|
* Logs that automated file export is not enabled.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logFileExportDisabled() throws InterruptedException {
|
void logFileExportDisabled() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, "Automated file export is not enabled");
|
log(MessageCategory.WARNING, "Automated file export is not enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Logs completion of file export.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logFileExportCompleted() throws InterruptedException {
|
void logFileExportCompleted() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.INFO, "Automated file export completed");
|
log(MessageCategory.INFO, "Automated file export completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Logs failure to complete file export.
|
||||||
*
|
*
|
||||||
* @param ex
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
*
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* acquire an exclusive lock on the log file.
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logFileExportError(Exception ex) throws InterruptedException {
|
void logFileExportError() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, String.format("Error exporting files: %s", ex.getMessage()));
|
log(MessageCategory.ERROR, "Error exporting files");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs discovery of a crashed auto ingest job for which recovery will be
|
* Logs discovery of a crashed auto ingest job for which recovery will be
|
||||||
* attempted.
|
* attempted.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logCrashRecoveryWithRetry() throws InterruptedException {
|
void logCrashRecoveryWithRetry() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, "Detected crash while processing, reprocessing");
|
log(MessageCategory.ERROR, "Detected crash while processing, reprocessing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,24 +378,16 @@ final class AutoIngestJobLogger {
|
|||||||
* Logs discovery of a crashed auto ingest job for which recovery will not
|
* Logs discovery of a crashed auto ingest job for which recovery will not
|
||||||
* be attempted because the retry limit for the job has been reached.
|
* be attempted because the retry limit for the job has been reached.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logCrashRecoveryNoRetry() throws InterruptedException {
|
void logCrashRecoveryNoRetry() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, "Detected crash while processing, reached retry limit for processing");
|
log(MessageCategory.ERROR, "Detected crash while processing, reached retry limit for processing");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs an unexpected runtime exception, e.g., an exception caught by the
|
|
||||||
* automated ingest job processing exception firewall.
|
|
||||||
*
|
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
|
||||||
* acquire an exclusive lock on the log file.
|
|
||||||
*/
|
|
||||||
void logErrorCondition(String message) throws InterruptedException {
|
|
||||||
log(MessageCategory.ERROR, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a message to the case auto ingest log.
|
* Writes a message to the case auto ingest log.
|
||||||
* <p>
|
* <p>
|
||||||
@ -392,25 +398,55 @@ final class AutoIngestJobLogger {
|
|||||||
* @param category The message category.
|
* @param category The message category.
|
||||||
* @param message The message.
|
* @param message The message.
|
||||||
*
|
*
|
||||||
* @throws InterruptedException if interrupted while blocked waiting to
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* acquire an exclusive lock on the log file.
|
* message.
|
||||||
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
|
* to acquire an exclusive lock on the
|
||||||
|
* log file.
|
||||||
*/
|
*/
|
||||||
private void log(MessageCategory category, String message) throws InterruptedException {
|
private void log(MessageCategory category, String message) throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
String prefix = String.format("Failed to write case auto ingest message (\"%s\") for %s", message, manifestPath);
|
|
||||||
try (Lock lock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, getLogPath(caseDirectoryPath).toString(), LOCK_TIME_OUT, LOCK_TIME_OUT_UNIT)) {
|
try (Lock lock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, getLogPath(caseDirectoryPath).toString(), LOCK_TIME_OUT, LOCK_TIME_OUT_UNIT)) {
|
||||||
if (null != lock) {
|
if (null != lock) {
|
||||||
File logFile = getLogPath(caseDirectoryPath).toFile();
|
File logFile = getLogPath(caseDirectoryPath).toFile();
|
||||||
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true)) {
|
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true)) {
|
||||||
writer.println(String.format("%s %s: %s\\%s: %-8s: %s", logDateFormat.format((Date.from(Instant.now()).getTime())), hostName, manifestPath, dataSourceFileName, category.toString(), message));
|
writer.println(String.format("%s %s: %s: %s: %-8s: %s", logDateFormat.format((Date.from(Instant.now()).getTime())), hostName, manifestFileName, dataSourceFileName, category.toString(), message));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
AutoIngestSystemLogger.getLogger().log(Level.SEVERE, String.format("%s due to I/O error", prefix), ex);
|
throw new AutoIngestJobLoggerException(String.format("Failed to write case auto ingest log message (\"%s\") for %s", message, manifestPath), ex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AutoIngestSystemLogger.getLogger().log(Level.SEVERE, String.format("%s due to lock timeout", prefix));
|
throw new AutoIngestJobLoggerException(String.format("Failed to write case auto ingest log message (\"%s\") for %s due to time out acquiring log lock", message, manifestPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
AutoIngestSystemLogger.getLogger().log(Level.SEVERE, String.format("%s due to coordination service error", prefix), ex);
|
throw new AutoIngestJobLoggerException(String.format("Failed to write case auto ingest log message (\"%s\") for %s", message, manifestPath), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when there is a problem writing a log message.
|
||||||
|
*/
|
||||||
|
final static class AutoIngestJobLoggerException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception to throw when there is a problem writing a
|
||||||
|
* log message.
|
||||||
|
*
|
||||||
|
* @param message The exception message.
|
||||||
|
*/
|
||||||
|
private AutoIngestJobLoggerException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception to throw when there is a problem writing a
|
||||||
|
* log message.
|
||||||
|
*
|
||||||
|
* @param message The exception message.
|
||||||
|
* @param cause The cause of the exception, if it was an exception.
|
||||||
|
*/
|
||||||
|
private AutoIngestJobLoggerException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
AutoIngestDashboard.bnRefresh.text=&Refresh
|
AutoIngestDashboard.bnRefresh.text=&Refresh
|
||||||
AutoIngestDashboard.lbCompleted.text=Completed
|
AutoIngestDashboard.lbCompleted.text=Completed Jobs
|
||||||
AutoIngestDashboard.lbRunning.text=Running
|
AutoIngestDashboard.lbRunning.text=Running Jobs
|
||||||
AutoIngestDashboard.lbPending.text=Pending
|
AutoIngestDashboard.lbPending.text=Pending Jobs
|
||||||
AutoIngestDashboard.bnCancelModule.text=Cancel &Module
|
AutoIngestDashboard.bnCancelModule.text=Cancel &Module
|
||||||
AutoIngestDashboard.bnExit.text=&Exit
|
AutoIngestDashboard.bnExit.text=&Exit
|
||||||
AutoIngestDashboard.bnOptions.text=&Options
|
AutoIngestDashboard.bnOptions.text=&Options
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.Case=Case
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.Case=Case
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.ImageFolder=Data Source
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.ImageFolder=Data Source
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.HostName=Host Name
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.HostName=Host Name
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.CreatedTime=Created Time
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.CreatedTime=Job Created
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.StartedTime=Started Time
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.StartedTime=Stage Started
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.CompletedTime=Completed Time
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.CompletedTime=Job Completed
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.Stage=Stage
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.Stage=Stage
|
||||||
AutoIngestDashboard.JobsTableModel.ColumnHeader.Status=Status
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.Status=Status
|
||||||
AutoIngestDashboard.bnShowProgress.text=&Show Progress
|
AutoIngestDashboard.JobsTableModel.ColumnHeader.ManifestFilePath= Manifest File Path
|
||||||
|
AutoIngestDashboard.bnShowProgress.text=Ingest Progress
|
||||||
AutoIngestDashboard.bnResume.text=Resume
|
AutoIngestDashboard.bnResume.text=Resume
|
||||||
AutoIngestDashboard.bnPause.text=Pause
|
AutoIngestDashboard.bnPause.text=Pause
|
||||||
AutoIngestDashboard.bnPause.confirmHeader=Are you sure you want to pause?
|
AutoIngestDashboard.bnPause.confirmHeader=Are you sure you want to pause?
|
||||||
@ -42,7 +43,7 @@ AutoIngestDashboard.ExitConsequences=This will cancel any currently running job
|
|||||||
AutoIngestDashboard.ExitingStatus=Exiting...
|
AutoIngestDashboard.ExitingStatus=Exiting...
|
||||||
AutoIngestDashboard.OK=OK
|
AutoIngestDashboard.OK=OK
|
||||||
AutoIngestDashboard.Cancel=Cancel
|
AutoIngestDashboard.Cancel=Cancel
|
||||||
AutoIngestDashboard.AutoIngestStartupFailed.Message=Failed to start automated ingest.\nPlease see application log for details.
|
AutoIngestDashboard.AutoIngestStartupFailed.Message=Failed to start automated ingest.\nPlease see auto ingest system log for details.
|
||||||
AutoIngestDashboard.AutoIngestStartupFailed.Title=Automated Ingest Error
|
AutoIngestDashboard.AutoIngestStartupFailed.Title=Automated Ingest Error
|
||||||
AutoIngestDashboard.AutoIngestStartupError=Failed to start automated ingest. Verify Multi-user Settings.
|
AutoIngestDashboard.AutoIngestStartupError=Failed to start automated ingest. Verify Multi-user Settings.
|
||||||
AutoIngestDashboard.AutoIngestStartupWarning.Title=Automated Ingest Warning
|
AutoIngestDashboard.AutoIngestStartupWarning.Title=Automated Ingest Warning
|
||||||
@ -60,7 +61,7 @@ AutoIngestDashboard.tbServicesStatusMessage.Message=Case databases {0}, keyword
|
|||||||
AutoIngestDashboard.tbServicesStatusMessage.Message.Up=up
|
AutoIngestDashboard.tbServicesStatusMessage.Message.Up=up
|
||||||
AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down
|
AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down
|
||||||
AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown=unknown
|
AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown=unknown
|
||||||
AutoIngestDashboard.PauseDueToSystemError=Paused due to system error, please consult the auto ingest system log"
|
AutoIngestDashboard.PauseDueToSystemError=Paused due to system error, please consult the auto ingest system log
|
||||||
ConfirmationDialog.DoNotDelete=Do not delete
|
ConfirmationDialog.DoNotDelete=Do not delete
|
||||||
ConfirmationDialog.Delete=Permanently delete
|
ConfirmationDialog.Delete=Permanently delete
|
||||||
ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case
|
ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case
|
||||||
@ -166,7 +167,7 @@ ReviewModeCasePanel.bnShowLog.text=&Show Log
|
|||||||
AutoIngestDashboard.bnPrioritizeCase.toolTipText=Move all images associated with a case to top of Pending queue.
|
AutoIngestDashboard.bnPrioritizeCase.toolTipText=Move all images associated with a case to top of Pending queue.
|
||||||
AutoIngestDashboard.bnPrioritizeCase.text=Prioriti&ze Case
|
AutoIngestDashboard.bnPrioritizeCase.text=Prioriti&ze Case
|
||||||
AutoIngestDashboard.bnShowCaseLog.toolTipText=Display case log file for selected case
|
AutoIngestDashboard.bnShowCaseLog.toolTipText=Display case log file for selected case
|
||||||
AutoIngestDashboard.bnShowCaseLog.text=Show &Log
|
AutoIngestDashboard.bnShowCaseLog.text=Show Case &Log
|
||||||
ReviewModeCasePanel.bnShowLog.toolTipText=Display case log file for selected case
|
ReviewModeCasePanel.bnShowLog.toolTipText=Display case log file for selected case
|
||||||
CopyFilesPanel.bnCancelPendingJob.text=Ca&ncel
|
CopyFilesPanel.bnCancelPendingJob.text=Ca&ncel
|
||||||
CopyFilesPanel.tbDestinationCase.text=
|
CopyFilesPanel.tbDestinationCase.text=
|
||||||
@ -197,8 +198,6 @@ CaseImportPanel.Complete=Complete
|
|||||||
CaseImportPanel.Blank=
|
CaseImportPanel.Blank=
|
||||||
CaseImportPanel.DeleteWarning=Make sure no important files are in the case source directory
|
CaseImportPanel.DeleteWarning=Make sure no important files are in the case source directory
|
||||||
AutoIngestDashboard.lbStatus.text=Status:
|
AutoIngestDashboard.lbStatus.text=Status:
|
||||||
AutoIngestDashboard.bnPrioritizeFolder.text=Prioritize &Folder
|
|
||||||
AutoIngestDashboard.bnPrioritizeFolder.toolTipText=Move this folder to the top of the Pending queue.
|
|
||||||
SingleUserCaseImporter.NonUniqueOutputFolder=Output folder not unique. Skipping
|
SingleUserCaseImporter.NonUniqueOutputFolder=Output folder not unique. Skipping
|
||||||
SingleUserCaseImporter.WillImport=Will import:
|
SingleUserCaseImporter.WillImport=Will import:
|
||||||
SingleUserCaseImporter.None=None
|
SingleUserCaseImporter.None=None
|
||||||
@ -283,4 +282,7 @@ FileExporterSettingsPanel.BrowseReportTooltip_1=Browse for the Reports Folder
|
|||||||
FileExporterSettingsPanel.NewRuleTooltip_1=Clear the rule editor to begin a new rule
|
FileExporterSettingsPanel.NewRuleTooltip_1=Clear the rule editor to begin a new rule
|
||||||
FileExporterSettingsPanel.DeleteTooltip_1=Delete the selected rule
|
FileExporterSettingsPanel.DeleteTooltip_1=Delete the selected rule
|
||||||
FileExporterSettingsPanel.SaveTooltip_1=Save the current rule
|
FileExporterSettingsPanel.SaveTooltip_1=Save the current rule
|
||||||
AutoIngestDashboard.bnOpenLogDir.text=Open Log Directory
|
AutoIngestDashboard.bnOpenLogDir.text=Open System Logs Directory
|
||||||
|
AutoIngestDashboard.bnPrioritizeJob.text=Prioritize Job
|
||||||
|
AutoIngestDashboard.bnPrioritizeJob.toolTipText=Move this folder to the top of the Pending queue.
|
||||||
|
AutoIngestDashboard.bnReprocessJob.text=Reprocess Job
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Namespace elements for auto ingest coordination service nodes.
|
||||||
*/
|
*/
|
||||||
final class CoordinationServiceNamespace {
|
final class CoordinationServiceNamespace {
|
||||||
static final String ROOT_COORD_SCV_NAMESPACE = "autopsy"; // RJCTODO: Move this elsewhere
|
private static final String ROOT = "autopsy";
|
||||||
|
|
||||||
static String getRoot() {
|
static String getRoot() {
|
||||||
return ROOT_COORD_SCV_NAMESPACE;
|
return ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CoordinationServiceNamespace() {
|
private CoordinationServiceNamespace() {
|
||||||
|
@ -19,34 +19,35 @@
|
|||||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* A coordination service node data transfer object for an auto ingest job
|
||||||
|
* manifest. The data include: processing status, priority, the number of times
|
||||||
|
* the auto ingest job for the manifest has crashed during processing, and the
|
||||||
|
* date the auto ingest job for the manifest was completed.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Consider making this encapsulate the locking as well, and to set the data as well
|
|
||||||
final class ManifestNodeData {
|
final class ManifestNodeData {
|
||||||
|
|
||||||
enum ProcessingStatus {
|
|
||||||
PENDING,
|
|
||||||
PROCESSING,
|
|
||||||
COMPLETED,
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int DEFAULT_PRIORITY = 0;
|
private static final int DEFAULT_PRIORITY = 0;
|
||||||
private final boolean nodeDataIsSet;
|
private final boolean coordSvcNodeDataWasSet;
|
||||||
private ProcessingStatus status;
|
private ProcessingStatus status;
|
||||||
private int priority;
|
private int priority;
|
||||||
private int numberOfCrashes;
|
private int numberOfCrashes;
|
||||||
|
private long completedDate;
|
||||||
|
private boolean errorsOccurred;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Constructs a coordination service node data data transfer object for an
|
||||||
|
* auto ingest manifest from the raw bytes obtained from the coordination
|
||||||
|
* service.
|
||||||
*
|
*
|
||||||
* @param nodeData
|
* @param nodeData The raw bytes received from the coordination service.
|
||||||
*/
|
*/
|
||||||
ManifestNodeData(byte[] nodeData) {
|
ManifestNodeData(byte[] nodeData) {
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(nodeData);
|
ByteBuffer buffer = ByteBuffer.wrap(nodeData);
|
||||||
this.nodeDataIsSet = buffer.hasRemaining();
|
this.coordSvcNodeDataWasSet = buffer.hasRemaining();
|
||||||
if (this.nodeDataIsSet) {
|
if (this.coordSvcNodeDataWasSet) {
|
||||||
int rawStatus = buffer.getInt();
|
int rawStatus = buffer.getInt();
|
||||||
if (ProcessingStatus.PENDING.ordinal() == rawStatus) {
|
if (ProcessingStatus.PENDING.ordinal() == rawStatus) {
|
||||||
this.status = ProcessingStatus.PENDING;
|
this.status = ProcessingStatus.PENDING;
|
||||||
@ -54,97 +55,183 @@ final class ManifestNodeData {
|
|||||||
this.status = ProcessingStatus.PROCESSING;
|
this.status = ProcessingStatus.PROCESSING;
|
||||||
} else if (ProcessingStatus.COMPLETED.ordinal() == rawStatus) {
|
} else if (ProcessingStatus.COMPLETED.ordinal() == rawStatus) {
|
||||||
this.status = ProcessingStatus.COMPLETED;
|
this.status = ProcessingStatus.COMPLETED;
|
||||||
|
}else if (ProcessingStatus.DELETED.ordinal() == rawStatus) {
|
||||||
|
this.status = ProcessingStatus.DELETED;
|
||||||
}
|
}
|
||||||
this.priority = buffer.getInt();
|
this.priority = buffer.getInt();
|
||||||
this.numberOfCrashes = buffer.getInt();
|
this.numberOfCrashes = buffer.getInt();
|
||||||
|
this.completedDate = buffer.getLong();
|
||||||
|
int errorFlag = buffer.getInt();
|
||||||
|
this.errorsOccurred = (1 == errorFlag);
|
||||||
} else {
|
} else {
|
||||||
this.status = ProcessingStatus.PENDING;
|
this.status = ProcessingStatus.PENDING;
|
||||||
this.priority = DEFAULT_PRIORITY;
|
this.priority = DEFAULT_PRIORITY;
|
||||||
this.numberOfCrashes = 0;
|
this.numberOfCrashes = 0;
|
||||||
|
this.completedDate = 0L;
|
||||||
|
this.errorsOccurred = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Constructs a coordination service node data data transfer object for an
|
||||||
|
* auto ingest manifest from values provided by the auto ingest system.
|
||||||
|
*
|
||||||
|
* @param status The processing status of the manifest.
|
||||||
|
* @param priority The priority of the manifest.
|
||||||
|
* @param numberOfCrashes The number of times auto ingest jobs for the
|
||||||
|
* manifest have crashed during processing.
|
||||||
|
* @param completedDate The date the auto ingest job for the manifest was
|
||||||
|
* completed.
|
||||||
*/
|
*/
|
||||||
ManifestNodeData(ProcessingStatus status, int priority, int numberOfCrashes) {
|
ManifestNodeData(ProcessingStatus status, int priority, int numberOfCrashes, Date completedDate, boolean errorOccurred) {
|
||||||
this.nodeDataIsSet = false;
|
this.coordSvcNodeDataWasSet = false;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
this.numberOfCrashes = numberOfCrashes;
|
this.numberOfCrashes = numberOfCrashes;
|
||||||
|
this.completedDate = completedDate.getTime();
|
||||||
|
this.errorsOccurred = errorOccurred;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Indicates whether or not the coordination service node data was set,
|
||||||
|
* i.e., this object was constructed from raw bytes from the ccordination
|
||||||
|
* service node for the manifest.
|
||||||
*
|
*
|
||||||
* @return
|
* @return True or false.
|
||||||
*/
|
*/
|
||||||
boolean isSet() {
|
// RJCTODO: This is confusing, consider changing the API so that the use case is to
|
||||||
return this.nodeDataIsSet;
|
// check the length of the node data from the coordination service before
|
||||||
|
// constructing an instance of this object. That would be much more clear!
|
||||||
|
boolean coordSvcNodeDataWasSet() {
|
||||||
|
return this.coordSvcNodeDataWasSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Gets the processing status of the manifest
|
||||||
*
|
*
|
||||||
* @return
|
* @return The processing status of the manifest.
|
||||||
*/
|
*/
|
||||||
ProcessingStatus getStatus() {
|
ProcessingStatus getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sets the processing status of the manifest
|
||||||
*
|
*
|
||||||
* @param status
|
* @param status The processing status of the manifest.
|
||||||
*/
|
*/
|
||||||
void setStatus(ProcessingStatus status) {
|
void setStatus(ProcessingStatus status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the priority of the manifest.
|
||||||
*
|
*
|
||||||
* @return
|
* @return The priority of the manifest.
|
||||||
*/
|
*/
|
||||||
int getPriority() {
|
int getPriority() {
|
||||||
return this.priority;
|
return this.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sets the priority of the manifest. A higher number indicates a higheer
|
||||||
|
* priority.
|
||||||
*
|
*
|
||||||
* @param priority
|
* @param priority The priority of the manifest.
|
||||||
*/
|
*/
|
||||||
void setPriority(int priority) {
|
void setPriority(int priority) {
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Gets the number of times auto ingest jobs for the manifest have crashed
|
||||||
|
* during processing.
|
||||||
*
|
*
|
||||||
* @return
|
* @return The number of times auto ingest jobs for the manifest have
|
||||||
|
* crashed during processing.
|
||||||
*/
|
*/
|
||||||
int getNumberOfCrashes() {
|
int getNumberOfCrashes() {
|
||||||
return this.numberOfCrashes;
|
return this.numberOfCrashes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Sets the number of times auto ingest jobs for the manifest have crashed
|
||||||
|
* during processing.
|
||||||
*
|
*
|
||||||
* @param attempts
|
* @param numberOfCrashes The number of times auto ingest jobs for the
|
||||||
|
* manifest have crashed during processing.
|
||||||
*/
|
*/
|
||||||
void setNumberOfCrashes(int attempts) {
|
void setNumberOfCrashes(int numberOfCrashes) {
|
||||||
this.numberOfCrashes = attempts;
|
this.numberOfCrashes = numberOfCrashes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* Gets the date the auto ingest job for the manifest was completed.
|
||||||
*
|
*
|
||||||
* @return
|
* @return The date the auto ingest job for the manifest was completed. The
|
||||||
|
* epoch (January 1, 1970, 00:00:00 GMT) indicates the date is not
|
||||||
|
* set, i.e., Date.getTime() returns 0L.
|
||||||
|
*/
|
||||||
|
Date getCompletedDate() {
|
||||||
|
return new Date(this.completedDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the date the auto ingest job for the manifest was completed.
|
||||||
|
*
|
||||||
|
* @param completedDate The date the auto ingest job for the manifest was
|
||||||
|
* completed. Use the epoch (January 1, 1970, 00:00:00
|
||||||
|
* GMT) to indicate the date is not set, i.e., new
|
||||||
|
* Date(0L).
|
||||||
|
*/
|
||||||
|
void setCompletedDate(Date completedDate) {
|
||||||
|
this.completedDate = completedDate.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries whether or not any errors occurred during the processing of the
|
||||||
|
* auto ingest job for the manifest.
|
||||||
|
*
|
||||||
|
* @return True or false.
|
||||||
|
*/
|
||||||
|
boolean getErrorsOccurred() {
|
||||||
|
return this.errorsOccurred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not any errors occurred during the processing of the auto
|
||||||
|
* ingest job for the manifest.
|
||||||
|
*
|
||||||
|
* @param errorsOccurred True or false.
|
||||||
|
*/
|
||||||
|
void setErrorsOccurred(boolean errorsOccurred) {
|
||||||
|
this.errorsOccurred = errorsOccurred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the node data as raw bytes that can be sent to the coordination
|
||||||
|
* service.
|
||||||
|
*
|
||||||
|
* @return The manifest node data as a byte array.
|
||||||
*/
|
*/
|
||||||
byte[] toArray() {
|
byte[] toArray() {
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES * 3);
|
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES * 4 + Long.BYTES);
|
||||||
buffer.putInt(this.status.ordinal());
|
buffer.putInt(this.status.ordinal());
|
||||||
buffer.putInt(this.priority);
|
buffer.putInt(this.priority);
|
||||||
buffer.putInt(this.numberOfCrashes);
|
buffer.putInt(this.numberOfCrashes);
|
||||||
|
buffer.putLong(this.completedDate);
|
||||||
|
buffer.putInt(this.errorsOccurred ? 1 : 0);
|
||||||
return buffer.array();
|
return buffer.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processing status for the auto ingest job for the manifest.
|
||||||
|
*/
|
||||||
|
enum ProcessingStatus {
|
||||||
|
PENDING,
|
||||||
|
PROCESSING,
|
||||||
|
COMPLETED,
|
||||||
|
DELETED
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,9 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
||||||
import org.sleuthkit.autopsy.casemodule.GeneralFilter;
|
import org.sleuthkit.autopsy.casemodule.GeneralFilter;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
|
|
||||||
final class PathUtils {
|
final class PathUtils {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(PathUtils.class.getName());
|
|
||||||
private static final List<String> CASE_METADATA_FILE_EXTS = Arrays.asList(new String[]{CaseMetadata.getFileExtension()});
|
private static final List<String> CASE_METADATA_FILE_EXTS = Arrays.asList(new String[]{CaseMetadata.getFileExtension()});
|
||||||
private static final GeneralFilter caseMetadataFileFilter = new GeneralFilter(CASE_METADATA_FILE_EXTS, "Autopsy Case File");
|
private static final GeneralFilter caseMetadataFileFilter = new GeneralFilter(CASE_METADATA_FILE_EXTS, "Autopsy Case File");
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ final class PathUtils {
|
|||||||
*
|
*
|
||||||
* @return A list of the output case folder paths.
|
* @return A list of the output case folder paths.
|
||||||
*/
|
*/
|
||||||
static List<Path> findCaseFolders(Path folderToSearch) {
|
static List<Path> findCaseFolders(Path folderToSearch) { // RJCTODO: Rename
|
||||||
File searchFolder = new File(folderToSearch.toString());
|
File searchFolder = new File(folderToSearch.toString());
|
||||||
if (!searchFolder.isDirectory()) {
|
if (!searchFolder.isDirectory()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -112,32 +110,6 @@ final class PathUtils {
|
|||||||
return caseDataFiles.length != 0;
|
return caseDataFiles.length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the path to the case images folder path from an image folder
|
|
||||||
* path.
|
|
||||||
*
|
|
||||||
* @param rootImageFoldersPath The root image folders path.
|
|
||||||
* @param imageFolderPath The image folder path.
|
|
||||||
*
|
|
||||||
* @return The root input folder path for a case.
|
|
||||||
*/
|
|
||||||
static Path caseImagesPathFromImageFolderPath(Path rootImageFoldersPath, Path imageFolderPath) {
|
|
||||||
return rootImageFoldersPath.resolve(imageFolderPath.subpath(0, rootImageFoldersPath.getNameCount() + 1).getFileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the case name from an image folder path.
|
|
||||||
*
|
|
||||||
* @param rootImageFoldersPath The root image folders path.
|
|
||||||
* @param imageFolderPath The image folder path.
|
|
||||||
*
|
|
||||||
* @return The case name.
|
|
||||||
*/
|
|
||||||
static String caseNameFromImageFolderPath(Path rootImageFoldersPath, Path imageFolderPath) {
|
|
||||||
Path caseImagesPath = PathUtils.caseImagesPathFromImageFolderPath(rootImageFoldersPath, imageFolderPath);
|
|
||||||
return caseImagesPath.getFileName().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the case name from a case folder path.
|
* Extracts the case name from a case folder path.
|
||||||
*
|
*
|
||||||
@ -163,7 +135,7 @@ final class PathUtils {
|
|||||||
*
|
*
|
||||||
* @return A case folder path with a time stamp suffix.
|
* @return A case folder path with a time stamp suffix.
|
||||||
*/
|
*/
|
||||||
static Path createCaseFolderPath(Path caseFoldersPath, String caseName) {
|
static Path createCaseFolderPath(Path caseFoldersPath, String caseName) { // RJCTODO: Rename
|
||||||
String folderName = caseName + "_" + TimeStampUtils.createTimeStamp();
|
String folderName = caseName + "_" + TimeStampUtils.createTimeStamp();
|
||||||
return Paths.get(caseFoldersPath.toString(), folderName);
|
return Paths.get(caseFoldersPath.toString(), folderName);
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ public final class ReviewModeCasePanel extends JPanel {
|
|||||||
private static final int STATUS_COL_MIN_WIDTH = 55;
|
private static final int STATUS_COL_MIN_WIDTH = 55;
|
||||||
private static final int STATUS_COL_MAX_WIDTH = 250;
|
private static final int STATUS_COL_MAX_WIDTH = 250;
|
||||||
private static final int STATUS_COL_PREFERRED_WIDTH = 60;
|
private static final int STATUS_COL_PREFERRED_WIDTH = 60;
|
||||||
private static final int MILLISECONDS_TO_WAIT_BEFORE_STARTING = 500;
|
private static final int MILLISECONDS_TO_WAIT_BEFORE_STARTING = 500; // RJCTODO: Shorten name
|
||||||
private static final int MILLISECONDS_TO_WAIT_BETWEEN_UPDATES = 30000;
|
private static final int MILLISECONDS_TO_WAIT_BETWEEN_UPDATES = 30000; // RJCTODO: Shorten name
|
||||||
private ScheduledThreadPoolExecutor casesTableRefreshExecutor;
|
private ScheduledThreadPoolExecutor casesTableRefreshExecutor;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -84,7 +84,7 @@ public final class ReviewModeCasePanel extends JPanel {
|
|||||||
CREATEDTIME,
|
CREATEDTIME,
|
||||||
COMPLETEDTIME,
|
COMPLETEDTIME,
|
||||||
STATUS_ICON,
|
STATUS_ICON,
|
||||||
OUTPUTFOLDER
|
OUTPUTFOLDER // RJCTODO: Change name
|
||||||
}
|
}
|
||||||
private final String[] columnNames = {CASE_HEADER, CREATEDTIME_HEADER, COMPLETEDTIME_HEADER, STATUS_ICON_HEADER, OUTPUT_FOLDER_HEADER};
|
private final String[] columnNames = {CASE_HEADER, CREATEDTIME_HEADER, COMPLETEDTIME_HEADER, STATUS_ICON_HEADER, OUTPUT_FOLDER_HEADER};
|
||||||
private DefaultTableModel caseTableModel;
|
private DefaultTableModel caseTableModel;
|
||||||
@ -325,7 +325,7 @@ public final class ReviewModeCasePanel extends JPanel {
|
|||||||
autoIngestCase.getCaseName(),
|
autoIngestCase.getCaseName(),
|
||||||
autoIngestCase.getCreationDate(),
|
autoIngestCase.getCreationDate(),
|
||||||
autoIngestCase.getLastAccessedDate(),
|
autoIngestCase.getLastAccessedDate(),
|
||||||
autoIngestCase.getStatus(),
|
(AutoIngestCase.CaseStatus.OK != autoIngestCase.getStatus()),
|
||||||
autoIngestCase.getCaseDirectoryPath().toString()});
|
autoIngestCase.getCaseDirectoryPath().toString()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user