diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 204e475ef3..873a0696c0 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -253,3 +253,8 @@ UnpackagePortableCaseProgressDialog.resultLabel.text=resultLabel UnpackagePortableCaseDialog.extractLabel.text=Folder to extract to: UnpackagePortableCaseDialog.caseLabel.text=Portable Case: NewCaseVisualPanel1.caseDataStoredLabel.text_1=Case data will be stored in the following directory: +SolrNotConfiguredDialog.okButton.text=OK +SolrNotConfiguredDialog.messageLabel.text=Warning: +SolrNotConfiguredDialog.messageLabel2.text=Multi-User cases are enabled but Solr 8 server has not been configured.
\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n +SolrNotConfiguredDialog.title=Solr 8 Server Not Configured +SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User. \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index f5c18a1640..ccb5d34592 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -471,3 +471,8 @@ UnpackagePortableCaseProgressDialog.resultLabel.text=resultLabel UnpackagePortableCaseDialog.extractLabel.text=Folder to extract to: UnpackagePortableCaseDialog.caseLabel.text=Portable Case: NewCaseVisualPanel1.caseDataStoredLabel.text_1=Case data will be stored in the following directory: +SolrNotConfiguredDialog.okButton.text=OK +SolrNotConfiguredDialog.messageLabel.text=Warning: +SolrNotConfiguredDialog.messageLabel2.text=Multi-User cases are enabled but Solr 8 server has not been configured.
\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n +SolrNotConfiguredDialog.title=Solr 8 Server Not Configured +SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User. diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.form b/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.form new file mode 100755 index 0000000000..b0774130fc --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.form @@ -0,0 +1,98 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java new file mode 100755 index 0000000000..dc3f281d7d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/SolrNotConfiguredDialog.java @@ -0,0 +1,122 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2013-2020 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.awt.Dimension; +import java.awt.Toolkit; +import javax.swing.JFrame; +import org.openide.util.ImageUtilities; +import org.openide.windows.WindowManager; + +/** + * A dialog to notify the user on startup when Solr 8 server is not configured. + */ +class SolrNotConfiguredDialog extends javax.swing.JDialog { + + private static final long serialVersionUID = 1L; + + /** + * Creates new form SolrNotConfiguredDialog + */ + SolrNotConfiguredDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), true); + // Center the startup window. + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); + int width = getSize().width; + int height = getSize().height; + setLocation((screenDimension.width - width) / 2, (screenDimension.height - height) / 2); + initComponents(); + setIconImage(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/warning16.png", false)); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + messageLabel = new javax.swing.JLabel(); + okButton = new javax.swing.JButton(); + messageLabel2 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(SolrNotConfiguredDialog.class, "SolrNotConfiguredDialog.title")); // NOI18N + setModal(true); + setName("toolsNotFound"); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(messageLabel, org.openide.util.NbBundle.getMessage(SolrNotConfiguredDialog.class, "SolrNotConfiguredDialog.messageLabel.text")); // NOI18N + messageLabel.setMaximumSize(new java.awt.Dimension(200, 16)); + + org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(SolrNotConfiguredDialog.class, "SolrNotConfiguredDialog.okButton.text")); // NOI18N + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(messageLabel2, org.openide.util.NbBundle.getMessage(SolrNotConfiguredDialog.class, "SolrNotConfiguredDialog.messageLabel2.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 15, Short.MAX_VALUE) + .addComponent(messageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 420, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(188, 188, 188) + .addComponent(messageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(189, 189, 189) + .addComponent(okButton))) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(messageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(messageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(okButton) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + this.dispose(); + }//GEN-LAST:event_okButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel messageLabel; + private javax.swing.JLabel messageLabel2; + private javax.swing.JButton okButton; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindowProvider.java b/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindowProvider.java index 8bec55f53c..594dc90783 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindowProvider.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindowProvider.java @@ -23,10 +23,14 @@ import java.util.Iterator; import java.util.logging.Level; import org.netbeans.spi.sendopts.OptionProcessor; import org.openide.util.Lookup; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.commandlineingest.CommandLineIngestManager; import org.sleuthkit.autopsy.commandlineingest.CommandLineOptionProcessor; import org.sleuthkit.autopsy.commandlineingest.CommandLineStartupWindow; +import org.sleuthkit.autopsy.core.RuntimeProperties; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; /** * Provides the start up window to rest of the application. It may return the @@ -68,6 +72,10 @@ public class StartupWindowProvider implements StartupWindowInterface { return; } + if (RuntimeProperties.runningWithGUI()) { + checkSolr(); + } + //discover the registered windows Collection startupWindows = Lookup.getDefault().lookupAll(StartupWindowInterface.class); @@ -107,6 +115,21 @@ public class StartupWindowProvider implements StartupWindowInterface { } } + private void checkSolr() { + + // if Multi-User settings are enabled and Solr8 server is not configured, + // display an error message and a dialog + if (UserPreferences.getIsMultiUserModeEnabled() && UserPreferences.getIndexingServerHost().isEmpty()) { + // Solr 8 host name is not configured. This could be the first time user + // runs Autopsy with Solr 8. Display a message. + MessageNotifyUtil.Notify.error(NbBundle.getMessage(CueBannerPanel.class, "SolrNotConfiguredDialog.title"), + NbBundle.getMessage(SolrNotConfiguredDialog.class, "SolrNotConfiguredDialog.EmptyKeywordSearchHostName")); + + SolrNotConfiguredDialog dialog = new SolrNotConfiguredDialog(); + dialog.setVisible(true); + } + } + /** * Checks whether Autopsy is running from command line. There is an * OptionProcessor that is responsible for processing command line inputs. diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties index fbc4798b6d..b106a1a123 100644 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties @@ -21,10 +21,9 @@ ServicesMonitor.statusChange.notify.msg=Status for {0} is {1} ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown ServicesMonitor.KeywordSearchNull=Cannot find Keyword Search service -ServicesMonitor.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User. ServicesMonitor.InvalidPortNumber=Invalid Solr 8 port number. ServicesMonitor.remoteCaseDatabase.displayName.text=Multi-user case database service ServicesMonitor.remoteKeywordSearch.displayName.text=Multi-user keyword search service ServicesMonitor.messaging.displayName.text=Messaging service ServicesMonitor.databaseConnectionInfo.error.msg=Error accessing case database connection info -ServicesMonitor.messagingService.connErr.text=Error accessing messaging service connection info \ No newline at end of file +ServicesMonitor.messagingService.connErr.text=Error accessing messaging service connection info diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index b45c57a7d8..cd9d1002cd 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -25,7 +25,6 @@ ServicesMonitor.statusChange.notify.msg=Status for {0} is {1} ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown ServicesMonitor.KeywordSearchNull=Cannot find Keyword Search service -ServicesMonitor.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User. ServicesMonitor.InvalidPortNumber=Invalid Solr 8 port number. ServicesMonitor.remoteCaseDatabase.displayName.text=Multi-user case database service ServicesMonitor.remoteKeywordSearch.displayName.text=Multi-user keyword search service diff --git a/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java b/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java index c453d85e51..f5ebe33efb 100644 --- a/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java +++ b/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2015 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -262,20 +262,22 @@ public class ServicesMonitor { KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class); try { if (kwsService != null) { + ServiceStatus status = ServiceStatus.DOWN; + // check Solr 8 String kwsHostName = UserPreferences.getIndexingServerHost(); - if (kwsHostName.isEmpty()) { - // Solr 8 host name is not configured. This could be the first time user - // runs Autopsy with Solr 8. Display a message. - String serviceDisplayName = Service.REMOTE_KEYWORD_SEARCH.getDisplayName(); - MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"), - NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.EmptyKeywordSearchHostName", serviceDisplayName)); - setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString(), - NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.EmptyKeywordSearchHostName")); - return; + if (!kwsHostName.isEmpty()) { + int port = Integer.parseUnsignedInt(UserPreferences.getIndexingServerPort()); + kwsService.tryConnect(UserPreferences.getIndexingServerHost(), port); + status = ServiceStatus.UP; } - int port = Integer.parseUnsignedInt(UserPreferences.getIndexingServerPort()); - kwsService.tryConnect(UserPreferences.getIndexingServerHost(), port); - setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.UP.toString(), ""); + + // check Solr 4 + if (!UserPreferences.getSolr4ServerHost().trim().isEmpty()) { + int port = Integer.parseUnsignedInt(UserPreferences.getSolr4ServerPort().trim()); + kwsService.tryConnect(UserPreferences.getSolr4ServerHost().trim(), port); + status = ServiceStatus.UP; + } + setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), status.toString(), ""); } else { setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString(), NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.KeywordSearchNull")); diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index bb49369e63..a2a252350a 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -56,11 +56,8 @@ public final class UserPreferences { public static final String EXTERNAL_DATABASE_TYPE = "ExternalDatabaseType"; //NON-NLS private static final String SOLR8_SERVER_HOST = "Solr8ServerHost"; //NON-NLS private static final String SOLR8_SERVER_PORT = "Solr8ServerPort"; //NON-NLS - private static final String SOLR4_SERVER_HOST = "Solr4ServerHost"; //NON-NLS - private static final String SOLR4_SERVER_PORT = "Solr4ServerPort"; //NON-NLS - private static final String INDEXING_MAX_SHARDS = "IndexingMaxShards"; //NON-NLS - private static final String INDEXING_DOC_QUEUE_SIZE = "IndexingDocumentQueueSize"; //NON-NLS - private static final String INDEXING_NUM_THREADS = "IndexingNumThreads"; //NON-NLS + private static final String SOLR4_SERVER_HOST = "IndexingServerHost"; //NON-NLS + private static final String SOLR4_SERVER_PORT = "IndexingServerPort"; //NON-NLS private static final String ZK_SERVER_HOST = "ZookeeperServerHost"; //NON-NLS private static final String ZK_SERVER_PORT = "ZookeeperServerPort"; //NON-NLS private static final String MESSAGE_SERVICE_PASSWORD = "MessageServicePassword"; //NON-NLS @@ -371,37 +368,13 @@ public final class UserPreferences { } public static String getZkServerPort() { - return preferences.get(ZK_SERVER_PORT, ""); + return preferences.get(ZK_SERVER_PORT, "9983"); } public static void setZkServerPort(String port) { preferences.put(ZK_SERVER_PORT, port); } - public static void setMaxNumShards(int maxShards) { - preferences.putInt(INDEXING_MAX_SHARDS, maxShards); - } - - public static int getMaxNumShards() { - return preferences.getInt(INDEXING_MAX_SHARDS, 0); - } - - public static int getNumThreads() { - return preferences.getInt(INDEXING_NUM_THREADS, 10); - } - - public static void setNumThreads(int maxShards) { - preferences.putInt(INDEXING_NUM_THREADS, maxShards); - } - - public static void setDocumentsQueueSize(int maxShards) { - preferences.putInt(INDEXING_DOC_QUEUE_SIZE, maxShards); - } - - public static int getDocumentsQueueSize() { - return preferences.getInt(INDEXING_DOC_QUEUE_SIZE, 1000); - } - public static void setTextTranslatorName(String textTranslatorName) { preferences.put(TEXT_TRANSLATOR_NAME, textTranslatorName); } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 7b22089d6d..30637b0489 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -84,6 +84,8 @@ MultiUserSettingsPanel.validationErrMsg.invalidMessageServicePort=Invalid messag MultiUserSettingsPanel.validationErrMsg.invalidIndexingServerPort=Invalid Solr 8 server port number MultiUserSettingsPanel.validationErrMsg.invalidSolr4ServerPort=Invalid Solr 4 server port number MultiUserSettingsPanel.validationErrMsg.invalidZkServerPort=Invalid ZooKeeper server port number +MultiUserSettingsPanel.validationErrMsg.invalidZkServerHostName=ZooKeeper server host name not set +MultiUserSettingsPanel.validationErrMsg.solrNotConfigured=Either Solr 8 or/and Solr 4 server needs to be configured MultiUserSettingsPanel.validationErrMsg.invalidMessgeServiceURI=Message service host and/or port not valid DataContentViewerHex.goToOffsetLabel.text=Jump to Offset DataContentViewerHex.goToOffsetTextField.text= @@ -218,12 +220,14 @@ ViewPreferencesPanel.scoColumnsWrapAroundText.text=to reduce loading times ViewPreferencesPanel.scoColumnsLabel.text=Do not add columns for: MultiUserSettingsPanel.tbSolr4Hostname.toolTipText=Solr 4 Hostname or IP Address MultiUserSettingsPanel.tbSolr4Port.toolTipText=Solr 4 Port Number -MultiUserSettingsPanel.lbZkSettings.text=ZooKeeper Server Settings (Optional) -MultiUserSettingsPanel.lbSolr4Settings.text=Solr 4 Server Settings (Optional) +MultiUserSettingsPanel.lbZkSettings.text=ZooKeeper Server Settings +MultiUserSettingsPanel.lbSolr4Settings.text=Solr 4 Server Settings MultiUserSettingsPanel.lbSolr8Settings.text=Solr 8 Server Settings MultiUserSettingsPanel.tbZkHostname.toolTipText=ZooKeeper Hostname or IP Address MultiUserSettingsPanel.tbZkPort.toolTipText=ZooKeeper Port Number MultiUserSettingsPanel.tbSolr8Hostname.toolTipText=Solr 8 Hostname or IP Address MultiUserSettingsPanel.tbSolr8Port.toolTipText=Solr 8 Port Number MultiUserSettingsPanel.restartRequiredLabel.text=Application restart required to take effect. -MultiUserSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect \ No newline at end of file +MultiUserSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect +MultiUserSettingsPanel.lbSolrNote1.text=NOTE: Enter Solr 8 and/or Solr 4 server settings. +MultiUserSettingsPanel.lbSolrNote2.text=New cases can only be created with Solr 8. diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index 3e44c568ed..084bd0e28a 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -133,6 +133,8 @@ MultiUserSettingsPanel.validationErrMsg.invalidMessageServicePort=Invalid messag MultiUserSettingsPanel.validationErrMsg.invalidIndexingServerPort=Invalid Solr 8 server port number MultiUserSettingsPanel.validationErrMsg.invalidSolr4ServerPort=Invalid Solr 4 server port number MultiUserSettingsPanel.validationErrMsg.invalidZkServerPort=Invalid ZooKeeper server port number +MultiUserSettingsPanel.validationErrMsg.invalidZkServerHostName=ZooKeeper server host name not set +MultiUserSettingsPanel.validationErrMsg.solrNotConfigured=Either Solr 8 or/and Solr 4 server needs to be configured MultiUserSettingsPanel.validationErrMsg.invalidMessgeServiceURI=Message service host and/or port not valid DataContentViewerHex.goToOffsetLabel.text=Jump to Offset DataContentViewerHex.goToOffsetTextField.text= @@ -269,8 +271,8 @@ ViewPreferencesPanel.scoColumnsWrapAroundText.text=to reduce loading times ViewPreferencesPanel.scoColumnsLabel.text=Do not add columns for: MultiUserSettingsPanel.tbSolr4Hostname.toolTipText=Solr 4 Hostname or IP Address MultiUserSettingsPanel.tbSolr4Port.toolTipText=Solr 4 Port Number -MultiUserSettingsPanel.lbZkSettings.text=ZooKeeper Server Settings (Optional) -MultiUserSettingsPanel.lbSolr4Settings.text=Solr 4 Server Settings (Optional) +MultiUserSettingsPanel.lbZkSettings.text=ZooKeeper Server Settings +MultiUserSettingsPanel.lbSolr4Settings.text=Solr 4 Server Settings MultiUserSettingsPanel.lbSolr8Settings.text=Solr 8 Server Settings MultiUserSettingsPanel.tbZkHostname.toolTipText=ZooKeeper Hostname or IP Address MultiUserSettingsPanel.tbZkPort.toolTipText=ZooKeeper Port Number @@ -278,3 +280,5 @@ MultiUserSettingsPanel.tbSolr8Hostname.toolTipText=Solr 8 Hostname or IP Address MultiUserSettingsPanel.tbSolr8Port.toolTipText=Solr 8 Port Number MultiUserSettingsPanel.restartRequiredLabel.text=Application restart required to take effect. MultiUserSettingsPanel.MustRestart=Autopsy must be restarted for new configuration to take effect +MultiUserSettingsPanel.lbSolrNote1.text=NOTE: Enter Solr 8 and/or Solr 4 server settings. +MultiUserSettingsPanel.lbSolrNote2.text=New cases can only be created with Solr 8. diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties index cdc7a60eb8..1c15032c82 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties @@ -274,3 +274,5 @@ MultiUserSettingsPanel.lbSolr8Settings.text=Solr\u8a2d\u5b9a MultiUserSettingsPanel.tbZkPort.toolTipText=\u30dd\u30fc\u30c8\u756a\u53f7 MultiUserSettingsPanel.tbSolr8Hostname.toolTipText=\u30db\u30b9\u30c8\u540d\u307e\u305f\u306fIP\u30a2\u30c9\u30ec\u30b9 MultiUserSettingsPanel.tbSolr8Port.toolTipText=\u30dd\u30fc\u30c8\u756a\u53f7 +MultiUserSettingsPanel.lbSolrNote1.text=Solr\u8a2d\u5b9a +MultiUserSettingsPanel.lbSolrNote2.text=Solr\u8a2d\u5b9a diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form index 9759b9e1a0..97273e1dbb 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form @@ -48,7 +48,7 @@ - + @@ -96,7 +96,7 @@ - + @@ -258,11 +258,16 @@ - - + + + + + + - + + @@ -285,18 +290,24 @@ + + + + - - - + + + + + - + @@ -455,6 +466,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -475,7 +510,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java index a90362a5c7..59f59c3ec0 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java @@ -65,6 +65,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { private static final String INVALID_MESSAGE_SERVICE_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidMessageServicePort"); private static final String INVALID_INDEXING_SERVER_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidIndexingServerPort"); private static final String INVALID_SOLR4_SERVER_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidSolr4ServerPort"); + private static final String SOLR_SERVER_NOT_CONFIGURED_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.solrNotConfigured"); + private static final String INVALID_ZK_SERVER_HOST_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidZkServerHostName"); private static final String INVALID_ZK_SERVER_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidZkServerPort"); private static final String SOLR8_HOST_NAME_OR_IP_PROMPT = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbSolr8Hostname.toolTipText"); private static final String SOLR8_PORT_PROMPT = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbSolr8Port.toolTipText"); @@ -150,6 +152,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { textBoxes.add(tbZkHostname); textBoxes.add(tbZkPort); + // as the user enters Solr 8 settings, we fill in the ZK settings with the embedded Solr 8 ZK connection info. + tbSolr8Hostname.getDocument().addDocumentListener(new MyDocumentListener()); + addDocumentListeners(textBoxes, textBoxChangedListener); goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); @@ -215,6 +220,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { lbZkSettings = new javax.swing.JLabel(); tbZkHostname = new javax.swing.JTextField(); tbZkPort = new javax.swing.JTextField(); + lbSolrNote1 = new javax.swing.JLabel(); + lbSolrNote2 = new javax.swing.JLabel(); pnMessagingSettings = new javax.swing.JPanel(); lbMessageServiceSettings = new javax.swing.JLabel(); tbMsgHostname = new javax.swing.JTextField(); @@ -272,7 +279,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { .addComponent(tbDbHostname) .addGroup(pnDatabaseSettingsLayout.createSequentialGroup() .addComponent(lbDatabaseSettings) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 231, Short.MAX_VALUE) .addComponent(bnTestDatabase) .addGap(18, 18, 18) .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -346,6 +353,12 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { tbZkPort.setFont(tbZkPort.getFont().deriveFont(tbZkPort.getFont().getSize()+1f)); tbZkPort.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbZkPort.toolTipText")); // NOI18N + lbSolrNote1.setFont(lbSolrNote1.getFont().deriveFont(lbSolrNote1.getFont().getSize()+1f)); + org.openide.awt.Mnemonics.setLocalizedText(lbSolrNote1, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbSolrNote1.text")); // NOI18N + + lbSolrNote2.setFont(lbSolrNote2.getFont().deriveFont(lbSolrNote2.getFont().getSize()+1f)); + org.openide.awt.Mnemonics.setLocalizedText(lbSolrNote2, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbSolrNote2.text")); // NOI18N + javax.swing.GroupLayout pnSolrSettingsLayout = new javax.swing.GroupLayout(pnSolrSettings); pnSolrSettings.setLayout(pnSolrSettingsLayout); pnSolrSettingsLayout.setHorizontalGroup( @@ -355,11 +368,15 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { .addGroup(pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(tbSolr8Hostname) .addGroup(pnSolrSettingsLayout.createSequentialGroup() - .addComponent(lbSolr8Settings) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 274, Short.MAX_VALUE) + .addGroup(pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lbSolr8Settings) + .addComponent(lbSolrNote1) + .addComponent(lbSolrNote2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 57, Short.MAX_VALUE) .addComponent(bnTestSolr) - .addGap(18, 18, 18) - .addComponent(lbTestSolr, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lbTestSolr, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(3, 3, 3)) .addComponent(tbSolr8Port) .addComponent(tbSolr4Hostname) .addComponent(tbSolr4Port) @@ -376,17 +393,22 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { pnSolrSettingsLayout.setVerticalGroup( pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnSolrSettingsLayout.createSequentialGroup() - .addContainerGap() + .addGap(8, 8, 8) + .addComponent(lbSolrNote1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lbSolrNote2) + .addGap(20, 20, 20) .addGroup(pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(bnTestSolr) - .addComponent(lbTestSolr, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbSolr8Settings, javax.swing.GroupLayout.Alignment.TRAILING)) + .addGroup(pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(lbSolr8Settings) + .addComponent(bnTestSolr)) + .addComponent(lbTestSolr, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tbSolr8Hostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tbSolr8Port, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) - .addComponent(lbSolr4Settings) + .addComponent(lbSolr4Settings, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tbSolr4Hostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -447,7 +469,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { .addComponent(tbMsgHostname) .addGroup(pnMessagingSettingsLayout.createSequentialGroup() .addComponent(lbMessageServiceSettings) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 229, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(bnTestMessageService) .addGap(18, 18, 18) .addComponent(lbTestMessageService, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -506,7 +528,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tbOops)) .addComponent(pnDatabaseSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnMessagingSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(pnMessagingSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(pnSolrSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(39, 39, 39)) @@ -642,24 +664,30 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { try { if (kwsService != null) { // test Solr 8 connectivity - int port = Integer.parseInt(tbSolr8Port.getText().trim()); - kwsService.tryConnect(tbSolr8Hostname.getText().trim(), port); + if (!tbSolr8Port.getText().trim().isEmpty() && !tbSolr8Hostname.getText().trim().isEmpty()) { + int port = Integer.parseInt(tbSolr8Port.getText().trim()); + kwsService.tryConnect(tbSolr8Hostname.getText().trim(), port); + } // test Solr 4 conenctivity if (!tbSolr4Port.getText().trim().isEmpty() && !tbSolr4Hostname.getText().trim().isEmpty()) { - port = Integer.parseInt(tbSolr4Port.getText().trim()); + int port = Integer.parseInt(tbSolr4Port.getText().trim()); kwsService.tryConnect(tbSolr4Hostname.getText().trim(), port); } - // test ZooKeeper connectivity - if (!tbZkPort.getText().trim().isEmpty() && !tbZkHostname.getText().trim().isEmpty()) { - if (false == CoordinationServiceUtils.isZooKeeperAccessible(tbZkHostname.getText().trim(), tbZkPort.getText().trim())) { - lbTestSolr.setIcon(badIcon); - lbTestSolrWarning.setText(NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.UnableToConnectToZK")); - return; - } + // test ZooKeeper connectivity (ZK settings are mandatory) + if (tbZkPort.getText().trim().isEmpty() || tbZkHostname.getText().trim().isEmpty()) { + lbTestSolr.setIcon(badIcon); + lbTestSolrWarning.setText(NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.UnableToConnectToZK")); + return; } - + + if (false == CoordinationServiceUtils.isZooKeeperAccessible(tbZkHostname.getText().trim(), tbZkPort.getText().trim())) { + lbTestSolr.setIcon(badIcon); + lbTestSolrWarning.setText(NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.UnableToConnectToZK")); + return; + } + lbTestSolr.setIcon(goodIcon); lbTestSolrWarning.setText(""); } else { @@ -709,32 +737,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { logger.log(Level.SEVERE, "Error accessing case database connection info", ex); //NON-NLS } - String indexingServerHost = UserPreferences.getIndexingServerHost().trim(); - if (!indexingServerHost.isEmpty()) { - tbSolr8Hostname.setText(indexingServerHost); - } - String indexingServerPort = UserPreferences.getIndexingServerPort().trim(); - if (portNumberIsValid(indexingServerPort)) { - tbSolr8Port.setText(indexingServerPort); - } - - String solr4ServerHost = UserPreferences.getSolr4ServerHost().trim(); - if (!solr4ServerHost.isEmpty()) { - tbSolr4Hostname.setText(solr4ServerHost); - } - String solr4ServerPort = UserPreferences.getSolr4ServerPort().trim(); - if (portNumberIsValid(solr4ServerPort)) { - tbSolr4Port.setText(solr4ServerPort); - } - - String zkServerHost = UserPreferences.getZkServerHost().trim(); - if (!zkServerHost.isEmpty()) { - tbZkHostname.setText(zkServerHost); - } - String zkServerPort = UserPreferences.getZkServerPort().trim(); - if (portNumberIsValid(zkServerPort)) { - tbZkPort.setText(zkServerPort); - } + populateSolrAndZkSettings(); lbTestDatabase.setIcon(null); lbTestSolr.setIcon(null); @@ -748,6 +751,52 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { this.valid(); // trigger validation to enable buttons based on current settings } + private void populateSolrAndZkSettings() { + + String indexingServerHost = UserPreferences.getIndexingServerHost().trim(); + if (!indexingServerHost.isEmpty()) { + tbSolr8Hostname.setText(indexingServerHost); + } + String indexingServerPort = UserPreferences.getIndexingServerPort().trim(); + if (portNumberIsValid(indexingServerPort)) { + tbSolr8Port.setText(indexingServerPort); + } + + String solr4ServerHost = UserPreferences.getSolr4ServerHost().trim(); + if (!solr4ServerHost.isEmpty()) { + tbSolr4Hostname.setText(solr4ServerHost); + } + String solr4ServerPort = UserPreferences.getSolr4ServerPort().trim(); + if (portNumberIsValid(solr4ServerPort)) { + tbSolr4Port.setText(solr4ServerPort); + } + + // if there are existing valid ZK settings, use those + String zkServerHost = UserPreferences.getZkServerHost().trim(); + String zkServerPort = UserPreferences.getZkServerPort().trim(); + if (!zkServerHost.isEmpty() && portNumberIsValid(zkServerPort)) { + tbZkHostname.setText(zkServerHost); + tbZkPort.setText(zkServerPort); + return; + } + + // If there are no previous Solr 4 settings, use Solr 8 settings + // to fill in the ZK settings with the embedded Solr 8 ZK connection info. + if (solr4ServerHost.isEmpty() && !indexingServerHost.isEmpty()) { + tbZkHostname.setText(indexingServerHost); + tbZkPort.setText(zkServerPort); // gets default ZK port, which is Solr port number + 1000 + return; + } + + // If there are existing Solr 4 settings and no Solr 8 settings, + // pre-populate the ZK settings with the Solr 4 embedded ZK settings. + if (!solr4ServerHost.isEmpty() && indexingServerHost.isEmpty()) { + tbZkHostname.setText(solr4ServerHost); + tbZkPort.setText(zkServerPort); // gets default ZK port, which is Solr port number + 1000 + return; + } + } + /** * Tests whether or not values have been entered in all of the database * settings text fields. @@ -769,21 +818,24 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { */ private boolean solrFieldsArePopulated() { - // all Solr 8 settings must be specified - if (tbSolr8Hostname.getText().trim().isEmpty() - || tbSolr8Port.getText().trim().isEmpty()) { - return false; + // either Solr 8 or/and Solr 4 seetings must be specified + boolean solrConfigured = false; + + // check if Solr 8 settings are set + if (!tbSolr8Hostname.getText().trim().isEmpty() + && !tbSolr8Port.getText().trim().isEmpty()) { + solrConfigured = true; } - // if either one of Solr 4 settings is set, then both settings must be set (!XOR) - if (tbSolr4Hostname.getText().trim().isEmpty() - ^ tbSolr4Port.getText().trim().isEmpty()) { - return false; + // check if Solr 4 settings are set + if (!tbSolr4Hostname.getText().trim().isEmpty() + && !tbSolr4Port.getText().trim().isEmpty()) { + solrConfigured = true; } - // if either one of ZK settings is set, then both settings must be set (!XOR) - return !(tbZkHostname.getText().trim().isEmpty() - ^ tbZkPort.getText().trim().isEmpty()); + // ZK settings are mandatory + return (solrConfigured && !tbZkHostname.getText().trim().isEmpty() + && !tbZkPort.getText().trim().isEmpty()); } /** @@ -867,7 +919,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { } UserPreferences.setIndexingServerHost(tbSolr8Hostname.getText().trim()); - UserPreferences.setIndexingServerPort(Integer.parseInt(tbSolr8Port.getText().trim())); + String solr8port = tbSolr8Port.getText().trim(); + if (!solr8port.isEmpty()) { + UserPreferences.setIndexingServerPort(Integer.parseInt(solr8port)); + } UserPreferences.setSolr4ServerHost(tbSolr4Hostname.getText().trim()); UserPreferences.setSolr4ServerPort(tbSolr4Port.getText().trim()); UserPreferences.setZkServerHost(tbZkHostname.getText().trim()); @@ -889,21 +944,14 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { } private boolean isRestartRequired() { - // Restart is required any time standalone ZK info has changed. - if (!(tbZkHostname.getText().trim().equalsIgnoreCase(UserPreferences.getZkServerHost())) - || !(tbZkPort.getText().trim().equals(UserPreferences.getZkServerPort()))) { - return true; - } - - // If standalone ZK info is not set, then restart is required if Solr settings - // have changed, because we are using the embedded ZK of the Solr server. - if (tbZkHostname.getText().trim().isEmpty() && tbZkPort.getText().trim().isEmpty()) { - if (!(tbSolr8Hostname.getText().trim().equalsIgnoreCase(UserPreferences.getIndexingServerHost())) - || !(tbSolr8Port.getText().trim().equals(UserPreferences.getIndexingServerPort()))) { + // if ZK was previously configured + if (!UserPreferences.getZkServerHost().isEmpty()) { + // Restart is required any time ZK info has changed + if (!(tbZkHostname.getText().trim().equalsIgnoreCase(UserPreferences.getZkServerHost())) + || !(tbZkPort.getText().trim().equals(UserPreferences.getZkServerPort()))) { return true; } - } - + } return false; } @@ -1012,8 +1060,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { * @return True or false. */ boolean indexingServerSettingsAreValid() { - // Solr 8 port must always be specified - if (!portNumberIsValid(tbSolr8Port.getText().trim())) { + + String solr8Port = tbSolr8Port.getText().trim(); + if (!solr8Port.isEmpty() && !portNumberIsValid(solr8Port)) { + // if the port is specified, it has to be valid tbOops.setText(INVALID_INDEXING_SERVER_PORT_MSG); return false; } @@ -1023,10 +1073,37 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { // if the port is specified, it has to be valid tbOops.setText(INVALID_SOLR4_SERVER_PORT_MSG); return false; + } + + // either Solr 8 or/and Solr 4 seetings must be specified + boolean solrConfigured = false; + + // check if Solr 8 settings are set + if (!tbSolr8Hostname.getText().trim().isEmpty() + && !tbSolr8Port.getText().trim().isEmpty()) { + solrConfigured = true; } - + + // check if Solr 4 settings are set + if (!tbSolr4Hostname.getText().trim().isEmpty() + && !tbSolr4Port.getText().trim().isEmpty()) { + solrConfigured = true; + } + + if (!solrConfigured) { + tbOops.setText(SOLR_SERVER_NOT_CONFIGURED_MSG); + return false; + } + + // ZK settings are mandatory + if (tbZkHostname.getText().trim().isEmpty()) { + tbOops.setText(INVALID_ZK_SERVER_HOST_MSG); + return false; + } + + // ZK settings are mandatory String zkPort = tbZkPort.getText().trim(); - if (!zkPort.isEmpty() && !portNumberIsValid(zkPort)) { + if (zkPort.isEmpty() || !portNumberIsValid(zkPort)) { // if the port is specified, it has to be valid tbOops.setText(INVALID_ZK_SERVER_PORT_MSG); return false; @@ -1065,6 +1142,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { private javax.swing.JLabel lbMessageServiceSettings; private javax.swing.JLabel lbSolr4Settings; private javax.swing.JLabel lbSolr8Settings; + private javax.swing.JLabel lbSolrNote1; + private javax.swing.JLabel lbSolrNote2; private javax.swing.JLabel lbTestDatabase; private javax.swing.JLabel lbTestDbWarning; private javax.swing.JLabel lbTestMessageService; @@ -1126,4 +1205,22 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel { controller.changed(); } } + + private class MyDocumentListener implements DocumentListener { + + @Override + public void changedUpdate(DocumentEvent e) { + tbZkHostname.setText(tbSolr8Hostname.getText().trim()); + } + + @Override + public void removeUpdate(DocumentEvent e) { + tbZkHostname.setText(tbSolr8Hostname.getText().trim()); + } + + @Override + public void insertUpdate(DocumentEvent e) { + tbZkHostname.setText(tbSolr8Hostname.getText().trim()); + } + }; } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java index a56f3cdd64..3807c26089 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java @@ -327,11 +327,13 @@ public class Server { private ConcurrentUpdateSolrClient getSolrClient(String solrUrl) { int numThreads = org.sleuthkit.autopsy.keywordsearch.UserPreferences.getNumThreads(); int numDocs = org.sleuthkit.autopsy.keywordsearch.UserPreferences.getDocumentsQueueSize(); - logger.log(Level.INFO, "Creating new ConcurrentUpdateSolrClient. Queue size = {0}, Number of threads = {1}", new Object[]{numDocs, numThreads}); //NON-NLS + int connectionTimeoutMs = org.sleuthkit.autopsy.keywordsearch.UserPreferences.getConnectionTimeout(); + logger.log(Level.INFO, "Creating new ConcurrentUpdateSolrClient: {0}", solrUrl); //NON-NLS + logger.log(Level.INFO, "Queue size = {0}, Number of threads = {1}, Connection Timeout (ms) = {2}", new Object[]{numDocs, numThreads, connectionTimeoutMs}); //NON-NLS ConcurrentUpdateSolrClient client = new ConcurrentUpdateSolrClient.Builder(solrUrl) .withQueueSize(numDocs) .withThreadCount(numThreads) - .withConnectionTimeout(1000) + .withConnectionTimeout(connectionTimeoutMs) .withResponseParser(new XMLResponseParser()) .build(); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java index bd76f409ff..d5fedbec61 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java @@ -154,12 +154,15 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService { if (host == null || host.isEmpty()) { throw new KeywordSearchServiceException(NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.MissingHostname")); //NON-NLS } + String solrUrl = "http://" + host + ":" + Integer.toString(port) + "/solr"; try { - solrServer = new ConcurrentUpdateSolrClient.Builder("http://" + host + ":" + Integer.toString(port) + "/solr").build(); //NON-NLS + solrServer = new ConcurrentUpdateSolrClient.Builder(solrUrl).build(); //NON-NLS KeywordSearch.getServer().connectToSolrServer(solrServer); } catch (SolrServerException ex) { + logger.log(Level.SEVERE, "Uanble to connect to Solr server: " + solrUrl, ex); throw new KeywordSearchServiceException(NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.HostnameOrPort")); //NON-NLS*/ } catch (IOException ex) { + logger.log(Level.SEVERE, "Uanble to connect to Solr server: " + solrUrl, ex); String result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.HostnameOrPort"); //NON-NLS String message = ex.getCause().getMessage().toLowerCase(); if (message.startsWith(SERVER_REFUSED_CONNECTION)) { @@ -179,8 +182,10 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService { } throw new KeywordSearchServiceException(result); } catch (NumberFormatException ex) { + logger.log(Level.SEVERE, "Uanble to connect to Solr server: " + solrUrl, ex); throw new KeywordSearchServiceException(Bundle.SolrConnectionCheck_Port()); } catch (IllegalArgumentException ex) { + logger.log(Level.SEVERE, "Uanble to connect to Solr server: " + solrUrl, ex); throw new KeywordSearchServiceException(ex.getMessage()); } finally { if (null != solrServer) { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/UserPreferences.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/UserPreferences.java index dec59d2145..c02cda3455 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/UserPreferences.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/UserPreferences.java @@ -27,12 +27,14 @@ import org.openide.util.NbPreferences; * Provides convenient access to a Preferences node for user preferences with * default values. */ -public final class UserPreferences { +final class UserPreferences { private static final Preferences preferences = NbPreferences.forModule(UserPreferences.class); private static final String INDEXING_MAX_SHARDS = "IndexingMaxShards"; //NON-NLS private static final String INDEXING_DOC_QUEUE_SIZE = "IndexingDocumentQueueSize"; //NON-NLS private static final String INDEXING_NUM_THREADS = "IndexingNumThreads"; //NON-NLS + private static final String SOLR_CONNECTION_TIMEOUT_MS = "SolrConnectionTimeoutMs"; //NON-NLS + private static final int DEFAULT_CONNECTION_TIMEOUT_MS = 120000; // 2 minutes // Prevent instantiation. private UserPreferences() { @@ -90,4 +92,12 @@ public final class UserPreferences { public static int getDocumentsQueueSize() { return preferences.getInt(INDEXING_DOC_QUEUE_SIZE, 1000); } + + public static void setConnectionTimeout(int connectionTimeoutMs) { + preferences.putInt(SOLR_CONNECTION_TIMEOUT_MS, connectionTimeoutMs); + } + + public static int getConnectionTimeout() { + return preferences.getInt(SOLR_CONNECTION_TIMEOUT_MS, DEFAULT_CONNECTION_TIMEOUT_MS); + } }