diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java index 0507e55cd6..753ccd598a 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * + * * Copyright 2011-2016 Basis Technology Corp. * Contact: carrier sleuthkit 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. @@ -163,12 +163,22 @@ public final class ExecUtil { process.waitFor(timeOut, units); if (process.isAlive() && terminator.shouldTerminateProcess()) { killProcess(process); + try { + process.waitFor(); //waiting to help ensure process is shutdown before calling interrupt() or returning + } catch (InterruptedException exx) { + Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, String.format("Wait for process termination following killProcess was interrupted for command %s", processBuilder.command().get(0))); + } } } while (process.isAlive()); } catch (InterruptedException ex) { if (process.isAlive()) { killProcess(process); } + try { + process.waitFor(); //waiting to help ensure process is shutdown before calling interrupt() or returning + } catch (InterruptedException exx) { + Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, String.format("Wait for process termination following killProcess was interrupted for command %s", processBuilder.command().get(0))); + } Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, "Thread interrupted while running {0}", processBuilder.command().get(0)); // NON-NLS Thread.currentThread().interrupt(); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexFinder.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexFinder.java index 2dae510a19..d1345dfa1d 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexFinder.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexFinder.java @@ -20,11 +20,13 @@ package org.sleuthkit.autopsy.keywordsearch; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.logging.Level; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.math.NumberUtils; import org.sleuthkit.autopsy.casemodule.Case; @@ -99,10 +101,10 @@ class IndexFinder { } /** - * Creates a copy of an existing Solr index. + * Creates a copy of an existing Solr index. * - * @param indexToUpgrade Index object to create a copy of - * @param context AutopsyService.CaseContext object + * @param indexToUpgrade Index object to create a copy of + * @param context AutopsyService.CaseContext object * * @return The absolute path of the new Solr index directory * @@ -120,20 +122,31 @@ class IndexFinder { List contents = getAllContentsInFolder(targetDirPath.getAbsolutePath()); if (!contents.isEmpty()) { // target directory is not empty - throw new AutopsyService.AutopsyServiceException("Directory to store the upgraded index must be empty " + targetDirPath.getAbsolutePath()); + try { + FileUtils.deleteDirectory(targetDirPath.getParentFile()); //We don't want partial copies + } catch (IOException | IllegalArgumentException deleteEx) { + throw new AutopsyService.AutopsyServiceException("Failed to delete existing directory to store the upgraded index " + targetDirPath.getAbsolutePath() + "which was not empty", deleteEx); + } + logger.log(Level.WARNING, String.format("Directory %s existed with contents and was deleted so the upgrade could proceed", indexFolderName)); } } targetDirPath.mkdirs(); FileUtils.copyDirectory(new File(indexToUpgrade.getIndexPath()), targetDirPath); return targetDirPath.getAbsolutePath(); } catch (AutopsyService.AutopsyServiceException | IOException ex) { + try { + Path targetDirPath = Paths.get(context.getCase().getModuleDirectory(), KWS_OUTPUT_FOLDER_NAME, KWS_DATA_FOLDER_NAME, indexFolderName); //NON-NLS + FileUtils.deleteDirectory(targetDirPath.toFile()); //We don't want partial copies + } catch (IOException | IllegalArgumentException deleteEx) { + logger.log(Level.SEVERE, String.format("Failed to delete %s when upgrade cancelled", indexFolderName), deleteEx); + } throw new AutopsyService.AutopsyServiceException("Error occurred while creating a copy of keyword search index", ex); } } /** - * Find existing Solr 4 Schema 1.8 index directory location for the case. This is done via - * subdirectory search of all existing + * Find existing Solr 4 Schema 1.8 index directory location for the case. + * This is done via subdirectory search of all existing * "ModuleOutput/node_name/keywordsearch/data/" folders. * * @param theCase the case to get index dir for @@ -146,8 +159,9 @@ class IndexFinder { // multi user cases contain a subfolder for each node that participated in case ingest or review. // Any one (but only one!) of those subfolders may contain the actual index. /* - * NOTE: the following path is an example of valid Solr 4 Schema 1.8 multi-user index - * path: X:\Case\ingest1\ModuleOutput\keywordsearch\data\index + * NOTE: the following path is an example of valid Solr 4 Schema 1.8 + * multi-user index path: + * X:\Case\ingest1\ModuleOutput\keywordsearch\data\index */ // get a list of all folder's contents @@ -169,8 +183,8 @@ class IndexFinder { } else { // single user case /* - * NOTE: the following path is valid single user Solr 4 Schema 1.8 index - * path: X:\Case\ModuleOutput\keywordsearch\data\index + * NOTE: the following path is valid single user Solr 4 Schema 1.8 + * index path: X:\Case\ModuleOutput\keywordsearch\data\index */ File path = Paths.get(theCase.getModuleDirectory(), KWS_OUTPUT_FOLDER_NAME, KWS_DATA_FOLDER_NAME, INDEX_FOLDER_NAME).toFile(); //NON-NLS // must be a non-empty index directory diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexUpgrader.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexUpgrader.java index 944afa4e3c..d355db1296 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexUpgrader.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/IndexUpgrader.java @@ -186,7 +186,7 @@ class IndexUpgrader { * * @return The new Solr index version. */ - private int upgradeSolrIndexVersion5to6(int currentIndexVersion, String solr5IndexPath, String tempResultsDir, UserCancelledProcessTerminator terminatior) throws AutopsyService.AutopsyServiceException, SecurityException, IOException { + private int upgradeSolrIndexVersion5to6(int currentIndexVersion, String solr5IndexPath, String tempResultsDir, UserCancelledProcessTerminator terminator) throws AutopsyService.AutopsyServiceException, SecurityException, IOException { if (currentIndexVersion != 5) { return currentIndexVersion; } @@ -218,7 +218,11 @@ class IndexUpgrader { ProcessBuilder processBuilder = new ProcessBuilder(commandLine); processBuilder.redirectOutput(new File(outputFileFullPath)); processBuilder.redirectError(new File(errFileFullPath)); - ExecUtil.execute(processBuilder, terminatior); + try { + ExecUtil.execute(processBuilder, terminator); + } catch (SecurityException | IOException ex) { + throw new AutopsyService.AutopsyServiceException("Error executing Solr 4 to Solr 5 upgrade tool"); + } // alternatively can execute lucene upgrade command from the folder where lucene jars are located // java -cp ".;lucene-core-6.2.1.jar;lucene-backward-codecs-6.2.1.jar;lucene-codecs-6.2.1.jar;lucene-analyzers-common-6.2.1.jar" org.apache.lucene.index.IndexUpgrader \path\to\index