Merge pull request #2736 from sleuthkit/release-4.4.0

Release 4.4.0
This commit is contained in:
Richard Cordovano 2017-04-21 11:28:34 -04:00 committed by GitHub
commit a4f8635857
17 changed files with 52 additions and 574 deletions

View File

@ -64,7 +64,6 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
import org.sleuthkit.autopsy.datamodel.EmptyNode;
import org.sleuthkit.autopsy.datamodel.ExtractedContent;
import org.sleuthkit.autopsy.datamodel.FileTypesByMimeType;
import org.sleuthkit.autopsy.datamodel.KeywordHits;
import org.sleuthkit.autopsy.datamodel.Reports;
import org.sleuthkit.autopsy.datamodel.Results;
import org.sleuthkit.autopsy.datamodel.ResultsNode;
@ -414,8 +413,9 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
tree.expandNode(results);
Children resultsChilds = results.getChildren();
tree.expandNode(resultsChilds.findChild(KeywordHits.NAME));
tree.expandNode(resultsChilds.findChild(ExtractedContent.NAME));
for (Node n : resultsChilds.getNodes()) {
tree.expandNode(n);
}
Accounts accounts = resultsChilds.findChild(Accounts.NAME).getLookup().lookup(Accounts.class);
showRejectedCheckBox.setAction(accounts.newToggleShowRejectedAction());

View File

@ -1,69 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 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 solr4indexupgrade;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexUpgrader;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
/**
* This class upgrades Solr 4 index to Solr 5 index.
*/
public class Solr4IndexUpgrade {
/**
* Upgrades Solr 4 index to Solr 5 index.
* @param args the command line arguments
* @throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("Must pass 1 input argument");
showUsage();
throw new IllegalArgumentException("Must pass 1 argument");
}
String solr4path = args[0];
upgrade(solr4path);
}
/**
* Display usage information for JDiff.
*/
public static void showUsage() {
System.out.println("usage: java -jar Solr4IndexUpgrade.jar \"\\path\\to\\index\"");
}
private static void upgrade(String solr4path) throws IOException {
Directory dir = FSDirectory.open(new File(solr4path).toPath());
// upgrade from Solr 4 to Solr 5
IndexWriterConfig config;
Analyzer analyzer = new StandardAnalyzer();
config = new IndexWriterConfig(analyzer);
IndexUpgrader upgrader = new IndexUpgrader(dir, config, true);
upgrader.upgrade();
}
}

View File

@ -1,70 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 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 solr5indexupgrade;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.UpgradeIndexMergePolicy;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
/**
* This class upgrades Solr 5 index to Solr 6 index.
*/
public class Solr5IndexUpgrade {
/**
* Upgrades Solr 5 index to Solr 6 index.
* @param args the command line arguments
* @throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("Must pass 1 argument");
showUsage();
throw new IllegalArgumentException("Must pass 1 argument");
}
String solr5path = args[0];
upgrade(solr5path);
}
/**
* Display usage information for JDiff.
*/
public static void showUsage() {
System.out.println("usage: java -jar Solr5IndexUpgrade.jar \"\\path\\to\\index\"");
}
private static void upgrade(String solr4path) throws IOException {
Directory dir = FSDirectory.open(new File(solr4path).toPath());
// upgrade from Solr 5 to Solr 6
IndexWriterConfig iwc = new IndexWriterConfig(new KeywordAnalyzer());
iwc.setMergePolicy(new UpgradeIndexMergePolicy(iwc.getMergePolicy()));
IndexWriter w = new IndexWriter(dir, iwc);
w.forceMerge(1);
w.close();
}
}

View File

