From 55029593461b77f7a850fc72e2ade8ea617e683c Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 26 Oct 2015 11:05:55 -0400 Subject: [PATCH 1/6] Make keyword search index creation thread-safe and noisy on failure --- .../autopsy/keywordsearch/Bundle.properties | 4 +- .../autopsy/keywordsearch/Installer.java | 5 +- .../autopsy/keywordsearch/KeywordSearch.java | 50 ++- .../KeywordSearchIngestModule.java | 6 +- .../autopsy/keywordsearch/Server.java | 287 ++++++++++++------ 5 files changed, 218 insertions(+), 134 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 62a15c1517..e6d36521c9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -83,6 +83,8 @@ KeywordSearchConfigurationPanel1.customizeComponents.title=Delete a keyword list KeywordSearchConfigurationPanel1.customizeComponents.body=This will delete the keyword list globally (for all Cases). Do you want to proceed with the deletion? KeywordSearchConfigurationPanel1.customizeComponents.keywordListEmptyErr=Keyword List is empty and cannot be saved KeywordSearch.newKwListTitle=New keyword list name\: +KeywordSearch.openCore.exception.msg=Could not create keyword search index for case {0} +KeywordSearch.closeCore.exception.msg=Error closing keyword search index for case {0} KeywordSearchConfigurationPanel1.customizeComponents.noOwDefaultMsg=Cannot overwrite default list KeywordSearchConfigurationPanel1.customizeComponents.kwListExistMsg=Keyword List <{0}> already exists, do you want to replace it? KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg=Keyword List <{0}> saved @@ -223,7 +225,6 @@ Server.connect.exception.msg=Failed to connect to Solr server\: Server.openCore.exception.msg=Core open requested, but server not yet running Server.openCore.exception.cantOpen.msg=Could not open Core Server.openCore.exception.cantOpen.msg2=Could not open Core -Server.openCore.exception.cantOpenForCase.msg=Could not create keyword search index for case {0} Server.request.exception.exception.msg=Could not issue Solr request Server.commit.exception.msg=Could not commit index Server.addDoc.exception.msg=Could not add document to index via update handler\: {0} @@ -287,6 +288,7 @@ KeywordSearchModuleFactory.createFileIngestModule.exception.msg=Expected setting SearchRunner.Searcher.done.err.msg=Error performing keyword search KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=Fastest overall, but no results until the end KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=No periodic searches +KeywordSearchIngestModule.startUp.noOpenCore.msg=The keyword search index for could not be opened or does not exist. Try closing and reopening the case. KeywordSearchIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. SolrConnectionCheck.HostnameOrPort=Invalid hostname and/or port number. SolrConnectionCheck.Hostname=Invalid hostname. diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java index 1008edaf56..fa4547aae7 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -38,13 +38,14 @@ import org.sleuthkit.autopsy.coreutils.Version; class Installer extends ModuleInstall { private static final Logger logger = Logger.getLogger(Installer.class.getName()); + private static final long serialVersionUID = 1L; @Override public void restored() { //Setup the default KeywordSearch configuration files KeywordSearchSettings.setDefaults(); - Case.addPropertyChangeListener(new KeywordSearch.CaseChangeListener()); + Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new KeywordSearch.CaseChangeListener()); final Server server = KeywordSearch.getServer(); try { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 627f2559f9..8628cceb33 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -75,9 +75,7 @@ public class KeywordSearch { TIKA_LOGGER.addHandler(tikaLogHandler); //do not forward to the parent autopsy logger TIKA_LOGGER.setUseParentHandlers(false); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } catch (SecurityException ex) { + } catch (IOException | SecurityException ex) { Exceptions.printStackTrace(ex); } } @@ -117,37 +115,29 @@ public class KeywordSearch { */ static class CaseChangeListener implements PropertyChangeListener { - CaseChangeListener() { - } - @Override public void propertyChange(PropertyChangeEvent evt) { - String changed = evt.getPropertyName(); - - final Logger logger = Logger.getLogger(CaseChangeListener.class.getName()); - if (changed.equals(Case.Events.CURRENT_CASE.toString())) { - /* - * don't call getOld/NewValue() unless they are needed, since - * they might do expensive db operations to load transient - * values lost in serialization - */ - Object oldValue = evt.getOldValue(); - Object newValue = evt.getNewValue(); - if (newValue != null) { - // new case is open - try { - server.openCore(); - } catch (Exception e) { - logger.log(Level.WARNING, "Could not open core."); //NON-NLS - } - } else if (oldValue != null) { - // a case was closed + if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) { + if (null != evt.getOldValue()) { + Case closedCase = (Case) evt.getOldValue(); try { BlackboardResultWriter.stopAllWriters(); - Thread.sleep(2000); + Thread.sleep(2000); // TODO (RC): This is a fragile way to wait here. server.closeCore(); - } catch (Exception e) { - logger.log(Level.WARNING, "Could not close core."); //NON-NLS + } catch (Exception ex) { + String caseName = closedCase.getName(); + logger.log(Level.SEVERE, String.format("Failed to close core for %s", caseName), ex); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.exception.msg", caseName), ex.getCause().getMessage()); + } + } + if (null != evt.getNewValue()) { + Case openedCase = (Case) evt.getNewValue(); + try { + server.openCoreForCase(openedCase); + } catch (Exception ex) { + String caseName = openedCase.getName(); + logger.log(Level.SEVERE, String.format("Failed to open or create core for %s", caseName), ex); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.exception.msg", caseName), ex.getCause().getMessage()); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java index b79fdca397..bb86774bbe 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java @@ -134,6 +134,11 @@ public final class KeywordSearchIngestModule implements FileIngestModule { jobId = context.getJobId(); dataSourceId = context.getDataSource().getId(); + Server server = KeywordSearch.getServer(); + if (server.coreIsOpen() == false) { + throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.startUp.noOpenCore.msg")); + } + try { fileTypeDetector = new FileTypeDetector(); } catch (FileTypeDetector.FileTypeDetectorInitException ex) { @@ -170,7 +175,6 @@ public final class KeywordSearchIngestModule implements FileIngestModule { } } else { // for single-user cases need to verify connection to local SOLR service - final Server server = KeywordSearch.getServer(); try { if (!server.isRunning()) { String msg = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.badInitMsg"); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java index d9e168b823..e76332d554 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java @@ -38,6 +38,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import org.openide.util.NbBundle; @@ -183,6 +184,7 @@ public class Server { private HttpSolrServer currentSolrServer; private Core currentCore; + private final ReentrantReadWriteLock currentCoreLock; private final File solrFolder; private final ServerAction serverAction; @@ -199,7 +201,9 @@ public class Server { serverAction = new ServerAction(); solrFolder = InstalledFileLocator.getDefault().locate("solr", Server.class.getPackage().getName(), false); //NON-NLS javaPath = PlatformUtil.getJavaPath(); - + + currentCoreLock = new ReentrantReadWriteLock(true); + logger.log(Level.INFO, "Created Server instance"); //NON-NLS } @@ -590,35 +594,57 @@ public class Server { /* * ** Convenience methods for use while we only open one case at a time *** */ - synchronized void openCore() throws KeywordSearchModuleException { - if (currentCore != null) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.openCore.exception.alreadyOpen.msg")); - } - - Case currentCase = Case.getCurrentCase(); - + /** + * Opens or creates a core (index) for a case. + * + * @param theCase the case for which the core is to be opened or created. + * + * @throws KeywordSearchModuleException + */ + void openCoreForCase(Case theCase) throws KeywordSearchModuleException { + currentCoreLock.writeLock().lock(); try { - currentCore = openCore(currentCase); - } catch (KeywordSearchModuleException ex) { - MessageNotifyUtil.Notify.error(NbBundle.getMessage(Server.class, "Server.openCore.exception.cantOpenForCase.msg", currentCase.getName()), ex.getCause().getMessage()); - throw ex; + currentCore = openCore(theCase); + serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STARTED); + } finally { + currentCoreLock.writeLock().unlock(); } - serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STARTED); } - synchronized void closeCore() throws KeywordSearchModuleException { - if (currentCore == null) { - return; + /** + * Determines whether or not there is a currently open core (index). + * + * @return true or false + */ + boolean coreIsOpen() { + currentCoreLock.readLock().lock(); + try { + return (null != currentCore); + } finally { + currentCoreLock.readLock().unlock(); } + } - currentCore.close(); - currentCore = null; - serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED); + void closeCore() throws KeywordSearchModuleException { + currentCoreLock.writeLock().lock(); + try { + if (null != currentCore) { + currentCore.close(); + currentCore = null; + serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED); + } + } finally { + currentCoreLock.writeLock().unlock(); + } } void addDocument(SolrInputDocument doc) throws KeywordSearchModuleException { - currentCore.addDocument(doc); + currentCoreLock.readLock().lock(); + try { + currentCore.addDocument(doc); + } finally { + currentCoreLock.readLock().unlock(); + } } /** @@ -651,7 +677,7 @@ public class Server { * * @return */ - private synchronized Core openCore(Case theCase) throws KeywordSearchModuleException { + private Core openCore(Case theCase) throws KeywordSearchModuleException { try { if (theCase.getCaseType() == CaseType.SINGLE_USER_CASE) { currentSolrServer = this.localSolrServer; @@ -673,22 +699,32 @@ public class Server { } /** - * commit current core if it exists + * Commits current core if it exists * * @throws SolrServerException, NoOpenCoreException */ - synchronized void commit() throws SolrServerException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); + void commit() throws SolrServerException, NoOpenCoreException { + currentCoreLock.readLock().lock(); + try { + if (null == currentCore) { + throw new NoOpenCoreException(); + } + currentCore.commit(); + } finally { + currentCoreLock.readLock().unlock(); } - currentCore.commit(); } NamedList request(SolrRequest request) throws SolrServerException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); + currentCoreLock.readLock().lock(); + try { + if (null == currentCore) { + throw new NoOpenCoreException(); + } + return currentCore.request(request); + } finally { + currentCoreLock.readLock().unlock(); } - return currentCore.request(request); } /** @@ -702,16 +738,19 @@ public class Server { * @throws NoOpenCoreException */ public int queryNumIndexedFiles() throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.queryNumIndexedFiles(); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.queryNumIdxFiles.exception.msg"), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.queryNumIndexedFiles(); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.queryNumIdxFiles.exception.msg"), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } - } /** @@ -724,14 +763,18 @@ public class Server { * @throws NoOpenCoreException */ public int queryNumIndexedChunks() throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.queryNumIndexedChunks(); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.queryNumIdxChunks.exception.msg"), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.queryNumIndexedChunks(); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.queryNumIdxChunks.exception.msg"), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } } @@ -745,14 +788,18 @@ public class Server { * @throws NoOpenCoreException */ public int queryNumIndexedDocuments() throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.queryNumIndexedDocuments(); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.queryNumIdxDocs.exception.msg"), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.queryNumIndexedDocuments(); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.queryNumIdxDocs.exception.msg"), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } } @@ -767,14 +814,19 @@ public class Server { * @throws NoOpenCoreException */ public boolean queryIsIndexed(long contentID) throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.queryIsIndexed(contentID); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.queryIsIdxd.exception.msg"), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.queryIsIndexed(contentID); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.queryIsIdxd.exception.msg"), ex); + } + + } finally { + currentCoreLock.readLock().unlock(); } } @@ -790,14 +842,18 @@ public class Server { * @throws NoOpenCoreException */ public int queryNumFileChunks(long fileID) throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.queryNumFileChunks(fileID); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.queryNumFileChunks.exception.msg"), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.queryNumFileChunks(fileID); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.queryNumFileChunks.exception.msg"), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } } @@ -812,14 +868,18 @@ public class Server { * @throws NoOpenCoreException */ public QueryResponse query(SolrQuery sq) throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.query(sq); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.query.exception.msg", sq.getQuery()), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.query(sq); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.query.exception.msg", sq.getQuery()), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } } @@ -835,14 +895,18 @@ public class Server { * @throws NoOpenCoreException */ public QueryResponse query(SolrQuery sq, SolrRequest.METHOD method) throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.query(sq, method); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.query2.exception.msg", sq.getQuery()), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.query(sq, method); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.query2.exception.msg", sq.getQuery()), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } } @@ -857,14 +921,18 @@ public class Server { * @throws NoOpenCoreException */ public TermsResponse queryTerms(SolrQuery sq) throws KeywordSearchModuleException, NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); - } + currentCoreLock.readLock().lock(); try { - return currentCore.queryTerms(sq); - } catch (SolrServerException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.queryTerms.exception.msg", sq.getQuery()), ex); + if (null == currentCore) { + throw new NoOpenCoreException(); + } + try { + return currentCore.queryTerms(sq); + } catch (SolrServerException ex) { + throw new KeywordSearchModuleException(NbBundle.getMessage(this.getClass(), "Server.queryTerms.exception.msg", sq.getQuery()), ex); + } + } finally { + currentCoreLock.readLock().unlock(); } } @@ -878,10 +946,15 @@ public class Server { * @throws NoOpenCoreException */ public String getSolrContent(final Content content) throws NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); + currentCoreLock.readLock().lock(); + try { + if (null == currentCore) { + throw new NoOpenCoreException(); + } + return currentCore.getSolrContent(content.getId(), 0); + } finally { + currentCoreLock.readLock().unlock(); } - return currentCore.getSolrContent(content.getId(), 0); } /** @@ -897,10 +970,15 @@ public class Server { * @throws NoOpenCoreException */ public String getSolrContent(final Content content, int chunkID) throws NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); + currentCoreLock.readLock().lock(); + try { + if (null == currentCore) { + throw new NoOpenCoreException(); + } + return currentCore.getSolrContent(content.getId(), chunkID); + } finally { + currentCoreLock.readLock().unlock(); } - return currentCore.getSolrContent(content.getId(), chunkID); } /** @@ -913,10 +991,15 @@ public class Server { * @throws NoOpenCoreException */ String getSolrContent(final long objectID) throws NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); + currentCoreLock.readLock().lock(); + try { + if (null == currentCore) { + throw new NoOpenCoreException(); + } + return currentCore.getSolrContent(objectID, 0); + } finally { + currentCoreLock.readLock().unlock(); } - return currentCore.getSolrContent(objectID, 0); } /** @@ -930,11 +1013,15 @@ public class Server { * @throws NoOpenCoreException */ String getSolrContent(final long objectID, final int chunkID) throws NoOpenCoreException { - if (currentCore == null) { - throw new NoOpenCoreException(); + currentCoreLock.readLock().lock(); + try { + if (null == currentCore) { + throw new NoOpenCoreException(); + } + return currentCore.getSolrContent(objectID, chunkID); + } finally { + currentCoreLock.readLock().unlock(); } - return currentCore.getSolrContent(objectID, chunkID); - } /** From ee3600e59afd80ffe5571e99c47a960adecef629 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 26 Oct 2015 14:40:16 -0400 Subject: [PATCH 2/6] Provide feedback if keyword search index create/open fails --- .../autopsy/core/RuntimeProperties.java | 7 +++++ .../autopsy/corecomponents/Bundle.properties | 4 +-- .../autopsy/keywordsearch/Bundle.properties | 10 +++---- .../keywordsearch/DropdownToolbar.java | 2 +- .../autopsy/keywordsearch/KeywordSearch.java | 4 +-- .../autopsy/keywordsearch/Server.java | 29 +++++++++---------- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java b/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java index c2c74bfff3..42b1e32e09 100644 --- a/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java +++ b/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java @@ -59,4 +59,11 @@ public class RuntimeProperties { public static boolean coreComponentsAreActive() { return coreComponentsActive; } + + /** + * Private constructor to prevent creatino of instances of this class. + */ + private RuntimeProperties() { + + } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 7364d72922..b5aaec94cc 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -195,5 +195,5 @@ MultiUserSettingsPanel.tbMsgHostname.text= MultiUserSettingsPanel.lbTestMessageWarning.text= MultiUserSettingsPanel.lbTestSolrWarning.text= MultiUserSettingsPanel.lbTestDbWarning.text= -MultiUserSettingsPanel.KeywordSearchNull=Cannot find Keyword Search service -MultiUserSettingsPanel.InvalidPortNumber=Invalid port number. \ No newline at end of file +MultiUserSettingsPanel.KeywordSearchNull=Cannot find keyword search service +MultiUserSettingsPanel.InvalidPortNumber=Invalid port number \ No newline at end of file diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index e6d36521c9..4bea1c5ac5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -83,8 +83,8 @@ KeywordSearchConfigurationPanel1.customizeComponents.title=Delete a keyword list KeywordSearchConfigurationPanel1.customizeComponents.body=This will delete the keyword list globally (for all Cases). Do you want to proceed with the deletion? KeywordSearchConfigurationPanel1.customizeComponents.keywordListEmptyErr=Keyword List is empty and cannot be saved KeywordSearch.newKwListTitle=New keyword list name\: -KeywordSearch.openCore.exception.msg=Could not create keyword search index for case {0} -KeywordSearch.closeCore.exception.msg=Error closing keyword search index for case {0} +KeywordSearch.openCore.exception.msg=Could not open keyword search index +KeywordSearch.closeCore.exception.msg=Error closing keyword search index KeywordSearchConfigurationPanel1.customizeComponents.noOwDefaultMsg=Cannot overwrite default list KeywordSearchConfigurationPanel1.customizeComponents.kwListExistMsg=Keyword List <{0}> already exists, do you want to replace it? KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg=Keyword List <{0}> saved @@ -224,7 +224,7 @@ Server.queryTerms.exception.msg=Error running terms query\: {0} Server.connect.exception.msg=Failed to connect to Solr server\: Server.openCore.exception.msg=Core open requested, but server not yet running Server.openCore.exception.cantOpen.msg=Could not open Core -Server.openCore.exception.cantOpen.msg2=Could not open Core +Server.openCore.exception.noIndexDir.msg=Index could not be created or missing Server.request.exception.exception.msg=Could not issue Solr request Server.commit.exception.msg=Could not commit index Server.addDoc.exception.msg=Could not add document to index via update handler\: {0} @@ -288,8 +288,8 @@ KeywordSearchModuleFactory.createFileIngestModule.exception.msg=Expected setting SearchRunner.Searcher.done.err.msg=Error performing keyword search KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.toolTipText=Fastest overall, but no results until the end KeywordSearchGlobalSearchSettingsPanel.timeRadioButton5.text=No periodic searches -KeywordSearchIngestModule.startUp.noOpenCore.msg=The keyword search index for could not be opened or does not exist. Try closing and reopening the case. -KeywordSearchIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. +KeywordSearchIngestModule.startUp.noOpenCore.msg=The index could not be opened or does not exist +KeywordSearchIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector SolrConnectionCheck.HostnameOrPort=Invalid hostname and/or port number. SolrConnectionCheck.Hostname=Invalid hostname. SolrConnectionCheck.Port=Invalid port number. diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java index 7c24b99337..7752adede9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/DropdownToolbar.java @@ -223,7 +223,7 @@ class DropdownToolbar extends javax.swing.JPanel { String changed = evt.getPropertyName(); if (changed.equals(Case.Events.CURRENT_CASE.toString())) { dropPanel.resetSearchBox(); - setFields(null != evt.getNewValue() && RuntimeProperties.coreComponentsAreActive()); + setFields(null != evt.getNewValue() && RuntimeProperties.coreComponentsAreActive() && KeywordSearch.getServer().coreIsOpen()); } else if (changed.equals(Server.CORE_EVT)) { final Server.CORE_EVT_STATES state = (Server.CORE_EVT_STATES) evt.getNewValue(); switch (state) { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 8628cceb33..90e9010057 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -127,7 +127,7 @@ public class KeywordSearch { } catch (Exception ex) { String caseName = closedCase.getName(); logger.log(Level.SEVERE, String.format("Failed to close core for %s", caseName), ex); - MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.exception.msg", caseName), ex.getCause().getMessage()); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.exception.msg"), ex.getCause().getMessage()); } } if (null != evt.getNewValue()) { @@ -137,7 +137,7 @@ public class KeywordSearch { } catch (Exception ex) { String caseName = openedCase.getName(); logger.log(Level.SEVERE, String.format("Failed to open or create core for %s", caseName), ex); - MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.exception.msg", caseName), ex.getCause().getMessage()); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.exception.msg"), ex.getCause().getMessage()); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java index e76332d554..ecf9afe0e5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java @@ -40,7 +40,6 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; - import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.AbstractAction; @@ -170,6 +169,7 @@ public class Server { private int currentSolrStopPort = 0; private static final boolean DEBUG = false;//(Version.getBuildType() == Version.Type.DEVELOPMENT); private final UNCPathUtilities uncPathUtilities = new UNCPathUtilities(); + private static final String INDEX_DIR_NAME = "index"; public enum CORE_EVT_STATES { @@ -1069,26 +1069,25 @@ public class Server { } if (!isCoreLoaded(coreName)) { - CoreAdminRequest.Create createCore = new CoreAdminRequest.Create(); - createCore.setDataDir(dataDir.getAbsolutePath()); - createCore.setCoreName(coreName); - createCore.setConfigSet("AutopsyConfig"); //NON-NLS - createCore.setIsLoadOnStartup(false); - createCore.setIsTransient(true); - - currentSolrServer.request(createCore); + CoreAdminRequest.Create createCoreRequest = new CoreAdminRequest.Create(); + createCoreRequest.setDataDir(dataDir.getAbsolutePath()); + createCoreRequest.setCoreName(coreName); + createCoreRequest.setConfigSet("AutopsyConfig"); //NON-NLS + createCoreRequest.setIsLoadOnStartup(false); + createCoreRequest.setIsTransient(true); + currentSolrServer.request(createCoreRequest); } - final Core newCore = new Core(coreName, caseType); + File indexDir = Paths.get(dataDir.getAbsolutePath(), INDEX_DIR_NAME).toFile(); + if (!indexDir.exists()) { + throw new IOException(NbBundle.getMessage(this.getClass(), "Server.openCore.exception.noIndexDir.msg")); + } - return newCore; + return new Core(coreName, caseType); - } catch (SolrServerException | SolrException ex) { + } catch (SolrServerException | SolrException | IOException ex) { throw new KeywordSearchModuleException( NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg"), ex); - } catch (IOException ex) { - throw new KeywordSearchModuleException( - NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg2"), ex); } } From f4f64810541b6a1a87701860da26b607f288b800 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 26 Oct 2015 14:57:01 -0400 Subject: [PATCH 3/6] Refine keyword search error notifications --- .../sleuthkit/autopsy/keywordsearch/Bundle.properties | 10 +++++----- .../sleuthkit/autopsy/keywordsearch/KeywordSearch.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 4bea1c5ac5..44d28244e7 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -83,8 +83,8 @@ KeywordSearchConfigurationPanel1.customizeComponents.title=Delete a keyword list KeywordSearchConfigurationPanel1.customizeComponents.body=This will delete the keyword list globally (for all Cases). Do you want to proceed with the deletion? KeywordSearchConfigurationPanel1.customizeComponents.keywordListEmptyErr=Keyword List is empty and cannot be saved KeywordSearch.newKwListTitle=New keyword list name\: -KeywordSearch.openCore.exception.msg=Could not open keyword search index -KeywordSearch.closeCore.exception.msg=Error closing keyword search index +KeywordSearch.openCore.notification.msg=Could not open keyword search index +KeywordSearch.closeCore.notification.msg=Error closing keyword search index KeywordSearchConfigurationPanel1.customizeComponents.noOwDefaultMsg=Cannot overwrite default list KeywordSearchConfigurationPanel1.customizeComponents.kwListExistMsg=Keyword List <{0}> already exists, do you want to replace it? KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg=Keyword List <{0}> saved @@ -222,9 +222,9 @@ Server.query.exception.msg=Error running query\: {0} Server.query2.exception.msg=Error running query\: {0} Server.queryTerms.exception.msg=Error running terms query\: {0} Server.connect.exception.msg=Failed to connect to Solr server\: -Server.openCore.exception.msg=Core open requested, but server not yet running -Server.openCore.exception.cantOpen.msg=Could not open Core -Server.openCore.exception.noIndexDir.msg=Index could not be created or missing +Server.openCore.exception.msg=Keyword search service not yet running +Server.openCore.exception.cantOpen.msg=Could not open index +Server.openCore.exception.noIndexDir.msg=Index directory could not be created or is missing Server.request.exception.exception.msg=Could not issue Solr request Server.commit.exception.msg=Could not commit index Server.addDoc.exception.msg=Could not add document to index via update handler\: {0} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 90e9010057..c662287257 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -127,7 +127,7 @@ public class KeywordSearch { } catch (Exception ex) { String caseName = closedCase.getName(); logger.log(Level.SEVERE, String.format("Failed to close core for %s", caseName), ex); - MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.exception.msg"), ex.getCause().getMessage()); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.closeCore.notification..msg"), ex.getCause().getMessage()); } } if (null != evt.getNewValue()) { @@ -137,7 +137,7 @@ public class KeywordSearch { } catch (Exception ex) { String caseName = openedCase.getName(); logger.log(Level.SEVERE, String.format("Failed to open or create core for %s", caseName), ex); - MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.exception.msg"), ex.getCause().getMessage()); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.notification..msg"), ex.getCause().getMessage()); } } } From 14c80d7d147c9b334c6b7a1a8764a4013aba514f Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 26 Oct 2015 14:58:51 -0400 Subject: [PATCH 4/6] Fix typo in core.RuntimeProperties comment --- Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java b/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java index 42b1e32e09..61e2c9112a 100644 --- a/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java +++ b/Core/src/org/sleuthkit/autopsy/core/RuntimeProperties.java @@ -61,7 +61,7 @@ public class RuntimeProperties { } /** - * Private constructor to prevent creatino of instances of this class. + * Private constructor to prevent creation of instances of this class. */ private RuntimeProperties() { From 4afd626f43a29757cd2369c29eb9916adc690a47 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 26 Oct 2015 15:02:21 -0400 Subject: [PATCH 5/6] Correct bundle key ref in keywordsearch.KeywordSearch --- .../src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index c662287257..47669eea94 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -137,7 +137,7 @@ public class KeywordSearch { } catch (Exception ex) { String caseName = openedCase.getName(); logger.log(Level.SEVERE, String.format("Failed to open or create core for %s", caseName), ex); - MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.notification..msg"), ex.getCause().getMessage()); + MessageNotifyUtil.Notify.error(NbBundle.getMessage(KeywordSearch.class, "KeywordSearch.openCore.notification.msg"), ex.getCause().getMessage()); } } } From a176ec3481410a62172b6dc56ece4eaa295552c0 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 26 Oct 2015 15:08:47 -0400 Subject: [PATCH 6/6] Remove console only stack trace print from keywordsearch.KeywordSearch --- .../src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 47669eea94..ed6c4621de 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -26,7 +26,6 @@ import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; @@ -76,7 +75,7 @@ public class KeywordSearch { //do not forward to the parent autopsy logger TIKA_LOGGER.setUseParentHandlers(false); } catch (IOException | SecurityException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.SEVERE, "Error setting up tika logging", ex); } }