19 package org.sleuthkit.autopsy.keywordsearch;
21 import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 import java.awt.event.ActionEvent;
23 import java.beans.PropertyChangeListener;
24 import java.io.BufferedReader;
25 import java.io.BufferedWriter;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.io.OutputStream;
32 import java.io.OutputStreamWriter;
33 import java.net.ConnectException;
34 import java.net.ServerSocket;
35 import java.net.SocketException;
36 import java.nio.charset.Charset;
37 import java.nio.file.Files;
38 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
39 import java.nio.file.Path;
40 import java.nio.file.Paths;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Collections;
44 import java.util.Iterator;
45 import java.util.List;
46 import java.util.Random;
47 import java.util.concurrent.ScheduledThreadPoolExecutor;
48 import java.util.concurrent.TimeUnit;
49 import java.util.concurrent.locks.ReentrantReadWriteLock;
50 import java.util.logging.Level;
51 import javax.swing.AbstractAction;
52 import org.apache.commons.io.FileUtils;
53 import java.util.concurrent.TimeoutException;
54 import static java.util.stream.Collectors.toList;
55 import org.apache.solr.client.solrj.SolrQuery;
56 import org.apache.solr.client.solrj.SolrRequest;
57 import org.apache.solr.client.solrj.SolrServerException;
58 import org.apache.solr.client.solrj.SolrClient;
59 import org.apache.solr.client.solrj.impl.HttpSolrClient;
60 import org.apache.solr.client.solrj.impl.CloudSolrClient;
61 import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
62 import org.apache.solr.client.solrj.impl.XMLResponseParser;
63 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
64 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
65 import org.apache.solr.client.solrj.request.CoreAdminRequest;
66 import org.apache.solr.client.solrj.response.CoreAdminResponse;
67 import org.apache.solr.client.solrj.impl.BaseHttpSolrClient.RemoteSolrException;
68 import org.apache.solr.client.solrj.response.QueryResponse;
69 import org.apache.solr.client.solrj.response.TermsResponse;
70 import org.apache.solr.common.SolrDocument;
71 import org.apache.solr.common.SolrDocumentList;
72 import org.apache.solr.common.SolrException;
73 import org.apache.solr.common.SolrInputDocument;
74 import org.apache.solr.common.util.NamedList;
75 import org.openide.modules.InstalledFileLocator;
76 import org.openide.modules.Places;
77 import org.openide.util.NbBundle;
78 import org.openide.windows.WindowManager;
107 public String toString() {
113 public String toString() {
120 public String toString() {
127 public String toString() {
128 return "content_str";
134 public String toString() {
142 public String toString() {
148 public String toString() {
154 public String toString() {
160 public String toString() {
167 public String toString() {
174 public String toString() {
181 public String toString() {
188 public String toString() {
194 public String toString() {
200 public String toString() {
211 public String toString() {
228 static final String PROPERTIES_FILE = KeywordSearchSettings.MODULE_NAME;
229 static final String PROPERTIES_CURRENT_SERVER_PORT =
"IndexingServerPort";
230 static final String PROPERTIES_CURRENT_STOP_PORT =
"IndexingServerStopPort";
231 private static final String
KEY =
"jjk#09s";
232 static final String DEFAULT_SOLR_SERVER_HOST =
"localhost";
233 static final int DEFAULT_SOLR_SERVER_PORT = 23232;
234 static final int DEFAULT_SOLR_STOP_PORT = 34343;
238 private static final String
SOLR =
"solr";
240 private static final boolean DEBUG =
false;
273 serverAction =
new ServerAction();
274 File solr8Folder = InstalledFileLocator.getDefault().locate(
"solr",
Server.class.getPackage().getName(),
false);
275 File solr4Folder = InstalledFileLocator.getDefault().locate(
"solr4",
Server.class.getPackage().getName(),
false);
286 if (!solr8Home.toFile().exists()) {
287 Files.createDirectory(solr8Home);
292 Files.copy(Paths.get(solr8Folder.getAbsolutePath(),
"server",
"solr",
"solr.xml"), solr8Home.resolve(
"solr.xml"), REPLACE_EXISTING);
293 Files.copy(Paths.get(solr8Folder.getAbsolutePath(),
"server",
"solr",
"zoo.cfg"), solr8Home.resolve(
"zoo.cfg"), REPLACE_EXISTING);
294 FileUtils.copyDirectory(Paths.get(solr8Folder.getAbsolutePath(),
"server",
"solr",
"configsets").toFile(), solr8Home.resolve(
"configsets").toFile());
295 }
catch (IOException ex) {
296 logger.log(Level.SEVERE,
"Failed to create Solr 8 home folder:", ex);
302 if (!solr4Home.toFile().exists()) {
303 Files.createDirectory(solr4Home);
305 Files.copy(Paths.get(solr4Folder.getAbsolutePath(),
"solr",
"solr.xml"), solr4Home.resolve(
"solr.xml"), REPLACE_EXISTING);
306 Files.copy(Paths.get(solr4Folder.getAbsolutePath(),
"solr",
"zoo.cfg"), solr4Home.resolve(
"zoo.cfg"), REPLACE_EXISTING);
307 }
catch (IOException ex) {
308 logger.log(Level.SEVERE,
"Failed to create Solr 4 home folder:", ex);
311 currentCoreLock =
new ReentrantReadWriteLock(
true);
313 logger.log(Level.INFO,
"Created Server instance using Java at {0}", javaPath);
321 }
catch (NumberFormatException nfe) {
322 logger.log(Level.WARNING,
"Could not decode indexing server port, value was not a valid port number, using the default. ", nfe);
323 localSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
326 localSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
333 }
catch (NumberFormatException nfe) {
334 logger.log(Level.WARNING,
"Could not decode indexing server stop port, value was not a valid port number, using default", nfe);
335 localSolrStopPort = DEFAULT_SOLR_STOP_PORT;
338 localSolrStopPort = DEFAULT_SOLR_STOP_PORT;
345 return new HttpSolrClient.Builder(solrUrl)
346 .withSocketTimeout(connectionTimeoutMs)
347 .withConnectionTimeout(connectionTimeoutMs)
348 .withResponseParser(
new XMLResponseParser())
356 logger.log(Level.INFO,
"Creating new ConcurrentUpdateSolrClient: {0}", solrUrl);
357 logger.log(Level.INFO,
"Queue size = {0}, Number of threads = {1}, Connection Timeout (ms) = {2}",
new Object[]{numDocs, numThreads, connectionTimeoutMs});
358 ConcurrentUpdateSolrClient client =
new ConcurrentUpdateSolrClient.Builder(solrUrl)
359 .withQueueSize(numDocs)
360 .withThreadCount(numThreads)
361 .withSocketTimeout(connectionTimeoutMs)
362 .withConnectionTimeout(connectionTimeoutMs)
363 .withResponseParser(
new XMLResponseParser())
371 List<String> solrUrls =
new ArrayList<>();
372 for (String server : solrServerList) {
373 solrUrls.add(
"http://" + server +
"/solr");
374 logger.log(Level.INFO,
"Using Solr server: {0}", server);
377 logger.log(Level.INFO,
"Creating new CloudSolrClient");
379 CloudSolrClient client =
new CloudSolrClient.Builder(solrUrls)
380 .withConnectionTimeout(connectionTimeoutMs)
381 .withSocketTimeout(connectionTimeoutMs)
382 .withResponseParser(
new XMLResponseParser())
384 if (!defaultCollectionName.isEmpty()) {
385 client.setDefaultCollection(defaultCollectionName);
392 public void finalize() throws java.lang.Throwable {
398 serverAction.addPropertyChangeListener(l);
401 int getLocalSolrServerPort() {
405 int getLocalSolrStopPort() {
416 volatile boolean doRun =
true;
419 this.stream = stream;
421 final String log = Places.getUserDirectory().getAbsolutePath()
422 + File.separator +
"var" + File.separator +
"log"
423 + File.separator +
"solr.log." + type;
424 File outputFile =
new File(log.concat(
".0"));
425 File first =
new File(log.concat(
".1"));
426 File second =
new File(log.concat(
".2"));
427 if (second.exists()) {
430 if (first.exists()) {
431 first.renameTo(second);
433 if (outputFile.exists()) {
434 outputFile.renameTo(first);
436 outputFile.createNewFile();
438 out =
new FileOutputStream(outputFile);
440 }
catch (Exception ex) {
441 logger.log(Level.WARNING,
"Failed to create solr log file", ex);
452 try (InputStreamReader isr =
new InputStreamReader(stream);
453 BufferedReader br =
new BufferedReader(isr);
455 BufferedWriter bw =
new BufferedWriter(osw);) {
458 while (doRun && (line = br.readLine()) != null) {
467 }
catch (IOException ex) {
468 logger.log(Level.SEVERE,
"Error redirecting Solr output stream", ex);
486 File solr8Folder = InstalledFileLocator.getDefault().locate(
"solr",
Server.class.getPackage().getName(),
false);
489 solr8CmdPath = Paths.get(solr8Folder.getAbsolutePath(),
"bin",
"autopsy-solr.cmd");
491 solr8CmdPath = Paths.get(solr8Folder.getAbsolutePath(),
"bin",
"autopsy-solr");
495 List<String> commandLine =
new ArrayList<>();
496 commandLine.add(solr8CmdPath.toString());
497 commandLine.addAll(solrArguments);
499 ProcessBuilder solrProcessBuilder =
new ProcessBuilder(commandLine);
500 solrProcessBuilder.directory(solr8Folder);
503 Path solrStdoutPath = Paths.get(Places.getUserDirectory().getAbsolutePath(),
"var",
"log",
"solr.log.stdout");
504 solrProcessBuilder.redirectOutput(solrStdoutPath.toFile());
506 Path solrStderrPath = Paths.get(Places.getUserDirectory().getAbsolutePath(),
"var",
"log",
"solr.log.stderr");
507 solrProcessBuilder.redirectError(solrStderrPath.toFile());
510 String jreFolderPath =
new File(javaPath).getParentFile().getParentFile().getAbsolutePath();
512 solrProcessBuilder.environment().put(
"SOLR_JAVA_HOME", jreFolderPath);
513 solrProcessBuilder.environment().put(
"SOLR_HOME", solr8Home.toString());
514 solrProcessBuilder.environment().put(
"STOP_KEY", KEY);
515 solrProcessBuilder.environment().put(
"SOLR_JAVA_MEM", MAX_SOLR_MEM_MB_PAR);
516 logger.log(Level.INFO,
"Setting Solr 8 directory: {0}", solr8Folder.toString());
517 logger.log(Level.INFO,
"Running Solr 8 command: {0} from {1}",
new Object[]{solrProcessBuilder.command(), solr8Folder.toString()});
518 Process process = solrProcessBuilder.start();
519 logger.log(Level.INFO,
"Finished running Solr 8 command");
534 File solr4Folder = InstalledFileLocator.getDefault().locate(
"solr4",
Server.class.getPackage().getName(),
false);
536 List<String> commandLine =
new ArrayList<>();
537 commandLine.add(javaPath);
538 commandLine.add(MAX_SOLR_MEM_MB_PAR);
539 commandLine.add(
"-DSTOP.PORT=" + localSolrStopPort);
540 commandLine.add(
"-Djetty.port=" + localSolrServerPort);
541 commandLine.add(
"-DSTOP.KEY=" + KEY);
542 commandLine.add(
"-jar");
543 commandLine.add(
"start.jar");
545 commandLine.addAll(solrArguments);
547 ProcessBuilder solrProcessBuilder =
new ProcessBuilder(commandLine);
548 solrProcessBuilder.directory(solr4Folder);
551 Path solrStdoutPath = Paths.get(Places.getUserDirectory().getAbsolutePath(),
"var",
"log",
"solr.log.stdout");
552 solrProcessBuilder.redirectOutput(solrStdoutPath.toFile());
554 Path solrStderrPath = Paths.get(Places.getUserDirectory().getAbsolutePath(),
"var",
"log",
"solr.log.stderr");
555 solrProcessBuilder.redirectError(solrStderrPath.toFile());
557 logger.log(Level.INFO,
"Running Solr 4 command: {0}", solrProcessBuilder.command());
558 Process process = solrProcessBuilder.start();
559 logger.log(Level.INFO,
"Finished running Solr 4 command");
568 List<Long> getSolrPIDs() {
569 List<Long> pids =
new ArrayList<>();
572 final String pidsQuery =
"Args.*.eq=-DSTOP.KEY=" + KEY +
",Args.*.eq=start.jar";
575 if (pidsArr != null) {
576 for (
int i = 0; i < pidsArr.length; ++i) {
577 pids.add(pidsArr[i]);
589 List<Long> solrPids = getSolrPIDs();
590 for (
long pid : solrPids) {
591 logger.log(Level.INFO,
"Trying to kill old Solr process, PID: {0}", pid);
592 PlatformUtil.killProcess(pid);
596 void start() throws KeywordSearchModuleException, SolrServerNoPortException, SolrServerException {
597 startLocalSolr(SOLR_VERSION.SOLR8);
606 if (IndexFinder.getCurrentSolrVersion().equals(index.getSolrVersion())) {
613 if (!this.isLocalSolrRunning()) {
614 logger.log(Level.SEVERE,
"Local Solr server is not running");
615 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.msg"));
622 connectToSolrServer(remoteSolrServer);
624 }
catch (SolrServerException | IOException ex) {
625 throw new KeywordSearchModuleException(NbBundle.getMessage(
Server.class,
"Server.connect.exception.msg", ex.getLocalizedMessage()), ex);
647 if (properties.
host.isEmpty() || properties.
port.isEmpty()) {
648 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.connectionInfoMissing.exception.msg", index.getSolrVersion()));
650 String solrUrl =
"http://" + properties.
host +
":" + properties.
port +
"/solr";
652 if (!name.isEmpty()) {
653 solrUrl = solrUrl +
"/" + name;
666 "Server.status.failed.msg=Local Solr server did not respond to status request. This may be because the server failed to start or is taking too long to initialize.",})
667 void startLocalSolr(SOLR_VERSION version)
throws KeywordSearchModuleException, SolrServerNoPortException, SolrServerException {
669 if (isLocalSolrRunning()) {
670 if (localServerVersion.equals(version)) {
680 localServerVersion = version;
682 if (!isPortAvailable(localSolrServerPort)) {
686 final List<Long> pids = this.getSolrPIDs();
690 if (pids.isEmpty()) {
691 throw new SolrServerNoPortException(localSolrServerPort);
700 if (!isPortAvailable(localSolrServerPort)) {
701 throw new SolrServerNoPortException(localSolrServerPort);
703 if (!isPortAvailable(localSolrStopPort)) {
704 throw new SolrServerNoPortException(localSolrStopPort);
708 if (isPortAvailable(localSolrServerPort)) {
709 logger.log(Level.INFO,
"Port [{0}] available, starting Solr", localSolrServerPort);
711 if (version == SOLR_VERSION.SOLR8) {
712 logger.log(Level.INFO,
"Starting Solr 8 server");
713 localSolrFolder = InstalledFileLocator.getDefault().locate(
"solr", Server.class.getPackage().getName(),
false);
715 Integer.toString(localSolrServerPort))));
718 localSolrFolder = InstalledFileLocator.getDefault().locate(
"solr4", Server.class.getPackage().getName(),
false);
719 logger.log(Level.INFO,
"Starting Solr 4 server");
721 Arrays.asList(
"-Dbootstrap_confdir=../solr/configsets/AutopsyConfig/conf",
722 "-Dcollection.configName=AutopsyConfig")));
726 for (
int numRetries = 0; numRetries < 6; numRetries++) {
727 if (isLocalSolrRunning()) {
728 localSolrServer =
getSolrClient(
"http://localhost:" + localSolrServerPort +
"/solr");
729 final List<Long> pids = this.getSolrPIDs();
730 logger.log(Level.INFO,
"New Solr process PID: {0}", pids);
737 TimeUnit.SECONDS.sleep(5);
738 }
catch (InterruptedException ex) {
739 logger.log(Level.WARNING,
"Timer interrupted");
745 logger.log(Level.WARNING,
"Local Solr server failed to respond to status requests.");
746 WindowManager.getDefault().invokeWhenUIReady(
new Runnable() {
749 MessageNotifyUtil.Notify.error(
750 NbBundle.getMessage(
this.getClass(),
"Installer.errorInitKsmMsg"),
751 Bundle.Server_status_failed_msg());
754 }
catch (SecurityException ex) {
755 throw new KeywordSearchModuleException(
756 NbBundle.getMessage(
this.getClass(),
"Server.start.exception.cantStartSolr.msg"), ex);
757 }
catch (IOException ex) {
758 throw new KeywordSearchModuleException(
759 NbBundle.getMessage(
this.getClass(),
"Server.start.exception.cantStartSolr.msg2"), ex);
769 static boolean isPortAvailable(
int port) {
770 ServerSocket ss = null;
773 ss =
new ServerSocket(port, 0, java.net.Inet4Address.getByName(
"localhost"));
775 ss.setReuseAddress(
true);
780 }
catch (IOException e) {
785 }
catch (IOException e) {
800 void changeSolrServerPort(
int port) {
801 localSolrServerPort = port;
802 ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT, String.valueOf(port));
810 void changeSolrStopPort(
int port) {
811 localSolrStopPort = port;
812 ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT, String.valueOf(port));
820 synchronized void stop() {
825 }
catch (KeywordSearchModuleException e) {
826 logger.log(Level.WARNING,
"Failed to close core: ", e);
840 logger.log(Level.INFO,
"Stopping Solr 8 server");
841 process =
runLocalSolr8ControlCommand(
new ArrayList<>(Arrays.asList(
"stop",
"-k", KEY,
"-p", Integer.toString(localSolrServerPort))));
844 logger.log(Level.INFO,
"Stopping Solr 4 server");
848 logger.log(Level.INFO,
"Waiting for Solr server to stop");
852 if (curSolrProcess != null) {
853 curSolrProcess.destroy();
854 curSolrProcess = null;
857 }
catch (IOException | InterruptedException ex) {
858 logger.log(Level.WARNING,
"Error while attempting to stop Solr server", ex);
862 if (errorRedirectThread != null) {
863 errorRedirectThread.stopRun();
864 errorRedirectThread = null;
871 logger.log(Level.INFO,
"Finished stopping Solr server");
882 synchronized boolean isLocalSolrRunning() throws KeywordSearchModuleException {
885 if (isPortAvailable(localSolrServerPort)) {
894 logger.log(Level.INFO,
"Solr server is running");
895 }
catch (SolrServerException ex) {
897 Throwable cause = ex.getRootCause();
902 if (cause instanceof ConnectException || cause instanceof SocketException) {
903 logger.log(Level.INFO,
"Solr server is not running, cause: {0}", cause.getMessage());
906 throw new KeywordSearchModuleException(
907 NbBundle.getMessage(
this.getClass(),
"Server.isRunning.exception.errCheckSolrRunning.msg"), ex);
909 }
catch (SolrException ex) {
911 logger.log(Level.INFO,
"Solr server is not running", ex);
913 }
catch (IOException ex) {
914 throw new KeywordSearchModuleException(
915 NbBundle.getMessage(
this.getClass(),
"Server.isRunning.exception.errCheckSolrRunning.msg2"), ex);
933 void openCoreForCase(Case theCase, Index index)
throws KeywordSearchModuleException {
934 currentCoreLock.writeLock().lock();
936 currentCollection =
openCore(theCase, index);
941 }
catch (NoOpenCoreException ex) {
942 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.cantOpen.msg"), ex);
945 serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STARTED);
947 currentCoreLock.writeLock().unlock();
956 boolean coreIsOpen() {
957 currentCoreLock.readLock().lock();
959 return (null != currentCollection);
961 currentCoreLock.readLock().unlock();
965 Index getIndexInfo() throws NoOpenCoreException {
966 currentCoreLock.readLock().lock();
968 if (null == currentCollection) {
969 throw new NoOpenCoreException();
971 return currentCollection.getIndexInfo();
973 currentCoreLock.readLock().unlock();
977 void closeCore() throws KeywordSearchModuleException {
978 currentCoreLock.writeLock().lock();
980 if (null != currentCollection) {
981 currentCollection.close();
982 serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED);
985 currentCollection = null;
986 currentCoreLock.writeLock().unlock();
990 void addDocument(SolrInputDocument doc)
throws KeywordSearchModuleException, NoOpenCoreException {
991 currentCoreLock.readLock().lock();
993 if (null == currentCollection) {
994 throw new NoOpenCoreException();
996 TimingMetric metric = HealthMonitor.getTimingMetric(
"Solr: Index chunk");
997 currentCollection.addDocument(doc);
998 HealthMonitor.submitTimingMetric(metric);
1000 currentCoreLock.readLock().unlock();
1012 @NbBundle.Messages({
1013 "# {0} - colelction name",
"Server.deleteCore.exception.msg=Failed to delete Solr colelction {0}",})
1014 void deleteCollection(String coreName, CaseMetadata metadata)
throws KeywordSearchServiceException, KeywordSearchModuleException {
1016 HttpSolrClient solrServer;
1017 if (metadata.getCaseType() == CaseType.SINGLE_USER_CASE) {
1018 solrServer =
getSolrClient(
"http://localhost:" + localSolrServerPort +
"/solr");
1019 CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, solrServer);
1020 if (null != response.getCoreStatus(coreName).get(
"instanceDir")) {
1030 org.apache.solr.client.solrj.request.CoreAdminRequest.unloadCore(coreName,
true,
true, solrServer);
1034 solrServer =
getSolrClient(
"http://" + properties.getHost() +
":" + properties.getPort() +
"/solr");
1035 connectToSolrServer(solrServer);
1037 CollectionAdminRequest.Delete deleteCollectionRequest = CollectionAdminRequest.deleteCollection(coreName);
1038 CollectionAdminResponse response = deleteCollectionRequest.process(solrServer);
1039 if (response.isSuccess()) {
1040 logger.log(Level.INFO,
"Deleted collection {0}", coreName);
1042 logger.log(Level.WARNING,
"Unable to delete collection {0}", coreName);
1045 }
catch (SolrServerException | IOException ex) {
1048 if (!ex.getMessage().equals(
"Already closed")) {
1049 throw new KeywordSearchServiceException(Bundle.Server_deleteCore_exception_msg(coreName), ex);
1065 @NbBundle.Messages({
1066 "Server.exceptionMessage.unableToCreateCollection=Unable to create Solr collection",
1067 "Server.exceptionMessage.unableToBackupCollection=Unable to backup Solr collection",
1068 "Server.exceptionMessage.unableToRestoreCollection=Unable to restore Solr collection",
1070 private Collection
openCore(
Case theCase, Index index)
throws KeywordSearchModuleException {
1072 int numShardsToUse = 1;
1081 }
catch (Exception ex) {
1083 throw new KeywordSearchModuleException(NbBundle.getMessage(
Server.class,
"Server.connect.exception.msg", ex.getLocalizedMessage()), ex);
1087 String collectionName = index.getIndexName();
1094 boolean doRetry =
false;
1099 }
catch (Exception ex) {
1100 if (reTryAttempt >= NUM_COLLECTION_CREATION_RETRIES) {
1101 logger.log(Level.SEVERE,
"Unable to create Solr collection " + collectionName, ex);
1102 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.cantOpen.msg"), ex);
1104 logger.log(Level.SEVERE,
"Unable to create Solr collection " + collectionName +
". Re-trying...", ex);
1105 Thread.sleep(1000L);
1117 File dataDir =
new File(
new File(index.getIndexPath()).getParent());
1118 if (!dataDir.exists()) {
1125 Path corePropertiesFile = Paths.get(localSolrFolder.toString(),
SOLR, collectionName,
CORE_PROPERTIES);
1126 if (corePropertiesFile.toFile().exists()) {
1128 corePropertiesFile.toFile().delete();
1129 }
catch (Exception ex) {
1130 logger.log(Level.INFO,
"Could not delete pre-existing core.properties prior to opening the core.");
1136 CoreAdminRequest.Create createCoreRequest =
new CoreAdminRequest.Create();
1137 createCoreRequest.setDataDir(dataDir.getAbsolutePath());
1138 createCoreRequest.setCoreName(collectionName);
1139 createCoreRequest.setConfigSet(
"AutopsyConfig");
1140 createCoreRequest.setIsLoadOnStartup(
false);
1141 createCoreRequest.setIsTransient(
true);
1142 localSolrServer.request(createCoreRequest);
1145 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.noIndexDir.msg"));
1150 return new Collection(collectionName, theCase, index);
1152 }
catch (Exception ex) {
1153 logger.log(Level.SEVERE,
"Exception during Solr collection creation.", ex);
1154 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.cantOpen.msg"), ex);
1168 return solrServerList.size();
1184 private boolean collectionExists(String collectionName)
throws SolrServerException, IOException {
1185 CollectionAdminRequest.List req =
new CollectionAdminRequest.List();
1186 CollectionAdminResponse response = req.process(remoteSolrServer);
1187 List<String> existingCollections = (List<String>) response.getResponse().get(
"collections");
1188 if (existingCollections == null) {
1189 existingCollections =
new ArrayList<>();
1191 return existingCollections.contains(collectionName);
1229 private void createMultiUserCollection(String collectionName,
int numShardsToUse)
throws KeywordSearchModuleException, SolrServerException, IOException {
1236 Integer numShards = numShardsToUse;
1237 logger.log(Level.INFO,
"numShardsToUse: {0}", numShardsToUse);
1238 Integer numNrtReplicas = 1;
1239 Integer numTlogReplicas = 0;
1240 Integer numPullReplicas = 0;
1241 CollectionAdminRequest.Create createCollectionRequest = CollectionAdminRequest.createCollection(collectionName,
"AutopsyConfig", numShards, numNrtReplicas, numTlogReplicas, numPullReplicas);
1243 CollectionAdminResponse createResponse = createCollectionRequest.process(remoteSolrServer);
1244 if (createResponse.isSuccess()) {
1245 logger.log(Level.INFO,
"Collection {0} successfully created.", collectionName);
1247 logger.log(Level.SEVERE,
"Unable to create Solr collection {0}", collectionName);
1248 throw new KeywordSearchModuleException(Bundle.Server_exceptionMessage_unableToCreateCollection());
1255 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.noIndexDir.msg"));
1259 private void backupCollection(String collectionName, String backupName, String pathToBackupLocation)
throws SolrServerException, IOException, KeywordSearchModuleException {
1260 CollectionAdminRequest.Backup backup = CollectionAdminRequest.backupCollection(collectionName, backupName)
1261 .setLocation(pathToBackupLocation);
1263 CollectionAdminResponse backupResponse = backup.process(remoteSolrServer);
1264 if (backupResponse.isSuccess()) {
1265 logger.log(Level.INFO,
"Collection {0} successfully backep up.", collectionName);
1267 logger.log(Level.SEVERE,
"Unable to back up Solr collection {0}", collectionName);
1268 throw new KeywordSearchModuleException(Bundle.Server_exceptionMessage_unableToBackupCollection());
1272 private void restoreCollection(String backupName, String restoreCollectionName, String pathToBackupLocation)
throws SolrServerException, IOException, KeywordSearchModuleException {
1274 CollectionAdminRequest.Restore restore = CollectionAdminRequest.restoreCollection(restoreCollectionName, backupName)
1275 .setLocation(pathToBackupLocation);
1277 CollectionAdminResponse restoreResponse = restore.process(remoteSolrServer);
1278 if (restoreResponse.isSuccess()) {
1279 logger.log(Level.INFO,
"Collection {0} successfully resored.", restoreCollectionName);
1281 logger.log(Level.SEVERE,
"Unable to restore Solr collection {0}", restoreCollectionName);
1282 throw new KeywordSearchModuleException(Bundle.Server_exceptionMessage_unableToRestoreCollection());
1300 private boolean coreIsLoaded(String coreName)
throws SolrServerException, IOException {
1301 CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, localSolrServer);
1302 return response.getCoreStatus(coreName).get(
"instanceDir") != null;
1318 CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, localSolrServer);
1319 Object dataDirPath = response.getCoreStatus(coreName).get(
"dataDir");
1320 if (null != dataDirPath) {
1321 File indexDir = Paths.get((String) dataDirPath,
"index").toFile();
1322 return indexDir.exists();
1342 Path serverFilePath = Paths.get(caseDirectory,
"solrserver.txt");
1343 if (serverFilePath.toFile().exists()) {
1345 List<String> lines = Files.readAllLines(serverFilePath);
1346 if (lines.isEmpty()) {
1347 logger.log(Level.SEVERE,
"solrserver.txt file does not contain any data");
1348 }
else if (!lines.get(0).contains(
",")) {
1349 logger.log(Level.SEVERE,
"solrserver.txt file is corrupt - could not read host/port from " + lines.get(0));
1351 String[] parts = lines.get(0).split(
",");
1352 if (parts.length != 2) {
1353 logger.log(Level.SEVERE,
"solrserver.txt file is corrupt - could not read host/port from " + lines.get(0));
1358 }
catch (IOException ex) {
1359 logger.log(Level.SEVERE,
"solrserver.txt file could not be read", ex);
1364 List<Index> indexes =
new ArrayList<>();
1366 IndexMetadata indexMetadata =
new IndexMetadata(caseDirectory);
1367 indexes = indexMetadata.getIndexes();
1368 }
catch (IndexMetadata.TextIndexMetadataException ex) {
1369 logger.log(Level.SEVERE,
"Unable to read text index metadata file: " + caseDirectory, ex);
1379 Index indexToUse = IndexFinder.identifyIndexToUse(indexes);
1380 if (indexToUse == null) {
1382 logger.log(Level.SEVERE,
"Unable to find index that can be used for case: {0}", caseDirectory);
1391 if (IndexFinder.getCurrentSolrVersion().equals(indexToUse.getSolrVersion())) {
1415 public static void selectSolrServerForCase(Path rootOutputDirectory, Path caseDirectoryPath)
throws KeywordSearchModuleException {
1417 String serverListName =
"solrServerList.txt";
1418 Path serverListPath = Paths.get(rootOutputDirectory.toString(), serverListName);
1419 if (serverListPath.toFile().exists()) {
1424 lines = Files.readAllLines(serverListPath);
1425 }
catch (IOException ex) {
1426 throw new KeywordSearchModuleException(serverListName +
" could not be read", ex);
1430 for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
1431 String line = iterator.next();
1432 if (!line.contains(
",")) {
1437 if (lines.isEmpty()) {
1438 throw new KeywordSearchModuleException(serverListName +
" had no valid server information");
1442 int rnd =
new Random().nextInt(lines.size());
1443 String[] parts = lines.get(rnd).split(
",");
1444 if (parts.length != 2) {
1445 throw new KeywordSearchModuleException(
"Invalid server data: " + lines.get(rnd));
1449 String host = parts[0];
1450 String port = parts[1];
1451 if (host.isEmpty() || port.isEmpty()) {
1452 throw new KeywordSearchModuleException(
"Invalid server data: " + lines.get(rnd));
1456 Path serverFile = Paths.get(caseDirectoryPath.toString(),
"solrserver.txt");
1458 caseDirectoryPath.toFile().mkdirs();
1459 if (!caseDirectoryPath.toFile().exists()) {
1460 throw new KeywordSearchModuleException(
"Case directory " + caseDirectoryPath.toString() +
" does not exist");
1462 Files.write(serverFile, lines.get(rnd).getBytes());
1463 }
catch (IOException ex) {
1464 throw new KeywordSearchModuleException(serverFile.toString() +
" could not be written", ex);
1506 void commit() throws SolrServerException, NoOpenCoreException {
1507 currentCoreLock.readLock().lock();
1509 if (null == currentCollection) {
1510 throw new NoOpenCoreException();
1512 currentCollection.commit();
1514 currentCoreLock.readLock().unlock();
1518 NamedList<Object> request(SolrRequest request)
throws SolrServerException, RemoteSolrException, NoOpenCoreException {
1519 currentCoreLock.readLock().lock();
1521 if (null == currentCollection) {
1522 throw new NoOpenCoreException();
1524 return currentCollection.request(request);
1526 currentCoreLock.readLock().unlock();
1541 currentCoreLock.readLock().lock();
1543 if (null == currentCollection) {
1544 throw new NoOpenCoreException();
1547 return currentCollection.queryNumIndexedFiles();
1548 }
catch (Exception ex) {
1550 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumIdxFiles.exception.msg"), ex);
1553 currentCoreLock.readLock().unlock();
1567 currentCoreLock.readLock().lock();
1569 if (null == currentCollection) {
1570 throw new NoOpenCoreException();
1573 return currentCollection.queryNumIndexedChunks();
1574 }
catch (Exception ex) {
1576 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumIdxChunks.exception.msg"), ex);
1579 currentCoreLock.readLock().unlock();
1593 currentCoreLock.readLock().lock();
1595 if (null == currentCollection) {
1596 throw new NoOpenCoreException();
1599 return currentCollection.queryNumIndexedDocuments();
1600 }
catch (Exception ex) {
1602 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumIdxDocs.exception.msg"), ex);
1605 currentCoreLock.readLock().unlock();
1619 public boolean queryIsIndexed(
long contentID)
throws KeywordSearchModuleException, NoOpenCoreException {
1620 currentCoreLock.readLock().lock();
1622 if (null == currentCollection) {
1623 throw new NoOpenCoreException();
1626 return currentCollection.queryIsIndexed(contentID);
1627 }
catch (Exception ex) {
1629 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryIsIdxd.exception.msg"), ex);
1633 currentCoreLock.readLock().unlock();
1649 currentCoreLock.readLock().lock();
1651 if (null == currentCollection) {
1652 throw new NoOpenCoreException();
1655 return currentCollection.queryNumFileChunks(fileID);
1656 }
catch (Exception ex) {
1658 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumFileChunks.exception.msg"), ex);
1661 currentCoreLock.readLock().unlock();
1675 public QueryResponse
query(SolrQuery sq)
throws KeywordSearchModuleException, NoOpenCoreException, IOException {
1676 currentCoreLock.readLock().lock();
1678 if (null == currentCollection) {
1679 throw new NoOpenCoreException();
1682 return currentCollection.query(sq);
1683 }
catch (Exception ex) {
1685 logger.log(Level.SEVERE,
"Solr query failed: " + sq.getQuery(), ex);
1686 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.query.exception.msg", sq.getQuery()), ex);
1689 currentCoreLock.readLock().unlock();
1704 public QueryResponse
query(SolrQuery sq, SolrRequest.METHOD method) throws KeywordSearchModuleException, NoOpenCoreException {
1705 currentCoreLock.readLock().lock();
1707 if (null == currentCollection) {
1708 throw new NoOpenCoreException();
1711 return currentCollection.query(sq, method);
1712 }
catch (Exception ex) {
1714 logger.log(Level.SEVERE,
"Solr query failed: " + sq.getQuery(), ex);
1715 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.query2.exception.msg", sq.getQuery()), ex);
1718 currentCoreLock.readLock().unlock();
1732 public TermsResponse
queryTerms(SolrQuery sq)
throws KeywordSearchModuleException, NoOpenCoreException {
1733 currentCoreLock.readLock().lock();
1735 if (null == currentCollection) {
1736 throw new NoOpenCoreException();
1739 return currentCollection.queryTerms(sq);
1740 }
catch (Exception ex) {
1742 logger.log(Level.SEVERE,
"Solr terms query failed: " + sq.getQuery(), ex);
1743 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryTerms.exception.msg", sq.getQuery()), ex);
1746 currentCoreLock.readLock().unlock();
1757 void deleteDataSource(Long dataSourceId)
throws IOException, KeywordSearchModuleException, NoOpenCoreException, SolrServerException {
1759 currentCoreLock.writeLock().lock();
1760 if (null == currentCollection) {
1761 throw new NoOpenCoreException();
1763 currentCollection.deleteDataSource(dataSourceId);
1764 currentCollection.commit();
1766 currentCoreLock.writeLock().unlock();
1780 currentCoreLock.readLock().lock();
1782 if (null == currentCollection) {
1783 throw new NoOpenCoreException();
1785 return currentCollection.getSolrContent(content.getId(), 0);
1787 currentCoreLock.readLock().unlock();
1803 public String
getSolrContent(
final Content content,
int chunkID)
throws NoOpenCoreException {
1804 currentCoreLock.readLock().lock();
1806 if (null == currentCollection) {
1807 throw new NoOpenCoreException();
1809 return currentCollection.getSolrContent(content.getId(), chunkID);
1811 currentCoreLock.readLock().unlock();
1825 currentCoreLock.readLock().lock();
1827 if (null == currentCollection) {
1828 throw new NoOpenCoreException();
1830 return currentCollection.getSolrContent(objectID, 0);
1832 currentCoreLock.readLock().unlock();
1846 public String
getSolrContent(
final long objectID,
final int chunkID)
throws NoOpenCoreException {
1847 currentCoreLock.readLock().lock();
1849 if (null == currentCollection) {
1850 throw new NoOpenCoreException();
1852 return currentCollection.getSolrContent(objectID, chunkID);
1854 currentCoreLock.readLock().unlock();
1878 HttpSolrClient solrServer =
getSolrClient(
"http://localhost:" + localSolrServerPort +
"/solr");
1880 CoreAdminRequest.getStatus(null, solrServer);
1885 void connectToSolrServer(String host, String port)
throws SolrServerException, IOException {
1886 try (HttpSolrClient solrServer =
getSolrClient(
"http://" + host +
":" + port +
"/solr")) {
1887 connectToSolrServer(solrServer);
1902 CollectionAdminRequest.ClusterStatus statusRequest = CollectionAdminRequest.getClusterStatus();
1903 CollectionAdminResponse statusResponse = statusRequest.process(solrServer);
1904 int statusCode = Integer.valueOf(((NamedList) statusResponse.getResponse().get(
"responseHeader")).
get(
"status").toString());
1905 if (statusCode != 0) {
1906 logger.log(Level.WARNING,
"Could not connect to Solr server ");
1908 logger.log(Level.INFO,
"Connected to Solr server ");
1913 private List<String>
getSolrServerList(String host, String port)
throws KeywordSearchModuleException {
1914 HttpSolrClient solrServer =
getSolrClient(
"http://" + host +
":" + port +
"/solr");
1918 private List<String>
getSolrServerList(HttpSolrClient solrServer)
throws KeywordSearchModuleException {
1921 CollectionAdminRequest.ClusterStatus statusRequest = CollectionAdminRequest.getClusterStatus();
1922 CollectionAdminResponse statusResponse;
1924 statusResponse = statusRequest.process(solrServer);
1925 }
catch (RemoteSolrException ex) {
1927 return Collections.emptyList();
1930 if (statusResponse == null) {
1931 return Collections.emptyList();
1934 NamedList error = (NamedList) statusResponse.getResponse().get(
"error");
1935 if (error != null) {
1936 return Collections.emptyList();
1939 NamedList cluster = (NamedList) statusResponse.getResponse().get(
"cluster");
1940 ArrayList<String> liveNodes = (ArrayList) cluster.get(
"live_nodes");
1942 }
catch (Exception ex) {
1944 throw new KeywordSearchModuleException(
1945 NbBundle.getMessage(
this.getClass(),
"Server.serverList.exception.msg", solrServer.getBaseURL()));
1992 private final String name;
1996 private final Index textIndex;
2002 private HttpSolrClient queryClient;
2003 private SolrClient indexingClient;
2005 private final int maxBufferSize;
2006 private final List<SolrInputDocument> buffer;
2007 private final Object bufferLock;
2009 private final ScheduledThreadPoolExecutor periodicTasksExecutor;
2010 private static final long PERIODIC_BATCH_SEND_INTERVAL_MINUTES = 10;
2011 private static final int NUM_BATCH_UPDATE_RETRIES = 10;
2012 private static final long SLEEP_BETWEEN_RETRIES_MS = 10000;
2014 private Collection(String name,
Case theCase, Index index)
throws TimeoutException, InterruptedException, KeywordSearchModuleException {
2017 this.textIndex = index;
2018 bufferLock =
new Object();
2022 queryClient =
getSolrClient(
"http://localhost:" + localSolrServerPort +
"/solr/" + name);
2023 indexingClient =
getSolrClient(
"http://localhost:" + localSolrServerPort +
"/solr/" + name);
2029 if (IndexFinder.getCurrentSolrVersion().equals(index.getSolrVersion())) {
2031 indexingClient =
getCloudSolrClient(properties.getHost(), properties.getPort(), name);
2039 logger.log(Level.INFO,
"Using Solr document queue size = {0}", maxBufferSize);
2040 buffer =
new ArrayList<>(maxBufferSize);
2041 periodicTasksExecutor =
new ScheduledThreadPoolExecutor(1,
new ThreadFactoryBuilder().setNameFormat(
"periodic-batched-document-task-%d").build());
2042 periodicTasksExecutor.scheduleWithFixedDelay(
new SendBatchedDocumentsTask(), PERIODIC_BATCH_SEND_INTERVAL_MINUTES, PERIODIC_BATCH_SEND_INTERVAL_MINUTES, TimeUnit.MINUTES);
2055 List<SolrInputDocument> clone;
2056 synchronized (bufferLock) {
2058 if (buffer.isEmpty()) {
2064 clone = buffer.stream().collect(toList());
2070 sendBufferedDocs(clone);
2071 }
catch (KeywordSearchModuleException ex) {
2072 logger.log(Level.SEVERE,
"Periodic batched document update failed", ex);
2086 private Index getIndexInfo() {
2087 return this.textIndex;
2090 private QueryResponse
query(SolrQuery sq)
throws SolrServerException, IOException {
2091 return queryClient.query(sq);
2094 private NamedList<Object> request(SolrRequest request)
throws SolrServerException, RemoteSolrException {
2096 return queryClient.request(request);
2097 }
catch (Exception e) {
2099 logger.log(Level.WARNING,
"Could not issue Solr request. ", e);
2100 throw new SolrServerException(
2101 NbBundle.getMessage(
this.getClass(),
"Server.request.exception.exception.msg"), e);
2106 private QueryResponse
query(SolrQuery sq, SolrRequest.METHOD method) throws SolrServerException, IOException {
2107 return queryClient.query(sq, method);
2110 private TermsResponse
queryTerms(SolrQuery sq)
throws SolrServerException, IOException {
2111 QueryResponse qres = queryClient.query(sq);
2112 return qres.getTermsResponse();
2115 private void commit() throws SolrServerException {
2116 List<SolrInputDocument> clone;
2117 synchronized (bufferLock) {
2120 clone = buffer.stream().collect(toList());
2125 sendBufferedDocs(clone);
2126 }
catch (KeywordSearchModuleException ex) {
2127 throw new SolrServerException(NbBundle.getMessage(
this.getClass(),
"Server.commit.exception.msg"), ex);
2132 indexingClient.commit(
true,
true);
2133 }
catch (Exception e) {
2135 logger.log(Level.WARNING,
"Could not commit index. ", e);
2136 throw new SolrServerException(NbBundle.getMessage(
this.getClass(),
"Server.commit.exception.msg"), e);
2140 private void deleteDataSource(Long dsObjId)
throws IOException, SolrServerException {
2141 String dataSourceId = Long.toString(dsObjId);
2142 String deleteQuery =
"image_id:" + dataSourceId;
2144 queryClient.deleteByQuery(deleteQuery);
2155 void addDocument(SolrInputDocument doc)
throws KeywordSearchModuleException {
2157 List<SolrInputDocument> clone;
2158 synchronized (bufferLock) {
2161 if (buffer.size() < maxBufferSize) {
2167 clone = buffer.stream().collect(toList());
2172 sendBufferedDocs(clone);
2183 private void sendBufferedDocs(List<SolrInputDocument> docBuffer)
throws KeywordSearchModuleException {
2185 if (docBuffer.isEmpty()) {
2190 boolean success =
true;
2191 for (
int reTryAttempt = 0; reTryAttempt < NUM_BATCH_UPDATE_RETRIES; reTryAttempt++) {
2194 indexingClient.add(docBuffer);
2195 }
catch (Exception ex) {
2197 if (reTryAttempt < NUM_BATCH_UPDATE_RETRIES - 1) {
2198 logger.log(Level.WARNING,
"Unable to send document batch to Solr. Re-trying...", ex);
2200 Thread.sleep(SLEEP_BETWEEN_RETRIES_MS);
2201 }
catch (InterruptedException ignore) {
2202 throw new KeywordSearchModuleException(
2203 NbBundle.getMessage(
this.getClass(),
"Server.addDocBatch.exception.msg"), ex);
2208 if (reTryAttempt > 0) {
2209 logger.log(Level.INFO,
"Batch update suceeded after {0} re-try", reTryAttempt);
2215 logger.log(Level.SEVERE,
"Unable to send document batch to Solr. All re-try attempts failed!");
2216 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.addDocBatch.exception.msg"));
2217 }
catch (Exception ex) {
2219 logger.log(Level.SEVERE,
"Could not add batched documents to index", ex);
2220 throw new KeywordSearchModuleException(
2221 NbBundle.getMessage(
this.getClass(),
"Server.addDocBatch.exception.msg"), ex);
2238 final SolrQuery q =
new SolrQuery();
2240 String filterQuery = Schema.ID.toString() +
":" + KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
2242 filterQuery = filterQuery + Server.CHUNK_ID_SEPARATOR + chunkID;
2244 q.addFilterQuery(filterQuery);
2245 q.setFields(Schema.TEXT.toString());
2248 SolrDocumentList solrDocuments = queryClient.query(q).getResults();
2250 if (!solrDocuments.isEmpty()) {
2251 SolrDocument solrDocument = solrDocuments.get(0);
2252 if (solrDocument != null) {
2253 java.util.Collection<Object> fieldValues = solrDocument.getFieldValues(Schema.TEXT.toString());
2254 if (fieldValues.size() == 1)
2256 return fieldValues.toArray(
new String[0])[0];
2260 return fieldValues.toArray(
new String[0])[1];
2264 }
catch (Exception ex) {
2266 logger.log(Level.SEVERE,
"Error getting content from Solr. Solr document id " + contentID +
", chunk id " + chunkID +
", query: " + filterQuery, ex);
2273 synchronized void close() throws KeywordSearchModuleException {
2278 ThreadUtils.shutDownTaskExecutor(periodicTasksExecutor);
2285 CoreAdminRequest.unloadCore(this.name, localSolrServer);
2286 }
catch (Exception ex) {
2288 throw new KeywordSearchModuleException(
2289 NbBundle.getMessage(
this.getClass(),
"Server.close.exception.msg"), ex);
2292 queryClient.close();
2294 indexingClient.close();
2295 indexingClient = null;
2296 }
catch (IOException ex) {
2297 throw new KeywordSearchModuleException(
2298 NbBundle.getMessage(
this.getClass(),
"Server.close.exception.msg2"), ex);
2326 SolrQuery q =
new SolrQuery(Server.Schema.ID +
":*" + Server.CHUNK_ID_SEPARATOR +
"*");
2328 int numChunks = (int)
query(q).getResults().getNumFound();
2343 SolrQuery q =
new SolrQuery(
"*:*");
2345 return (
int)
query(q).getResults().getNumFound();
2357 private boolean queryIsIndexed(
long contentID)
throws SolrServerException, IOException {
2358 String
id = KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
2359 SolrQuery q =
new SolrQuery(
"*:*");
2360 q.addFilterQuery(Server.Schema.ID.toString() +
":" + id);
2363 return (
int)
query(q).getResults().getNumFound() != 0;
2377 private int queryNumFileChunks(
long contentID)
throws SolrServerException, IOException {
2378 String
id = KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
2380 =
new SolrQuery(Server.Schema.ID +
":" +
id + Server.CHUNK_ID_SEPARATOR +
"*");
2382 return (
int)
query(q).getResults().getNumFound();
2386 class ServerAction
extends AbstractAction {
2388 private static final long serialVersionUID = 1L;
2391 public void actionPerformed(ActionEvent e) {
2392 logger.log(Level.INFO, e.paramString().trim());
2399 class SolrServerNoPortException
extends SocketException {
2401 private static final long serialVersionUID = 1L;
2406 private final int port;
2408 SolrServerNoPortException(
int port) {
2409 super(NbBundle.getMessage(Server.class,
"Server.solrServerNoPortException.msg", port,
2410 Server.PROPERTIES_CURRENT_SERVER_PORT));
2414 int getPortNumber() {
static synchronized String getConfigSetting(String moduleName, String settingName)
HttpSolrClient localSolrServer
int queryNumIndexedFiles()
String getSolrContent(final long objectID)
final ReentrantReadWriteLock currentCoreLock
int queryNumIndexedChunks()
ConcurrentUpdateSolrClient getConcurrentClient(String solrUrl)
static String getSolr4ServerPort()
static final char ID_CHUNK_SEP
final ServerAction serverAction
static String getIndexingServerPort()
static IndexingServerProperties getMultiUserServerProperties(String caseDirectory)
String getCaseDirectory()
Collection openCore(Case theCase, Index index)
static final String CORE_PROPERTIES
void connectToSolrServer(HttpSolrClient solrServer)
boolean coreIsLoaded(String coreName)
Process runLocalSolr8ControlCommand(List< String > solrArguments)
List< String > getSolrServerList(String host, String port)
static final int NUM_COLLECTION_CREATION_RETRIES
void backupCollection(String collectionName, String backupName, String pathToBackupLocation)
void configureSolrConnection(Case theCase, Index index)
CloudSolrClient getCloudSolrClient(String host, String port, String defaultCollectionName)
boolean collectionExists(String collectionName)
Collection currentCollection
static final Logger logger
static TimingMetric getTimingMetric(String name)
SOLR_VERSION localServerVersion
static int getMaxSolrVMSize()
static void selectSolrServerForCase(Path rootOutputDirectory, Path caseDirectoryPath)
void addServerActionListener(PropertyChangeListener l)
static synchronized boolean settingExists(String moduleName, String settingName)
static final String HL_ANALYZE_CHARS_UNLIMITED
String getSolrContent(final Content content)
static final long MAX_CONTENT_SIZE
HttpSolrClient remoteSolrServer
boolean coreIndexFolderExists(String coreName)
void restoreCollection(String backupName, String restoreCollectionName, String pathToBackupLocation)
int queryNumIndexedDocuments()
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
HttpSolrClient configureMultiUserConnection(Case theCase, Index index, String name)
static final String CHUNK_ID_SEPARATOR
static final String CORE_EVT
static final Charset DEFAULT_INDEXED_TEXT_CHARSET
default Charset to index text as
static String getSolr4ServerHost()
InputStreamPrinterThread errorRedirectThread
Process runLocalSolr4ControlCommand(List< String > solrArguments)
List< String > getSolrServerList(HttpSolrClient solrServer)
QueryResponse query(SolrQuery sq)
static void submitTimingMetric(TimingMetric metric)
TermsResponse queryTerms(SolrQuery sq)
boolean queryIsIndexed(long contentID)
void connectToEmbeddedSolrServer()
void createMultiUserCollection(String collectionName, int numShardsToUse)
String getSolrContent(final Content content, int chunkID)
String getSolrContent(final long objectID, final int chunkID)
HttpSolrClient getSolrClient(String solrUrl)
synchronized static Logger getLogger(String name)
static String getChunkIdString(long parentID, int childID)
static boolean deleteDir(File dirPath)
static String getIndexingServerHost()
int queryNumFileChunks(long fileID)
static final boolean DEBUG
QueryResponse query(SolrQuery sq, SolrRequest.METHOD method)