@ -14,14 +14,7 @@
</copy>
</target>
<target name="get-solr-upgrader-jars" description="copy the solr index upgrader jars into release">
<copy file="SolrUpgradeTools/Solr4IndexUpgrade.jar"
todir="${basedir}/release/Solr4to5IndexUpgrade" />
<copy file="SolrUpgradeTools/Solr5IndexUpgrade.jar"
todir="${basedir}/release/Solr5to6IndexUpgrade" />
</target>
<target name="get-deps" depends="init-ivy, get-solr-deployment,get-solr-upgrader-jars">
<target name="get-deps" depends="init-ivy, get-solr-deployment">
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
<ivy:resolve/>
<ivy:retrieve conf="autopsy" pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
@ -31,8 +24,6 @@
<ivy:retrieve conf="solr-libs" pattern="${basedir}/release/solr/solr/lib/[artifact]-[revision](-[classifier]).[ext]" />
<ivy:retrieve conf="slf4j-libs" pattern="${basedir}/release/solr/lib/ext/[artifact]-[revision](-[classifier]).[ext]" />
<ivy:retrieve conf="servlet" pattern="${basedir}/release/solr/lib/servlet-api-3.0.jar" />
<ivy:retrieve conf="solr4to5" pattern="${basedir}/release/Solr4to5IndexUpgrade/lib/[artifact]-[revision](-[classifier]).[ext]" />
<ivy:retrieve conf="solr5to6" pattern="${basedir}/release/Solr5to6IndexUpgrade/lib/[artifact]-[revision](-[classifier]).[ext]" />
</target>
<target name="init" depends="get-deps, harness.init"/>

View File

