diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
index 00c6616c5b..5e6b5e5ceb 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
@@ -39,6 +39,7 @@ import javax.swing.JOptionPane;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
+import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskData.DbType;
/**
@@ -112,7 +113,7 @@ final class NewCaseWizardAction extends CallableSystemAction {
get();
CaseType currentCaseType = CaseType.values()[(int) wizardDescriptor.getProperty("caseType")]; //NON-NLS
CaseDbConnectionInfo info = UserPreferences.getDatabaseConnectionInfo();
- if ((currentCaseType == CaseType.SINGLE_USER_CASE) || ((info.getDbType() != DbType.SQLITE) && info.canConnect())) {
+ if ((currentCaseType == CaseType.SINGLE_USER_CASE) || ((info.getDbType() != DbType.SQLITE) && SleuthkitCase.tryConnectOld(info.getHost(), info.getPort(), info.getUserName(), info.getPassword(), info.getDbType()))) {
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
addImageAction.actionPerformed(null);
} else {
diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties
index 4fa84d55dc..36d6bd4a25 100644
--- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties
@@ -19,5 +19,5 @@ ServicesMonitor.restoredService.notify.msg=Connection to {0} is up
ServicesMonitor.statusChange.notify.title=Service Status Update
ServicesMonitor.statusChange.notify.msg=Status for {0} is {1}
ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null
-ServicesMonitor.nullStatusOrDetails.excepton.txt=Status or details string is null
-ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown
\ No newline at end of file
+ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown
+ServicesMonitor.KeywordSearchNull=Keyword Search potentially not initialized
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java b/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java
index b7144c98fc..277f458892 100644
--- a/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java
+++ b/Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.core;
import org.sleuthkit.autopsy.core.events.ServiceEvent;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeListener;
+import java.io.IOException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -34,6 +35,13 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
+import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
+import java.net.URISyntaxException;
+import java.sql.SQLException;
+import javax.jms.JMSException;
+import org.sleuthkit.datamodel.CaseDbConnectionInfo;
+import org.sleuthkit.datamodel.SleuthkitCase;
+import org.sleuthkit.datamodel.TskCoreException;
/**
* This class periodically checks availability of collaboration resources -
@@ -149,28 +157,8 @@ public class ServicesMonitor {
* @param status Updated status for the service.
* @param details Details of the event.
*
- * @throws
- * org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException Thrown
- * if
- * either
- * of
- * input
- * parameters
- * is
- * null.
*/
- public void setServiceStatus(String service, String status, String details) throws ServicesMonitorException {
-
- if (service == null) {
- logger.log(Level.SEVERE, "Call to setServiceStatus() with null service name"); //NON-NLS
- throw new ServicesMonitorException(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.nullServiceName.excepton.txt"));
- }
-
- if (status == null || details == null) {
- logger.log(Level.SEVERE, "Call to setServiceStatus() with null status or details"); //NON-NLS
- throw new ServicesMonitorException(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.nullStatusOrDetails.excepton.txt"));
- }
-
+ public void setServiceStatus(String service, String status, String details) {
// if the status update is for an existing service who's status hasn't changed - do nothing.
if (statusByService.containsKey(service) && status.equals(statusByService.get(service))) {
return;
@@ -211,15 +199,8 @@ public class ServicesMonitor {
*
* @return ServiceStatus Status for the service.
*
- * @throws
- * org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException Thrown
- * if
- * service
- * name is
- * null or
- * service
- * doesn't
- * exist.
+ * @throws ServicesMonitorException If service name is null or service
+ * doesn't exist.
*/
public String getServiceStatus(String service) throws ServicesMonitorException {
@@ -260,14 +241,12 @@ public class ServicesMonitor {
* Performs case database service availability status check.
*/
private void checkDatabaseConnectionStatus() {
+ CaseDbConnectionInfo info = UserPreferences.getDatabaseConnectionInfo();
try {
- if (UserPreferences.getDatabaseConnectionInfo().canConnect()) {
- setServiceStatus(Service.REMOTE_CASE_DATABASE.toString(), ServiceStatus.UP.toString(), "");
- } else {
- setServiceStatus(Service.REMOTE_CASE_DATABASE.toString(), ServiceStatus.DOWN.toString(), "");
- }
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Exception while checking database connection status", ex); //NON-NLS
+ SleuthkitCase.tryConnect(info.getHost(), info.getPort(), info.getUserName(), info.getPassword(), info.getDbType());
+ setServiceStatus(Service.REMOTE_CASE_DATABASE.toString(), ServiceStatus.UP.toString(), "");
+ } catch (ClassNotFoundException | SQLException | TskCoreException ex) {
+ setServiceStatus(Service.REMOTE_CASE_DATABASE.toString(), ServiceStatus.DOWN.toString(), SleuthkitCase.getUserWarning(ex, info.getHost()));
}
}
@@ -275,15 +254,19 @@ public class ServicesMonitor {
* Performs keyword search service availability status check.
*/
private void checkKeywordSearchServerConnectionStatus() {
+ KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
try {
- KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
- if (kwsService != null && kwsService.canConnectToRemoteSolrServer(UserPreferences.getIndexingServerHost(), UserPreferences.getIndexingServerPort())) {
+ if (kwsService != null) {
+ kwsService.tryConnect(UserPreferences.getIndexingServerHost(), UserPreferences.getIndexingServerPort());
setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.UP.toString(), "");
} else {
- setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString(), "");
+ setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString(),
+ NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.KeywordSearchNull"));
}
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Exception while checking keyword search server connection status", ex); //NON-NLS
+ } catch (NumberFormatException | IOException | TskCoreException ex) {
+ String rootCause = kwsService.getUserWarning(ex, UserPreferences.getIndexingServerHost());
+ logger.log(Level.SEVERE, "Unable to connect to messaging server: " + rootCause, ex); //NON-NLS
+ setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString(), rootCause);
}
}
@@ -291,14 +274,14 @@ public class ServicesMonitor {
* Performs messaging service availability status check.
*/
private void checkMessagingServerConnectionStatus() {
+ MessageServiceConnectionInfo info = UserPreferences.getMessageServiceConnectionInfo();
try {
- if (UserPreferences.getMessageServiceConnectionInfo().canConnect()) {
- setServiceStatus(Service.MESSAGING.toString(), ServiceStatus.UP.toString(), "");
- } else {
- setServiceStatus(Service.MESSAGING.toString(), ServiceStatus.DOWN.toString(), "");
- }
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Exception while checking messaging server connection status", ex); //NON-NLS
+ info.tryConnect();
+ setServiceStatus(Service.MESSAGING.toString(), ServiceStatus.UP.toString(), "");
+ } catch (URISyntaxException | JMSException | TskCoreException ex) {
+ String rootCause = info.getUserWarning(ex, info.getHost());
+ logger.log(Level.SEVERE, "Unable to connect to messaging server: " + rootCause, ex); //NON-NLS
+ setServiceStatus(Service.MESSAGING.toString(), ServiceStatus.DOWN.toString(), rootCause);
}
}
@@ -396,6 +379,7 @@ public class ServicesMonitor {
* Exception thrown when service status query results in an error.
*/
public class ServicesMonitorException extends Exception {
+ private static final long serialVersionUID = 1L;
public ServicesMonitorException(String message) {
super(message);
diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
index 2f1c6a5ae5..565ec6f395 100755
--- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
@@ -181,10 +181,10 @@ public final class UserPreferences {
* @param info An object encapsulating the message service info.
*/
public static void setMessageServiceConnectionInfo(MessageServiceConnectionInfo info) {
- preferences.put(MESSAGE_SERVICE_USER, info.getUserName());
- preferences.put(MESSAGE_SERVICE_PASSWORD, info.getPassword());
preferences.put(MESSAGE_SERVICE_HOST, info.getHost());
preferences.put(MESSAGE_SERVICE_PORT, info.getPort());
+ preferences.put(MESSAGE_SERVICE_USER, info.getUserName());
+ preferences.put(MESSAGE_SERVICE_PASSWORD, info.getPassword());
}
/**
@@ -193,10 +193,11 @@ public final class UserPreferences {
* @return An object encapsulating the message service info.
*/
public static MessageServiceConnectionInfo getMessageServiceConnectionInfo() {
- return new MessageServiceConnectionInfo(preferences.get(MESSAGE_SERVICE_USER, ""),
- preferences.get(MESSAGE_SERVICE_PASSWORD, ""),
+ return new MessageServiceConnectionInfo(
preferences.get(MESSAGE_SERVICE_HOST, ""),
- preferences.get(MESSAGE_SERVICE_PORT, "61616"));
+ preferences.get(MESSAGE_SERVICE_PORT, "61616"),
+ preferences.get(MESSAGE_SERVICE_USER, ""),
+ preferences.get(MESSAGE_SERVICE_PASSWORD, ""));
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index 3b2ee0dac2..f878750bb9 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -191,3 +191,7 @@ MultiUserSettingsPanel.tbMsgPassword.toolTipText=Password
MultiUserSettingsPanel.tbMsgPassword.text=
MultiUserSettingsPanel.tbMsgHostname.toolTipText=Hostname or IP Address
MultiUserSettingsPanel.tbMsgHostname.text=
+MultiUserSettingsPanel.lbTestMessageWarning.text=
+MultiUserSettingsPanel.lbTestSolrWarning.text=
+MultiUserSettingsPanel.lbTestDbWarning.text=
+MultiUserSettingsPanel.KeywordSearchNull=Keyword Search potentially not initialized
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form
index 3cf719efcc..57f1eca7d5 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form
@@ -16,12 +16,12 @@
-
+
-
+
@@ -57,10 +57,10 @@
-
+
-
+
@@ -78,7 +78,7 @@
-
+
@@ -92,6 +92,10 @@
+
+
+
+
@@ -114,7 +118,9 @@
-
+
+
+
@@ -201,6 +207,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -215,7 +231,7 @@
-
+
@@ -227,6 +243,10 @@
+
+
+
+
@@ -247,7 +267,9 @@
-
+
+
+
@@ -300,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -314,7 +346,7 @@
-
+
@@ -328,6 +360,10 @@
+
+
+
+
@@ -344,7 +380,7 @@
-
+
@@ -353,6 +389,8 @@
+
+
@@ -437,6 +475,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java
index 807390cd25..1a58c2764a 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java
@@ -18,11 +18,17 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
import org.sleuthkit.autopsy.coreutils.Logger;
import java.awt.Cursor;
-import java.util.logging.Level;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.sql.SQLException;
+import java.util.MissingResourceException;
+import javax.jms.JMSException;
import javax.swing.ImageIcon;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
+import org.sleuthkit.datamodel.SleuthkitCase;
+import org.sleuthkit.datamodel.TskCoreException;
public final class MultiUserSettingsPanel extends javax.swing.JPanel {
@@ -41,7 +47,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(MultiUserSettingsPanel.class.getName());
private final ImageIcon goodIcon;
private final ImageIcon badIcon;
-
+
/**
* Creates new form AutopsyMultiUserSettingsPanel
*
@@ -50,7 +56,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
public MultiUserSettingsPanel(MultiUserSettingsPanelController theController) {
initComponents();
controller = theController;
-
+ setSize(555, 600);
+
/**
* Add text prompts to all of the text fields.
*/
@@ -98,9 +105,6 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
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));
- lbTestDatabase.setIcon(null);
- lbTestSolr.setIcon(null);
- lbTestMessageService.setIcon(null);
enableMultiUserComponents(textBoxes, cbEnableMultiUser.isSelected());
}
@@ -148,12 +152,14 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
lbDatabaseSettings = new javax.swing.JLabel();
bnTestDatabase = new javax.swing.JButton();
lbTestDatabase = new javax.swing.JLabel();
+ lbTestDbWarning = new javax.swing.JLabel();
pnSolrSettings = new javax.swing.JPanel();
lbSolrSettings = new javax.swing.JLabel();
tbSolrHostname = new javax.swing.JTextField();
tbSolrPort = new javax.swing.JTextField();
bnTestSolr = new javax.swing.JButton();
lbTestSolr = new javax.swing.JLabel();
+ lbTestSolrWarning = new javax.swing.JLabel();
pnMessagingSettings = new javax.swing.JPanel();
lbMessageServiceSettings = new javax.swing.JLabel();
tbMsgHostname = new javax.swing.JTextField();
@@ -162,6 +168,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
tbMsgPassword = new javax.swing.JPasswordField();
bnTestMessageService = new javax.swing.JButton();
lbTestMessageService = new javax.swing.JLabel();
+ lbTestMessageWarning = new javax.swing.JLabel();
cbEnableMultiUser = new javax.swing.JCheckBox();
tbOops = new javax.swing.JTextField();
@@ -197,6 +204,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabase, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbTestDatabase.text")); // NOI18N
lbTestDatabase.setAutoscrolls(true);
+ lbTestDbWarning.setForeground(new java.awt.Color(255, 0, 0));
+ org.openide.awt.Mnemonics.setLocalizedText(lbTestDbWarning, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbTestDbWarning.text")); // NOI18N
+
javax.swing.GroupLayout pnDatabaseSettingsLayout = new javax.swing.GroupLayout(pnDatabaseSettings);
pnDatabaseSettings.setLayout(pnDatabaseSettingsLayout);
pnDatabaseSettingsLayout.setHorizontalGroup(
@@ -213,7 +223,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(tbDbPort)
.addComponent(tbDbUsername)
- .addComponent(tbDbPassword))
+ .addComponent(tbDbPassword)
+ .addGroup(pnDatabaseSettingsLayout.createSequentialGroup()
+ .addComponent(lbTestDbWarning)
+ .addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
pnDatabaseSettingsLayout.setVerticalGroup(
@@ -232,7 +245,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(tbDbUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tbDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(13, 13, 13))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lbTestDbWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
);
pnSolrSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder());
@@ -255,6 +270,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(lbTestSolr, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbTestSolr.text")); // NOI18N
+ lbTestSolrWarning.setForeground(new java.awt.Color(255, 0, 0));
+ org.openide.awt.Mnemonics.setLocalizedText(lbTestSolrWarning, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbTestSolrWarning.text")); // NOI18N
+
javax.swing.GroupLayout pnSolrSettingsLayout = new javax.swing.GroupLayout(pnSolrSettings);
pnSolrSettings.setLayout(pnSolrSettingsLayout);
pnSolrSettingsLayout.setHorizontalGroup(
@@ -269,7 +287,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(bnTestSolr)
.addGap(18, 18, 18)
.addComponent(lbTestSolr, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(tbSolrPort))
+ .addComponent(tbSolrPort)
+ .addGroup(pnSolrSettingsLayout.createSequentialGroup()
+ .addComponent(lbTestSolrWarning)
+ .addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
pnSolrSettingsLayout.setVerticalGroup(
@@ -285,7 +306,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(tbSolrHostname, 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(tbSolrPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(45, 45, 45))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lbTestSolrWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
);
pnMessagingSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder());
@@ -318,6 +341,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(lbTestMessageService, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbTestMessageService.text")); // NOI18N
+ lbTestMessageWarning.setForeground(new java.awt.Color(255, 0, 0));
+ org.openide.awt.Mnemonics.setLocalizedText(lbTestMessageWarning, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbTestMessageWarning.text")); // NOI18N
+
javax.swing.GroupLayout pnMessagingSettingsLayout = new javax.swing.GroupLayout(pnMessagingSettings);
pnMessagingSettings.setLayout(pnMessagingSettingsLayout);
pnMessagingSettingsLayout.setHorizontalGroup(
@@ -334,7 +360,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(lbTestMessageService, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(tbMsgPort)
.addComponent(tbMsgUsername)
- .addComponent(tbMsgPassword))
+ .addComponent(tbMsgPassword)
+ .addGroup(pnMessagingSettingsLayout.createSequentialGroup()
+ .addComponent(lbTestMessageWarning)
+ .addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
pnMessagingSettingsLayout.setVerticalGroup(
@@ -346,7 +375,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(bnTestMessageService, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lbMessageServiceSettings))
.addComponent(lbTestMessageService, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tbMsgHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tbMsgPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@@ -354,7 +383,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addComponent(tbMsgUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tbMsgPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap())
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lbTestMessageWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
org.openide.awt.Mnemonics.setLocalizedText(cbEnableMultiUser, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.cbEnableMultiUser.text")); // NOI18N
@@ -395,21 +426,21 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnDatabaseSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pnSolrSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 106, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(pnSolrSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnMessagingSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap(39, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnOverallPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnOverallPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 555, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnOverallPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnOverallPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 559, javax.swing.GroupLayout.PREFERRED_SIZE)
);
}// //GEN-END:initComponents
@@ -433,6 +464,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
lbTestSolr.setIcon(null);
bnTestMessageService.setEnabled(false);
lbTestMessageService.setIcon(null);
+ lbTestDbWarning.setText("");
+ lbTestSolrWarning.setText("");
+ lbTestMessageWarning.setText("");
}
enableMultiUserComponents(textBoxes, cbEnableMultiUser.isSelected());
controller.changed();
@@ -440,50 +474,76 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private void bnTestDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestDatabaseActionPerformed
lbTestDatabase.setIcon(null);
+ lbTestDbWarning.setText("");
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- CaseDbConnectionInfo dbInfo = new CaseDbConnectionInfo(
- this.tbDbHostname.getText(),
- this.tbDbPort.getText(),
- this.tbDbUsername.getText(),
- new String(this.tbDbPassword.getPassword()),
- DbType.POSTGRESQL);
- if (dbInfo.canConnect()) {
+ try {
+ SleuthkitCase.tryConnect(this.tbDbHostname.getText().trim(),
+ this.tbDbPort.getText().trim(),
+ this.tbDbUsername.getText().trim(),
+ new String(this.tbDbPassword.getPassword()),
+ DbType.POSTGRESQL);
lbTestDatabase.setIcon(goodIcon);
- } else {
+ lbTestDbWarning.setText("");
+ } catch (ClassNotFoundException | SQLException | TskCoreException ex) {
lbTestDatabase.setIcon(badIcon);
+ lbTestDbWarning.setText(SleuthkitCase.getUserWarning(ex, this.tbDbHostname.getText().trim()));
+ } finally {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}//GEN-LAST:event_bnTestDatabaseActionPerformed
private void bnTestMessageServiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestMessageServiceActionPerformed
lbTestMessageService.setIcon(null);
+ lbTestMessageWarning.setText("");
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- MessageServiceConnectionInfo messagingConnectionInfo = new MessageServiceConnectionInfo(
- this.tbMsgUsername.getText(),
- new String(this.tbMsgPassword.getPassword()),
- this.tbMsgHostname.getText(),
- this.tbMsgPort.getText());
- if (messagingConnectionInfo.canConnect()) {
+ MessageServiceConnectionInfo info = new MessageServiceConnectionInfo(
+ this.tbMsgHostname.getText().trim(),
+ this.tbMsgPort.getText().trim(),
+ this.tbMsgUsername.getText().trim(),
+ new String(this.tbMsgPassword.getPassword()));
+ try {
+ info.tryConnect();
lbTestMessageService.setIcon(goodIcon);
- } else {
+ lbTestMessageWarning.setText("");
+ } catch (JMSException | URISyntaxException | TskCoreException ex) {
lbTestMessageService.setIcon(badIcon);
+ lbTestMessageWarning.setText(info.getUserWarning(ex, tbMsgHostname.getText().trim()));
+ } finally {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}//GEN-LAST:event_bnTestMessageServiceActionPerformed
private void bnTestSolrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestSolrActionPerformed
lbTestSolr.setIcon(null);
+ lbTestSolrWarning.setText("");
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
- if (kwsService != null && kwsService.canConnectToRemoteSolrServer(tbSolrHostname.getText(), tbSolrPort.getText())) {
- lbTestSolr.setIcon(goodIcon);
- } else {
+ try {
+ if (kwsService != null) {
+ kwsService.tryConnect(tbSolrHostname.getText().trim(), tbSolrPort.getText().trim());
+ lbTestSolr.setIcon(goodIcon);
+ lbTestSolrWarning.setText("");
+ } else {
+ lbTestSolr.setIcon(badIcon);
+ lbTestSolrWarning.setText(NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.KeywordSearchNull"));
+ }
+ } catch (NumberFormatException | IOException | TskCoreException | MissingResourceException ex) {
lbTestSolr.setIcon(badIcon);
+ lbTestSolrWarning.setText(kwsService.getUserWarning(ex, tbSolrHostname.getText().trim()));
+ } finally {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}//GEN-LAST:event_bnTestSolrActionPerformed
void load() {
+ lbTestDatabase.setIcon(null);
+ lbTestSolr.setIcon(null);
+ lbTestMessageService.setIcon(null);
+ lbTestDbWarning.setText("");
+ lbTestSolrWarning.setText("");
+ lbTestMessageWarning.setText("");
+
CaseDbConnectionInfo dbInfo = UserPreferences.getDatabaseConnectionInfo();
tbDbHostname.setText(dbInfo.getHost().trim());
tbDbPort.setText(dbInfo.getPort().trim());
@@ -524,9 +584,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
* @return True or false.
*/
private boolean databaseFieldsArePopulated() {
- return !tbDbHostname.getText().isEmpty()
- && !tbDbPort.getText().isEmpty()
- && !tbDbUsername.getText().isEmpty()
+ return !tbDbHostname.getText().trim().isEmpty()
+ && !tbDbPort.getText().trim().isEmpty()
+ && !tbDbUsername.getText().trim().isEmpty()
&& tbDbPassword.getPassword().length != 0;
}
@@ -537,8 +597,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
* @return True or false.
*/
private boolean solrFieldsArePopulated() {
- return !tbSolrHostname.getText().isEmpty()
- && !tbSolrPort.getText().isEmpty();
+ return !tbSolrHostname.getText().trim().isEmpty()
+ && !tbSolrPort.getText().trim().isEmpty();
}
/**
@@ -548,9 +608,9 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
* @return True or false.
*/
private boolean messageServiceFieldsArePopulated() {
- return !tbMsgHostname.getText().isEmpty()
- && !tbMsgPort.getText().isEmpty()
- && !tbMsgUsername.getText().isEmpty()
+ return !tbMsgHostname.getText().trim().isEmpty()
+ && !tbMsgPort.getText().trim().isEmpty()
+ && !tbMsgUsername.getText().trim().isEmpty()
&& tbMsgPassword.getPassword().length != 0;
}
@@ -573,10 +633,11 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
UserPreferences.setDatabaseConnectionInfo(info);
MessageServiceConnectionInfo msgServiceInfo = new MessageServiceConnectionInfo(
- tbMsgUsername.getText().trim(),
- new String(tbMsgPassword.getPassword()),
tbMsgHostname.getText().trim(),
- tbMsgPort.getText().trim());
+ tbMsgPort.getText().trim(),
+ tbMsgUsername.getText().trim(),
+ new String(tbMsgPassword.getPassword()));
+
UserPreferences.setMessageServiceConnectionInfo(msgServiceInfo);
UserPreferences.setIndexingServerHost(tbSolrHostname.getText().trim());
@@ -638,7 +699,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
* @return True or false.
*/
boolean databaseSettingsAreValid() {
- if (portNumberIsValid(tbDbPort.getText())) {
+ if (portNumberIsValid(tbDbPort.getText().trim())) {
return true;
} else {
tbOops.setText(INVALID_DB_PORT_MSG);
@@ -652,7 +713,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
* @return True or false.
*/
boolean messageServiceSettingsAreValid() {
- if (!portNumberIsValid(tbMsgPort.getText())) {
+ if (!portNumberIsValid(tbMsgPort.getText().trim())) {
tbOops.setText(INVALID_MESSAGE_SERVICE_PORT_MSG);
return false;
}
@@ -666,7 +727,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
* @return True or false.
*/
boolean indexingServerSettingsAreValid() {
- if (!portNumberIsValid(tbSolrPort.getText())) {
+ if (!portNumberIsValid(tbSolrPort.getText().trim())) {
tbOops.setText(INVALID_INDEXING_SERVER_PORT_MSG);
return false;
}
@@ -703,8 +764,11 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private javax.swing.JLabel lbMessageServiceSettings;
private javax.swing.JLabel lbSolrSettings;
private javax.swing.JLabel lbTestDatabase;
+ private javax.swing.JLabel lbTestDbWarning;
private javax.swing.JLabel lbTestMessageService;
+ private javax.swing.JLabel lbTestMessageWarning;
private javax.swing.JLabel lbTestSolr;
+ private javax.swing.JLabel lbTestSolrWarning;
private javax.swing.JPanel pnDatabaseSettings;
private javax.swing.JPanel pnMessagingSettings;
private javax.swing.JPanel pnOverallPanel;
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java
index 80b3f9bb58..8cb2ce53a3 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanelController.java
@@ -27,6 +27,7 @@ import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import java.util.logging.Level;
+import org.openide.util.NbPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Multi_User_Settings",
diff --git a/Core/src/org/sleuthkit/autopsy/events/Bundle.properties b/Core/src/org/sleuthkit/autopsy/events/Bundle.properties
new file mode 100755
index 0000000000..9552399239
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/events/Bundle.properties
@@ -0,0 +1,18 @@
+MessageServiceConnectionInfo.tbMsgPort.toolTipText=Port Number
+MessageServiceConnectionInfo.tbMsgPort.text=
+MessageServiceConnectionInfo.tbMsgUsername.toolTipText=User Name
+MessageServiceConnectionInfo.tbMsgUsername.text=
+MessageServiceConnectionInfo.tbMsgPassword.toolTipText=Password
+MessageServiceConnectionInfo.tbMsgPassword.text=
+MessageServiceConnectionInfo.tbMsgHostname.toolTipText=Hostname or IP Address
+MessageServiceConnectionInfo.tbMsgHostname.text=
+MessageServiceConnectionInfo.ConnectionCheck.Everything=Check hostname, port number, username, and password.
+MessageServiceConnectionInfo.ConnectionCheck.Hostname=Check hostname.
+MessageServiceConnectionInfo.ConnectionCheck.Port=Check port number.
+MessageServiceConnectionInfo.ConnectionCheck.Username=Check username.
+MessageServiceConnectionInfo.ConnectionCheck.Password=Check password.
+MessageServiceConnectionInfo.ConnectionCheck.HostnameOrPort=Check hostname and/or port number.
+MessageServiceConnectionInfo.MissingHostname=Missing hostname.
+MessageServiceConnectionInfo.MissingPort=Missing port number.
+MessageServiceConnectionInfo.MissingUsername=Missing username.
+MessageServiceConnectionInfo.MissingPassword=Missing password.
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/events/MessageServiceConnectionInfo.java b/Core/src/org/sleuthkit/autopsy/events/MessageServiceConnectionInfo.java
index acb20776bc..0cd0ac4816 100644
--- a/Core/src/org/sleuthkit/autopsy/events/MessageServiceConnectionInfo.java
+++ b/Core/src/org/sleuthkit/autopsy/events/MessageServiceConnectionInfo.java
@@ -24,6 +24,11 @@ import javax.annotation.concurrent.Immutable;
import javax.jms.Connection;
import javax.jms.JMSException;
import org.apache.activemq.ActiveMQConnectionFactory;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.MissingResourceException;
+import org.openide.util.NbBundle;
+import org.sleuthkit.datamodel.TskCoreException;
/**
* Connection info for a Java Message Service (JMS) provider. Thread-safe.
@@ -32,6 +37,9 @@ import org.apache.activemq.ActiveMQConnectionFactory;
public final class MessageServiceConnectionInfo {
private static final String MESSAGE_SERVICE_URI = "tcp://%s:%s?wireFormat.maxInactivityDuration=0";
+ private static final String CONNECTION_TIMED_OUT = "connection timed out";
+ private static final String CONNECTION_REFUSED = "connection refused";
+ private static final int IS_REACHABLE_TIMEOUT_MS = 1000;
private final String userName;
private final String password;
private final String host;
@@ -41,17 +49,18 @@ public final class MessageServiceConnectionInfo {
* Constructs an object containing connection info for a Java Message
* Service (JMS) provider.
*
- * @param userName The user name to use for a message service connection.
- * @param password The password to use for a message service connection.
* @param host The host to use for a message service connection. May be
* a host name or an IP address.
* @param port The port number to use for a message service connection.
+ * @param userName The user name to use for a message service connection.
+ * @param password The password to use for a message service connection.
+ *
*/
- public MessageServiceConnectionInfo(String userName, String password, String host, String port) {
- this.userName = userName;
- this.password = password;
+ public MessageServiceConnectionInfo(String host, String port, String userName, String password) {
this.host = host;
this.port = port;
+ this.userName = userName;
+ this.password = password;
}
/**
@@ -106,17 +115,76 @@ public final class MessageServiceConnectionInfo {
/**
* Verifies connection to messaging service.
*
- * @return True if connection can be established, false otherwise.
+ * @return throws if we cannot communicate with ActiveMQ.
+ *
+ * @throws java.net.URISyntaxException
+ * @throws javax.jms.JMSException
*/
- public boolean canConnect() {
- try {
- ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(getUserName(), getPassword(), getURI());
- Connection connection = connectionFactory.createConnection(getUserName(), getPassword());
- connection.start();
- connection.close();
- return true;
- } catch (URISyntaxException | JMSException ex) {
- return false;
+ public void tryConnect() throws URISyntaxException, JMSException, TskCoreException {
+ if (host == null || host.isEmpty()) {
+ throw new TskCoreException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingHostname")); //NON-NLS
+ } else if (port == null || port.isEmpty()) {
+ throw new TskCoreException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingPort")); //NON-NLS
+ } else if (userName == null || userName.isEmpty()) {
+ throw new TskCoreException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingUsername")); //NON-NLS
+ } else if (password == null || password.isEmpty()) {
+ throw new TskCoreException(NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.MissingPassword")); //NON-NLS
}
+
+ URI uri = new URI(String.format(MESSAGE_SERVICE_URI, getHost(), getPort()));
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(getUserName(), getPassword(), uri);
+ Connection connection = connectionFactory.createConnection(getUserName(), getPassword());
+ connection.start();
+ connection.close();
+ }
+
+ /**
+ * This method handles exceptions from the ActiveMQ tester, returning the
+ * appropriate text for the exception received.
+ *
+ * @param ex the Exception to analyze
+ * @param ipAddress the IP address to check against
+ *
+ * @return returns the String message to show the user
+ */
+ public String getUserWarning(Exception ex, String ipAddress) {
+ String result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Everything"); //NON-NLS
+
+ if (ex instanceof JMSException) {
+ Throwable cause = ex.getCause();
+ if (cause != null) {
+ // there is more information from another exception
+ String msg = cause.getMessage();
+ if (msg.startsWith(CONNECTION_TIMED_OUT)) {
+ // The hostname or IP address seems bad
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Hostname"); //NON-NLS
+ } else if (msg.toLowerCase().startsWith(CONNECTION_REFUSED)) {
+ // The port seems bad
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Port"); //NON-NLS
+ } else {
+ // Could be either hostname or port number
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.HostnameOrPort"); //NON-NLS
+ }
+ } else {
+ // there is no more information from another exception
+ try {
+ if (InetAddress.getByName(ipAddress).isReachable(IS_REACHABLE_TIMEOUT_MS)) {
+ // if we can reach the host, then it's probably a port problem
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Port"); //NON-NLS
+ } else {
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Hostname"); //NON-NLS
+ }
+ } catch (IOException | MissingResourceException any) {
+ // it may be anything
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.Everything"); //NON-NLS
+ }
+ }
+ } else if (ex instanceof URISyntaxException) {
+ // The hostname or port seems bad
+ result = NbBundle.getMessage(MessageServiceConnectionInfo.class, "MessageServiceConnectionInfo.ConnectionCheck.HostnameOrPort"); //NON-NLS
+ } else if (ex instanceof TskCoreException) {
+ result = ex.getMessage();
+ }
+ return result;
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java b/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java
index aa32d61916..a3579601d8 100644
--- a/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java
+++ b/Core/src/org/sleuthkit/autopsy/keywordsearchservice/KeywordSearchService.java
@@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.keywordsearchservice;
import java.io.Closeable;
+import java.io.IOException;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
@@ -38,13 +39,26 @@ public interface KeywordSearchService extends Closeable {
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException;
/**
- * Are we able to connect to the remote Solr server.
+ * Checks if we can communicate with Solr using the passed-in host and port.
+ * Closes the connection upon exit. Throws if it cannot communicate with
+ * Solr.
*
- * @param host the hostname or IP address of the server
- * @param port the port to connect to
+ * @param host the remote hostname or IP address of the Solr server
+ * @param port the remote port for Solr
*
- * @return true if we can connect, otherwise false
+ * @throws java.io.IOException
+ * @throws org.sleuthkit.datamodel.TskCoreException
*/
- public boolean canConnectToRemoteSolrServer(String host, String port);
+ public void tryConnect(String host, String port) throws NumberFormatException, IOException, TskCoreException;
+ /**
+ * This method handles exceptions from the connection tester, tryConnect(),
+ * returning the appropriate user-facing text for the exception received.
+ *
+ * @param ex the exception that was returned
+ * @param ipAddress the IP address to connect to
+ *
+ * @return returns the String message to show the user
+ */
+ public String getUserWarning(Exception ex, String ipAddress);
}
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties
index dcf82c78f3..2847b35618 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties
@@ -106,7 +106,6 @@ KeywordSearchFilterNode.getFileActions.openExternViewActLbl=Open in External Vie
KeywordSearchFilterNode.getFileActions.searchSameMd5=Search for files with the same MD5 hash
KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=View in New Window
KeywordSearchIngestModule.init.badInitMsg=Keyword search server was not properly initialized, cannot run keyword search ingest.
-KeywordSearchIngestModule.init.verifyConnection=Please verify credentials and connectivity to multi-user keyword search service.
KeywordSearchIngestModule.init.tryStopSolrMsg={0}
Please try stopping old java Solr process (if it exists) and restart the application.
KeywordSearchIngestModule.init.noKwInLstMsg=No keywords in keyword list.
KeywordSearchIngestModule.init.onlyIdxKwSkipMsg=Only indexing will be done and and keyword search will be skipped (you can still add keyword lists using the Keyword Lists - Add to Ingest).
@@ -288,3 +287,8 @@ 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.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
+SolrConnectionCheck.HostnameOrPort=Check hostname and/or port number.
+SolrConnectionCheck.Hostname=Check hostname.
+SolrConnectionCheck.Port=Check port number.
+SolrConnectionCheck.MissingHostname=Missing hostname.
+SolrConnectionCheck.MissingPort=Missing port number.
\ No newline at end of file
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
index 861d6f04e0..b5df6bc179 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
@@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.keywordsearch;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -147,10 +148,12 @@ public final class KeywordSearchIngestModule implements FileIngestModule {
if (Case.getCurrentCase().getCaseType() == Case.CaseType.MULTI_USER_CASE) {
// for multi-user cases need to verify connection to remore SOLR server
KeywordSearchService kwsService = new SolrSearchService();
- if (!kwsService.canConnectToRemoteSolrServer(UserPreferences.getIndexingServerHost(), UserPreferences.getIndexingServerPort())) {
+ try {
+ kwsService.tryConnect(UserPreferences.getIndexingServerHost(), UserPreferences.getIndexingServerPort());
+ } catch (NumberFormatException | IOException | TskCoreException ex) {
String msg = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.badInitMsg");
- logger.log(Level.SEVERE, msg);
- String details = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.verifyConnection");
+ String details = kwsService.getUserWarning(ex, UserPreferences.getIndexingServerHost());
+ logger.log(Level.SEVERE, "{0}: {1}", new Object[]{msg, details});
services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(), msg, details));
throw new IngestModuleException(msg);
}
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java
index 50e4e9ec99..2d61e9fefb 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SolrSearchService.java
@@ -33,6 +33,9 @@ import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase;
+import org.openide.util.NbBundle;
+import java.net.InetAddress;
+import java.util.MissingResourceException;
/**
* An implementation of the KeywordSearchService interface that uses Solr for
@@ -41,6 +44,10 @@ import org.sleuthkit.datamodel.SleuthkitCase;
@ServiceProvider(service = KeywordSearchService.class)
public class SolrSearchService implements KeywordSearchService {
+ private static final String BAD_IP_ADDRESS_FORMAT = "ioexception occured when talking to server";
+ private static final String SERVER_REFUSED_CONNECTION = "server refused connection";
+ private static final int IS_REACHABLE_TIMEOUT_MS = 1000;
+
@Override
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException {
if (artifact == null) {
@@ -157,39 +164,75 @@ public class SolrSearchService implements KeywordSearchService {
/**
* Checks if we can communicate with Solr using the passed-in host and port.
- * Closes the connection upon exit.
+ * Closes the connection upon exit. Throws if it cannot communicate with
+ * Solr.
*
* @param host the remote hostname or IP address of the Solr server
* @param port the remote port for Solr
*
- * @return true if communication with Solr is functional, false otherwise
+ * @throws java.io.IOException
+ * @throws org.sleuthkit.datamodel.TskCoreException
*/
@Override
- public boolean canConnectToRemoteSolrServer(String host, String port) {
- if (host.isEmpty() || port.isEmpty()) {
- return false;
- }
-
+ public void tryConnect(String host, String port) throws NumberFormatException, IOException, TskCoreException {
try {
- // if the port value is invalid, return false
+ if (host == null || host.isEmpty()) {
+ throw new TskCoreException(NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.MissingHostname")); //NON-NLS
+ } else if (port == null || port.isEmpty()) {
+ throw new TskCoreException(NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.MissingPort")); //NON-NLS
+ }
+ // if the port value is invalid, throw
Integer.parseInt(port);
- } catch (NumberFormatException ex) {
- return false;
- }
-
- HttpSolrServer solrServer = null;
- try {
- solrServer = new HttpSolrServer("http://" + host + ":" + port + "/solr"); //NON-NLS;
+ HttpSolrServer solrServer = new HttpSolrServer("http://" + host + ":" + port + "/solr"); //NON-NLS;
KeywordSearch.getServer().connectToSolrServer(solrServer);
- return true; // if we get here, it's at least up and responding
- } catch (SolrServerException | IOException ignore) {
- } finally {
- if (solrServer != null) {
+ if (null != solrServer) {
solrServer.shutdown();
}
+ } catch (SolrServerException ex) {
+ throw new IOException(ex);
}
+ }
- return false;
+ /**
+ * This method handles exceptions from the connection tester, tryConnect(),
+ * returning the appropriate user-facing text for the exception received.
+ *
+ * @param ex the exception that was returned
+ * @param ipAddress the IP address to connect to
+ *
+ * @return returns the String message to show the user
+ */
+ @Override
+ public String getUserWarning(Exception ex, String ipAddress) {
+
+ String result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.HostnameOrPort"); //NON-NLS
+ if (ex instanceof IOException) {
+ String message = ex.getCause().getMessage().toLowerCase();
+ if (message.startsWith(SERVER_REFUSED_CONNECTION)) {
+ try {
+ if (InetAddress.getByName(ipAddress).isReachable(IS_REACHABLE_TIMEOUT_MS)) {
+ // if we can reach the host, then it's probably port problem
+ result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.Port"); //NON-NLS
+ } else {
+ result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.HostnameOrPort"); //NON-NLS
+ }
+ } catch (IOException | MissingResourceException any) {
+ // it may be anything
+ result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.HostnameOrPort"); //NON-NLS
+ }
+ } else if (message.startsWith(BAD_IP_ADDRESS_FORMAT)) {
+ result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.Hostname"); //NON-NLS
+ }
+ } else if (ex instanceof SolrServerException) {
+ result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.HostnameOrPort"); //NON-NLS
+ } else if (ex instanceof NumberFormatException) {
+ result = NbBundle.getMessage(SolrSearchService.class, "SolrConnectionCheck.Port"); //NON-NLS
+ } else if (ex instanceof TskCoreException) {
+ result = ex.getMessage();
+ } else {
+ result = ex.getMessage();
+ }
+ return result;
}
@Override