SOLR-10910: Clean up a few details left over from pluggable transient core and untangling CoreDescriptor/CoreContainer references

This commit is contained in:
Erick Erickson 2017-06-28 21:02:14 -07:00
parent 811621c6ea
commit 8f71bb40a5
10 changed files with 138 additions and 122 deletions

View File

@ -495,6 +495,9 @@ when using one of Exact*StatsCache (Mikhail Khludnev)
* SOLR-10963: Fix example json in MultipleAdditiveTreesModel javadocs.
(Stefan Langenmaier via Christine Poerschke)
* SOLR-10910: Clean up a few details left over from pluggable transient core and untangling
CoreDescriptor/CoreContainer references (Erick Erickson)
Optimizations
----------------------
* SOLR-10634: JSON Facet API: When a field/terms facet will retrieve all buckets (i.e. limit:-1)

View File

@ -135,7 +135,7 @@ public class CoreContainer {
protected CoreAdminHandler coreAdminHandler = null;
protected CollectionsHandler collectionsHandler = null;
protected TransientSolrCoreCache transientSolrCoreCache = null;
private InfoHandler infoHandler;
protected ConfigSetsHandler configSetsHandler = null;
@ -150,8 +150,6 @@ public class CoreContainer {
private UpdateShardHandler updateShardHandler;
private TransientSolrCoreCacheFactory transientCoreCache;
private ExecutorService coreContainerWorkExecutor = ExecutorUtil.newMDCAwareCachedThreadPool(
new DefaultSolrThreadFactory("coreContainerWorkExecutor") );
@ -507,7 +505,8 @@ public class CoreContainer {
updateShardHandler = new UpdateShardHandler(cfg.getUpdateShardHandlerConfig());
updateShardHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), "updateShardHandler");
transientCoreCache = TransientSolrCoreCacheFactory.newInstance(loader, this);
solrCores.load(loader);
logging = LogWatcher.newRegisteredLogWatcher(cfg.getLogWatcherConfig(), loader);
@ -596,7 +595,7 @@ public class CoreContainer {
for (final CoreDescriptor cd : cds) {
if (cd.isTransient() || !cd.isLoadOnStartup()) {
getTransientCacheHandler().addTransientDescriptor(cd.getName(), cd);
solrCores.getTransientCacheHandler().addTransientDescriptor(cd.getName(), cd);
} else if (asyncSolrCoreLoad) {
solrCores.markCoreAsLoading(cd);
}
@ -660,16 +659,6 @@ public class CoreContainer {
}
public TransientSolrCoreCache getTransientCacheHandler() {
if (transientCoreCache == null) {
log.error("No transient handler has been defined. Check solr.xml to see if an attempt to provide a custom " +
"TransientSolrCoreCacheFactory was done incorrectly since the default should have been used otherwise.");
return null;
}
return transientCoreCache.getTransientSolrCoreCache();
}
public void securityNodeChanged() {
log.info("Security node changed, reloading security.json");
reloadSecurityProperties();
@ -843,13 +832,13 @@ public class CoreContainer {
core.close();
throw new IllegalStateException("This CoreContainer has been closed");
}
solrCores.addCoreDescriptor(cd);
SolrCore old = solrCores.putCore(cd, core);
/*
* set both the name of the descriptor and the name of the
* core, since the descriptors name is used for persisting.
*/
solrCores.addCoreDescriptor(new CoreDescriptor(cd.getName(), cd));
core.setName(cd.getName());
coreInitFailures.remove(cd.getName());
@ -893,7 +882,8 @@ public class CoreContainer {
CoreDescriptor cd = new CoreDescriptor(coreName, instancePath, parameters, getContainerProperties(), isZooKeeperAware());
// TODO: There's a race here, isn't there?
if (getLoadedCoreNames().contains(coreName)) {
// Since the core descriptor is removed when a core is unloaded, it should never be anywhere when a core is created.
if (getAllCoreNames().contains(coreName)) {
log.warn("Creating a core with existing name is not allowed");
// TODO: Shouldn't this be a BAD_REQUEST?
throw new SolrException(ErrorCode.SERVER_ERROR, "Core with name '" + coreName + "' already exists.");
@ -991,6 +981,7 @@ public class CoreContainer {
return core;
} catch (Exception e) {
coreInitFailures.put(dcore.getName(), new CoreLoadFailure(dcore, e));
solrCores.removeCoreDescriptor(dcore);
final SolrException solrException = new SolrException(ErrorCode.SERVER_ERROR, "Unable to create core [" + dcore.getName() + "]", e);
if(core != null && !core.isClosed())
IOUtils.closeQuietly(core);
@ -998,6 +989,7 @@ public class CoreContainer {
} catch (Throwable t) {
SolrException e = new SolrException(ErrorCode.SERVER_ERROR, "JVM Error creating core [" + dcore.getName() + "]: " + t.getMessage(), t);
coreInitFailures.put(dcore.getName(), new CoreLoadFailure(dcore, e));
solrCores.removeCoreDescriptor(dcore);
if(core != null && !core.isClosed())
IOUtils.closeQuietly(core);
throw t;
@ -1104,24 +1096,30 @@ public class CoreContainer {
}
/**
* @return a Collection of the names that loaded cores are mapped to
* Gets the cores that are currently loaded, i.e. cores that have
* 1: loadOnStartup=true and are either not-transient or, if transient, have been loaded and have not been aged out
* 2: loadOnStartup=false and have been loaded but are either non-transient or have not been aged out.
*
* Put another way, this will not return any names of cores that are lazily loaded but have not been called for yet
* or are transient and either not loaded or have been swapped out.
*
*/
public Collection<String> getLoadedCoreNames() {
return solrCores.getLoadedCoreNames();
}
/** This method is currently experimental.
* @return a Collection of the names that a specific core is mapped to.
*
* @return a Collection of the names that a specific core object is mapped to, there are more than one.
*/
public Collection<String> getCoreNames(SolrCore core) {
return solrCores.getCoreNames(core);
public Collection<String> getNamesForCore(SolrCore core) {
return solrCores.getNamesForCore(core);
}
/**
* get a list of all the cores that are currently loaded
* @return a list of al lthe available core names in either permanent or transient core lists.
* get a list of all the cores that are currently known, whether currently loaded or not
* @return a list of all the available core names in either permanent or transient cores
*
* Note: this implies that the core is loaded
*/
public Collection<String> getAllCoreNames() {
return solrCores.getAllCoreNames();
@ -1266,6 +1264,8 @@ public class CoreContainer {
*/
public void unload(String name, boolean deleteIndexDir, boolean deleteDataDir, boolean deleteInstanceDir) {
CoreDescriptor cd = solrCores.getCoreDescriptor(name);
if (name != null) {
// check for core-init errors first
CoreLoadFailure loadFailure = coreInitFailures.remove(name);
@ -1274,11 +1274,15 @@ public class CoreContainer {
// which we may not be able to do because of the init error. So we just go with what we
// can glean from the CoreDescriptor - datadir and instancedir
SolrCore.deleteUnloadedCore(loadFailure.cd, deleteDataDir, deleteInstanceDir);
// If last time around we didn't successfully load, make sure that all traces of the coreDescriptor are gone.
if (cd != null) {
solrCores.removeCoreDescriptor(cd);
coresLocator.delete(this, cd);
}
return;
}
}
CoreDescriptor cd = solrCores.getCoreDescriptor(name);
if (cd == null) {
throw new SolrException(ErrorCode.BAD_REQUEST, "Cannot unload non-existent core [" + name + "]");
}

View File

@ -1137,7 +1137,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
manager.registerGauge(this, registry, () -> getIndexSize(), true, "sizeInBytes", Category.INDEX.toString());
manager.registerGauge(this, registry, () -> NumberUtils.readableSize(getIndexSize()), true, "size", Category.INDEX.toString());
if (coreContainer != null) {
manager.registerGauge(this, registry, () -> coreContainer.getCoreNames(this), true, "aliases", Category.CORE.toString());
manager.registerGauge(this, registry, () -> coreContainer.getNamesForCore(this), true, "aliases", Category.CORE.toString());
final CloudDescriptor cd = getCoreDescriptor().getCloudDescriptor();
if (cd != null) {
manager.registerGauge(this, registry, () -> {

View File

@ -64,6 +64,10 @@ class SolrCores implements Observer {
// to essentially queue them up to be handled via pendingCoreOps.
private static final List<SolrCore> pendingCloses = new ArrayList<>();
private TransientSolrCoreCacheFactory transientCoreCache;
private TransientSolrCoreCache transientSolrCoreCache = null;
SolrCores(CoreContainer container) {
this.container = container;
}
@ -71,8 +75,10 @@ class SolrCores implements Observer {
protected void addCoreDescriptor(CoreDescriptor p) {
synchronized (modifyLock) {
if (p.isTransient()) {
if (container.getTransientCacheHandler() != null) {
container.getTransientCacheHandler().addTransientDescriptor(p.getName(), p);
if (getTransientCacheHandler() != null) {
getTransientCacheHandler().addTransientDescriptor(p.getName(), p);
} else {
log.warn("We encountered a core marked as transient, but there is no transient handler defined. This core will be inaccessible");
}
} else {
residentDesciptors.put(p.getName(), p);
@ -83,8 +89,8 @@ class SolrCores implements Observer {
protected void removeCoreDescriptor(CoreDescriptor p) {
synchronized (modifyLock) {
if (p.isTransient()) {
if (container.getTransientCacheHandler() != null) {
container.getTransientCacheHandler().removeTransientDescriptor(p.getName());
if (getTransientCacheHandler() != null) {
getTransientCacheHandler().removeTransientDescriptor(p.getName());
}
} else {
residentDesciptors.remove(p.getName());
@ -92,6 +98,9 @@ class SolrCores implements Observer {
}
}
public void load(SolrResourceLoader loader) {
transientCoreCache = TransientSolrCoreCacheFactory.newInstance(loader, container);
}
// We are shutting down. You can't hold the lock on the various lists of cores while they shut down, so we need to
// make a temporary copy of the names and shut them down outside the lock.
protected void close() {
@ -99,7 +108,7 @@ class SolrCores implements Observer {
Collection<SolrCore> coreList = new ArrayList<>();
TransientSolrCoreCache transientSolrCoreCache = container.getTransientCacheHandler();
TransientSolrCoreCache transientSolrCoreCache = getTransientCacheHandler();
// Release observer
if (transientSolrCoreCache != null) {
transientSolrCoreCache.close();
@ -147,25 +156,14 @@ class SolrCores implements Observer {
} while (coreList.size() > 0);
}
//WARNING! This should be the _only_ place you put anything into the list of transient cores!
protected SolrCore putTransientCore(NodeConfig cfg, String name, SolrCore core, SolrResourceLoader loader) {
SolrCore retCore = null;
log.info("Opening transient core {}", name);
synchronized (modifyLock) {
if (container.getTransientCacheHandler() != null) {
retCore = container.getTransientCacheHandler().addCore(name, core);
}
}
return retCore;
}
// Returns the old core if there was a core of the same name.
//WARNING! This should be the _only_ place you put anything into the list of transient cores!
protected SolrCore putCore(CoreDescriptor cd, SolrCore core) {
synchronized (modifyLock) {
if (cd.isTransient()) {
if (container.getTransientCacheHandler() != null) {
return container.getTransientCacheHandler().addCore(cd.getName(), core);
if (getTransientCacheHandler() != null) {
return getTransientCacheHandler().addCore(cd.getName(), core);
}
} else {
return cores.put(cd.getName(), core);
@ -196,8 +194,8 @@ class SolrCores implements Observer {
/**
* Gets the cores that are currently loaded, i.e. cores that have
* 1> loadOnStartup=true and are either not-transient or, if transient, have been loaded and have not been swapped out
* 2> loadOnStartup=false and have been loaded but either non-transient or have not been swapped out.
* 1> loadOnStartup=true and are either not-transient or, if transient, have been loaded and have not been aged out
* 2> loadOnStartup=false and have been loaded but either non-transient or have not been aged out.
*
* Put another way, this will not return any names of cores that are lazily loaded but have not been called for yet
* or are transient and either not loaded or have been swapped out.
@ -209,20 +207,19 @@ class SolrCores implements Observer {
synchronized (modifyLock) {
set.addAll(cores.keySet());
if (container.getTransientCacheHandler() != null) {
set.addAll(container.getTransientCacheHandler().getLoadedCoreNames());
if (getTransientCacheHandler() != null) {
set.addAll(getTransientCacheHandler().getLoadedCoreNames());
}
}
return set;
}
/** This method is currently experimental.
* @return a Collection of the names that a specific core is mapped to.
*
* Note: this implies that the core is loaded
*
* @return a Collection of the names that a specific core object is mapped to, there are more than one.
*/
@Experimental
List<String> getCoreNames(SolrCore core) {
List<String> getNamesForCore(SolrCore core) {
List<String> lst = new ArrayList<>();
synchronized (modifyLock) {
@ -231,8 +228,8 @@ class SolrCores implements Observer {
lst.add(entry.getKey());
}
}
if (container.getTransientCacheHandler() != null) {
lst.addAll(container.getTransientCacheHandler().getNamesForCore(core));
if (getTransientCacheHandler() != null) {
lst.addAll(getTransientCacheHandler().getNamesForCore(core));
}
}
return lst;
@ -241,14 +238,14 @@ class SolrCores implements Observer {
/**
* Gets a list of all cores, loaded and unloaded
*
* @return all cores names, whether loaded or unloaded, transient or permenent.
* @return all cores names, whether loaded or unloaded, transient or permanent.
*/
public Collection<String> getAllCoreNames() {
Set<String> set = new TreeSet<>();
synchronized (modifyLock) {
set.addAll(cores.keySet());
if (container.getTransientCacheHandler() != null) {
set.addAll(container.getTransientCacheHandler().getAllCoreNames());
if (getTransientCacheHandler() != null) {
set.addAll(getTransientCacheHandler().getAllCoreNames());
}
set.addAll(residentDesciptors.keySet());
}
@ -302,7 +299,7 @@ class SolrCores implements Observer {
SolrCore ret = cores.remove(name);
// It could have been a newly-created core. It could have been a transient core. The newly-created cores
// in particular should be checked. It could have been a dynamic core.
TransientSolrCoreCache transientHandler = container.getTransientCacheHandler();
TransientSolrCoreCache transientHandler = getTransientCacheHandler();
if (ret == null && transientHandler != null) {
ret = transientHandler.removeCore(name);
}
@ -315,8 +312,8 @@ class SolrCores implements Observer {
synchronized (modifyLock) {
SolrCore core = cores.get(name);
if (core == null && container.getTransientCacheHandler() != null) {
core = container.getTransientCacheHandler().getCore(name);
if (core == null && getTransientCacheHandler() != null) {
core = getTransientCacheHandler().getCore(name);
}
if (core != null && incRefCount) {
@ -336,7 +333,7 @@ class SolrCores implements Observer {
if (cores.containsKey(name)) {
return true;
}
if (container.getTransientCacheHandler() != null && container.getTransientCacheHandler().containsCore(name)) {
if (getTransientCacheHandler() != null && getTransientCacheHandler().containsCore(name)) {
// Check pending
for (SolrCore core : pendingCloses) {
if (core.getName().equals(name)) {
@ -355,7 +352,7 @@ class SolrCores implements Observer {
if (cores.containsKey(name)) {
return true;
}
if (container.getTransientCacheHandler() != null && container.getTransientCacheHandler().containsCore(name)) {
if (getTransientCacheHandler() != null && getTransientCacheHandler().containsCore(name)) {
return true;
}
}
@ -367,8 +364,8 @@ class SolrCores implements Observer {
synchronized (modifyLock) {
CoreDescriptor desc = residentDesciptors.get(cname);
if (desc == null) {
if (container.getTransientCacheHandler() == null) return null;
desc = container.getTransientCacheHandler().getTransientDescriptor(cname);
if (getTransientCacheHandler() == null) return null;
desc = getTransientCacheHandler().getTransientDescriptor(cname);
if (desc == null) {
return null;
}
@ -456,7 +453,7 @@ class SolrCores implements Observer {
synchronized (modifyLock) {
if (residentDesciptors.containsKey(coreName))
return residentDesciptors.get(coreName);
return container.getTransientCacheHandler().getTransientDescriptor(coreName);
return getTransientCacheHandler().getTransientDescriptor(coreName);
}
}
@ -545,4 +542,16 @@ class SolrCores implements Observer {
modifyLock.notifyAll(); // Wakes up closer thread too
}
}
public TransientSolrCoreCache getTransientCacheHandler() {
if (transientCoreCache == null) {
log.error("No transient handler has been defined. Check solr.xml to see if an attempt to provide a custom " +
"TransientSolrCoreCacheFactory was done incorrectly since the default should have been used otherwise.");
return null;
}
return transientCoreCache.getTransientSolrCoreCache();
}
}

View File

@ -105,7 +105,6 @@ public class SolrResourceLoader implements ResourceLoader,Closeable
private final List<ResourceLoaderAware> waitingForResources = Collections.synchronizedList(new ArrayList<ResourceLoaderAware>());
private static final Charset UTF_8 = StandardCharsets.UTF_8;
//TODO: Solr5. Remove this completely when you obsolete putting <core> tags in solr.xml (See Solr-4196)
private final Properties coreProperties;
private volatile boolean live;

View File

@ -535,9 +535,8 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
}
private void testStopAndStartCoresInOneInstance() throws Exception {
SolrClient client = clients.get(0);
String url3 = getBaseUrl(client);
try (final HttpSolrClient httpSolrClient = getHttpSolrClient(url3)) {
JettySolrRunner jetty = jettys.get(0);
try (final HttpSolrClient httpSolrClient = (HttpSolrClient) jetty.newClient()) {
httpSolrClient.setConnectionTimeout(15000);
httpSolrClient.setSoTimeout(60000);
ThreadPoolExecutor executor = null;
@ -548,7 +547,7 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
int cnt = 3;
// create the cores
createCores(httpSolrClient, executor, "multiunload2", 1, cnt);
createCollectionInOneInstance(httpSolrClient, jetty.getNodeName(), executor, "multiunload2", 1, cnt);
} finally {
if (executor != null) {
ExecutorUtil.shutdownAndAwaitTermination(executor);
@ -573,8 +572,13 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
}
protected void createCores(final HttpSolrClient client,
ThreadPoolExecutor executor, final String collection, final int numShards, int cnt) {
/**
* Create a collection in single node
*/
protected void createCollectionInOneInstance(final SolrClient client, String nodeName,
ThreadPoolExecutor executor, final String collection,
final int numShards, int numReplicas) {
assertNotNull(nodeName);
try {
assertEquals(0, CollectionAdminRequest.createCollection(collection, "conf1", numShards, 1)
.setCreateNodeSet("")
@ -582,22 +586,13 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
} catch (SolrServerException | IOException e) {
throw new RuntimeException(e);
}
String nodeName = null;
for (JettySolrRunner jetty : jettys) {
if (client.getBaseURL().contains(":"+jetty.getLocalPort())) {
nodeName = jetty.getNodeName();
break;
}
}
assertNotNull(nodeName);
for (int i = 0; i < cnt; i++) {
for (int i = 0; i < numReplicas; i++) {
final int freezeI = i;
final String freezeNodename = nodeName;
executor.execute(() -> {
try {
assertTrue(CollectionAdminRequest.addReplicaToShard(collection, "shard"+((freezeI%numShards)+1))
.setCoreName(collection + freezeI)
.setNode(freezeNodename).process(client).isSuccess());
.setNode(nodeName).process(client).isSuccess());
} catch (SolrServerException | IOException e) {
throw new RuntimeException(e);
}

View File

@ -18,7 +18,6 @@ package org.apache.solr.cloud;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
@ -348,18 +347,17 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest {
}
private void testUnloadLotsOfCores() throws Exception {
SolrClient client = clients.get(2);
String url3 = getBaseUrl(client);
try (final HttpSolrClient adminClient = getHttpSolrClient(url3)) {
JettySolrRunner jetty = jettys.get(0);
try (final HttpSolrClient adminClient = (HttpSolrClient) jetty.newClient()) {
adminClient.setConnectionTimeout(15000);
adminClient.setSoTimeout(60000);
int cnt = atLeast(3);
int numReplicas = atLeast(3);
ThreadPoolExecutor executor = new ExecutorUtil.MDCAwareThreadPoolExecutor(0, Integer.MAX_VALUE,
5, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
new DefaultSolrThreadFactory("testExecutor"));
try {
// create the cores
createCores(adminClient, executor, "multiunload", 2, cnt);
createCollectionInOneInstance(adminClient, jetty.getNodeName(), executor, "multiunload", 2, numReplicas);
} finally {
ExecutorUtil.shutdownAndAwaitTermination(executor);
}
@ -368,7 +366,7 @@ public class UnloadDistributedZkTest extends BasicDistributedZkTest {
TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
new DefaultSolrThreadFactory("testExecutor"));
try {
for (int j = 0; j < cnt; j++) {
for (int j = 0; j < numReplicas; j++) {
final int freezeJ = j;
executor.execute(() -> {
Unload unloadCmd = new Unload(true);

View File

@ -30,7 +30,6 @@ import org.apache.solr.core.CloudConfig;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrXmlConfig;
import org.apache.solr.core.TransientSolrCoreCache;
import org.apache.solr.handler.admin.CoreAdminHandler;
import org.apache.solr.handler.component.HttpShardHandlerFactory;
import org.apache.solr.update.UpdateShardHandler;
@ -328,30 +327,26 @@ public class ZkControllerTest extends SolrTestCaseJ4 {
private static class MockCoreContainer extends CoreContainer {
UpdateShardHandler updateShardHandler = new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT);
public MockCoreContainer() {
super(SolrXmlConfig.fromString(null, "<solr/>"));
this.shardHandlerFactory = new HttpShardHandlerFactory();
this.coreAdminHandler = new CoreAdminHandler();
}
@Override
public void load() {}
public void load() {
}
@Override
public UpdateShardHandler getUpdateShardHandler() {
return updateShardHandler;
}
@Override
public void shutdown() {
updateShardHandler.close();
super.shutdown();
}
@Override
public TransientSolrCoreCache getTransientCacheHandler() {
return transientSolrCoreCache;
}
}
}
}

View File

@ -22,6 +22,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Properties;
import com.google.common.collect.ImmutableMap;
@ -152,7 +153,7 @@ public class TestCoreDiscovery extends SolrTestCaseJ4 {
try {
TestLazyCores.checkInCores(cc, "core1");
TestLazyCores.checkNotInCores(cc, "lazy1", "core2");
TestLazyCores.checkNotInCores(cc, Arrays.asList("lazy1", "core2"));
// force loading of core2 and lazy1 by getting them from the CoreContainer
try (SolrCore core1 = cc.getCore("core1");

View File

@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -100,8 +101,8 @@ public class TestLazyCores extends SolrTestCaseJ4 {
// NOTE: This checks the initial state for loading, no need to do this elsewhere.
checkInCores(cc, "collection1", "collection2", "collection5");
checkNotInCores(cc, "collection3", "collection4", "collection6", "collection7",
"collection8", "collection9");
checkNotInCores(cc, Arrays.asList("collection3", "collection4", "collection6", "collection7",
"collection8", "collection9"));
SolrCore core1 = cc.getCore("collection1");
assertFalse("core1 should not be transient", core1.getCoreDescriptor().isTransient());
@ -176,7 +177,7 @@ public class TestLazyCores extends SolrTestCaseJ4 {
CoreContainer cc = init();
try {
// Make sure Lazy4 isn't loaded. Should be loaded on the get
checkNotInCores(cc, "collection4");
checkNotInCores(cc, Arrays.asList("collection4"));
SolrCore core4 = cc.getCore("collection4");
checkSearch(core4);
@ -205,7 +206,7 @@ public class TestLazyCores extends SolrTestCaseJ4 {
// First check that all the cores that should be loaded at startup actually are.
checkInCores(cc, "collection1", "collection2", "collection5");
checkNotInCores(cc, "collection3", "collection4", "collection6", "collection7", "collection8", "collection9");
checkNotInCores(cc, Arrays.asList("collection3", "collection4", "collection6", "collection7", "collection8", "collection9"));
// By putting these in non-alpha order, we're also checking that we're not just seeing an artifact.
SolrCore core1 = cc.getCore("collection1");
@ -215,28 +216,28 @@ public class TestLazyCores extends SolrTestCaseJ4 {
SolrCore core5 = cc.getCore("collection5");
checkInCores(cc, "collection1", "collection2", "collection3", "collection4", "collection5");
checkNotInCores(cc, "collection6", "collection7", "collection8", "collection9");
checkNotInCores(cc, Arrays.asList("collection6", "collection7", "collection8", "collection9"));
// map should be full up, add one more and verify
SolrCore core6 = cc.getCore("collection6");
checkInCores(cc, "collection1", "collection2", "collection3", "collection4", "collection5",
"collection6");
checkNotInCores(cc, "collection7", "collection8", "collection9");
checkNotInCores(cc, Arrays.asList("collection7", "collection8", "collection9"));
SolrCore core7 = cc.getCore("collection7");
checkInCores(cc, "collection1", "collection2", "collection3", "collection4", "collection5",
"collection6", "collection7");
checkNotInCores(cc, "collection8", "collection9");
checkNotInCores(cc, Arrays.asList("collection8", "collection9"));
SolrCore core8 = cc.getCore("collection8");
checkInCores(cc, "collection1", "collection2", "collection4", "collection5", "collection6",
"collection7", "collection8");
checkNotInCores(cc, "collection3", "collection9");
checkNotInCores(cc, Arrays.asList("collection3", "collection9"));
SolrCore core9 = cc.getCore("collection9");
checkInCores(cc, "collection1", "collection4", "collection5", "collection6", "collection7",
"collection8", "collection9");
checkNotInCores(cc, "collection2", "collection3");
checkNotInCores(cc, Arrays.asList("collection2", "collection3"));
// Note decrementing the count when the core is removed from the lazyCores list is appropriate, since the
@ -396,8 +397,8 @@ public class TestLazyCores extends SolrTestCaseJ4 {
final SolrCore c4 = cc.getCore("core4");
final SolrCore c5 = cc.getCore("core5");
checkNotInCores(cc, "core1", "collection2", "collection3", "collection4", "collection6"
, "collection7", "collection8", "collection9");
checkNotInCores(cc, Arrays.asList("core1", "collection2", "collection3", "collection4", "collection6"
, "collection7", "collection8", "collection9"));
checkInCores(cc, "collection1", "collection5", "core2", "core3", "core4", "core5");
@ -467,7 +468,7 @@ public class TestLazyCores extends SolrTestCaseJ4 {
checkInCores(cc, "core1", "core2");
// Did the bad cores fail to load?
checkNotInCores(cc, "badSchema1", "badSchema2", "badConfig1", "badConfig2");
checkNotInCores(cc, Collections.emptyList(), Arrays.asList("badSchema1", "badSchema2", "badConfig1", "badConfig2"));
// Can we still search the "good" cores even though there were core init failures?
SolrCore core1 = cc.getCore("core1");
@ -644,7 +645,10 @@ public class TestLazyCores extends SolrTestCaseJ4 {
}
}
public static void checkNotInCores(CoreContainer cc, String... nameCheck) {
public static void checkNotInCores(CoreContainer cc, List<String> nameCheck) {
checkNotInCores(cc, nameCheck, Collections.emptyList());
}
public static void checkNotInCores(CoreContainer cc, List<String> nameCheck, List<String> namesBad) {
Collection<String> loadedNames = cc.getLoadedCoreNames();
for (String name : nameCheck) {
assertFalse("core " + name + " was found in the list of cores", loadedNames.contains(name));
@ -657,7 +661,7 @@ public class TestLazyCores extends SolrTestCaseJ4 {
// the names in nameCheck should be loaded and thus should not be in names.
Collection<String> allNames = cc.getAllCoreNames();
// Every core, loaded or not should be in the accumulated coredescriptors:
// Every core that has not failed to load should be in coreDescriptors.
List<CoreDescriptor> descriptors = cc.getCoreDescriptors();
assertEquals("There should be as many coreDescriptors as coreNames", allNames.size(), descriptors.size());
@ -671,10 +675,18 @@ public class TestLazyCores extends SolrTestCaseJ4 {
allNames.contains(name));
}
// failed cores should have had their descriptors removed.
for (String name : nameCheck) {
assertTrue("Not-currently-loaded core " + name + " should have been found in the list of all possible core names",
allNames.contains(name));
}
// Failed cores should not be in coreDescriptors.
for (String name : namesBad) {
assertFalse("Failed core " + name + " should have been found in the list of all possible core names",
allNames.contains(name));
}
}
public static void checkInCores(CoreContainer cc, String... nameCheck) {
@ -795,7 +807,7 @@ public class TestLazyCores extends SolrTestCaseJ4 {
}
// Just proving that some cores have been aged out.
checkNotInCores(cc, "collection2", "collection3");
checkNotInCores(cc, Arrays.asList("collection2", "collection3"));
// Close our get of all cores above.
for (SolrCore core : openCores) core.close();
@ -807,7 +819,7 @@ public class TestLazyCores extends SolrTestCaseJ4 {
for (String coreName : coreList) {
// The point of this test is to insure that when cores are aged out and re-opened
// that the docs are there, so insure that the core we're testing is gone, gone, gone.
checkNotInCores(cc, coreName);
checkNotInCores(cc, Arrays.asList(coreName));
// Load the core up again.
SolrCore core = cc.getCore(coreName);