@ -19,15 +19,11 @@
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;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -42,7 +38,7 @@ class IndexFinder {
private static final String KWS_OUTPUT_FOLDER_NAME = "keywordsearch";
private static final String KWS_DATA_FOLDER_NAME = "data";
private static final String INDEX_FOLDER_NAME = "index";
private static final String CURRENT_SOLR_VERSION = "6";
private static final String CURRENT_SOLR_VERSION = "4";
private static final String CURRENT_SOLR_SCHEMA_VERSION = "2.0";
static String getCurrentSolrVersion() {
@ -54,10 +50,8 @@ class IndexFinder {
}
static Index findLatestVersionIndexDir(List<Index> allIndexes) {
String indexFolderName = "solr" + CURRENT_SOLR_VERSION + "_schema" + CURRENT_SOLR_SCHEMA_VERSION;
for (Index index : allIndexes) {
String path = index.getIndexPath();
if (path.contains(indexFolderName)) {
if (index.getSolrVersion().equals(CURRENT_SOLR_VERSION) && index.getSchemaVersion().equals(CURRENT_SOLR_SCHEMA_VERSION)) {
return index;
}
}
@ -74,7 +68,7 @@ class IndexFinder {
return new Index(targetDirPath.getAbsolutePath(), CURRENT_SOLR_VERSION, CURRENT_SOLR_SCHEMA_VERSION, "", theCase.getName());
}
static Index identifyIndexToUpgrade(List<Index> allIndexes) {
static Index identifyIndexToUse(List<Index> allIndexes) {
/*
* NOTE: All of the following paths are valid multi-user index paths:
* (Solr 4, schema 1.8)
@ -100,50 +94,6 @@ class IndexFinder {
return bestCandidateIndex;
}
/**
* Creates a copy of an existing Solr index.
*
* @param indexToUpgrade Index object to create a copy of
* @param context AutopsyService.CaseContext object
*
* @return The absolute path of the new Solr index directory
*
* @throws
* org.sleuthkit.autopsy.framework.AutopsyService.AutopsyServiceException
*/
static String copyExistingIndex(Index indexToUpgrade, AutopsyService.CaseContext context) throws AutopsyService.AutopsyServiceException {
// folder name for the upgraded index should be latest Solr version BUT schema verion of the existing index
String indexFolderName = "solr" + CURRENT_SOLR_VERSION + "_schema" + indexToUpgrade.getSchemaVersion();
try {
// new index should be stored in "\ModuleOutput\keywordsearch\data\solrX_schemaY\index"
File targetDirPath = Paths.get(context.getCase().getModuleDirectory(), KWS_OUTPUT_FOLDER_NAME, KWS_DATA_FOLDER_NAME, indexFolderName, INDEX_FOLDER_NAME).toFile(); //NON-NLS
if (targetDirPath.exists()) {
// targetDirPath should not exist, at least the target directory should be empty
List<File> contents = getAllContentsInFolder(targetDirPath.getAbsolutePath());
if (!contents.isEmpty()) {
// target directory is not empty
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

View File

@ -1,252 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ExecUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.framework.AutopsyService;
import org.sleuthkit.autopsy.framework.ProgressIndicator;
/**
* This class handles the task of upgrading old indexes to the latest supported
* Solr version.
*/
class IndexUpgrader {
private static final Logger logger = Logger.getLogger(IndexFinder.class.getName());
private final String JAVA_PATH;
IndexUpgrader() {
JAVA_PATH = PlatformUtil.getJavaPath();
}
/**
* Perform Solr text index upgrade to the latest supported version of Solr.
*
* @param newIndexDir Full path to directory of Solr index to be
* upgraded
* @param indexToUpgrade Index object of the existing Solr index
* @param context AutopsyService.CaseContext object
* @param numCompletedWorkUnits Number of completed progress units so far
*
* @return Index object of the upgraded index, null if cancelled.
*
* @throws
* org.sleuthkit.autopsy.framework.AutopsyService.AutopsyServiceException
*/
@NbBundle.Messages({
"SolrSearch.upgrade4to5.msg=Upgrading existing text index from Solr 4 to Solr 5",
"SolrSearch.upgrade5to6.msg=Upgrading existing text index from Solr 5 to Solr 6",
"SolrSearch.upgradeFailed.msg=Upgrade of existing Solr text index failed, deleting temporary directories",})
Index performIndexUpgrade(String newIndexDir, Index indexToUpgrade, AutopsyService.CaseContext context, int startingNumCompletedWorkUnits) throws AutopsyService.AutopsyServiceException {
int numCompletedWorkUnits = startingNumCompletedWorkUnits;
ProgressIndicator progress = context.getProgressIndicator();
// Run the upgrade tools on the contents (core) in ModuleOutput/keywordsearch/data/solrX_schema_Y/index
String tempResultsDir = context.getCase().getTempDirectory();
File tmpDir = Paths.get(tempResultsDir, "IndexUpgrade").toFile(); //NON-NLS
tmpDir.mkdirs();
Index upgradedIndex;
int currentSolrVersion = NumberUtils.toInt(indexToUpgrade.getSolrVersion());
try {
if (context.cancelRequested()) {
return null;
}
// create process terminator that will monitor the cancellation flag
UserCancelledProcessTerminator terminatior = new UserCancelledProcessTerminator(context);
// upgrade from Solr 4 to 5
numCompletedWorkUnits++;
progress.progress(Bundle.SolrSearch_upgrade4to5_msg(), numCompletedWorkUnits);
currentSolrVersion = upgradeSolrIndexVersion4to5(currentSolrVersion, newIndexDir, tempResultsDir, terminatior);
if (Thread.currentThread().isInterrupted() || context.cancelRequested()) {
return null;
}
// upgrade from Solr 5 to 6
numCompletedWorkUnits++;
progress.progress(Bundle.SolrSearch_upgrade5to6_msg(), numCompletedWorkUnits);
currentSolrVersion = upgradeSolrIndexVersion5to6(currentSolrVersion, newIndexDir, tempResultsDir, terminatior);
if (Thread.currentThread().isInterrupted() || context.cancelRequested()) {
return null;
}
// create upgraded index object
upgradedIndex = new Index(newIndexDir, Integer.toString(currentSolrVersion), indexToUpgrade.getSchemaVersion(), context.getCase().getTextIndexName(), context.getCase().getName());
return upgradedIndex;
} catch (Exception ex) {
// catch-all firewall for exceptions thrown by Solr upgrade tools
// upgrade did not complete, delete the new index directories
progress.progress(Bundle.SolrSearch_upgradeFailed_msg(), numCompletedWorkUnits);
File newIndexVersionDir = new File(newIndexDir).getParentFile();
try {
FileUtils.deleteDirectory(newIndexVersionDir);
} catch (IOException exx) {
logger.log(Level.SEVERE, String.format("Failed to delete %s when upgrade failed", newIndexVersionDir), exx);
}
throw new AutopsyService.AutopsyServiceException("Exception while running Solr index upgrade in " + newIndexDir, ex); //NON-NLS
}
}
/**
* Upgrades Solr index from version 4 to 5.
*
* @param currentIndexVersion Current Solr index version
* @param solr4IndexPath Full path to Solr v4 index directory
* @param tempResultsDir Path to directory where to store log output
* @param terminator Implementation of ExecUtil.ProcessTerminator
* to terminate upgrade process
*
* @return The new Solr index version.
*/
private int upgradeSolrIndexVersion4to5(int currentIndexVersion, String solr4IndexPath, String tempResultsDir, UserCancelledProcessTerminator terminator) throws AutopsyService.AutopsyServiceException {
if (currentIndexVersion != 4) {
return currentIndexVersion;
}
String outputFileName = "output.txt";
logger.log(Level.INFO, "Upgrading KWS index {0} from Solr 4 to Solr 5", solr4IndexPath); //NON-NLS
// find the index upgrade tool
final File upgradeToolFolder = InstalledFileLocator.getDefault().locate("Solr4to5IndexUpgrade", IndexFinder.class.getPackage().getName(), false); //NON-NLS
if (upgradeToolFolder == null) {
throw new AutopsyService.AutopsyServiceException("Unable to locate Sorl 4 to Solr 5 upgrade tool");
}
// full path to index upgrade jar file
File upgradeJarPath = Paths.get(upgradeToolFolder.getAbsolutePath(), "Solr4IndexUpgrade.jar").toFile();
if (!upgradeJarPath.exists() || !upgradeJarPath.isFile()) {
throw new AutopsyService.AutopsyServiceException("Unable to locate Solr 4 to Solr 5 upgrade tool's JAR file");
}
// create log output directory if it doesn't exist
new File(tempResultsDir).mkdirs();
final String outputFileFullPath = Paths.get(tempResultsDir, outputFileName).toString();
final String errFileFullPath = Paths.get(tempResultsDir, outputFileName + ".err").toString(); //NON-NLS
List<String> commandLine = new ArrayList<>();
commandLine.add(JAVA_PATH);
commandLine.add("-jar");
commandLine.add(upgradeJarPath.getAbsolutePath());
commandLine.add(solr4IndexPath);
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
processBuilder.redirectOutput(new File(outputFileFullPath));
processBuilder.redirectError(new File(errFileFullPath));
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-5.5.1.jar;lucene-backward-codecs-5.5.1.jar;lucene-codecs-5.5.1.jar;lucene-analyzers-common-5.5.1.jar" org.apache.lucene.index.IndexUpgrader \path\to\index
return 5;
}
/**
* Upgrades Solr index from version 5 to 6.
*
* @param currentIndexVersion Current Solr index version
* @param solr5IndexPath Full path to Solr v5 index directory
* @param tempResultsDir Path to directory where to store log output
* @param terminatior Implementation of ExecUtil.ProcessTerminator
* to terminate upgrade process
*
* @return The new Solr index version.
*/
private int upgradeSolrIndexVersion5to6(int currentIndexVersion, String solr5IndexPath, String tempResultsDir, UserCancelledProcessTerminator terminator) throws AutopsyService.AutopsyServiceException, SecurityException, IOException {
if (currentIndexVersion != 5) {
return currentIndexVersion;
}
String outputFileName = "output.txt";
logger.log(Level.INFO, "Upgrading KWS index {0} from Sorl 5 to Solr 6", solr5IndexPath); //NON-NLS
// find the index upgrade tool
final File upgradeToolFolder = InstalledFileLocator.getDefault().locate("Solr5to6IndexUpgrade", IndexFinder.class.getPackage().getName(), false); //NON-NLS
if (upgradeToolFolder == null) {
throw new AutopsyService.AutopsyServiceException("Unable to locate Sorl 5 to Solr 6 upgrade tool");
}
// full path to index upgrade jar file
File upgradeJarPath = Paths.get(upgradeToolFolder.getAbsolutePath(), "Solr5IndexUpgrade.jar").toFile();
if (!upgradeJarPath.exists() || !upgradeJarPath.isFile()) {
throw new AutopsyService.AutopsyServiceException("Unable to locate Sorl 5 to Solr 6 upgrade tool's JAR file");
}
// create log output directory if it doesn't exist
new File(tempResultsDir).mkdirs();
final String outputFileFullPath = Paths.get(tempResultsDir, outputFileName).toString();
final String errFileFullPath = Paths.get(tempResultsDir, outputFileName + ".err").toString(); //NON-NLS
List<String> commandLine = new ArrayList<>();
commandLine.add(JAVA_PATH);
commandLine.add("-jar");
commandLine.add(upgradeJarPath.getAbsolutePath());
commandLine.add(solr5IndexPath);
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
processBuilder.redirectOutput(new File(outputFileFullPath));
processBuilder.redirectError(new File(errFileFullPath));
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
return 6;
}
/**
* Process terminator that can be used to kill Solr index upgrade processes
* if a user has requested to cancel the upgrade.
*/
private class UserCancelledProcessTerminator implements ExecUtil.ProcessTerminator {
AutopsyService.CaseContext context = null;
UserCancelledProcessTerminator(AutopsyService.CaseContext context) {
this.context = context;
}
@Override
public boolean shouldTerminateProcess() {
if (context.cancelRequested()) {
return true;
}
return false;
}
}
}

View File

@ -18,7 +18,6 @@
*/
package org.sleuthkit.autopsy.keywordsearch;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
@ -29,7 +28,6 @@ import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
@ -184,7 +182,7 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
}
/**
* Creates/opens/upgrades the Solr core/text index for a case
* Creates/opens the Solr core/text index for a case
*
* @param context The case context.
*
@ -198,13 +196,12 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
"SolrSearch.findingIndexes.msg=Looking for existing text index directories",
"SolrSearch.creatingNewIndex.msg=Creating new text index",
"SolrSearch.checkingForLatestIndex.msg=Looking for text index with latest Solr and schema version",
"SolrSearch.indentifyingIndex.msg=Identifying text index for upgrade",
"SolrSearch.copyIndex.msg=Copying existing text index",
"SolrSearch.indentifyingIndex.msg=Identifying text index to use",
"SolrSearch.openCore.msg=Opening text index",
"SolrSearch.complete.msg=Text index successfully opened"})
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
ProgressIndicator progress = context.getProgressIndicator();
int totalNumProgressUnits = 8;
int totalNumProgressUnits = 7;
int progressUnitsCompleted = 0;
String caseDirPath = context.getCase().getCaseDirectory();
@ -224,7 +221,7 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
}
} else {
// metadata file doesn't exist.
// do case subdirectory search to look for Solr 4 Schema 1.8 indexes that can be upgraded
// do case subdirectory search to look for Solr 4 Schema 1.8 indexes
progressUnitsCompleted++;
progress.progress(Bundle.SolrSearch_findingIndexes_msg(), progressUnitsCompleted);
Index oldIndex = IndexFinder.findOldIndexDir(theCase);
@ -238,7 +235,7 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
return;
}
// check if we found an index that needs upgrade
// check if we found any existing indexes
Index currentVersionIndex = null;
if (indexes.isEmpty()) {
// new case that doesn't have an existing index. create new index folder
@ -256,10 +253,10 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
// found existing index(es) but none were for latest Solr version and schema version
progressUnitsCompleted++;
progress.progress(Bundle.SolrSearch_indentifyingIndex_msg(), progressUnitsCompleted);
Index indexToUpgrade = IndexFinder.identifyIndexToUpgrade(indexes);
if (indexToUpgrade == null) {
// unable to find index that can be upgraded
throw new AutopsyServiceException("Unable to find index that can be upgraded to the latest version of Solr");
Index indexToUse = IndexFinder.identifyIndexToUse(indexes);
if (indexToUse == null) {
// unable to find index that can be used
throw new AutopsyServiceException("Unable to find index that can be used for this case");
}
if (context.cancelRequested()) {
@ -267,12 +264,9 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
}
double currentSolrVersion = NumberUtils.toDouble(IndexFinder.getCurrentSolrVersion());
double indexSolrVersion = NumberUtils.toDouble(indexToUpgrade.getSolrVersion());
if (indexSolrVersion > currentSolrVersion) {
// oops!
throw new AutopsyServiceException("Unable to find index to use for Case open");
} else if (indexSolrVersion == currentSolrVersion) {
// latest Solr version but not latest schema. index should be used in read-only mode and not be upgraded.
double indexSolrVersion = NumberUtils.toDouble(indexToUse.getSolrVersion());
if (indexSolrVersion == currentSolrVersion) {
// latest Solr version but not latest schema. index should be used in read-only mode
if (RuntimeProperties.runningWithGUI()) {
// pop up a message box to indicate the read-only restrictions.
JOptionPane optionPane = new JOptionPane(
@ -292,61 +286,10 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
}
}
// proceed with case open
currentVersionIndex = indexToUpgrade;
currentVersionIndex = indexToUse;
} else {
// index needs to be upgraded to latest supported version of Solr
if (RuntimeProperties.runningWithGUI()) {
//pop up a message box to indicate the restrictions on adding additional
//text and performing regex searches
JOptionPane optionPane = new JOptionPane(
NbBundle.getMessage(this.getClass(), "SolrSearchService.IndexUpgradeDialog.msg"),
JOptionPane.WARNING_MESSAGE,
JOptionPane.YES_NO_OPTION);
try {
SwingUtilities.invokeAndWait(() -> {
JDialog dialog = optionPane.createDialog(NbBundle.getMessage(this.getClass(), "SolrSearchService.IndexUpgradeDialog.title"));
dialog.setVisible(true);
});
} catch (InterruptedException ex) {
// Cancelled
return;
} catch (InvocationTargetException ex) {
throw new AutopsyServiceException("Error displaying upgrade confirmation dialog", ex);
}
Object response = optionPane.getValue();
if (JOptionPane.NO_OPTION == (int) response) {
return;
}
}
// Copy the existing index and config set into ModuleOutput/keywordsearch/data/solrX_schema_Y/
progressUnitsCompleted++;
progress.progress(Bundle.SolrSearch_copyIndex_msg(), progressUnitsCompleted);
String newIndexDirPath = IndexFinder.copyExistingIndex(indexToUpgrade, context);
File newIndexVersionDir = new File(newIndexDirPath).getParentFile();
if (context.cancelRequested()) {
try {
FileUtils.deleteDirectory(newIndexVersionDir);
} catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Failed to delete %s when upgrade cancelled", newIndexVersionDir), ex);
}
return;
}
// upgrade the existing index to the latest supported Solr version
IndexUpgrader indexUpgrader = new IndexUpgrader();
currentVersionIndex = indexUpgrader.performIndexUpgrade(newIndexDirPath, indexToUpgrade, context, progressUnitsCompleted);
if (currentVersionIndex == null) {
try {
FileUtils.deleteDirectory(newIndexVersionDir);
} catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Failed to delete %s when upgrade cancelled", newIndexVersionDir), ex);
}
return;
}
// add current index to the list of indexes that exist for this case
indexes.add(currentVersionIndex);
throw new AutopsyServiceException("Unable to find index to use for Case open");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -7,7 +7,7 @@ A central Solr server is needed to store keyword indexes. Zookeeper is used to m
You will need:
- 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html.
- Download the latest Solr 6 installation package from https://bitnami.com/stack/solr/installer#windows. For the purposes of this guide that was the Bitnami Solr 6.2.1-2.
- Download the Apache Solr 4.10.3-0 installation package from https://sourceforge.net/projects/autopsy/files/CollaborativeServices/Solr or Direct Download Link
- Access to an installed version of Autopsy so that you can copy files from it.
- A network-accessible machine to install Solr upon. Note that the Solr process will need to write data out to the main shared storage drive, and needs adequate permissions to write to this location, which may be across a network.
@ -39,7 +39,7 @@ If you need the JRE, install it with the default settings.
The following steps will configure Solr to run using an account that will have access to the network storage.
1. Run the Bitnami installer, <i>"bitnami-solr-6.2.1-2-windows-installer.exe"</i>
1. Run the Bitnami installer, <i>"bitnami-solr-4.10.3-0-windows-installer.exe"</i>
2. If Windows prompts with User Account Control, click _Yes_
3. Follow the prompts through to completion. You do not need to <i>"Learn more about Bitnami cloud hosting"</i> so you can clear the check box.
4. If you see an error dialog like the following, you may safely ignore it.
@ -50,29 +50,28 @@ The following steps will configure Solr to run using an account that will have a
\subsection install_solr_config Solr Configuration
1. Stop the _solrJetty_ service by pressing _Start_, typing _services.msc_, pressing _Enter_, and locating the _solrJetty_ Windows service. Select the service and press _Stop the service_. If the service is already stopped and there is no _Stop the service_ available, this is okay.
2. Edit the <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\scripts\serviceinstall.bat"</i> script. You need administrator permission to change this file. The easiest way around this is to save a copy on the Desktop, edit the Desktop version, and copy the new one back over the top of the old. Windows will ask for permission to overwrite the old file; allow it. You should make the following changes to this file:
2. Edit the <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\scripts\serviceinstall.bat"</i> script. You need administrator permission to change this file. The easiest way around this is to save a copy on the Desktop, edit the Desktop version, and copy the new one back over the top of the old. Windows will ask for permission to overwrite the old file; allow it. You should make the following changes to this file:
<br>
<br>
- Add the following options in the line that begins with <i>"-StartParams"</i> :
+ <i>-StartParams="start;-c;-Dbootstrap_confdir=C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\configsets\AutopsyConfig\conf;-Dcollection.configName=AutopsyConfig" ^</i>
- Add the following options in the line that begins with <i>"C:\Bitnami\solr-4.10.3-0/apache-solr\scripts\prunsrv.exe"</i> :
+ <i>++JvmOptions=-Dcollection.configName=AutopsyConfig</i>
+ <i>++JvmOptions=-Dbootstrap_confdir="C:\Bitnami\solr-4.10.3-0\apache-solr\solr\configsets\AutopsyConfig\conf"</i>
+ <i>++JvmOptions=-DzkRun </i>
<br>
- Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: <i>-JavaHome="C:\Program Files\Java\jre1.8.0_111"</i>
<br><br>
A portion of an updated _serviceinstall.bat_ is shown below, with the changes marked in yellow.
<br><br>
\image html updatedServiceInstall.PNG
<br><br>
3. Edit <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\bin\solr.cmd"</i> and point _JAVA_HOME_ to _JavaHome_ path on your machine.
Changes in _solr.cmd_ are highlighted in yellow
<br><br>
\image html updatedSolr_cmd.PNG
<br><br>
4. Edit <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\solr.xml"</i> to set the _transientCacheSize_ to the maximum number of cases expected to be open concurrently. If you expect ten concurrent cases, the text to add is
\image html serviceinstall.PNG
<br><br>
3. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr\solr.xml"</i> to set the _transientCacheSize_ to the maximum number of cases expected to be open concurrently. If you expect ten concurrent cases, the text to add is
<i>\<int name="transientCacheSize">10\</int></i>
<br><br>
The added part is highlighted in yellow below. Ensure that it is inside the <i>\<solr></i> tag as follows:
<br>
\image html transientcache.PNG
<br><br>
5. Edit <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\server\resources\log4j.properties"</i> to configure Solr log settings:
4. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\resources/log4j.properties"</i> to configure Solr log settings:
- Increase the log rotation size threshold (_log4j\.appender\.file\.MaxFileSize_) from 4MB to 100MB.
- Remove the _CONSOLE_ appender from the _log4j\.rootLogger_ line.
<br><br>
@ -80,40 +79,26 @@ The following steps will configure Solr to run using an account that will have a
<br><br>
\image html log4j.PNG
<br><br>
6. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-XXX(current version)\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\configsets"</i>.
7. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-XXX(current version)\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\lib"</i>.
5. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-XXX(current version)\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
6. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-XXX(current version)\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
\subsection configure_Zookeeper Zookeeper Configuration
The following steps will configure Zookeeper.
1. Stop the <i>solrJetty</i> service by pressing <i>Start</i>, typing <i>services.msc</i>, pressing Enter, and locating the <i>solrJetty</i> Windows service. Select the service and press <i>Stop the service</i>. If the service is already stopped and there is no <i>Stop the service</i> available, this is okay.
2. Start a Windows command prompt as administrator by pressing Start, typing <i>command</i>, right clicking on <i>Command Prompt</i>, and clicking on <i>Run as administrator</i>. Then run the following command to uninstall the solrJetty service:
cmd /c C:\Bitnami\solr-6.2.1-2\apache-solr\scripts\serviceinstall.bat UNINSTALL
cmd /c C:\Bitnami\solr-4.10.3-0\apache-solr\scripts\serviceinstall.bat UNINSTALL
You will very likely see a result that says "The solrJetty service is not started." This is okay.
3. Create a folder <i>"C:\Bitnami\zookeeper"</i> if it does not exist.
4. Edit <i>"C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\zoo.cfg"</i> to include the text <i>dataDir=C:/Bitnami/zookeeper</i> as shown in the screenshot below
4. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\server\solr\zoo.cfg"</i> to include the text <i>dataDir=C:/Bitnami/zookeeper</i> as shown in the screenshot below
<br><br>
\image html zooDir.PNG
<br>
5. Edit <i> "C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\zoo.cfg"</i> to include the text
<br>
<br>
- <i>autopurge.snapRetainCount=3</i>
<br> # ZooKeeper auto purge feature retains the autopurge.snapRetainCount most recent snapshots and the corresponding transaction logs in the dataDir and dataLogDir respectively and deletes the rest. Defaults to 3. Minimum value is 3.
<br>
- <i>autopurge.purgeInterval=24</i>
<br> # The time interval in hours for which the purge task has to be triggered. Set to a positive integer (1 and above) to enable the auto purging. Defaults to 0.
<br>
<br>
as shown in yellow in the screenshot below
<br><br>
\image html zooPurge.PNG
<br>
6. Start a Windows command prompt as administrator by pressing Start, typing <i>command</i>, right clicking on <i>Command Prompt</i>, and clicking on <i>Run as administrator</i>. Then run the following command to install the solrJetty service:
5. Start a Windows command prompt as administrator by pressing Start, typing <i>command</i>, right clicking on <i>Command Prompt</i>, and clicking on <i>Run as administrator</i>. Then run the following command to install the solrJetty service:
cmd /c C:\Bitnami\solr-6.2.1-2\apache-solr\scripts\serviceinstall.bat INSTALL
cmd /c C:\Bitnami\solr-4.10.3-0\apache-solr\scripts\serviceinstall.bat INSTALL
<br> Note the argument "INSTALL" is case sensitive. Your command prompt should look like the screenshot below. Very likely your command prompt will say "The solrJetty service could not be started." This is okay.
<br><br>
\image html solrinstall1.PNG

View File

@ -127,7 +127,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
numFiles = len(files)
self.log(Level.INFO, "found " + str(numFiles) + " files")
progressBar.switchToDeterminate(numFiles)
fileCount = 0;
fileCount = 0
for file in files:
# Check if the user pressed cancel while we were busy
@ -169,4 +169,4 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
"Sample Jython Data Source Ingest Module", "Found %d files" % fileCount)
IngestServices.getInstance().postMessage(message)
return IngestModule.ProcessResult.OK;
return IngestModule.ProcessResult.OK

View File

@ -110,8 +110,8 @@ class SampleJythonFileIngestModule(FileIngestModule):
# TODO: Add your analysis code in here.
def process(self, file):
# Skip non-files
if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) or
(file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) or
if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) or
(file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) or
(file.isFile() == False)):
return IngestModule.ProcessResult.OK
@ -128,7 +128,7 @@ class SampleJythonFileIngestModule(FileIngestModule):
# Make an artifact on the blackboard. TSK_INTERESTING_FILE_HIT is a generic type of
# artifact. Refer to the developer docs for other examples.
art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT)
att = BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME,
att = BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME,
SampleJythonFileIngestModuleFactory.moduleName, "Text Files")
art.addAttribute(att)
@ -141,15 +141,15 @@ class SampleJythonFileIngestModule(FileIngestModule):
# Fire an event to notify the UI and others that there is a new artifact
IngestServices.getInstance().fireModuleDataEvent(
ModuleDataEvent(SampleJythonFileIngestModuleFactory.moduleName,
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, None));
ModuleDataEvent(SampleJythonFileIngestModuleFactory.moduleName,
BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, None))
# For the example (this wouldn't be needed normally), we'll query the blackboard for data that was added
# by other modules. We then iterate over its attributes. We'll just print them, but you would probably
# want to do something with them.
# want to do something with them.
artifactList = file.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT)
for artifact in artifactList:
attributeList = artifact.getAttributes();
attributeList = artifact.getAttributes()
for attrib in attributeList:
self.log(Level.INFO, attrib.toString())
@ -169,6 +169,6 @@ class SampleJythonFileIngestModule(FileIngestModule):
def shutDown(self):
# As a final part of this example, we'll send a message to the ingest inbox with the number of files found (in this thread)
message = IngestMessage.createMessage(
IngestMessage.MessageType.DATA, SampleJythonFileIngestModuleFactory.moduleName,
IngestMessage.MessageType.DATA, SampleJythonFileIngestModuleFactory.moduleName,
str(self.filesFound) + " files found")
ingestServices = IngestServices.getInstance().postMessage(message)

View File

@ -71,7 +71,7 @@ class SampleGeneralReportModule(GeneralReportModuleAdapter):
# The 'progressBar' object is of type ReportProgressPanel.
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1report_1_1_report_progress_panel.html
def generateReport(self, baseReportDir, progressBar):
# For an example, we write a file with the number of files created in the past 2 weeks
# Configure progress bar for 2 tasks
progressBar.setIndeterminate(False)
@ -101,7 +101,7 @@ class SampleGeneralReportModule(GeneralReportModuleAdapter):
report.close()
# Add the report to the Case, so it is shown in the tree
Case.getCurrentCase().addReport(fileName, self.moduleName, "File Count Report");
Case.getCurrentCase().addReport(fileName, self.moduleName, "File Count Report")
progressBar.increment()