Skip to content
Permalink
Browse files

Ensure an embedded Solr is available for Solr dump/restore operations

Otherwise, these operations triggered NullPointerException when only an
external Solr index is attached.
  • Loading branch information...
luccioman committed Apr 7, 2018
1 parent d92b191 commit 0d34034f17922e1c0dcd82bbccf9564f2100d1ef
Showing with 64 additions and 22 deletions.
  1. +13 −4 htroot/IndexExport_p.html
  2. +32 −8 htroot/IndexExport_p.java
  3. +19 −10 source/net/yacy/search/index/Fulltext.java
@@ -68,27 +68,36 @@ <h2>Index Export</h2>
#(dumprestore)#::
<form action="IndexExport_p.html" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
<fieldset><legend>Dump and Restore of Solr Index</legend>
#(dumpRestoreEnabled)#<div class="alert alert-info">This feature is available only when a local embedded Solr is active.</div>::#(/dumpRestoreEnabled)#
<dl>
<dt>&nbsp;</dt>
<dd><input type="submit" name="indexdump" value="Create Dump" class="btn btn-primary" style="width:240px;"/>
<dd><input type="submit" name="indexdump" value="Create Dump" class="btn btn-primary" style="width:240px;" #(dumpRestoreEnabled)#disabled="disabled"::#(/dumpRestoreEnabled)#/>
</dd>
</dl>
<dl>
<dt class="TableCellDark">Dump File</dt>
<dd><input type="text" name="dumpfile" value="#[dumpfile]#" size="80" maxlength="250" />
<dd><input type="text" name="dumpfile" value="#[dumpfile]#" size="80" maxlength="250" #(dumpRestoreEnabled)#disabled="disabled"::#(/dumpRestoreEnabled)#/>
</dd>
<dt>&nbsp;</dt>
<dd><input type="submit" name="indexrestore" value="Restore Dump" class="btn btn-primary" style="width:240px;"/>
<dd><input type="submit" name="indexrestore" value="Restore Dump" class="btn btn-primary" style="width:240px;" #(dumpRestoreEnabled)#disabled="disabled"::#(/dumpRestoreEnabled)#/>
</dd>
</dl>
</fieldset>
</form>::
#(/dumprestore)#

#(indexdump)#::
<div class="alert alert-success">Stored a solr dump to file #[dumpfile]#</div>::
<div class="alert alert-success" role="alert">Stored a solr dump to file #[dumpfile]#</div>::
<div class="alert alert-danger" role="alert">Could not create the Solr dump : no embedded Solr is available.</div>::
<div class="alert alert-danger" role="alert">An error occurred while trying to create the Solr dump.</div>
#(/indexdump)#

#(indexRestore)#::
<div class="alert alert-success" role="alert">Successfully restored Solr index from dump file!</div>::
<div class="alert alert-danger" role="alert">Could not restore the Solr dump : no embedded Solr is available.</div>::
<div class="alert alert-danger" role="alert">An error occurred while trying to restore the Solr dump.</div>
#(/indexRestore)#

#%env/templates/footer.template%#
</body>
</html>
@@ -25,9 +25,13 @@
import java.io.IOException;
import java.util.List;

import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;

