diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index 6ee83a3dfb..ffe67c43be 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -141,20 +141,20 @@ public class Case implements SleuthkitCase.ErrorObserver {
SINGLE_USER_CASE("Single-user case"),
MULTI_USER_CASE("Multi-user case");
- private final String caseName;
+ private final String caseType;
private CaseType(String s) {
- caseName = s;
+ caseType = s;
}
- public boolean equalsName(String otherName) {
- return (otherName == null) ? false : caseName.equals(otherName);
+ public boolean equalsName(String otherType) {
+ return (otherType == null) ? false : caseType.equals(otherType);
}
- public static CaseType fromString(String text) {
- if (text != null) {
+ public static CaseType fromString(String typeName) {
+ if (typeName != null) {
for (CaseType c : CaseType.values()) {
- if (text.equalsIgnoreCase(c.caseName)) {
+ if (typeName.equalsIgnoreCase(c.caseType)) {
return c;
}
}
@@ -164,7 +164,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
@Override
public String toString() {
- return caseName;
+ return caseType;
}
};
@@ -176,6 +176,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
private final SleuthkitCase db;
// Track the current case (only set with changeCase() method)
private static Case currentCase = null;
+ private CaseType caseType;
private final Services services;
private static final Logger logger = Logger.getLogger(Case.class.getName());
static final String CASE_EXTENSION = "aut"; //NON-NLS
@@ -189,12 +190,13 @@ public class Case implements SleuthkitCase.ErrorObserver {
/**
* Constructor for the Case class
*/
- private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db) {
+ private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db, CaseType type) {
this.name = name;
this.number = number;
this.examiner = examiner;
this.configFilePath = configFilePath;
this.xmlcm = xmlcm;
+ this.caseType = type;
this.db = db;
this.services = new Services(db);
// messenger = new Messenger(this.name);
@@ -344,16 +346,20 @@ public class Case implements SleuthkitCase.ErrorObserver {
XMLCaseManagement xmlcm = new XMLCaseManagement();
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
+ Date date = new Date();
+ String indexName = caseName + "_" + dateFormat.format(date);
+
String dbName = null;
- // figure out the database name
+
+ // figure out the database name and index name for text extraction
if (caseType == CaseType.SINGLE_USER_CASE) {
dbName = caseDir + File.separator + "autopsy.db"; //NON-NLS
} else if (caseType == CaseType.MULTI_USER_CASE) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
- dbName = caseName + "_" + dateFormat.format(new Date());
+ dbName = caseName + "_" + dateFormat.format(date);
}
- xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName); // create a new XML config file
+ xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName, indexName); // create a new XML config file
xmlcm.writeFile();
SleuthkitCase db = null;
@@ -373,7 +379,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Two-stage initialization to avoid leaking reference to "this" in
* constructor.
*/
- Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db);
+ Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
newCase.init();
// newCase.messenger.start();
@@ -403,7 +409,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
SleuthkitCase db;
if (caseType == CaseType.SINGLE_USER_CASE) {
- // if the caseName is "", case / config file can't be opened
+ // if the caseType is "", case / config file can't be opened
if (caseName.equals("")) {
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.open.exception.blankCase.msg"));
}
@@ -434,7 +440,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Two-stage initialization to avoid leaking reference to "this" in
* constructor.
*/
- Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db);
+ Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
openedCase.init();
// openedCase.messenger.start();
@@ -789,6 +795,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
}
}
+ /**
+ * Get the case type.
+ * @return
+ */
+ public CaseType getCaseType() {
+ return this.caseType;
+ }
+
/**
* Gets the full path to the temp directory of this case
*
@@ -854,6 +868,19 @@ public class Case implements SleuthkitCase.ErrorObserver {
}
}
+ /**
+ * Get the name of the index where extracted text is stored for the case.
+ *
+ * @return Index name.
+ */
+ public String getTextIndexName() {
+ if (xmlcm == null) {
+ return "";
+ } else {
+ return xmlcm.getTextIndexName();
+ }
+ }
+
/**
* Get absolute module output directory path where modules should save their
* permanent data The directory is a subdirectory of this case dir.
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseSchema.xsd b/Core/src/org/sleuthkit/autopsy/casemodule/CaseSchema.xsd
index 442eae823f..63c9aa49df 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseSchema.xsd
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseSchema.xsd
@@ -16,6 +16,8 @@
+
+
@@ -99,6 +101,7 @@
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java b/Core/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java
index f1ad541b5e..86b9ddc770 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java
@@ -60,6 +60,7 @@ import org.xml.sax.SAXException;
final static String SCHEMA_VERSION_NAME = "SchemaVersion"; //NON-NLS
final static String AUTOPSY_CRVERSION_NAME = "AutopsyCreatedVersion"; //NON-NLS
final static String AUTOPSY_MVERSION_NAME = "AutopsySavedVersion"; //NON-NLS
+ final static String CASE_TEXT_INDEX_NAME = "TextIndexName"; //NON-NLS
// folders inside case directory
final static String LOG_FOLDER_NAME = "LogFolder"; //NON-NLS
final static String LOG_FOLDER_RELPATH = "Log"; //NON-NLS
@@ -88,6 +89,7 @@ import org.xml.sax.SAXException;
private String autopsySavedVersion;
private CaseType caseType; // The type of case: local or shared
private String dbName; // The name of the database
+ private String textIndexName; // The name of the index where extracted text is stored.
// for error handling
private JPanel caller;
@@ -247,6 +249,34 @@ import org.xml.sax.SAXException;
}
/**
+ * Sets the text index name internally (on local variable in this class)
+ *
+ * @param textIndexName the new name for the index where extracted text
+ * is stored for the case.
+ */
+ private void setTextIndexName(String textIndexName) {
+ this.textIndexName= textIndexName; // change this to change the xml file if needed
+ }
+
+ /**
+ * Gets the name of the index where extracted text is stored.
+ *
+ * @return the index name
+ */
+ public String getTextIndexName() {
+ if (doc == null) {
+ return "";
+ } else {
+ if (getCaseElement().getElementsByTagName(CASE_TEXT_INDEX_NAME).getLength() > 0) {
+ Element nameElement = (Element) getCaseElement().getElementsByTagName(CASE_TEXT_INDEX_NAME).item(0);
+ return nameElement.getTextContent();
+ } else {
+ return ""; /// couldn't find one, so return a blank index name
+ }
+ }
+ }
+
+ /**
* Sets the examiner name internally (on local variable in this class)
*
* @param givenExaminer the new examiner
@@ -503,8 +533,9 @@ import org.xml.sax.SAXException;
* @param caseNumber case number (optional), can be empty
* @param dbName the name of the database. Could be a local path, could be
* a Postgre db name.
+ * @param textIndexName The name of the index where extracted text is stored.
*/
- protected void create(String dirPath, String caseName, String examiner, String caseNumber, CaseType caseType, String dbName) throws CaseActionException {
+ protected void create(String dirPath, String caseName, String examiner, String caseNumber, CaseType caseType, String dbName, String textIndexName) throws CaseActionException {
clear(); // clear the previous data
// set the case Name and Directory and the parent directory
@@ -514,6 +545,7 @@ import org.xml.sax.SAXException;
setNumber(caseNumber);
setCaseType(caseType);
setDatabaseName(dbName);
+ setTextIndexName(textIndexName);
DocumentBuilder docBuilder;
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
@@ -593,6 +625,10 @@ import org.xml.sax.SAXException;
dbNameElement.appendChild(doc.createTextNode(dbName));
caseElement.appendChild(dbNameElement);
+ Element indexNameElement = doc.createElement(CASE_TEXT_INDEX_NAME); // ...
+ indexNameElement.appendChild(doc.createTextNode(textIndexName));
+ caseElement.appendChild(indexNameElement);
+
// write more code if needed ...
}
@@ -761,5 +797,6 @@ import org.xml.sax.SAXException;
examiner = "";
caseType = CaseType.SINGLE_USER_CASE;
dbName = "";
+ textIndexName = "";
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
index 3f3365d4fe..92385abf1a 100755
--- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
@@ -45,6 +45,8 @@ public final class UserPreferences {
public static final String EXTERNAL_DATABASE_PASSWORD = "ExternalDatabasePassword"; //NON-NLS
public static final String EXTERNAL_DATABASE_TYPE = "ExternalDatabaseType"; //NON-NLS
public static final String NEW_CASE_TYPE = "NewCaseType"; //NON-NLS
+ public static final String INDEXING_SERVER_HOST = "IndexingServerHost"; //NON-NLS
+ public static final String INDEXING_SERVER_PORT = "IndexingServerPort"; //NON-NLS
private static final String MESSAGE_SERVICE_PASSWORD = "MessageServicePassword"; //NON-NLS
private static final String MESSAGE_SERVICE_USER = "MessageServiceUser"; //NON-NLS
private static final String MESSAGE_SERVICE_HOST = "MessageServiceHost"; //NON-NLS
@@ -132,6 +134,22 @@ public final class UserPreferences {
public static void setNewCaseType(int value) {
preferences.putInt(NEW_CASE_TYPE, value);
}
+
+ public static String getIndexingServerHost() {
+ return preferences.get(INDEXING_SERVER_HOST, "");
+ }
+
+ public static void setIndexingServerHost(String hostName) {
+ preferences.put(INDEXING_SERVER_HOST, hostName);
+ }
+
+ public static String getIndexingServerPort() {
+ return preferences.get(INDEXING_SERVER_PORT, "");
+ }
+
+ public static void setIndexingServerPort(int port) {
+ preferences.putInt(INDEXING_SERVER_PORT, port);
+ }
/**
* Persists message service connection info.
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index c2a7d818e4..c5089ca52c 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -165,6 +165,7 @@ MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings
MultiUserSettingsPanel.validationErrMsg.incomplete=Fill in all values
MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database port number
MultiUserSettingsPanel.validationErrMsg.invalidMessageServicePort=Invalid message service port number
+MultiUserSettingsPanel.validationErrMsg.invalidIndexingServerPort=Invalid Solr server port number
MultiUserSettingsPanel.validationErrMsg.invalidMessgeServiceURI=Message service host and/or port not valid
MultiUserSettingsPanel.msgHostTextField.text=
MultiUserSettingsPanel.msgHostTextField.toolTipText=Hostname or IP Address
@@ -174,3 +175,7 @@ MultiUserSettingsPanel.msgPasswordField.toolTipText=Password
MultiUserSettingsPanel.msgPasswordField.text=
MultiUserSettingsPanel.msgPortTextField.toolTipText=Hostname or IP Address
MultiUserSettingsPanel.msgPortTextField.text=
+MultiUserSettingsPanel.tbIndexingServerHost.text=localhost
+MultiUserSettingsPanel.tbIndexingServerPort.text=23232
+MultiUserSettingsPanel.tbIndexingServerHost.toolTipText=Hostname or IP Address
+MultiUserSettingsPanel.tbIndexingServerPort.toolTipText=Port Number
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form
index 89d75fd3df..723f7b999b 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.form
@@ -16,7 +16,7 @@
-
+
@@ -55,7 +55,7 @@
-
+
@@ -126,6 +126,9 @@
+
+
+
@@ -191,10 +194,17 @@
-
+
+
+
+
+
+
+
+
+
+
-
-
@@ -203,7 +213,11 @@
-
+
+
+
+
+
@@ -219,6 +233,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java
index 32d3cdaade..b5bc13392f 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MultiUserSettingsPanel.java
@@ -27,6 +27,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private static final String INCOMPLETE_SETTINGS_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.incomplete");
private static final String INVALID_DB_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort");
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 final MultiUserSettingsPanelController controller;
private final Collection textBoxes = new ArrayList<>();
private final TextBoxChangedListener textBoxChangedListener;
@@ -51,6 +52,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
textPrompts.add(new TextPrompt(PORT_PROMPT, msgPortTextField));
textPrompts.add(new TextPrompt(USER_NAME_PROMPT, msgUserNameTextField));
textPrompts.add(new TextPrompt(PASSWORD_PROMPT, msgPasswordField));
+ textPrompts.add(new TextPrompt(HOST_NAME_OR_IP_PROMPT, tbIndexingServerHost));
+ textPrompts.add(new TextPrompt(PORT_PROMPT, tbIndexingServerPort));
configureTextPrompts(textPrompts);
/// Register for notifications when the text boxes get updated.
@@ -63,6 +66,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
textBoxes.add(msgPortTextField);
textBoxes.add(msgUserNameTextField);
textBoxes.add(msgPasswordField);
+ textBoxes.add(tbIndexingServerHost);
+ textBoxes.add(tbIndexingServerPort);
addDocumentListeners(textBoxes, textBoxChangedListener);
enableMultiUserComponents(textBoxes, cbEnableMultiUser.isSelected());
@@ -112,6 +117,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
lbDatabaseSettings = new javax.swing.JLabel();
pnSolrSettings = new javax.swing.JPanel();
lbSolrSettings = new javax.swing.JLabel();
+ tbIndexingServerHost = new javax.swing.JTextField();
+ tbIndexingServerPort = new javax.swing.JTextField();
lbOops = new javax.swing.JLabel();
pnMessagingSettings = new javax.swing.JPanel();
lbMessagingSettings = new javax.swing.JLabel();
@@ -126,6 +133,11 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
tbHostnameOrIp.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
tbHostnameOrIp.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbHostnameOrIp.text")); // NOI18N
tbHostnameOrIp.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbHostnameOrIp.toolTipText")); // NOI18N
+ tbHostnameOrIp.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ tbHostnameOrIpActionPerformed(evt);
+ }
+ });
tbPortNumber.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
tbPortNumber.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbPortNumber.text")); // NOI18N
@@ -180,21 +192,48 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
lbSolrSettings.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbSolrSettings, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbSolrSettings.text")); // NOI18N
+ tbIndexingServerHost.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
+ tbIndexingServerHost.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerHost.text")); // NOI18N
+ tbIndexingServerHost.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerHost.toolTipText")); // NOI18N
+ tbIndexingServerHost.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ tbIndexingServerHostActionPerformed(evt);
+ }
+ });
+
+ tbIndexingServerPort.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
+ tbIndexingServerPort.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerPort.text")); // NOI18N
+ tbIndexingServerPort.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerPort.toolTipText")); // NOI18N
+ tbIndexingServerPort.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ tbIndexingServerPortActionPerformed(evt);
+ }
+ });
+
javax.swing.GroupLayout pnSolrSettingsLayout = new javax.swing.GroupLayout(pnSolrSettings);
pnSolrSettings.setLayout(pnSolrSettingsLayout);
pnSolrSettingsLayout.setHorizontalGroup(
pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSolrSettingsLayout.createSequentialGroup()
.addContainerGap()
- .addComponent(lbSolrSettings)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnSolrSettingsLayout.createSequentialGroup()
+ .addComponent(lbSolrSettings)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addComponent(tbIndexingServerHost, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(tbIndexingServerPort, javax.swing.GroupLayout.Alignment.TRAILING))
+ .addContainerGap())
);
pnSolrSettingsLayout.setVerticalGroup(
pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSolrSettingsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lbSolrSettings)
- .addContainerGap(75, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(tbIndexingServerHost, 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(tbIndexingServerPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(45, 45, 45))
);
lbOops.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
@@ -285,7 +324,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addGroup(pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cbEnableMultiUser)
.addComponent(lbOops))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 6, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.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, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@@ -298,7 +337,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnOverallPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 511, Short.MAX_VALUE)
+ .addComponent(pnOverallPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -325,6 +364,18 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
controller.changed();
}//GEN-LAST:event_cbEnableMultiUserItemStateChanged
+ private void tbHostnameOrIpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbHostnameOrIpActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_tbHostnameOrIpActionPerformed
+
+ private void tbIndexingServerHostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbIndexingServerHostActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_tbIndexingServerHostActionPerformed
+
+ private void tbIndexingServerPortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbIndexingServerPortActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_tbIndexingServerPortActionPerformed
+
void load() {
CaseDbConnectionInfo dbInfo = UserPreferences.getDatabaseConnectionInfo();
tbHostnameOrIp.setText(dbInfo.getHost());
@@ -338,6 +389,15 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
msgUserNameTextField.setText(msgServiceInfo.getUserName());
msgPasswordField.setText(msgServiceInfo.getPassword());
+ String indexingServerHost = UserPreferences.getIndexingServerHost();
+ if (!indexingServerHost.isEmpty()) {
+ tbIndexingServerHost.setText(indexingServerHost);
+ }
+ String indexingServerPort = UserPreferences.getIndexingServerPort();
+ if (portNumberIsValid(indexingServerPort)) {
+ tbIndexingServerPort.setText(indexingServerPort);
+ }
+
if (dbInfo.getDbType() == DbType.UNKNOWN) {
cbEnableMultiUser.setSelected(false);
} else {
@@ -381,6 +441,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
msgHostTextField.getText(),
msgPortTextField.getText());
UserPreferences.setMessageServiceConnectionInfo(msgServiceInfo);
+
+ UserPreferences.setIndexingServerHost(tbIndexingServerHost.getText());
+ UserPreferences.setIndexingServerPort(Integer.parseInt(tbIndexingServerPort.getText()));
+
}
/**
@@ -391,7 +455,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
boolean valid() {
lbOops.setText("");
if (cbEnableMultiUser.isSelected()) {
- return settingsAreComplete() && databaseSettingsAreValid() && messageServiceSettingsAreValid();
+ return settingsAreComplete() && databaseSettingsAreValid() && indexingServerSettingsAreValid() && messageServiceSettingsAreValid();
} else {
return true;
}
@@ -444,6 +508,20 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
return true;
}
+ /**
+ * Tests whether or not the indexing server settings are valid.
+ *
+ * @return True or false.
+ */
+ boolean indexingServerSettingsAreValid() {
+ if (!portNumberIsValid(tbIndexingServerPort.getText())) {
+ lbOops.setText(INVALID_INDEXING_SERVER_PORT_MSG);
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Determines whether or not a port number is within the range of valid port
* numbers.
@@ -478,6 +556,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private javax.swing.JPanel pnOverallPanel;
private javax.swing.JPanel pnSolrSettings;
private javax.swing.JTextField tbHostnameOrIp;
+ private javax.swing.JTextField tbIndexingServerHost;
+ private javax.swing.JTextField tbIndexingServerPort;
private javax.swing.JPasswordField tbPassword;
private javax.swing.JTextField tbPortNumber;
private javax.swing.JTextField tbUsername;
@@ -503,6 +583,6 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
public void removeUpdate(DocumentEvent e) {
controller.changed();
- }
+ }
}
}
diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml
index f07f7894a0..0f823bd9be 100644
--- a/KeywordSearch/nbproject/project.xml
+++ b/KeywordSearch/nbproject/project.xml
@@ -169,58 +169,14 @@
ext/bcmail-jdk15-1.45.jar
release/modules/ext/bcmail-jdk15-1.45.jar
-
- ext/bcprov-jdk15-1.45.jar
- release/modules/ext/bcprov-jdk15-1.45.jar
-
-
- ext/commons-logging-api-1.1.jar
- release/modules/ext/commons-logging-api-1.1.jar
-
-
- ext/commons-logging-1.1.1.jar
- release/modules/ext/commons-logging-1.1.1.jar
-
-
- ext/commons-compress-1.5.jar
- release/modules/ext/commons-compress-1.5.jar
-
-
- ext/commons-lang-2.4.jar
- release/modules/ext/commons-lang-2.4.jar
-
-
- ext/commons-lang-2.4-javadoc.jar
- release/modules/ext/commons-lang-2.4-javadoc.jar
-
-
- ext/commons-lang-2.4-sources.jar
- release/modules/ext/commons-lang-2.4-sources.jar
-
ext/tika-parsers-1.5.jar
release/modules/ext/tika-parsers-1.5.jar
-
- ext/tika-core-1.5.jar
- release/modules/ext/tika-core-1.5.jar
-
-
- ext/metadata-extractor-2.7.2.jar
- release/modules/ext/metadata-extractor-2.7.2.jar
-
-
- ext/xmpcore-5.1.2.jar
- release/modules/ext/xmpcore-5.1.2.jar
-
ext/jericho-html-3.3.jar
release/modules/ext/jericho-html-3.3.jar
-
- ext/jericho-html-3.3-sources.jar
- release/modules/ext/jericho-html-3.3-sources.jar
-
ext/org.osgi.compendium-4.0.0.jar
release/modules/ext/org.osgi.compendium-4.0.0.jar
@@ -234,33 +190,57 @@
release/modules/ext/xmlbeans-2.3.0.jar
- ext/asm-all-3.1.jar
- release/modules/ext/asm-all-3.1.jar
-
-
- ext/poi-3.10-beta2.jar
- release/modules/ext/poi-3.10-beta2.jar
+ ext/jempbox-1.8.4.jar
+ release/modules/ext/jempbox-1.8.4.jar
ext/poi-ooxml-3.10-beta2.jar
release/modules/ext/poi-ooxml-3.10-beta2.jar
- ext/poi-ooxml-schemas-3.10-beta2.jar
- release/modules/ext/poi-ooxml-schemas-3.10-beta2.jar
+ ext/commons-logging-api-1.1.jar
+ release/modules/ext/commons-logging-api-1.1.jar
- ext/poi-scratchpad-3.10-beta2.jar
- release/modules/ext/poi-scratchpad-3.10-beta2.jar
+ ext/asm-all-3.1.jar
+ release/modules/ext/asm-all-3.1.jar
+
+
+ ext/solr-solrj-4.9.1-javadoc.jar
+ release/modules/ext/solr-solrj-4.9.1-javadoc.jar
+
+
+ ext/poi-3.10-beta2.jar
+ release/modules/ext/poi-3.10-beta2.jar
ext/icu4j-3.8.jar
release/modules/ext/icu4j-3.8.jar
+
+ ext/fontbox-1.8.4.jar
+ release/modules/ext/fontbox-1.8.4.jar
+
+
+ ext/xmpcore-5.1.2.jar
+ release/modules/ext/xmpcore-5.1.2.jar
+
+
+ ext/metadata-extractor-2.7.2.jar
+ release/modules/ext/metadata-extractor-2.7.2.jar
+
ext/tagsoup-1.2.1.jar
release/modules/ext/tagsoup-1.2.1.jar
+
+ ext/commons-compress-1.5.jar
+ release/modules/ext/commons-compress-1.5.jar
+
+
+ ext/commons-lang-2.4-javadoc.jar
+ release/modules/ext/commons-lang-2.4-javadoc.jar
+
ext/org.osgi.core-4.0.0.jar
release/modules/ext/org.osgi.core-4.0.0.jar
@@ -269,14 +249,6 @@
ext/httpclient-4.3.1.jar
release/modules/ext/httpclient-4.3.1.jar
-
- ext/httpcore-4.3.jar
- release/modules/ext/httpcore-4.3.jar
-
-
- ext/httpmime-4.3.1.jar
- release/modules/ext/httpmime-4.3.1.jar
-
ext/isoparser-1.0-RC-1.jar
release/modules/ext/isoparser-1.0-RC-1.jar
@@ -285,6 +257,14 @@
ext/log4j-1.2.17.jar
release/modules/ext/log4j-1.2.17.jar
+
+ ext/commons-lang-2.4-sources.jar
+ release/modules/ext/commons-lang-2.4-sources.jar
+
+
+ ext/tika-core-1.5.jar
+ release/modules/ext/tika-core-1.5.jar
+
ext/jericho-html-3.3-javadoc.jar
release/modules/ext/jericho-html-3.3-javadoc.jar
@@ -302,12 +282,12 @@
release/modules/ext/solr-solrj-4.9.1.jar
- ext/solr-solrj-4.9.1-javadoc.jar
- release/modules/ext/solr-solrj-4.9.1-javadoc.jar
+ ext/poi-scratchpad-3.10-beta2.jar
+ release/modules/ext/poi-scratchpad-3.10-beta2.jar
- ext/solr-solrj-4.9.1-sources.jar
- release/modules/ext/solr-solrj-4.9.1-sources.jar
+ ext/commons-logging-1.1.1.jar
+ release/modules/ext/commons-logging-1.1.1.jar
ext/netcdf-4.2-min.jar
@@ -317,6 +297,18 @@
ext/vorbis-java-core-0.1-tests.jar
release/modules/ext/vorbis-java-core-0.1-tests.jar
+
+ ext/commons-io-2.3.jar
+ release/modules/ext/commons-io-2.3.jar
+
+
+ ext/jericho-html-3.3-sources.jar
+ release/modules/ext/jericho-html-3.3-sources.jar
+
+
+ ext/solr-solrj-4.9.1-sources.jar
+ release/modules/ext/solr-solrj-4.9.1-sources.jar
+
ext/juniversalchardet-1.0.3.jar
release/modules/ext/juniversalchardet-1.0.3.jar
@@ -333,10 +325,22 @@
ext/apache-mime4j-core-0.7.2.jar
release/modules/ext/apache-mime4j-core-0.7.2.jar
+
+ ext/httpmime-4.3.1.jar
+ release/modules/ext/httpmime-4.3.1.jar
+
ext/qdox-1.12.jar
release/modules/ext/qdox-1.12.jar
+
+ ext/httpcore-4.3.jar
+ release/modules/ext/httpcore-4.3.jar
+
+
+ ext/commons-lang-2.4.jar
+ release/modules/ext/commons-lang-2.4.jar
+
ext/rome-0.9.jar
release/modules/ext/rome-0.9.jar
@@ -353,18 +357,14 @@
ext/jdom-1.0.jar
release/modules/ext/jdom-1.0.jar
+
+ ext/poi-ooxml-schemas-3.10-beta2.jar
+ release/modules/ext/poi-ooxml-schemas-3.10-beta2.jar
+
ext/pdfbox-1.8.4.jar
release/modules/ext/pdfbox-1.8.4.jar
-
- ext/fontbox-1.8.4.jar
- release/modules/ext/fontbox-1.8.4.jar
-
-
- ext/jempbox-1.8.4.jar
- release/modules/ext/jempbox-1.8.4.jar
-
ext/wstx-asl-3.2.7.jar
release/modules/ext/wstx-asl-3.2.7.jar
@@ -377,6 +377,10 @@
ext/dom4j-1.6.1.jar
release/modules/ext/dom4j-1.6.1.jar
+
+ ext/bcprov-jdk15-1.45.jar
+ release/modules/ext/bcprov-jdk15-1.45.jar
+
diff --git a/KeywordSearch/release/solr/solr/solr.xml b/KeywordSearch/release/solr/solr/solr.xml
index f2d49d693e..94d60b6a29 100644
--- a/KeywordSearch/release/solr/solr/solr.xml
+++ b/KeywordSearch/release/solr/solr/solr.xml
@@ -17,17 +17,29 @@
-->
-
+ This is an example of a simple "solr.xml" file for configuring one or
+ more Solr Cores, as well as allowing Cores to be added, removed, and
+ reloaded via HTTP requests.
+
+ More information about options available in this configuration file,
+ and Solr Core administration can be found online:
+ http://wiki.apache.org/solr/CoreAdmin
+-->
+
+
+
+
+ ${host:}
+ ${jetty.port:8983}
+ ${hostContext:solr}
+ ${zkClientTimeout:30000}
+ ${genericCoreNodeNames:true}
+
+
+
+ ${socketTimeout:0}
+ ${connTimeout:0}
+
-
-
-
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java
index 99f4f288d4..677ad0e4c4 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Installer.java
@@ -38,7 +38,6 @@ import org.sleuthkit.autopsy.coreutils.Version;
class Installer extends ModuleInstall {
private static final Logger logger = Logger.getLogger(Installer.class.getName());
- private final static int SERVER_START_RETRIES = 5;
@Override
public void restored() {
@@ -48,138 +47,19 @@ class Installer extends ModuleInstall {
Case.addPropertyChangeListener(new KeywordSearch.CaseChangeListener());
final Server server = KeywordSearch.getServer();
- int retries = SERVER_START_RETRIES;
-
- //TODO revise this logic, handle other server types, move some logic to Server class
try {
- //check if running from previous application instance and try to shut down
- logger.log(Level.INFO, "Checking if server is running"); //NON-NLS
- if (server.isRunning()) {
- //TODO this could hang if other type of server is running
- logger.log(Level.WARNING, "Already a server running on " + server.getCurrentSolrServerPort() //NON-NLS
- + " port, maybe leftover from a previous run. Trying to shut it down."); //NON-NLS
- //stop gracefully
- server.stop();
- logger.log(Level.INFO, "Re-checking if server is running"); //NON-NLS
- if (server.isRunning()) {
- int serverPort = server.getCurrentSolrServerPort();
- int serverStopPort = server.getCurrentSolrStopPort();
- logger.log(Level.SEVERE, "There's already a server running on " //NON-NLS
- + serverPort + " port that can't be shutdown."); //NON-NLS
- if (!Server.isPortAvailable(serverPort)) {
- reportPortError(serverPort);
- } else if (!Server.isPortAvailable(serverStopPort)) {
- reportStopPortError(serverStopPort);
- } else {
- //some other reason
- reportInitError();
- }
-
- //in this case give up
-
- } else {
- logger.log(Level.INFO, "Old Solr server shutdown successfully."); //NON-NLS
- //make sure there really isn't a hang Solr process, in case isRunning() reported false
- server.killSolr();
- }
- }
- } catch (KeywordSearchModuleException e) {
- logger.log(Level.SEVERE, "Starting server failed, will try to kill. ", e); //NON-NLS
- server.killSolr();
+ server.start();
+ } catch (SolrServerNoPortException ex) {
+ logger.log(Level.SEVERE, "Failed to start Keyword Search server: ", ex); //NON-NLS
+ if (ex.getPortNumber() == server.getCurrentSolrServerPort())
+ reportPortError(ex.getPortNumber());
+ else
+ reportStopPortError(ex.getPortNumber());
}
-
-
- try {
- //Ensure no other process is still bound to that port, even if we think solr is not running
- //Try to bind to the port 4 times at 1 second intervals.
- //TODO move some of this logic to Server class
- for (int i = 0; i <= 3; i++) {
- logger.log(Level.INFO, "Checking if port available."); //NON-NLS
- if (Server.isPortAvailable(server.getCurrentSolrServerPort())) {
- logger.log(Level.INFO, "Port available, trying to start server."); //NON-NLS
- server.start();
- break;
- } else if (i == 3) {
- logger.log(Level.INFO, "No port available, done retrying."); //NON-NLS
- reportPortError(server.getCurrentSolrServerPort());
- retries = 0;
- break;
- } else {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException iex) {
- logger.log(Level.WARNING, "Timer interrupted"); //NON-NLS
- }
- }
- }
- } catch (SolrServerNoPortException npe) {
- logger.log(Level.SEVERE, "Starting server failed due to no port available. ", npe); //NON-NLS
- //try to kill it
-
- } catch (KeywordSearchModuleException e) {
- logger.log(Level.SEVERE, "Starting server failed. ", e); //NON-NLS
- }
-
-
- //retry if needed
- //TODO this loop may be now redundant
- while (retries-- > 0) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ex) {
- logger.log(Level.WARNING, "Timer interrupted."); //NON-NLS
- }
-
- try {
- logger.log(Level.INFO, "Ensuring the server is running, retries remaining: " + retries); //NON-NLS
- if (!server.isRunning()) {
- logger.log(Level.WARNING, "Server still not running"); //NON-NLS
- try {
- logger.log(Level.WARNING, "Trying to start the server. "); //NON-NLS
- server.start();
- } catch (SolrServerNoPortException npe) {
- logger.log(Level.SEVERE, "Starting server failed due to no port available. ", npe); //NON-NLS
- }
- } else {
- logger.log(Level.INFO, "Server appears now running. "); //NON-NLS
- break;
- }
- } catch (KeywordSearchModuleException ex) {
- logger.log(Level.SEVERE, "Starting server failed. ", ex); //NON-NLS
- //retry if has retries
- }
-
- } //end of retry while loop
-
-
- //last check if still not running to report errors
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ex) {
- logger.log(Level.WARNING, "Timer interrupted."); //NON-NLS
- }
- try {
- logger.log(Level.INFO, "Last check if server is running. "); //NON-NLS
- if (!server.isRunning()) {
- logger.log(Level.SEVERE, "Server is still not running. "); //NON-NLS
- //check if port is taken or some other reason
- int serverPort = server.getCurrentSolrServerPort();
- int serverStopPort = server.getCurrentSolrStopPort();
- if (!Server.isPortAvailable(serverPort)) {
- reportPortError(serverPort);
- } else if (!Server.isPortAvailable(serverStopPort)) {
- reportStopPortError(serverStopPort);
- } else {
- //some other reason
- reportInitError();
- }
- }
- } catch (KeywordSearchModuleException ex) {
- logger.log(Level.SEVERE, "Starting server failed. ", ex); //NON-NLS
- reportInitError();
- }
-
-
+ catch (KeywordSearchModuleException ex) {
+ logger.log(Level.SEVERE, "Failed to start Keyword Search server: ", ex); //NON-NLS
+ reportInitError(ex.getMessage());
+ }
}
@Override
@@ -218,13 +98,10 @@ class Installer extends ModuleInstall {
});
}
- private void reportInitError() {
+ private void reportInitError(final String msg) {
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
@Override
public void run() {
- final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportInitError", KeywordSearch.getServer().getCurrentSolrServerPort(), Version.getName(), Server.PROPERTIES_CURRENT_SERVER_PORT, Server.PROPERTIES_FILE);
- MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
-
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
}
});
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java
index de6871788c..ac80816888 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Server.java
@@ -45,7 +45,6 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.AbstractAction;
import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
@@ -63,6 +62,8 @@ import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException;
+import org.sleuthkit.autopsy.casemodule.Case.CaseType;
+import org.sleuthkit.autopsy.core.UserPreferences;
/**
* Handles for keeping track of a Solr server and its cores
@@ -148,7 +149,6 @@ public class Server {
public static final long MAX_CONTENT_SIZE = 1L * 1024 * 1024 * 1024;
private static final Logger logger = Logger.getLogger(Server.class.getName());
private static final String DEFAULT_CORE_NAME = "coreCase"; //NON-NLS
- // TODO: DEFAULT_CORE_NAME needs to be replaced with unique names to support multiple open cases
public static final String CORE_EVT = "CORE_EVT"; //NON-NLS
public static final char ID_CHUNK_SEP = '_';
private String javaPath = "java"; //NON-NLS
@@ -160,6 +160,7 @@ public class Server {
static final String PROPERTIES_CURRENT_SERVER_PORT = "IndexingServerPort"; //NON-NLS
static final String PROPERTIES_CURRENT_STOP_PORT = "IndexingServerStopPort"; //NON-NLS
private static final String KEY = "jjk#09s"; //NON-NLS
+ static final String DEFAULT_SOLR_SERVER_HOST = "localhost"; //NON-NLS
static final int DEFAULT_SOLR_SERVER_PORT = 23232;
static final int DEFAULT_SOLR_STOP_PORT = 34343;
private int currentSolrServerPort = 0;
@@ -170,23 +171,27 @@ public class Server {
STOPPED, STARTED
};
- private SolrServer solrServer;
- private String instanceDir;
- private File solrFolder;
- private ServerAction serverAction;
+
+ // A reference to the locally running Solr instance.
+ private final HttpSolrServer localSolrServer;
+
+ // A reference to the Solr server we are currently connected to for the Case.
+ // This could be a local or remote server.
+ private HttpSolrServer currentSolrServer;
+
+ private final String instanceDir;
+ private final File solrFolder;
+ private final ServerAction serverAction;
private InputStreamPrinterThread errorRedirectThread;
- private String solrUrl;
/**
* New instance for the server at the given URL
*
- * @param url should be something like "http://localhost:23232/solr/"
*/
Server() {
initSettings();
- this.solrUrl = "http://localhost:" + currentSolrServerPort + "/solr"; //NON-NLS
- this.solrServer = new HttpSolrServer(solrUrl);
+ this.localSolrServer = new HttpSolrServer("http://localhost:" + currentSolrServerPort + "/solr"); //NON-NLS
serverAction = new ServerAction();
solrFolder = InstalledFileLocator.getDefault().locate("solr", Server.class.getPackage().getName(), false); //NON-NLS
instanceDir = solrFolder.getAbsolutePath() + File.separator + "solr"; //NON-NLS
@@ -196,6 +201,7 @@ public class Server {
}
private void initSettings() {
+
if (ModuleSettings.settingExists(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT)) {
try {
currentSolrServerPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT));
@@ -207,7 +213,7 @@ public class Server {
currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT, String.valueOf(currentSolrServerPort));
}
-
+
if (ModuleSettings.settingExists(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT)) {
try {
currentSolrStopPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT));
@@ -325,10 +331,10 @@ public class Server {
* @return
*/
List getSolrPIDs() {
- List pids = new ArrayList();
+ List pids = new ArrayList<>();
//NOTE: these needs to be in sync with process start string in start()
- final String pidsQuery = "Args.4.eq=-DSTOP.KEY=" + KEY + ",Args.7.eq=start.jar"; //NON-NLS
+ final String pidsQuery = "Args.4.eq=-DSTOP.KEY=" + KEY + ",Args.6.eq=start.jar"; //NON-NLS
long[] pidsArr = PlatformUtil.getJavaPIDs(pidsQuery);
if (pidsArr != null) {
@@ -353,12 +359,44 @@ public class Server {
}
/**
- * Tries to start a Solr instance in a separate process. Returns immediately
+ * Tries to start a local Solr instance in a separate process. Returns immediately
* (probably before the server is ready) and doesn't check whether it was
* successful.
*/
void start() throws KeywordSearchModuleException, SolrServerNoPortException {
+ if (isRunning()) {
+ // If a Solr server is running we stop it.
+ stop();
+ }
+
+ if (!isPortAvailable(currentSolrServerPort)){
+ // There is something already listening on our port. Let's see if
+ // this is from an earlier run that didn't successfully shut down
+ // and if so kill it.
+ final List pids = this.getSolrPIDs();
+
+ // If the culprit listening on the port is not a Solr process
+ // we refuse to start.
+ if (pids.isEmpty()) {
+ throw new SolrServerNoPortException(currentSolrServerPort);
+ }
+
+ // Ok, we've tried to stop it above but there still appears to be
+ // a Solr process listening on our port so we forcefully kill it.
+ killSolr();
+
+ // If either of the ports are still in use after our attempt to kill
+ // previously running processes we give up and throw an exception.
+ if (!isPortAvailable(currentSolrServerPort)) {
+ throw new SolrServerNoPortException(currentSolrServerPort);
+ }
+ if (!isPortAvailable(currentSolrStopPort)) {
+ throw new SolrServerNoPortException(currentSolrStopPort);
+ }
+ }
+
logger.log(Level.INFO, "Starting Solr server from: " + solrFolder.getAbsolutePath()); //NON-NLS
+
if (isPortAvailable(currentSolrServerPort)) {
logger.log(Level.INFO, "Port [" + currentSolrServerPort + "] available, starting Solr"); //NON-NLS
try {
@@ -405,6 +443,7 @@ public class Server {
} catch (InterruptedException ex) {
logger.log(Level.WARNING, "Timer interrupted"); //NON-NLS
}
+
final List pids = this.getSolrPIDs();
logger.log(Level.INFO, "New Solr process PID: " + pids); //NON-NLS
} catch (SecurityException ex) {
@@ -416,10 +455,7 @@ public class Server {
throw new KeywordSearchModuleException(
NbBundle.getMessage(this.getClass(), "Server.start.exception.cantStartSolr.msg2"), ex);
}
- } else {
- logger.log(Level.SEVERE, "Could not start Solr server process, port [" + currentSolrServerPort + "] not available!"); //NON-NLS
- throw new SolrServerNoPortException(currentSolrServerPort);
- }
+ }
}
/**
@@ -472,11 +508,12 @@ public class Server {
}
/**
- * Tries to stop a Solr instance.
+ * Tries to stop the local Solr instance.
*
* Waits for the stop command to finish before returning.
*/
synchronized void stop() {
+
try {
logger.log(Level.INFO, "Stopping Solr server from: " + solrFolder.getAbsolutePath()); //NON-NLS
//try graceful shutdown
@@ -498,8 +535,7 @@ public class Server {
curSolrProcess = null;
}
- } catch (InterruptedException ex) {
- } catch (IOException ex) {
+ } catch (InterruptedException | IOException ex) {
} finally {
//stop Solr stream -> log redirect threads
try {
@@ -517,7 +553,7 @@ public class Server {
}
/**
- * Tests if there's a Solr server running by sending it a core-status
+ * Tests if there's a local Solr server running by sending it a core-status
* request.
*
* @return false if the request failed with a connection error, otherwise
@@ -525,13 +561,20 @@ public class Server {
*/
synchronized boolean isRunning() throws KeywordSearchModuleException {
try {
+
+ if (isPortAvailable(currentSolrServerPort)) {
+ return false;
+ }
+
+ if (curSolrProcess != null && !curSolrProcess.isAlive()) {
+ return false;
+ }
+
// making a status request here instead of just doing solrServer.ping(), because
// that doesn't work when there are no cores
- //TODO check if port avail and return false if it is
-
//TODO handle timeout in cases when some other type of server on that port
- CoreAdminRequest.getStatus(null, solrServer);
+ CoreAdminRequest.getStatus(null, localSolrServer);
logger.log(Level.INFO, "Solr server is running"); //NON-NLS
} catch (SolrServerException ex) {
@@ -642,7 +685,8 @@ public class Server {
*/
private synchronized Core openCore(Case theCase) throws KeywordSearchModuleException {
String dataDir = getIndexDirPath(theCase);
- return this.openCore(DEFAULT_CORE_NAME, new File(dataDir));
+ String coreName = theCase.getTextIndexName();
+ return this.openCore(coreName.isEmpty() ? DEFAULT_CORE_NAME : coreName, new File(dataDir), theCase.getCaseType());
}
/**
@@ -914,7 +958,7 @@ public class Server {
* @param dataDir directory to load/store the core data from/to
* @return new core
*/
- private Core openCore(String coreName, File dataDir) throws KeywordSearchModuleException {
+ private Core openCore(String coreName, File dataDir, CaseType caseType) throws KeywordSearchModuleException {
try {
if (!dataDir.exists()) {
dataDir.mkdirs();
@@ -929,17 +973,24 @@ public class Server {
CoreAdminRequest.Create createCore = new CoreAdminRequest.Create();
createCore.setDataDir(dataDir.getAbsolutePath());
- createCore.setInstanceDir(instanceDir);
createCore.setCoreName(coreName);
createCore.setConfigSet("AutopsyConfig");
- this.solrServer.request(createCore);
+ if (caseType == CaseType.SINGLE_USER_CASE) {
+ currentSolrServer = this.localSolrServer;
+ //createCore.setInstanceDir(instanceDir);
+ }
+ else {
+ currentSolrServer = connectToRemoteSolrServer();
+ }
+
+ currentSolrServer.request(createCore);
final Core newCore = new Core(coreName);
return newCore;
- } catch (SolrServerException ex) {
+ } catch (SolrServerException | SolrException ex) {
throw new KeywordSearchModuleException(
NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg"), ex);
} catch (IOException ex) {
@@ -948,6 +999,13 @@ public class Server {
}
}
+ private HttpSolrServer connectToRemoteSolrServer() {
+ String host = UserPreferences.getIndexingServerHost();
+ String port = UserPreferences.getIndexingServerPort();
+
+ return new HttpSolrServer("http://" + host + ":" + port + "/solr");
+ }
+
class Core {
// handle to the core in Solr
@@ -959,7 +1017,7 @@ public class Server {
private Core(String name) {
this.name = name;
- this.solrCore = new HttpSolrServer(solrUrl + "/" + name);
+ this.solrCore = new HttpSolrServer(currentSolrServer.getBaseURL() + "/" + name);
//TODO test these settings
//solrCore.setSoTimeout(1000 * 60); // socket read timeout, make large enough so can index larger files
@@ -1062,7 +1120,7 @@ public class Server {
synchronized void close() throws KeywordSearchModuleException {
try {
- CoreAdminRequest.unloadCore(this.name, solrServer);
+ CoreAdminRequest.unloadCore(this.name, currentSolrServer);
} catch (SolrServerException ex) {
throw new KeywordSearchModuleException(
NbBundle.getMessage(this.getClass(), "Server.close.exception.msg"), ex);