mirror of https://github.com/apache/lucene.git
SOLR-5087, CoreAdminHandler.handleMergeAction generating NullPointerException. Thanks Patrick
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1508476 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4d29e7e20e
commit
460a1be8a9
|
@ -18,6 +18,7 @@
|
|||
package org.apache.solr.handler.admin;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
|
@ -295,17 +296,17 @@ public class CoreAdminHandler extends RequestHandlerBase {
|
|||
}
|
||||
|
||||
|
||||
protected void handleMergeAction(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException {
|
||||
protected void handleMergeAction(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
|
||||
SolrParams params = req.getParams();
|
||||
String cname = params.required().get(CoreAdminParams.CORE);
|
||||
SolrCore core = coreContainer.getCore(cname);
|
||||
SolrQueryRequest wrappedReq = null;
|
||||
|
||||
SolrCore[] sourceCores = null;
|
||||
RefCounted<SolrIndexSearcher>[] searchers = null;
|
||||
List<SolrCore> sourceCores = Lists.newArrayList();
|
||||
List<RefCounted<SolrIndexSearcher>> searchers = Lists.newArrayList();
|
||||
// stores readers created from indexDir param values
|
||||
DirectoryReader[] readersToBeClosed = null;
|
||||
Directory[] dirsToBeReleased = null;
|
||||
List<DirectoryReader> readersToBeClosed = Lists.newArrayList();
|
||||
List<Directory> dirsToBeReleased = Lists.newArrayList();
|
||||
if (core != null) {
|
||||
try {
|
||||
String[] dirNames = params.getParams(CoreAdminParams.INDEX_DIR);
|
||||
|
@ -315,38 +316,34 @@ public class CoreAdminHandler extends RequestHandlerBase {
|
|||
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
|
||||
"At least one indexDir or srcCore must be specified");
|
||||
|
||||
sourceCores = new SolrCore[sources.length];
|
||||
for (int i = 0; i < sources.length; i++) {
|
||||
String source = sources[i];
|
||||
SolrCore srcCore = coreContainer.getCore(source);
|
||||
if (srcCore == null)
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
|
||||
"Core: " + source + " does not exist");
|
||||
sourceCores[i] = srcCore;
|
||||
sourceCores.add(srcCore);
|
||||
}
|
||||
} else {
|
||||
readersToBeClosed = new DirectoryReader[dirNames.length];
|
||||
dirsToBeReleased = new Directory[dirNames.length];
|
||||
DirectoryFactory dirFactory = core.getDirectoryFactory();
|
||||
for (int i = 0; i < dirNames.length; i++) {
|
||||
Directory dir = dirFactory.get(dirNames[i], DirContext.DEFAULT, core.getSolrConfig().indexConfig.lockType);
|
||||
dirsToBeReleased[i] = dir;
|
||||
dirsToBeReleased.add(dir);
|
||||
// TODO: why doesn't this use the IR factory? what is going on here?
|
||||
readersToBeClosed[i] = DirectoryReader.open(dir);
|
||||
readersToBeClosed.add(DirectoryReader.open(dir));
|
||||
}
|
||||
}
|
||||
|
||||
DirectoryReader[] readers = null;
|
||||
if (readersToBeClosed != null) {
|
||||
List<DirectoryReader> readers = null;
|
||||
if (readersToBeClosed.size() > 0) {
|
||||
readers = readersToBeClosed;
|
||||
} else {
|
||||
readers = new DirectoryReader[sourceCores.length];
|
||||
searchers = new RefCounted[sourceCores.length];
|
||||
for (int i = 0; i < sourceCores.length; i++) {
|
||||
SolrCore solrCore = sourceCores[i];
|
||||
readers = Lists.newArrayList();
|
||||
for (SolrCore solrCore: sourceCores) {
|
||||
// record the searchers so that we can decref
|
||||
searchers[i] = solrCore.getSearcher();
|
||||
readers[i] = searchers[i].get().getIndexReader();
|
||||
RefCounted<SolrIndexSearcher> searcher = solrCore.getSearcher();
|
||||
searchers.add(searcher);
|
||||
readers.add(searcher.get().getIndexReader());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,23 +353,21 @@ public class CoreAdminHandler extends RequestHandlerBase {
|
|||
UpdateRequestProcessor processor =
|
||||
processorChain.createProcessor(wrappedReq, rsp);
|
||||
processor.processMergeIndexes(new MergeIndexesCommand(readers, req));
|
||||
} catch (Exception e) {
|
||||
// log and rethrow so that if the finally fails we don't lose the original problem
|
||||
log.error("ERROR executing merge:", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (searchers != null) {
|
||||
for (RefCounted<SolrIndexSearcher> searcher : searchers) {
|
||||
if (searcher != null) searcher.decref();
|
||||
}
|
||||
for (RefCounted<SolrIndexSearcher> searcher : searchers) {
|
||||
if (searcher != null) searcher.decref();
|
||||
}
|
||||
if (sourceCores != null) {
|
||||
for (SolrCore solrCore : sourceCores) {
|
||||
if (solrCore != null) solrCore.close();
|
||||
}
|
||||
for (SolrCore solrCore : sourceCores) {
|
||||
if (solrCore != null) solrCore.close();
|
||||
}
|
||||
if (readersToBeClosed != null) IOUtils.closeWhileHandlingException(readersToBeClosed);
|
||||
if (dirsToBeReleased != null) {
|
||||
for (Directory dir : dirsToBeReleased) {
|
||||
DirectoryFactory dirFactory = core.getDirectoryFactory();
|
||||
dirFactory.release(dir);
|
||||
}
|
||||
IOUtils.closeWhileHandlingException(readersToBeClosed);
|
||||
for (Directory dir : dirsToBeReleased) {
|
||||
DirectoryFactory dirFactory = core.getDirectoryFactory();
|
||||
dirFactory.release(dir);
|
||||
}
|
||||
if (wrappedReq != null) wrappedReq.close();
|
||||
core.close();
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
|
@ -432,11 +433,11 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
|
|||
|
||||
log.info("start " + cmd);
|
||||
|
||||
IndexReader[] readers = cmd.readers;
|
||||
if (readers != null && readers.length > 0) {
|
||||
List<DirectoryReader> readers = cmd.readers;
|
||||
if (readers != null && readers.size() > 0) {
|
||||
RefCounted<IndexWriter> iw = solrCoreState.getIndexWriter(core);
|
||||
try {
|
||||
iw.get().addIndexes(readers);
|
||||
iw.get().addIndexes(readers.toArray(new IndexReader[readers.size()]));
|
||||
} finally {
|
||||
iw.decref();
|
||||
}
|
||||
|
|
|
@ -17,9 +17,14 @@
|
|||
|
||||
package org.apache.solr.update;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A merge indexes command encapsulated in an object.
|
||||
*
|
||||
|
@ -27,9 +32,9 @@ import org.apache.solr.request.SolrQueryRequest;
|
|||
*
|
||||
*/
|
||||
public class MergeIndexesCommand extends UpdateCommand {
|
||||
public DirectoryReader[] readers;
|
||||
public List<DirectoryReader> readers;
|
||||
|
||||
public MergeIndexesCommand(DirectoryReader[] readers, SolrQueryRequest req) {
|
||||
public MergeIndexesCommand(List<DirectoryReader> readers, SolrQueryRequest req) {
|
||||
super(req);
|
||||
this.readers = readers;
|
||||
}
|
||||
|
@ -42,12 +47,13 @@ public class MergeIndexesCommand extends UpdateCommand {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(super.toString());
|
||||
if (readers != null && readers.length > 0) {
|
||||
sb.append(readers[0].directory());
|
||||
for (int i = 1; i < readers.length; i++) {
|
||||
sb.append(",").append(readers[i].directory());
|
||||
Joiner joiner = Joiner.on(",");
|
||||
Iterable<String> directories = Iterables.transform(readers, new Function<DirectoryReader, String>() {
|
||||
public String apply(DirectoryReader reader) {
|
||||
return reader.directory().toString();
|
||||
}
|
||||
}
|
||||
});
|
||||
joiner.skipNulls().join(sb, directories);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package org.apache.solr.handler.admin;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.common.params.CoreAdminParams;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.core.MockFSDirectoryFactory;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class CoreMergeIndexesAdminHandlerTest extends SolrTestCaseJ4 {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
useFactory(FailingDirectoryFactory.class.getName());
|
||||
initCore("solrconfig.xml", "schema.xml");
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());
|
||||
|
||||
|
||||
private static String FAILING_MSG = "Creating a directory using FailingDirectoryFactoryException always fails";
|
||||
public static class FailingDirectoryFactory extends MockFSDirectoryFactory {
|
||||
public class FailingDirectoryFactoryException extends RuntimeException {
|
||||
public FailingDirectoryFactoryException() {
|
||||
super(FAILING_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean fail = false;
|
||||
@Override
|
||||
public Directory create(String path, DirContext dirContext) throws IOException {
|
||||
if (fail) {
|
||||
throw new FailingDirectoryFactoryException();
|
||||
} else {
|
||||
return super.create(path, dirContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeIndexesCoreAdminHandler() throws Exception {
|
||||
final File workDir = new File(TEMP_DIR, this.getClass().getName());
|
||||
|
||||
if (workDir.exists()) {
|
||||
FileUtils.deleteDirectory(workDir);
|
||||
}
|
||||
assertTrue("Failed to mkdirs workDir", workDir.mkdirs());
|
||||
|
||||
final CoreContainer cores = h.getCoreContainer();
|
||||
|
||||
final CoreAdminHandler admin = new CoreAdminHandler(cores);
|
||||
|
||||
SolrCore core = cores.getCore("collection1");
|
||||
try {
|
||||
FailingDirectoryFactory dirFactory = (FailingDirectoryFactory)core.getDirectoryFactory();
|
||||
|
||||
try {
|
||||
dirFactory.fail = true;
|
||||
ignoreException(FAILING_MSG);
|
||||
|
||||
SolrQueryResponse resp = new SolrQueryResponse();
|
||||
admin.handleRequestBody
|
||||
(req(CoreAdminParams.ACTION,
|
||||
CoreAdminParams.CoreAdminAction.MERGEINDEXES.toString(),
|
||||
CoreAdminParams.CORE, "collection1",
|
||||
CoreAdminParams.INDEX_DIR, workDir.getAbsolutePath()),
|
||||
resp);
|
||||
fail("exception expected");
|
||||
} catch (FailingDirectoryFactory.FailingDirectoryFactoryException e) {
|
||||
// expected if error handling properly
|
||||
} finally {
|
||||
unIgnoreException(FAILING_MSG);
|
||||
}
|
||||
dirFactory.fail = false;
|
||||
} finally {
|
||||
core.close();
|
||||
}
|
||||
|
||||
// cleanup
|
||||
FileUtils.deleteDirectory(workDir);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue