mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-09 14:49:32 +00:00
Merge pull request #4690 from rcordovano/4922-delete-orphan-manifest-nodes
4922 delete orphan manifest nodes
This commit is contained in:
commit
4e3530e3c7
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Collects the auto ingest job node data stored in the manifest file
|
||||
* coordination service nodes.
|
||||
*/
|
||||
final class AutoIngestJobNodeDataCollector {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AutoIngestJobNodeDataCollector.class.getName());
|
||||
|
||||
static List<AutoIngestJobNodeData> getNodeData() throws CoordinationServiceException, InterruptedException {
|
||||
final CoordinationService coordinationService = CoordinationService.getInstance();
|
||||
final List<String> nodePaths = coordinationService.getNodeList(CoordinationService.CategoryNode.MANIFESTS);
|
||||
final List<AutoIngestJobNodeData> nodeDataList = new ArrayList<>();
|
||||
for (String nodePath : nodePaths) {
|
||||
try {
|
||||
final byte[] nodeBytes = coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, nodePath);
|
||||
AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(nodeBytes);
|
||||
nodeDataList.add(nodeData);
|
||||
} catch (AutoIngestJobNodeData.InvalidDataException ex) {
|
||||
logger.log(Level.WARNING, String.format("Error reading node data from manifest file coordination service node %s", nodePath), ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
return nodeDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents instantiation of this utility class.
|
||||
*/
|
||||
private AutoIngestJobNodeDataCollector() {
|
||||
}
|
||||
|
||||
}
|
@ -19,39 +19,60 @@
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import javax.swing.AbstractAction;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.progress.AppFrameProgressBar;
|
||||
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||
import org.sleuthkit.autopsy.progress.TaskCancellable;
|
||||
|
||||
/**
|
||||
* An action class that kicks off a cancellable case nodes cleanup task that
|
||||
* runs in a background thread and reports progress using an application frame
|
||||
* progress bar.
|
||||
* A base class for action classes that kick off a cancellable task that runs in
|
||||
* a background thread and reports progress using an application frame progress
|
||||
* bar.
|
||||
*/
|
||||
final class CaseNodesCleanupAction extends AbstractAction {
|
||||
abstract class BackgroundTaskAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String progressDisplayName;
|
||||
|
||||
/**
|
||||
* Constructs the base class part of action classes that kick off a
|
||||
* cancellable task that runs in a background thread and reports progress
|
||||
* using an application frame progress bar.
|
||||
*
|
||||
* @param actionName The name of the action.
|
||||
* @param progressDisplayName The display name for the progress bar.
|
||||
*/
|
||||
BackgroundTaskAction(String actionName, String progressDisplayName) {
|
||||
super(actionName);
|
||||
this.progressDisplayName = progressDisplayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"CaseNodesCleanupAction.progressDisplayName=Cleanup Case Znodes"
|
||||
})
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
final AppFrameProgressBar progress = new AppFrameProgressBar(Bundle.CaseNodesCleanupAction_progressDisplayName());
|
||||
final AppFrameProgressBar progress = new AppFrameProgressBar(progressDisplayName);
|
||||
final TaskCancellable taskCanceller = new TaskCancellable(progress);
|
||||
progress.setCancellationBehavior(taskCanceller);
|
||||
final Runnable task = new CaseNodesCleanupTask(progress);
|
||||
final Runnable task = getTask(progress);
|
||||
final FutureTask<Void> future = new FutureTask<>(task, null);
|
||||
taskCanceller.setFuture(future);
|
||||
new Thread(future).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the background task to be executed. The task is expected to report
|
||||
* its progress using the supplied progress indicator and to check for
|
||||
* cancellation by checking to see if the thread it is running in has been
|
||||
* interrupted.
|
||||
*
|
||||
* @param progress A progress indicator for the task.
|
||||
*
|
||||
* @return The Runnnable task.
|
||||
*/
|
||||
abstract Runnable getTask(ProgressIndicator progress);
|
||||
|
||||
@Override
|
||||
public CaseNodesCleanupAction clone() throws CloneNotSupportedException {
|
||||
public BackgroundTaskAction clone() throws CloneNotSupportedException {
|
||||
super.clone();
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
@ -255,4 +255,5 @@ AinStatusDashboard.nodeStatusTableTitle.text=Auto Ingest Nodes
|
||||
AinStatusDashboard.healthMonitorButton.text=Health Monitor
|
||||
CasesDashboardTopComponent.refreshButton.text=Refresh
|
||||
AutoIngestCasesDeletionDialog.jLabel1.text=Progress
|
||||
CasesDashboardTopComponent.cleanCaseNodesButton.text=Clean Case Znodes
|
||||
CasesDashboardTopComponent.deleteOrphanCaseNodesButton.text=Delete Orphan Case Znodes
|
||||
CasesDashboardTopComponent.deleteOrphanManifestNodesButton.text=Delete Orphan Manifest Znodes
|
||||
|
@ -138,12 +138,6 @@ AutoIngestJobsNode.status.text=Status
|
||||
AutoIngestJobsPanel.waitNode.text=Please Wait...
|
||||
AutoIngestMetricsDialog.initReportText=Select a date above and click the 'Generate Metrics Report' button to generate\na metrics report.
|
||||
AutoIngestMetricsDialog.title.text=Auto Ingest Metrics
|
||||
CaseNodesCleanupAction.progressDisplayName=Cleanup Case Znodes
|
||||
CaseNodesCleanupTask.progress.connectingToCoordSvc=Connecting to the coordination service...
|
||||
# {0} - node path
|
||||
CaseNodesCleanupTask.progress.deletingOrphanedCaseNode=Deleting orphaned case node {0}...
|
||||
CaseNodesCleanupTask.progress.gettingCaseNodesListing=Querying coordination service for case nodes...
|
||||
CaseNodesCleanupTask.progress.startMessage=Starting orphaned case znode cleanup...
|
||||
ConfirmationDialog.DoNotDelete=Do not delete
|
||||
ConfirmationDialog.Delete=Permanently delete
|
||||
ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case
|
||||
@ -210,6 +204,18 @@ DeleteCaseTask.progress.parsingManifest=Parsing manifest file {0}...
|
||||
# {0} - manifest file path
|
||||
DeleteCaseTask.progress.releasingManifestLock=Releasing lock on the manifest file {0}...
|
||||
DeleteCaseTask.progress.startMessage=Starting deletion...
|
||||
DeleteOrphanCaseNodesAction.progressDisplayName=Cleanup Case Znodes
|
||||
DeleteOrphanCaseNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service
|
||||
# {0} - node path
|
||||
DeleteOrphanCaseNodesTask.progress.deletingOrphanedCaseNode=Deleting orphaned case znode {0}
|
||||
DeleteOrphanCaseNodesTask.progress.gettingCaseNodesListing=Querying coordination service for case znodes
|
||||
DeleteOrphanCaseNodesTask.progress.startMessage=Starting orphaned case znode cleanup
|
||||
DeleteOrphanManifestNodesAction.progressDisplayName=Cleanup Manifest File Znodes
|
||||
DeleteOrphanManifestNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service
|
||||
# {0} - node path
|
||||
DeleteOrphanManifestNodesTask.progress.deletingOrphanedManifestNode=Deleting orphaned manifest file znode {0}
|
||||
DeleteOrphanManifestNodesTask.progress.gettingManifestNodes=Querying the coordination service for manifest file znodes
|
||||
DeleteOrphanManifestNodesTask.progress.startMessage=Starting orphaned manifest file znode cleanup
|
||||
HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases
|
||||
OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted.
|
||||
OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details.
|
||||
@ -446,4 +452,5 @@ AinStatusDashboard.nodeStatusTableTitle.text=Auto Ingest Nodes
|
||||
AinStatusDashboard.healthMonitorButton.text=Health Monitor
|
||||
CasesDashboardTopComponent.refreshButton.text=Refresh
|
||||
AutoIngestCasesDeletionDialog.jLabel1.text=Progress
|
||||
CasesDashboardTopComponent.cleanCaseNodesButton.text=Clean Case Znodes
|
||||
CasesDashboardTopComponent.deleteOrphanCaseNodesButton.text=Delete Orphan Case Znodes
|
||||
CasesDashboardTopComponent.deleteOrphanManifestNodesButton.text=Delete Orphan Manifest Znodes
|
||||
|
@ -20,10 +20,12 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="refreshButton" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="refreshButton" linkSize="3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cleanCaseNodesButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="313" max="32767" attributes="0"/>
|
||||
<Component id="deleteOrphanCaseNodesButton" linkSize="3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="deleteOrphanManifestNodesButton" linkSize="3" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="caseBrowserScrollPane" max="32767" attributes="0"/>
|
||||
@ -40,8 +42,9 @@
|
||||
<Component id="caseBrowserScrollPane" pref="246" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="refreshButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cleanCaseNodesButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="refreshButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteOrphanCaseNodesButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="deleteOrphanManifestNodesButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -63,14 +66,24 @@
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="cleanCaseNodesButton">
|
||||
<Component class="javax.swing.JButton" name="deleteOrphanCaseNodesButton">
|
||||
<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="CasesDashboardTopComponent.cleanCaseNodesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="CasesDashboardTopComponent.deleteOrphanCaseNodesButton.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="cleanCaseNodesButtonActionPerformed"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteOrphanCaseNodesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteOrphanManifestNodesButton">
|
||||
<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="CasesDashboardTopComponent.deleteOrphanManifestNodesButton.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="deleteOrphanManifestNodesButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
|
@ -119,7 +119,8 @@ public final class CasesDashboardTopComponent extends TopComponent implements Ex
|
||||
|
||||
refreshButton = new javax.swing.JButton();
|
||||
caseBrowserScrollPane = new javax.swing.JScrollPane();
|
||||
cleanCaseNodesButton = new javax.swing.JButton();
|
||||
deleteOrphanCaseNodesButton = new javax.swing.JButton();
|
||||
deleteOrphanManifestNodesButton = new javax.swing.JButton();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(CasesDashboardTopComponent.class, "CasesDashboardTopComponent.refreshButton.text")); // NOI18N
|
||||
refreshButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -128,10 +129,17 @@ public final class CasesDashboardTopComponent extends TopComponent implements Ex
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cleanCaseNodesButton, org.openide.util.NbBundle.getMessage(CasesDashboardTopComponent.class, "CasesDashboardTopComponent.cleanCaseNodesButton.text")); // NOI18N
|
||||
cleanCaseNodesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteOrphanCaseNodesButton, org.openide.util.NbBundle.getMessage(CasesDashboardTopComponent.class, "CasesDashboardTopComponent.deleteOrphanCaseNodesButton.text")); // NOI18N
|
||||
deleteOrphanCaseNodesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cleanCaseNodesButtonActionPerformed(evt);
|
||||
deleteOrphanCaseNodesButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteOrphanManifestNodesButton, org.openide.util.NbBundle.getMessage(CasesDashboardTopComponent.class, "CasesDashboardTopComponent.deleteOrphanManifestNodesButton.text")); // NOI18N
|
||||
deleteOrphanManifestNodesButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deleteOrphanManifestNodesButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@ -145,12 +153,17 @@ public final class CasesDashboardTopComponent extends TopComponent implements Ex
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(refreshButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cleanCaseNodesButton)
|
||||
.addGap(0, 313, Short.MAX_VALUE))
|
||||
.addComponent(deleteOrphanCaseNodesButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(deleteOrphanManifestNodesButton)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(caseBrowserScrollPane)
|
||||
.addContainerGap())))
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deleteOrphanCaseNodesButton, deleteOrphanManifestNodesButton, refreshButton});
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
@ -159,22 +172,31 @@ public final class CasesDashboardTopComponent extends TopComponent implements Ex
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(refreshButton)
|
||||
.addComponent(cleanCaseNodesButton))
|
||||
.addComponent(deleteOrphanCaseNodesButton)
|
||||
.addComponent(deleteOrphanManifestNodesButton))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteOrphanCaseNodesButton, deleteOrphanManifestNodesButton, refreshButton});
|
||||
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
|
||||
caseBrowserPanel.displayCases();
|
||||
}//GEN-LAST:event_refreshButtonActionPerformed
|
||||
|
||||
private void cleanCaseNodesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cleanCaseNodesButtonActionPerformed
|
||||
new CaseNodesCleanupAction().actionPerformed(evt);
|
||||
}//GEN-LAST:event_cleanCaseNodesButtonActionPerformed
|
||||
private void deleteOrphanCaseNodesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteOrphanCaseNodesButtonActionPerformed
|
||||
new DeleteOrphanCaseNodesAction().actionPerformed(evt);
|
||||
}//GEN-LAST:event_deleteOrphanCaseNodesButtonActionPerformed
|
||||
|
||||
private void deleteOrphanManifestNodesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteOrphanManifestNodesButtonActionPerformed
|
||||
new DeleteOrphanManifestNodesAction().actionPerformed(evt);
|
||||
}//GEN-LAST:event_deleteOrphanManifestNodesButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane caseBrowserScrollPane;
|
||||
private javax.swing.JButton cleanCaseNodesButton;
|
||||
private javax.swing.JButton deleteOrphanCaseNodesButton;
|
||||
private javax.swing.JButton deleteOrphanManifestNodesButton;
|
||||
private javax.swing.JButton refreshButton;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||
|
||||
/**
|
||||
* An action class that kicks off a cancellable orphaned case nodes deletion
|
||||
* task that runs in a background thread and reports progress using an
|
||||
* application frame progress bar.
|
||||
*/
|
||||
final class DeleteOrphanCaseNodesAction extends BackgroundTaskAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an instance of an action class that kicks off a cancellable
|
||||
* orphaned case nodes deletion task that runs in a background thread and
|
||||
* reports progress using an application frame progress bar.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"DeleteOrphanCaseNodesAction.progressDisplayName=Cleanup Case Znodes"
|
||||
})
|
||||
DeleteOrphanCaseNodesAction() {
|
||||
super(Bundle.DeleteOrphanCaseNodesAction_progressDisplayName(), Bundle.DeleteOrphanCaseNodesAction_progressDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
Runnable getTask(ProgressIndicator progress) {
|
||||
return new DeleteOrphanCaseNodesTask(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeleteOrphanCaseNodesAction clone() throws CloneNotSupportedException {
|
||||
super.clone();
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
|
||||
}
|
@ -31,53 +31,53 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||
|
||||
/**
|
||||
* Task for cleaning up case coordination service nodes for which there is no
|
||||
* Task for deleting case coordination service nodes for which there is no
|
||||
* longer a corresponding case.
|
||||
*/
|
||||
final class CaseNodesCleanupTask implements Runnable {
|
||||
final class DeleteOrphanCaseNodesTask implements Runnable {
|
||||
|
||||
private static final Logger logger = AutoIngestDashboardLogger.getLogger();
|
||||
private final ProgressIndicator progress;
|
||||
|
||||
/**
|
||||
* Constucts an instance of a task for cleaning up case coordination service
|
||||
* Constucts an instance of a task for deleting case coordination service
|
||||
* nodes for which there is no longer a corresponding case.
|
||||
*
|
||||
* @param progress
|
||||
*/
|
||||
CaseNodesCleanupTask(ProgressIndicator progress) {
|
||||
DeleteOrphanCaseNodesTask(ProgressIndicator progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"CaseNodesCleanupTask.progress.startMessage=Starting orphaned case znode cleanup...",
|
||||
"CaseNodesCleanupTask.progress.connectingToCoordSvc=Connecting to the coordination service...",
|
||||
"CaseNodesCleanupTask.progress.gettingCaseNodesListing=Querying coordination service for case nodes..."
|
||||
"DeleteOrphanCaseNodesTask.progress.startMessage=Starting orphaned case znode cleanup",
|
||||
"DeleteOrphanCaseNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service",
|
||||
"DeleteOrphanCaseNodesTask.progress.gettingCaseNodesListing=Querying coordination service for case znodes"
|
||||
})
|
||||
public void run() {
|
||||
progress.start(Bundle.CaseNodesCleanupTask_progress_startMessage());
|
||||
progress.start(Bundle.DeleteOrphanCaseNodesTask_progress_startMessage());
|
||||
try {
|
||||
progress.progress(Bundle.CaseNodesCleanupTask_progress_connectingToCoordSvc());
|
||||
logger.log(Level.INFO, "Connecting to the coordination service for orphan case node clean up"); // NON-NLS
|
||||
progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_connectingToCoordSvc());
|
||||
logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_connectingToCoordSvc());
|
||||
CoordinationService coordinationService;
|
||||
try {
|
||||
coordinationService = CoordinationService.getInstance();
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.WARNING, "Error connecting to the coordination service", ex); // NON-NLS
|
||||
logger.log(Level.SEVERE, "Error connecting to the coordination service", ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
progress.progress(Bundle.CaseNodesCleanupTask_progress_gettingCaseNodesListing());
|
||||
logger.log(Level.INFO, "Querying coordination service for case nodes for orphaned case node clean up"); // NON-NLS
|
||||
progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_gettingCaseNodesListing());
|
||||
logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_gettingCaseNodesListing());
|
||||
List<CaseNodeData> nodeDataList;
|
||||
try {
|
||||
nodeDataList = CaseNodeDataCollector.getNodeData();
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.WARNING, "Error collecting case node data", ex); // NON-NLS
|
||||
logger.log(Level.SEVERE, "Error collecting case node data", ex); //NON-NLS
|
||||
return;
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.WARNING, "Unexpected interrupt while collecting case node data", ex); // NON-NLS
|
||||
} catch (InterruptedException unused) {
|
||||
logger.log(Level.WARNING, "Task cancelled while collecting case node data"); //NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
@ -100,8 +100,8 @@ final class CaseNodesCleanupTask implements Runnable {
|
||||
nodePath = CoordinationServiceUtils.getCaseDirectoryNodePath(caseDirectoryPath);
|
||||
deleteNode(coordinationService, caseName, nodePath);
|
||||
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.WARNING, String.format("Unexpected interrupt while deleting orphaned znode %s for %s", nodePath, caseName), ex); // NON-NLS
|
||||
} catch (InterruptedException unused) {
|
||||
logger.log(Level.WARNING, String.format("Task cancelled while deleting orphaned znode %s for %s", nodePath, caseName)); //NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -113,9 +113,9 @@ final class CaseNodesCleanupTask implements Runnable {
|
||||
* where there is no call to get() on a Future<Void> associated with
|
||||
* the task, so this ensures that any such errors get logged.
|
||||
*/
|
||||
logger.log(Level.SEVERE, "Unexpected error during orphan case znode cleanup", ex); // NON-NLS
|
||||
logger.log(Level.SEVERE, "Unexpected error during orphan case znode cleanup", ex); //NON-NLS
|
||||
throw ex;
|
||||
|
||||
|
||||
} finally {
|
||||
progress.finish();
|
||||
}
|
||||
@ -132,16 +132,16 @@ final class CaseNodesCleanupTask implements Runnable {
|
||||
* interrupted during the delete operation.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"# {0} - node path", "CaseNodesCleanupTask.progress.deletingOrphanedCaseNode=Deleting orphaned case node {0}..."
|
||||
"# {0} - node path", "DeleteOrphanCaseNodesTask.progress.deletingOrphanedCaseNode=Deleting orphaned case znode {0}"
|
||||
})
|
||||
private void deleteNode(CoordinationService coordinationService, String caseName, String nodePath) throws InterruptedException {
|
||||
try {
|
||||
progress.progress(Bundle.CaseNodesCleanupTask_progress_deletingOrphanedCaseNode(nodePath));
|
||||
logger.log(Level.INFO, String.format("Deleting orphaned case node %s for %s", nodePath, caseName)); // NON-NLS
|
||||
progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_deletingOrphanedCaseNode(nodePath));
|
||||
logger.log(Level.INFO, String.format("Deleting orphaned case node %s for %s", nodePath, caseName)); //NON-NLS
|
||||
coordinationService.deleteNode(CoordinationService.CategoryNode.CASES, nodePath);
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
if (!DeleteCaseUtils.isNoNodeException(ex)) {
|
||||
logger.log(Level.SEVERE, String.format("Error deleting orphaned case node %s for %s", nodePath, caseName), ex); // NON-NLS
|
||||
logger.log(Level.SEVERE, String.format("Error deleting orphaned case node %s for %s", nodePath, caseName), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||
|
||||
/**
|
||||
* An action class that kicks off a cancellable orphaned manifest file nodes
|
||||
* deletion task that runs in a background thread and reports progress using an
|
||||
* application frame progress bar.
|
||||
*/
|
||||
public class DeleteOrphanManifestNodesAction extends BackgroundTaskAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an instance of an action class that kicks off a cancellable
|
||||
* orphaned manifest file nodes deletion task that runs in a background
|
||||
* thread and reports progress using an application frame progress bar.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"DeleteOrphanManifestNodesAction.progressDisplayName=Cleanup Manifest File Znodes"
|
||||
})
|
||||
DeleteOrphanManifestNodesAction() {
|
||||
super(Bundle.DeleteOrphanManifestNodesAction_progressDisplayName(), Bundle.DeleteOrphanManifestNodesAction_progressDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
Runnable getTask(ProgressIndicator progress) {
|
||||
return new DeleteOrphanManifestNodesTask(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeleteOrphanManifestNodesAction clone() throws CloneNotSupportedException {
|
||||
super.clone();
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019-2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.progress.ProgressIndicator;
|
||||
|
||||
/**
|
||||
* A task class for cleaning up auto ingest job coordination service nodes for
|
||||
* which there is no longer a corresponding manifest file.
|
||||
*/
|
||||
final class DeleteOrphanManifestNodesTask implements Runnable {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DeleteOrphanManifestNodesTask.class.getName());
|
||||
private final ProgressIndicator progress;
|
||||
|
||||
/**
|
||||
* Constucts an instance of a task for cleaning up case coordination service
|
||||
* nodes for which there is no longer a corresponding case.
|
||||
*
|
||||
* @param progress
|
||||
*/
|
||||
DeleteOrphanManifestNodesTask(ProgressIndicator progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"DeleteOrphanManifestNodesTask.progress.startMessage=Starting orphaned manifest file znode cleanup",
|
||||
"DeleteOrphanManifestNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service",
|
||||
"DeleteOrphanManifestNodesTask.progress.gettingManifestNodes=Querying the coordination service for manifest file znodes",
|
||||
"# {0} - node path", "DeleteOrphanManifestNodesTask.progress.deletingOrphanedManifestNode=Deleting orphaned manifest file znode {0}"
|
||||
})
|
||||
public void run() {
|
||||
progress.start(Bundle.DeleteOrphanManifestNodesTask_progress_startMessage());
|
||||
try {
|
||||
progress.progress(Bundle.DeleteOrphanManifestNodesTask_progress_connectingToCoordSvc());
|
||||
logger.log(Level.INFO, Bundle.DeleteOrphanManifestNodesTask_progress_connectingToCoordSvc());
|
||||
CoordinationService coordinationService;
|
||||
try {
|
||||
coordinationService = CoordinationService.getInstance();
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.SEVERE, "Error connecting to the coordination service", ex); // NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
progress.progress(Bundle.DeleteOrphanManifestNodesTask_progress_gettingManifestNodes());
|
||||
logger.log(Level.INFO, Bundle.DeleteOrphanManifestNodesTask_progress_gettingManifestNodes());
|
||||
List<AutoIngestJobNodeData> nodeDataList;
|
||||
try {
|
||||
nodeDataList = AutoIngestJobNodeDataCollector.getNodeData();
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.SEVERE, "Error collecting auto ingest job node data", ex); // NON-NLS
|
||||
return;
|
||||
} catch (InterruptedException unused) {
|
||||
logger.log(Level.WARNING, "Task cancelled while collecting auto ingest job node data"); // NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
for (AutoIngestJobNodeData nodeData : nodeDataList) {
|
||||
final String caseName = nodeData.getCaseName();
|
||||
final Path manifestFilePath = nodeData.getManifestFilePath();
|
||||
final File manifestFile = manifestFilePath.toFile();
|
||||
if (!manifestFile.exists()) {
|
||||
try {
|
||||
progress.progress(Bundle.DeleteOrphanManifestNodesTask_progress_deletingOrphanedManifestNode(manifestFilePath));
|
||||
logger.log(Level.INFO, String.format("Deleting orphaned manifest file znode %s for %s", manifestFilePath, caseName));
|
||||
coordinationService.deleteNode(CoordinationService.CategoryNode.MANIFESTS, manifestFilePath.toString());
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
if (!DeleteCaseUtils.isNoNodeException(ex)) {
|
||||
logger.log(Level.SEVERE, String.format("Error deleting %s znode for %s", manifestFilePath, caseName), ex); // NON-NLS
|
||||
}
|
||||
} catch (InterruptedException unused) {
|
||||
logger.log(Level.WARNING, String.format("Task cancelled while deleting %s znode for %s", manifestFilePath, caseName)); // NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
/*
|
||||
* This is an unexpected runtime exceptions firewall. It is here
|
||||
* because this task is designed to be able to be run in scenarios
|
||||
* where there is no call to get() on a Future<Void> associated with
|
||||
* the task, so this ensures that any such errors get logged.
|
||||
*/
|
||||
logger.log(Level.SEVERE, "Unexpected error deleting orphan manifest file znodes", ex); // NON-NLS
|
||||
throw ex;
|
||||
|
||||
} finally {
|
||||
progress.finish();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user