import net.yacy.cora.protocol.RequestHeader;
import net.yacy.data.WorkTables;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.search.index.Fulltext;
import net.yacy.search.index.Segment;
import net.yacy.server.serverObjects;
@@ -48,9 +52,12 @@ public static serverObjects respond(@SuppressWarnings("unused") final RequestHea
prop.put("otherHosts", "");
prop.put("reload", 0);
prop.put("indexdump", 0);
prop.put("indexRestore", 0);
prop.put("lurlexport", 0);
prop.put("reload", 0);
prop.put("dumprestore", 1);
prop.put("dumprestore_dumpRestoreEnabled", sb.getConfigBool(SwitchboardConstants.CORE_SERVICE_FULLTEXT,
SwitchboardConstants.CORE_SERVICE_FULLTEXT_DEFAULT));
List<File> dumpFiles = segment.fulltext().dumpFiles();
prop.put("dumprestore_dumpfile", dumpFiles.size() == 0 ? "" : dumpFiles.get(dumpFiles.size() - 1).getAbsolutePath());
prop.put("dumprestore_optimizemax", 10);
@@ -132,17 +139,34 @@ public static serverObjects respond(@SuppressWarnings("unused") final RequestHea
}

if (post.containsKey("indexdump")) {
final File dump = segment.fulltext().dumpSolr();
prop.put("indexdump", 1);
prop.put("indexdump_dumpfile", dump.getAbsolutePath());
dumpFiles = segment.fulltext().dumpFiles();
prop.put("dumprestore_dumpfile", dumpFiles.size() == 0 ? "" : dumpFiles.get(dumpFiles.size() - 1).getAbsolutePath());
//sb.tables.recordAPICall(post, "IndexExport_p.html", WorkTables.TABLE_API_TYPE_STEERING, "solr dump generation");
try {
final File dump = segment.fulltext().dumpEmbeddedSolr();
prop.put("indexdump", 1);
prop.put("indexdump_dumpfile", dump.getAbsolutePath());
dumpFiles = segment.fulltext().dumpFiles();
prop.put("dumprestore_dumpfile", dumpFiles.size() == 0 ? "" : dumpFiles.get(dumpFiles.size() - 1).getAbsolutePath());
// sb.tables.recordAPICall(post, "IndexExport_p.html", WorkTables.TABLE_API_TYPE_STEERING, "solr dump generation");
} catch(final SolrException e) {
if(ErrorCode.SERVICE_UNAVAILABLE.code == e.code()) {
prop.put("indexdump", 2);
} else {
prop.put("indexdump", 3);
}
}
}

if (post.containsKey("indexrestore")) {
final File dump = new File(post.get("dumpfile", ""));
segment.fulltext().restoreSolr(dump);
try {
final File dump = new File(post.get("dumpfile", ""));
segment.fulltext().restoreEmbeddedSolr(dump);
prop.put("indexRestore", 1);
} catch(final SolrException e) {
if(ErrorCode.SERVICE_UNAVAILABLE.code == e.code()) {
prop.put("indexRestore", 2);
} else {
prop.put("indexRestore", 3);
}
}
}

// insert constants
@@ -82,6 +82,7 @@
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.core.SolrInfoMBean;
import org.apache.lucene.util.Version;

@@ -581,13 +582,17 @@ public long getLoadTime(final String urlHash) throws IOException {
}

/**
* create a dump file from the current solr directory
* Create a dump file from the current embedded solr directory
* @return file reference to the dump
* @throws SolrException when no embedded Solr is available
*/
public File dumpSolr() {
EmbeddedInstance esc = this.solrInstances.getEmbedded();
File storagePath = esc.getContainerPath();
File zipOut = new File(this.archivePath, storagePath.getName() + "_" + GenericFormatter.SHORT_DAY_FORMATTER.format() + ".zip");
public File dumpEmbeddedSolr() throws SolrException {
final EmbeddedInstance esc = this.solrInstances.getEmbedded();
if(esc == null) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "No embedded Solr available.");
}
final File storagePath = esc.getContainerPath();
final File zipOut = new File(this.archivePath, storagePath.getName() + "_" + GenericFormatter.SHORT_DAY_FORMATTER.format() + ".zip");
synchronized (this.solrInstances) {
this.disconnectLocalSolr();
try {
@@ -606,12 +611,16 @@ public File dumpSolr() {
}

/**
* restore a solr dump to the current solr directory
* @param solrDumpZipFile
* Restore a solr dump to the current embedded solr directory
* @param solrDumpZipFile the dump file to use
* @throws SolrException when no embedded Solr is available
*/
public void restoreSolr(File solrDumpZipFile) {
EmbeddedInstance esc = this.solrInstances.getEmbedded();
File storagePath = esc.getContainerPath();
public void restoreEmbeddedSolr(final File solrDumpZipFile) {
final EmbeddedInstance esc = this.solrInstances.getEmbedded();
if(esc == null) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "No embedded Solr available.");
}
final File storagePath = esc.getContainerPath();
synchronized (this.solrInstances) {
// this.disconnectLocalSolr(); // moved to (InstanceMirror) sorlInstances.close()
this.solrInstances.close();

0 comments on commit 0d34034

Please sign in to comment.
You can’t perform that action at this time.