mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Initial commit of case znodes cleanup admin action
This commit is contained in:
parent
6ac9b96f1b
commit
b52d15e437
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.awt.event.ActionEvent;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import javax.swing.AbstractAction;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.progress.AppFrameProgressBar;
|
||||
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.
|
||||
*/
|
||||
final class CaseNodesCleanupAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"CaseNodesCleanupAction.progressDisplayName=Cleanup Case Znodes"
|
||||
})
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
final AppFrameProgressBar progress = new AppFrameProgressBar(Bundle.CaseNodesCleanupAction_progressDisplayName());
|
||||
final TaskCancellable taskCanceller = new TaskCancellable(progress);
|
||||
progress.setCancellationBehavior(taskCanceller);
|
||||
final Runnable task = new CaseNodesCleanupTask(progress);
|
||||
final FutureTask<Void> future = new FutureTask<>(task, null);
|
||||
taskCanceller.setFuture(future);
|
||||
new Thread(future).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseNodesCleanupAction clone() throws CloneNotSupportedException {
|
||||
super.clone();
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
|
||||
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeDataCollector;
|
||||
import org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils;
|
||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
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
|
||||
* longer a corresponding case.
|
||||
*/
|
||||
final class CaseNodesCleanupTask 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
|
||||
* nodes for which there is no longer a corresponding case.
|
||||
*
|
||||
* @param progress
|
||||
*/
|
||||
CaseNodesCleanupTask(ProgressIndicator progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
CoordinationService coordinationService;
|
||||
try {
|
||||
coordinationService = CoordinationService.getInstance();
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.WARNING, "Error connecting to the coordination service", ex); // NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
List<CaseNodeData> nodeDataList;
|
||||
try {
|
||||
nodeDataList = CaseNodeDataCollector.getNodeData();
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
logger.log(Level.WARNING, "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
|
||||
return;
|
||||
}
|
||||
|
||||
for (CaseNodeData nodeData : nodeDataList) {
|
||||
final Path caseDirectoryPath = nodeData.getDirectory();
|
||||
final File caseDirectory = caseDirectoryPath.toFile();
|
||||
if (!caseDirectory.exists()) {
|
||||
String caseName = nodeData.getDisplayName();
|
||||
String nodePath = ""; // NON-NLS
|
||||
try {
|
||||
nodePath = CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath);
|
||||
deleteNode(coordinationService, caseName, nodePath);
|
||||
|
||||
nodePath = CoordinationServiceUtils.getCaseResourcesNodePath(caseDirectoryPath);
|
||||
deleteNode(coordinationService, caseName, nodePath);
|
||||
|
||||
nodePath = CoordinationServiceUtils.getCaseAutoIngestLogNodePath(caseDirectoryPath);
|
||||
deleteNode(coordinationService, caseName, nodePath);
|
||||
|
||||
nodePath = CoordinationServiceUtils.getCaseDirectoryNodePath(caseDirectoryPath);
|
||||
deleteNode(coordinationService, caseName, nodePath);
|
||||
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.WARNING, String.format("Unexpected interrupt while deleting znode %s for %s", nodePath, caseName), ex); // NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to delete a case coordination service node.
|
||||
*
|
||||
* @param coordinationService The ccordination service.
|
||||
* @param caseName The case name.
|
||||
* @param nodePath The path of the node to delete.
|
||||
*
|
||||
* @throws InterruptedException If the thread executing this task is
|
||||
* interrupted during the delete operation.
|
||||
*/
|
||||
private static void deleteNode(CoordinationService coordinationService, String caseName, String nodePath) throws InterruptedException {
|
||||
try {
|
||||
coordinationService.deleteNode(CoordinationService.CategoryNode.CASES, nodePath);
|
||||
} catch (CoordinationService.CoordinationServiceException ex) {
|
||||
if (!DeleteCaseUtils.isNoNodeException(ex)) {
|
||||
logger.log(Level.SEVERE, String.format("Error deleting %s znode for %s", nodePath, caseName), ex); // NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||
|
||||
/**
|
||||
* A utility class supplying helper methods for case deletion.
|
||||
*/
|
||||
final class DeleteCaseUtils {
|
||||
|
||||
private static final String NO_NODE_ERROR_MSG_FRAGMENT = "KeeperErrorCode = NoNode";
|
||||
|
||||
/**
|
||||
* Examines a coordination service exception to try to determine if it is a
|
||||
* no node exception.
|
||||
*
|
||||
* @param ex A coordination service exception.
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
static boolean isNoNodeException(CoordinationService.CoordinationServiceException ex) {
|
||||
boolean isNodeNodeEx = false;
|
||||
Throwable cause = ex.getCause();
|
||||
if (cause != null) {
|
||||
String causeMessage = cause.getMessage();
|
||||
isNodeNodeEx = causeMessage.contains(NO_NODE_ERROR_MSG_FRAGMENT);
|
||||
}
|
||||
return isNodeNodeEx;
|
||||
}
|
||||
|
||||
/**
|
||||
* A private constructor to prevent instantiation.
|
||||
*/
|
||||
private DeleteCaseUtils() {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user