reformatting

This commit is contained in:
Noble Paul 2019-06-25 17:02:17 +10:00
parent 4589bbe47b
commit 742c80550c
8 changed files with 716 additions and 639 deletions

View File

@ -89,6 +89,7 @@ public class BlobRepository {
} }
// I wanted to {@link SolrCore#loadDecodeAndCacheBlob(String, Decoder)} below but precommit complains // I wanted to {@link SolrCore#loadDecodeAndCacheBlob(String, Decoder)} below but precommit complains
/** /**
* Returns the contents of a blob containing a ByteBuffer and increments a reference count. Please return the * Returns the contents of a blob containing a ByteBuffer and increments a reference count. Please return the
* same object to decrease the refcount. This is normally used for storing jar files, and binary raw data. * same object to decrease the refcount. This is normally used for storing jar files, and binary raw data.
@ -164,6 +165,7 @@ public class BlobRepository {
blobs.put(keyPlusName, aBlob); blobs.put(keyPlusName, aBlob);
return aBlob; return aBlob;
} }
static String INVALID_JAR_MSG = "Invalid jar from {0} , expected sha512 hash : {1} , actual : {2}"; static String INVALID_JAR_MSG = "Invalid jar from {0} , expected sha512 hash : {1} , actual : {2}";
private ByteBuffer fetchBlobAndVerify(String key, String url, String sha512) { private ByteBuffer fetchBlobAndVerify(String key, String url, String sha512) {
@ -234,9 +236,11 @@ public class BlobRepository {
ZkStateReader zkStateReader = this.coreContainer.getZkController().getZkStateReader(); ZkStateReader zkStateReader = this.coreContainer.getZkController().getZkStateReader();
ClusterState cs = zkStateReader.getClusterState(); ClusterState cs = zkStateReader.getClusterState();
DocCollection coll = cs.getCollectionOrNull(CollectionAdminParams.SYSTEM_COLL); DocCollection coll = cs.getCollectionOrNull(CollectionAdminParams.SYSTEM_COLL);
if (coll == null) throw new SolrException(SERVICE_UNAVAILABLE, CollectionAdminParams.SYSTEM_COLL + " collection not available"); if (coll == null)
throw new SolrException(SERVICE_UNAVAILABLE, CollectionAdminParams.SYSTEM_COLL + " collection not available");
ArrayList<Slice> slices = new ArrayList<>(coll.getActiveSlices()); ArrayList<Slice> slices = new ArrayList<>(coll.getActiveSlices());
if (slices.isEmpty()) throw new SolrException(SERVICE_UNAVAILABLE, "No active slices for " + CollectionAdminParams.SYSTEM_COLL + " collection"); if (slices.isEmpty())
throw new SolrException(SERVICE_UNAVAILABLE, "No active slices for " + CollectionAdminParams.SYSTEM_COLL + " collection");
Collections.shuffle(slices, RANDOM); //do load balancing Collections.shuffle(slices, RANDOM); //do load balancing
Replica replica = null; Replica replica = null;
@ -313,7 +317,9 @@ public class BlobRepository {
* *
* @return The name of the decoding, defaults to empty string. * @return The name of the decoding, defaults to empty string.
*/ */
default String getName() { return ""; } default String getName() {
return "";
}
/** /**
* A routine that knows how to convert the stream of bytes from the blob into a Java object. * A routine that knows how to convert the stream of bytes from the blob into a Java object.

View File

@ -44,9 +44,8 @@ import org.slf4j.LoggerFactory;
* A {@link DirectoryFactory} impl base class for caching Directory instances * A {@link DirectoryFactory} impl base class for caching Directory instances
* per path. Most DirectoryFactory implementations will want to extend this * per path. Most DirectoryFactory implementations will want to extend this
* class and simply implement {@link DirectoryFactory#create(String, LockFactory, DirContext)}. * class and simply implement {@link DirectoryFactory#create(String, LockFactory, DirContext)}.
* * <p>
* This is an expert class and these API's are subject to change. * This is an expert class and these API's are subject to change.
*
*/ */
public abstract class CachingDirectoryFactory extends DirectoryFactory { public abstract class CachingDirectoryFactory extends DirectoryFactory {
protected static class CacheValue { protected static class CacheValue {
@ -64,6 +63,7 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
// for debug // for debug
// this.originTrace = new RuntimeException("Originated from:"); // this.originTrace = new RuntimeException("Originated from:");
} }
public int refCnt = 1; public int refCnt = 1;
// has doneWithDirectory(Directory) been called on this? // has doneWithDirectory(Directory) been called on this?
public boolean closeCacheValueCalled = false; public boolean closeCacheValueCalled = false;
@ -493,8 +493,8 @@ public abstract class CachingDirectoryFactory extends DirectoryFactory {
/** /**
* Method for inspecting the cache * Method for inspecting the cache
* @return paths in the cache which have not been marked "done"
* *
* @return paths in the cache which have not been marked "done"
* @see #doneWithDirectory * @see #doneWithDirectory
*/ */
public synchronized Set<String> getLivePaths() { public synchronized Set<String> getLivePaths() {

View File

@ -134,7 +134,6 @@ import static org.apache.solr.core.CorePropertiesLocator.PROPERTIES_FILENAME;
import static org.apache.solr.security.AuthenticationPlugin.AUTHENTICATION_PLUGIN_PROP; import static org.apache.solr.security.AuthenticationPlugin.AUTHENTICATION_PLUGIN_PROP;
/** /**
*
* @since solr 1.3 * @since solr 1.3
*/ */
public class CoreContainer { public class CoreContainer {
@ -268,6 +267,7 @@ public class CoreContainer {
/** /**
* Create a new CoreContainer using system properties to detect the solr home * Create a new CoreContainer using system properties to detect the solr home
* directory. The container's cores are not loaded. * directory. The container's cores are not loaded.
*
* @see #load() * @see #load()
*/ */
public CoreContainer() { public CoreContainer() {
@ -277,6 +277,7 @@ public class CoreContainer {
/** /**
* Create a new CoreContainer using the given SolrResourceLoader. The container's * Create a new CoreContainer using the given SolrResourceLoader. The container's
* cores are not loaded. * cores are not loaded.
*
* @param loader the SolrResourceLoader * @param loader the SolrResourceLoader
* @see #load() * @see #load()
*/ */
@ -287,6 +288,7 @@ public class CoreContainer {
/** /**
* Create a new CoreContainer using the given solr home directory. The container's * Create a new CoreContainer using the given solr home directory. The container's
* cores are not loaded. * cores are not loaded.
*
* @param solrHome a String containing the path to the solr home directory * @param solrHome a String containing the path to the solr home directory
* @see #load() * @see #load()
*/ */
@ -298,6 +300,7 @@ public class CoreContainer {
* Create a new CoreContainer using the given SolrResourceLoader, * Create a new CoreContainer using the given SolrResourceLoader,
* configuration and CoresLocator. The container's cores are * configuration and CoresLocator. The container's cores are
* not loaded. * not loaded.
*
* @param config a ConfigSolr representation of this container's configuration * @param config a ConfigSolr representation of this container's configuration
* @see #load() * @see #load()
*/ */
@ -529,6 +532,7 @@ public class CoreContainer {
/** /**
* Create a new CoreContainer and load its cores * Create a new CoreContainer and load its cores
*
* @param solrHome the solr home directory * @param solrHome the solr home directory
* @param configFile the file containing this container's configuration * @param configFile the file containing this container's configuration
* @return a loaded CoreContainer * @return a loaded CoreContainer
@ -1078,8 +1082,7 @@ public class CoreContainer {
zkSys.registerInZk(core, false, skipRecovery); zkSys.registerInZk(core, false, skipRecovery);
} }
return null; return null;
} } else {
else {
log.debug("replacing core: " + cd.getName()); log.debug("replacing core: " + cd.getName());
old.close(); old.close();
if (registerInZk) { if (registerInZk) {
@ -1091,6 +1094,7 @@ public class CoreContainer {
/** /**
* Creates a new core, publishing the core state to the cluster * Creates a new core, publishing the core state to the cluster
*
* @param coreName the core name * @param coreName the core name
* @param parameters the core parameters * @param parameters the core parameters
* @return the newly created core * @return the newly created core
@ -1101,6 +1105,7 @@ public class CoreContainer {
/** /**
* Creates a new core in a specified instance directory, publishing the core state to the cluster * Creates a new core in a specified instance directory, publishing the core state to the cluster
*
* @param coreName the core name * @param coreName the core name
* @param instancePath the instance directory * @param instancePath the instance directory
* @param parameters the core parameters * @param parameters the core parameters
@ -1185,7 +1190,7 @@ public class CoreContainer {
* *
* @param dcore a core descriptor * @param dcore a core descriptor
* @param publishState publish core state to the cluster if true * @param publishState publish core state to the cluster if true
* * <p>
* WARNING: Any call to this method should be surrounded by a try/finally block * WARNING: Any call to this method should be surrounded by a try/finally block
* that calls solrCores.waitAddPendingCoreOps(...) and solrCores.removeFromPendingOps(...) * that calls solrCores.waitAddPendingCoreOps(...) and solrCores.removeFromPendingOps(...)
* *
@ -1199,13 +1204,12 @@ public class CoreContainer {
* } * }
* </code> * </code>
* </pre> * </pre>
* * <p>
* Trying to put the waitAddPending... in this method results in Bad Things Happening due to race conditions. * Trying to put the waitAddPending... in this method results in Bad Things Happening due to race conditions.
* getCore() depends on getting the core returned _if_ it's in the pending list due to some other thread opening it. * getCore() depends on getting the core returned _if_ it's in the pending list due to some other thread opening it.
* If the core is not in the pending list and not loaded, then getCore() calls this method. Anything that called * If the core is not in the pending list and not loaded, then getCore() calls this method. Anything that called
* to check if the core was loaded _or_ in pending ops and, based on the return called createFromDescriptor would * to check if the core was loaded _or_ in pending ops and, based on the return called createFromDescriptor would
* introduce a race condition, see getCore() for the place it would be a problem * introduce a race condition, see getCore() for the place it would be a problem
*
* @return the newly created core * @return the newly created core
*/ */
@SuppressWarnings("resource") @SuppressWarnings("resource")
@ -1283,18 +1287,13 @@ public class CoreContainer {
* Take action when we failed to create a SolrCore. If error is due to corrupt index, try to recover. Various recovery * Take action when we failed to create a SolrCore. If error is due to corrupt index, try to recover. Various recovery
* strategies can be specified via system properties "-DCoreInitFailedAction={fromleader, none}" * strategies can be specified via system properties "-DCoreInitFailedAction={fromleader, none}"
* *
* @see CoreInitFailedAction * @param original the problem seen when loading the core the first time.
* * @param dcore core descriptor for the core to create
* @param original * @param coreConfig core config for the core to create
* the problem seen when loading the core the first time.
* @param dcore
* core descriptor for the core to create
* @param coreConfig
* core config for the core to create
* @return if possible * @return if possible
* @throws SolrException * @throws SolrException rethrows the original exception if we will not attempt to recover, throws a new SolrException with the
* rethrows the original exception if we will not attempt to recover, throws a new SolrException with the
* original exception as a suppressed exception if there is a second problem creating the solr core. * original exception as a suppressed exception if there is a second problem creating the solr core.
* @see CoreInitFailedAction
*/ */
private SolrCore processCoreCreateException(SolrException original, CoreDescriptor dcore, ConfigSet coreConfig) { private SolrCore processCoreCreateException(SolrException original, CoreDescriptor dcore, ConfigSet coreConfig) {
// Traverse full chain since CIE may not be root exception // Traverse full chain since CIE may not be root exception
@ -1382,16 +1381,16 @@ public class CoreContainer {
* Gets the cores that are currently loaded, i.e. cores that have * 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 * 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. * 2: loadOnStartup=false and have been loaded but are either non-transient or have not been aged out.
* * <p>
* Put another way, this will not return any names of cores that are lazily loaded but have not been called for yet * 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. * or are transient and either not loaded or have been swapped out.
*
*/ */
public Collection<String> getLoadedCoreNames() { public Collection<String> getLoadedCoreNames() {
return solrCores.getLoadedCoreNames(); return solrCores.getLoadedCoreNames();
} }
/** This method is currently experimental. /**
* This method is currently experimental.
* *
* @return a Collection of the names that a specific core object is mapped to, there are more than one. * @return a Collection of the names that a specific core object is mapped to, there are more than one.
*/ */
@ -1401,8 +1400,8 @@ public class CoreContainer {
/** /**
* get a list of all the cores that are currently known, whether currently loaded or not * 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
* *
* @return a list of all the available core names in either permanent or transient cores
*/ */
public Collection<String> getAllCoreNames() { public Collection<String> getAllCoreNames() {
return solrCores.getAllCoreNames(); return solrCores.getAllCoreNames();
@ -1576,6 +1575,7 @@ public class CoreContainer {
/** /**
* Unload a core from this container, leaving all files on disk * Unload a core from this container, leaving all files on disk
*
* @param name the name of the core to unload * @param name the name of the core to unload
*/ */
public void unload(String name) { public void unload(String name) {
@ -1680,6 +1680,7 @@ public class CoreContainer {
/** /**
* Get the CoreDescriptors for all cores managed by this container * Get the CoreDescriptors for all cores managed by this container
*
* @return a List of CoreDescriptors * @return a List of CoreDescriptors
*/ */
public List<CoreDescriptor> getCoreDescriptors() { public List<CoreDescriptor> getCoreDescriptors() {
@ -1697,10 +1698,10 @@ public class CoreContainer {
/** /**
* Gets a core by name and increase its refcount. * Gets a core by name and increase its refcount.
* *
* @see SolrCore#close()
* @param name the core name * @param name the core name
* @return the core if found, null if a SolrCore by this name does not exist * @return the core if found, null if a SolrCore by this name does not exist
* @exception SolrCoreInitializationException if a SolrCore with this name failed to be initialized * @throws SolrCoreInitializationException if a SolrCore with this name failed to be initialized
* @see SolrCore#close()
*/ */
public SolrCore getCore(String name) { public SolrCore getCore(String name) {
@ -1742,8 +1743,7 @@ public class CoreContainer {
core = createFromDescriptor(desc, true, false); // This should throw an error if it fails. core = createFromDescriptor(desc, true, false); // This should throw an error if it fails.
} }
core.open(); core.open();
} } finally {
finally {
solrCores.removeFromPendingOps(name); solrCores.removeFromPendingOps(name);
} }
@ -1789,7 +1789,9 @@ public class CoreContainer {
return collectionsHandler; return collectionsHandler;
} }
public HealthCheckHandler getHealthCheckHandler() { return healthCheckHandler; } public HealthCheckHandler getHealthCheckHandler() {
return healthCheckHandler;
}
public InfoHandler getInfoHandler() { public InfoHandler getInfoHandler() {
return infoHandler; return infoHandler;
@ -1820,7 +1822,6 @@ public class CoreContainer {
/** /**
* Determines whether the core is already loaded or not but does NOT load the core * Determines whether the core is already loaded or not but does NOT load the core
*
*/ */
public boolean isLoaded(String name) { public boolean isLoaded(String name) {
return solrCores.isLoaded(name); return solrCores.isLoaded(name);
@ -1834,6 +1835,7 @@ public class CoreContainer {
public void queueCoreToClose(SolrCore coreToClose) { public void queueCoreToClose(SolrCore coreToClose) {
solrCores.queueCoreToClose(coreToClose); solrCores.queueCoreToClose(coreToClose);
} }
/** /**
* Gets a solr core descriptor for a core that is not loaded. Note that if the caller calls this on a * Gets a solr core descriptor for a core that is not loaded. Note that if the caller calls this on a
* loaded core, the unloaded descriptor will be returned. * loaded core, the unloaded descriptor will be returned.
@ -1861,7 +1863,9 @@ public class CoreContainer {
return cfg; return cfg;
} }
/** The default ShardHandlerFactory used to communicate with other solr instances */ /**
* The default ShardHandlerFactory used to communicate with other solr instances
*/
public ShardHandlerFactory getShardHandlerFactory() { public ShardHandlerFactory getShardHandlerFactory() {
return shardHandlerFactory; return shardHandlerFactory;
} }
@ -1905,11 +1909,10 @@ public class CoreContainer {
/** /**
*
* @param cd CoreDescriptor, presumably a deficient one * @param cd CoreDescriptor, presumably a deficient one
* @param prop The property that needs to be repaired. * @param prop The property that needs to be repaired.
* @return true if we were able to successfuly perisist the repaired coreDescriptor, false otherwise. * @return true if we were able to successfuly perisist the repaired coreDescriptor, false otherwise.
* * <p>
* See SOLR-11503, This can be removed when there's no chance we'll need to upgrade a * See SOLR-11503, This can be removed when there's no chance we'll need to upgrade a
* Solr installation created with legacyCloud=true from 6.6.1 through 7.1 * Solr installation created with legacyCloud=true from 6.6.1 through 7.1
*/ */

View File

@ -243,7 +243,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
return metricNames; return metricNames;
} }
public Date getStartTimeStamp() { return startTime; } public Date getStartTimeStamp() {
return startTime;
}
private final Map<IndexReader.CacheKey, IndexFingerprint> perSegmentFingerprintCache = new MapMaker().weakKeys().makeMap(); private final Map<IndexReader.CacheKey, IndexFingerprint> perSegmentFingerprintCache = new MapMaker().weakKeys().makeMap();
@ -267,6 +269,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* The SolrResourceLoader used to load all resources for this core. * The SolrResourceLoader used to load all resources for this core.
*
* @since solr 1.3 * @since solr 1.3
*/ */
public SolrResourceLoader getResourceLoader() { public SolrResourceLoader getResourceLoader() {
@ -275,6 +278,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Gets the configuration resource name used by this core instance. * Gets the configuration resource name used by this core instance.
*
* @since solr 1.3 * @since solr 1.3
*/ */
public String getConfigResource() { public String getConfigResource() {
@ -290,6 +294,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Gets the schema resource name used by this core instance. * Gets the schema resource name used by this core instance.
*
* @since solr 1.3 * @since solr 1.3
*/ */
public String getSchemaResource() { public String getSchemaResource() {
@ -309,6 +314,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* If the specified <code>replacementSchema</code> uses a {@link SimilarityFactory} which is * If the specified <code>replacementSchema</code> uses a {@link SimilarityFactory} which is
* {@link SolrCoreAware} then this method will {@link SolrCoreAware#inform} that factory about * {@link SolrCoreAware} then this method will {@link SolrCoreAware#inform} that factory about
* this SolrCore prior to using the <code>replacementSchema</code> * this SolrCore prior to using the <code>replacementSchema</code>
*
* @see #getLatestSchema * @see #getLatestSchema
*/ */
public void setLatestSchema(IndexSchema replacementSchema) { public void setLatestSchema(IndexSchema replacementSchema) {
@ -355,7 +361,6 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* and indexwriters. Use the getIndexDir() method to know the active index directory * and indexwriters. Use the getIndexDir() method to know the active index directory
* *
* @return the indexdir as given in index.properties * @return the indexdir as given in index.properties
*
* @throws SolrException if for any reason the a reasonable index directory cannot be determined. * @throws SolrException if for any reason the a reasonable index directory cannot be determined.
*/ */
public String getNewIndexDir() { public String getNewIndexDir() {
@ -462,8 +467,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
} }
public String getLogId() public String getLogId() {
{
return this.logid; return this.logid;
} }
@ -622,8 +626,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* *
* @see SolrCoreAware * @see SolrCoreAware
*/ */
public void registerFirstSearcherListener( SolrEventListener listener ) public void registerFirstSearcherListener(SolrEventListener listener) {
{
firstSearcherListeners.add(listener); firstSearcherListeners.add(listener);
} }
@ -634,8 +637,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* *
* @see SolrCoreAware * @see SolrCoreAware
*/ */
public void registerNewSearcherListener( SolrEventListener listener ) public void registerNewSearcherListener(SolrEventListener listener) {
{
newSearcherListeners.add(listener); newSearcherListeners.add(listener);
} }
@ -724,6 +726,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Returns <code>true</code> iff the index in the named directory is * Returns <code>true</code> iff the index in the named directory is
* currently locked. * currently locked.
*
* @param directory the directory to check for a lock * @param directory the directory to check for a lock
* @throws IOException if there is a low-level IO error * @throws IOException if there is a low-level IO error
* @deprecated Use of this method can only lead to race conditions. Try * @deprecated Use of this method can only lead to race conditions. Try
@ -889,13 +892,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* Creates a new core and register it in the list of cores. If a core with the * Creates a new core and register it in the list of cores. If a core with the
* same name already exists, it will be stopped and replaced by this one. * same name already exists, it will be stopped and replaced by this one.
* *
* @param dataDir * @param dataDir the index directory
* the index directory * @param config a solr config instance
* @param config * @param schema a solr schema instance
* a solr config instance
* @param schema
* a solr schema instance
*
* @since solr 1.3 * @since solr 1.3
*/ */
public SolrCore(CoreContainer coreContainer, String name, String dataDir, SolrConfig config, public SolrCore(CoreContainer coreContainer, String name, String dataDir, SolrConfig config,
@ -1078,7 +1077,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
} }
/** Set UpdateLog to buffer updates if the slice is in construction. */ /**
* Set UpdateLog to buffer updates if the slice is in construction.
*/
private void bufferUpdatesIfConstructing(CoreDescriptor coreDescriptor) { private void bufferUpdatesIfConstructing(CoreDescriptor coreDescriptor) {
if (coreContainer != null && coreContainer.isZooKeeperAware()) { if (coreContainer != null && coreContainer.isZooKeeperAware()) {
@ -1142,6 +1143,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Initializes the "Latest Schema" for this SolrCore using either the provided <code>schema</code> * Initializes the "Latest Schema" for this SolrCore using either the provided <code>schema</code>
* if non-null, or a new instance build via the factory identified in the specified <code>config</code> * if non-null, or a new instance build via the factory identified in the specified <code>config</code>
*
* @see IndexSchemaFactory * @see IndexSchemaFactory
* @see #setLatestSchema * @see #setLatestSchema
*/ */
@ -1248,18 +1250,13 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Locate the data directory for a given config and core descriptor. * Locate the data directory for a given config and core descriptor.
* *
* @param directoryFactory * @param directoryFactory The directory factory to use if necessary to calculate an absolute path. Should be the same as what will
* The directory factory to use if necessary to calculate an absolute path. Should be the same as what will
* be used to open the data directory later. * be used to open the data directory later.
* @param dataDir * @param dataDir An optional hint to the data directory location. Will be normalized and used if not null.
* An optional hint to the data directory location. Will be normalized and used if not null. * @param config A solr config to retrieve the default data directory location, if used.
* @param config * @param coreDescriptor descriptor to load the actual data dir from, if not using the defualt.
* A solr config to retrieve the default data directory location, if used.
* @param coreDescriptor
* descriptor to load the actual data dir from, if not using the defualt.
* @return a normalized data directory name * @return a normalized data directory name
* @throws SolrException * @throws SolrException if the data directory cannot be loaded from the core descriptor
* if the data directory cannot be loaded from the core descriptor
*/ */
static String findDataDir(DirectoryFactory directoryFactory, String dataDir, SolrConfig config, CoreDescriptor coreDescriptor) { static String findDataDir(DirectoryFactory directoryFactory, String dataDir, SolrConfig config, CoreDescriptor coreDescriptor) {
if (dataDir == null) { if (dataDir == null) {
@ -1313,6 +1310,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Write the index.properties file with the new index sub directory name * Write the index.properties file with the new index sub directory name
*
* @param dir a data directory (containing an index.properties file) * @param dir a data directory (containing an index.properties file)
* @param tmpFileName the file name to write the new index.properties to * @param tmpFileName the file name to write the new index.properties to
* @param tmpIdxDirName new index directory name * @param tmpIdxDirName new index directory name
@ -1364,6 +1362,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Close the core, if it is still in use waits until is no longer in use. * Close the core, if it is still in use waits until is no longer in use.
*
* @see #close() * @see #close()
* @see #isClosed() * @see #isClosed()
*/ */
@ -1474,8 +1473,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* @return an update processor registered to the given name. Throw an exception if this chain is undefined * @return an update processor registered to the given name. Throw an exception if this chain is undefined
*/ */
public UpdateRequestProcessorChain getUpdateProcessingChain( final String name ) public UpdateRequestProcessorChain getUpdateProcessingChain(final String name) {
{
UpdateRequestProcessorChain chain = updateProcessorChains.get(name); UpdateRequestProcessorChain chain = updateProcessorChains.get(name);
if (chain == null) { if (chain == null) {
throw new SolrException(ErrorCode.BAD_REQUEST, throw new SolrException(ErrorCode.BAD_REQUEST,
@ -1499,7 +1497,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
// this core current usage count // this core current usage count
private final AtomicInteger refCount = new AtomicInteger(1); private final AtomicInteger refCount = new AtomicInteger(1);
/** expert: increments the core reference count */ /**
* expert: increments the core reference count
*/
public void open() { public void open() {
refCount.incrementAndGet(); refCount.incrementAndGet();
} }
@ -1526,6 +1526,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* is taken. * is taken.
* </li> * </li>
* </ul> * </ul>
*
* @see #isClosed() * @see #isClosed()
*/ */
@Override @Override
@ -1688,12 +1689,16 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
assert ObjectReleaseTracker.release(this); assert ObjectReleaseTracker.release(this);
} }
/** Current core usage count. */ /**
* Current core usage count.
*/
public int getOpenCount() { public int getOpenCount() {
return refCount.get(); return refCount.get();
} }
/** Whether this core is closed. */ /**
* Whether this core is closed.
*/
public boolean isClosed() { public boolean isClosed() {
return refCount.get() <= 0; return refCount.get() <= 0;
} }
@ -1703,17 +1708,18 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Add a close callback hook * Add a close callback hook
*/ */
public void addCloseHook( CloseHook hook ) public void addCloseHook(CloseHook hook) {
{
if (closeHooks == null) { if (closeHooks == null) {
closeHooks = new ArrayList<>(); closeHooks = new ArrayList<>();
} }
closeHooks.add(hook); closeHooks.add(hook);
} }
/** @lucene.internal /**
* Debugging aid only. No non-test code should be released with uncommented verbose() calls. */ * @lucene.internal Debugging aid only. No non-test code should be released with uncommented verbose() calls.
*/
public static boolean VERBOSE = Boolean.parseBoolean(System.getProperty("tests.verbose", "false")); public static boolean VERBOSE = Boolean.parseBoolean(System.getProperty("tests.verbose", "false"));
public static void verbose(Object... args) { public static void verbose(Object... args) {
if (!VERBOSE) return; if (!VERBOSE) return;
StringBuilder sb = new StringBuilder("VERBOSE:"); StringBuilder sb = new StringBuilder("VERBOSE:");
@ -1734,7 +1740,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Get the request handler registered to a given name. * Get the request handler registered to a given name.
* * <p>
* This function is thread safe. * This function is thread safe.
*/ */
public SolrRequestHandler getRequestHandler(String handlerName) { public SolrRequestHandler getRequestHandler(String handlerName) {
@ -1752,17 +1758,17 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Registers a handler at the specified location. If one exists there, it will be replaced. * Registers a handler at the specified location. If one exists there, it will be replaced.
* To remove a handler, register <code>null</code> at its path * To remove a handler, register <code>null</code> at its path
* * <p>
* Once registered the handler can be accessed through: * Once registered the handler can be accessed through:
* <pre> * <pre>
* http://${host}:${port}/${context}/${handlerName} * http://${host}:${port}/${context}/${handlerName}
* or: * or:
* http://${host}:${port}/${context}/select?qt=${handlerName} * http://${host}:${port}/${context}/select?qt=${handlerName}
* </pre> * </pre>
* * <p>
* Handlers <em>must</em> be initialized before getting registered. Registered * Handlers <em>must</em> be initialized before getting registered. Registered
* handlers can immediately accept requests. * handlers can immediately accept requests.
* * <p>
* This call is thread safe. * This call is thread safe.
* *
* @return the previous <code>SolrRequestHandler</code> registered to this name <code>null</code> if none. * @return the previous <code>SolrRequestHandler</code> registered to this name <code>null</code> if none.
@ -1774,8 +1780,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Register the default search components * Register the default search components
*/ */
private void loadSearchComponents() private void loadSearchComponents() {
{
Map<String, SearchComponent> instances = createInstances(SearchComponent.standard_components); Map<String, SearchComponent> instances = createInstances(SearchComponent.standard_components);
for (Map.Entry<String, SearchComponent> e : instances.entrySet()) e.getValue().setName(e.getKey()); for (Map.Entry<String, SearchComponent> e : instances.entrySet()) e.getValue().setName(e.getKey());
searchComponents.init(instances, this); searchComponents.init(instances, this);
@ -1789,6 +1794,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
} }
} }
/** /**
* @return a Search Component registered to a given name. Throw an exception if the component is undefined * @return a Search Component registered to a given name. Throw an exception if the component is undefined
*/ */
@ -1798,6 +1804,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/** /**
* Accessor for all the Search Components * Accessor for all the Search Components
*
* @return An unmodifiable Map of Search Components * @return An unmodifiable Map of Search Components
*/ */
public PluginBag<SearchComponent> getSearchComponents() { public PluginBag<SearchComponent> getSearchComponents() {
@ -1864,6 +1871,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* {@link org.apache.solr.request.SolrQueryRequest#getSearcher()} instead. * {@link org.apache.solr.request.SolrQueryRequest#getSearcher()} instead.
* If you still think you need to call this, consider {@link #withSearcher(IOFunction)} instead which is easier to * If you still think you need to call this, consider {@link #withSearcher(IOFunction)} instead which is easier to
* use. * use.
*
* @see SolrQueryRequest#getSearcher() * @see SolrQueryRequest#getSearcher()
* @see #withSearcher(IOFunction) * @see #withSearcher(IOFunction)
*/ */
@ -1965,7 +1973,8 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
return openNew ? getRealtimeSearcher() : null; return openNew ? getRealtimeSearcher() : null;
} }
/** Gets the latest real-time searcher w/o forcing open a new searcher if one already exists. /**
* Gets the latest real-time searcher w/o forcing open a new searcher if one already exists.
* The reference count will be incremented. * The reference count will be incremented.
*/ */
public RefCounted<SolrIndexSearcher> getRealtimeSearcher() { public RefCounted<SolrIndexSearcher> getRealtimeSearcher() {
@ -2001,15 +2010,16 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
/** Opens a new searcher and returns a RefCounted&lt;SolrIndexSearcher&gt; with its reference incremented. /**
* * Opens a new searcher and returns a RefCounted&lt;SolrIndexSearcher&gt; with its reference incremented.
* <p>
* "realtime" means that we need to open quickly for a realtime view of the index, hence don't do any * "realtime" means that we need to open quickly for a realtime view of the index, hence don't do any
* autowarming and add to the _realtimeSearchers queue rather than the _searchers queue (so it won't * autowarming and add to the _realtimeSearchers queue rather than the _searchers queue (so it won't
* be used for autowarming by a future normal searcher). A "realtime" searcher will currently never * be used for autowarming by a future normal searcher). A "realtime" searcher will currently never
* become "registered" (since it currently lacks caching). * become "registered" (since it currently lacks caching).
* * <p>
* realtimeSearcher is updated to the latest opened searcher, regardless of the value of "realtime". * realtimeSearcher is updated to the latest opened searcher, regardless of the value of "realtime".
* * <p>
* This method acquires openSearcherLock - do not call with searchLock held! * This method acquires openSearcherLock - do not call with searchLock held!
*/ */
public RefCounted<SolrIndexSearcher> openNewSearcher(boolean updateHandlerReopens, boolean realtime) { public RefCounted<SolrIndexSearcher> openNewSearcher(boolean updateHandlerReopens, boolean realtime) {
@ -2141,8 +2151,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} catch (Exception e) { } catch (Exception e) {
throw new SolrException(ErrorCode.SERVER_ERROR, "Error opening new searcher", e); throw new SolrException(ErrorCode.SERVER_ERROR, "Error opening new searcher", e);
} } finally {
finally {
openSearcherLock.unlock(); openSearcherLock.unlock();
if (newestSearcher != null) { if (newestSearcher != null) {
newestSearcher.decref(); newestSearcher.decref();
@ -2184,6 +2193,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
* <tt>null</tt> in which case the SolrIndexSearcher created has already been registered at the time * <tt>null</tt> in which case the SolrIndexSearcher created has already been registered at the time
* this method returned. * this method returned.
* <p> * <p>
*
* @param forceNew if true, force the open of a new index searcher regardless if there is already one open. * @param forceNew if true, force the open of a new index searcher regardless if there is already one open.
* @param returnSearcher if true, returns a {@link SolrIndexSearcher} holder with the refcount already incremented. * @param returnSearcher if true, returns a {@link SolrIndexSearcher} holder with the refcount already incremented.
* @param waitSearcher if non-null, will be filled in with a {@link Future} that will return after the new searcher is registered. * @param waitSearcher if non-null, will be filled in with a {@link Future} that will return after the new searcher is registered.
@ -2394,7 +2404,8 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
timerContext.close(); timerContext.close();
if (!success) { if (!success) {
newSearcherOtherErrorsCounter.inc();; newSearcherOtherErrorsCounter.inc();
;
synchronized (searcherLock) { synchronized (searcherLock) {
onDeckSearchers--; onDeckSearchers--;
@ -2512,7 +2523,6 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
public void closeSearcher() { public void closeSearcher() {
log.debug("{}Closing main searcher on request.", logid); log.debug("{}Closing main searcher on request.", logid);
synchronized (searcherLock) { synchronized (searcherLock) {
@ -2616,7 +2626,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
} }
/** Put status, QTime, and possibly request handler and params, in the response header */ /**
* Put status, QTime, and possibly request handler and params, in the response header
*/
public static void postDecorateResponse public static void postDecorateResponse
(SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp) { (SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp) {
// TODO should check that responseHeader has not been replaced by handler // TODO should check that responseHeader has not been replaced by handler
@ -2669,6 +2681,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
private final PluginBag<QueryResponseWriter> responseWriters = new PluginBag<>(QueryResponseWriter.class, this); private final PluginBag<QueryResponseWriter> responseWriters = new PluginBag<>(QueryResponseWriter.class, this);
public static final Map<String, QueryResponseWriter> DEFAULT_RESPONSE_WRITERS; public static final Map<String, QueryResponseWriter> DEFAULT_RESPONSE_WRITERS;
static { static {
HashMap<String, QueryResponseWriter> m = new HashMap<>(15, 1); HashMap<String, QueryResponseWriter> m = new HashMap<>(15, 1);
m.put("xml", new XMLResponseWriter()); m.put("xml", new XMLResponseWriter());
@ -2727,11 +2740,14 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
default String getContentType() { default String getContentType() {
return BinaryResponseParser.BINARY_CONTENT_TYPE; return BinaryResponseParser.BINARY_CONTENT_TYPE;
} }
void write(OutputStream os) throws IOException; void write(OutputStream os) throws IOException;
} }
/** Configure the query response writers. There will always be a default writer; additional /**
* writers may also be configured. */ * Configure the query response writers. There will always be a default writer; additional
* writers may also be configured.
*/
private void initWriters() { private void initWriters() {
responseWriters.init(DEFAULT_RESPONSE_WRITERS, this); responseWriters.init(DEFAULT_RESPONSE_WRITERS, this);
// configure the default response writer; this one should never be null // configure the default response writer; this one should never be null
@ -2739,12 +2755,15 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
/** Finds a writer by name, or returns the default writer if not found. */ /**
* Finds a writer by name, or returns the default writer if not found.
*/
public final QueryResponseWriter getQueryResponseWriter(String writerName) { public final QueryResponseWriter getQueryResponseWriter(String writerName) {
return responseWriters.get(writerName, true); return responseWriters.get(writerName, true);
} }
/** Returns the appropriate writer for a request. If the request specifies a writer via the /**
* Returns the appropriate writer for a request. If the request specifies a writer via the
* 'wt' parameter, attempts to find that one; otherwise return the default writer. * 'wt' parameter, attempts to find that one; otherwise return the default writer.
*/ */
public final QueryResponseWriter getQueryResponseWriter(SolrQueryRequest request) { public final QueryResponseWriter getQueryResponseWriter(SolrQueryRequest request) {
@ -2816,7 +2835,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
} }
/**For a given List of PluginInfo return the instances as a List /**
* For a given List of PluginInfo return the instances as a List
*
* @param defClassName The default classname if PluginInfo#className == null * @param defClassName The default classname if PluginInfo#className == null
* @return The instances initialized * @return The instances initialized
*/ */
@ -2828,7 +2849,6 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
/** /**
*
* @param registry The map to which the instance should be added to. The key is the name attribute * @param registry The map to which the instance should be added to. The key is the name attribute
* @param type The type of the Plugin. These should be standard ones registered by type.getName() in SolrConfig * @param type The type of the Plugin. These should be standard ones registered by type.getName() in SolrConfig
* @return The default if any * @return The default if any
@ -2977,7 +2997,8 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
} }
/**Register to notify for any file change in the conf directory. /**
* Register to notify for any file change in the conf directory.
* If the file change results in a core reload , then the listener * If the file change results in a core reload , then the listener
* is not fired * is not fired
*/ */
@ -2985,13 +3006,15 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
confListeners.add(runnable); confListeners.add(runnable);
} }
/**Remove a listener /**
* */ * Remove a listener
*/
public boolean removeConfListener(Runnable runnable) { public boolean removeConfListener(Runnable runnable) {
return confListeners.remove(runnable); return confListeners.remove(runnable);
} }
/**This registers one listener for the entire conf directory. In zookeeper /**
* This registers one listener for the entire conf directory. In zookeeper
* there is no event fired when children are modified. So , we expect everyone * there is no event fired when children are modified. So , we expect everyone
* to 'touch' the /conf directory by setting some data so that events are triggered. * to 'touch' the /conf directory by setting some data so that events are triggered.
*/ */

View File

@ -1462,7 +1462,9 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
// These "copy" methods were once SolrParams.getAll but were moved here as there is no universal way that // These "copy" methods were once SolrParams.getAll but were moved here as there is no universal way that
// a SolrParams can be represented in a Map; there are various choices. // a SolrParams can be represented in a Map; there are various choices.
/**Copy all params to the given map or if the given map is null create a new one */ /**
* Copy all params to the given map or if the given map is null create a new one
*/
static Map<String, Object> copy(SolrParams source, Map<String, Object> sink, Collection<String> paramNames) { static Map<String, Object> copy(SolrParams source, Map<String, Object> sink, Collection<String> paramNames) {
if (sink == null) sink = new LinkedHashMap<>(); if (sink == null) sink = new LinkedHashMap<>();
for (String param : paramNames) { for (String param : paramNames) {
@ -1478,7 +1480,9 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
return sink; return sink;
} }
/**Copy all params to the given map or if the given map is null create a new one */ /**
* Copy all params to the given map or if the given map is null create a new one
*/
static Map<String, Object> copy(SolrParams source, Map<String, Object> sink, String... paramNames) { static Map<String, Object> copy(SolrParams source, Map<String, Object> sink, String... paramNames) {
return copy(source, sink, paramNames == null ? Collections.emptyList() : Arrays.asList(paramNames)); return copy(source, sink, paramNames == null ? Collections.emptyList() : Arrays.asList(paramNames));
} }

View File

@ -87,7 +87,9 @@ public class ZkStateReader implements SolrCloseable {
public static final String STATE_PROP = "state"; public static final String STATE_PROP = "state";
// if this flag equals to false and the replica does not exist in cluster state, set state op become no op (default is true) // if this flag equals to false and the replica does not exist in cluster state, set state op become no op (default is true)
public static final String FORCE_SET_STATE_PROP = "force_set_state"; public static final String FORCE_SET_STATE_PROP = "force_set_state";
/** SolrCore name. */ /**
* SolrCore name.
*/
public static final String CORE_NAME_PROP = "core"; public static final String CORE_NAME_PROP = "core";
public static final String COLLECTION_PROP = "collection"; public static final String COLLECTION_PROP = "collection";
public static final String ELECTION_NODE_PROP = "election_node"; public static final String ELECTION_NODE_PROP = "election_node";
@ -147,33 +149,48 @@ public class ZkStateReader implements SolrCloseable {
public static final String REPLICA_TYPE = "type"; public static final String REPLICA_TYPE = "type";
/** A view of the current state of all collections; combines all the different state sources into a single view. */ /**
* A view of the current state of all collections; combines all the different state sources into a single view.
*/
protected volatile ClusterState clusterState; protected volatile ClusterState clusterState;
private static final int GET_LEADER_RETRY_INTERVAL_MS = 50; private static final int GET_LEADER_RETRY_INTERVAL_MS = 50;
private static final int GET_LEADER_RETRY_DEFAULT_TIMEOUT = Integer.parseInt(System.getProperty("zkReaderGetLeaderRetryTimeoutMs", "4000"));; private static final int GET_LEADER_RETRY_DEFAULT_TIMEOUT = Integer.parseInt(System.getProperty("zkReaderGetLeaderRetryTimeoutMs", "4000"));
;
public static final String LEADER_ELECT_ZKNODE = "leader_elect"; public static final String LEADER_ELECT_ZKNODE = "leader_elect";
public static final String SHARD_LEADERS_ZKNODE = "leaders"; public static final String SHARD_LEADERS_ZKNODE = "leaders";
public static final String ELECTION_NODE = "election"; public static final String ELECTION_NODE = "election";
/** Collections tracked in the legacy (shared) state format, reflects the contents of clusterstate.json. */ /**
* Collections tracked in the legacy (shared) state format, reflects the contents of clusterstate.json.
*/
private Map<String, ClusterState.CollectionRef> legacyCollectionStates = emptyMap(); private Map<String, ClusterState.CollectionRef> legacyCollectionStates = emptyMap();
/** Last seen ZK version of clusterstate.json. */ /**
* Last seen ZK version of clusterstate.json.
*/
private int legacyClusterStateVersion = 0; private int legacyClusterStateVersion = 0;
/** Collections with format2 state.json, "interesting" and actively watched. */ /**
* Collections with format2 state.json, "interesting" and actively watched.
*/
private final ConcurrentHashMap<String, DocCollection> watchedCollectionStates = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, DocCollection> watchedCollectionStates = new ConcurrentHashMap<>();
/** Collections with format2 state.json, not "interesting" and not actively watched. */ /**
* Collections with format2 state.json, not "interesting" and not actively watched.
*/
private final ConcurrentHashMap<String, LazyCollectionRef> lazyCollectionStates = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, LazyCollectionRef> lazyCollectionStates = new ConcurrentHashMap<>();
/** Collection properties being actively watched */ /**
* Collection properties being actively watched
*/
private final ConcurrentHashMap<String, VersionedCollectionProps> watchedCollectionProps = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, VersionedCollectionProps> watchedCollectionProps = new ConcurrentHashMap<>();
/** Collection properties being actively watched */ /**
* Collection properties being actively watched
*/
private final ConcurrentHashMap<String, PropsWatcher> collectionPropsWatchers = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, PropsWatcher> collectionPropsWatchers = new ConcurrentHashMap<>();
private volatile SortedSet<String> liveNodes = emptySortedSet(); private volatile SortedSet<String> liveNodes = emptySortedSet();
@ -199,7 +216,9 @@ public class ZkStateReader implements SolrCloseable {
private Set<ClusterPropertiesListener> clusterPropertiesListeners = ConcurrentHashMap.newKeySet(); private Set<ClusterPropertiesListener> clusterPropertiesListeners = ConcurrentHashMap.newKeySet();
/** Used to submit notifications to Collection Properties watchers in order **/ /**
* Used to submit notifications to Collection Properties watchers in order
**/
private final ExecutorService collectionPropsNotifications = ExecutorUtil.newMDCAwareSingleThreadExecutor(new SolrjNamedThreadFactory("collectionPropsNotifications")); private final ExecutorService collectionPropsNotifications = ExecutorUtil.newMDCAwareSingleThreadExecutor(new SolrjNamedThreadFactory("collectionPropsNotifications"));
private static final long LAZY_CACHE_TIME = TimeUnit.NANOSECONDS.convert(STATE_UPDATE_DELAY, TimeUnit.MILLISECONDS); private static final long LAZY_CACHE_TIME = TimeUnit.NANOSECONDS.convert(STATE_UPDATE_DELAY, TimeUnit.MILLISECONDS);
@ -208,6 +227,7 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Get current {@link AutoScalingConfig}. * Get current {@link AutoScalingConfig}.
*
* @return current configuration from <code>autoscaling.json</code>. NOTE: * @return current configuration from <code>autoscaling.json</code>. NOTE:
* this data is retrieved from ZK on each call. * this data is retrieved from ZK on each call.
*/ */
@ -217,6 +237,7 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Get current {@link AutoScalingConfig}. * Get current {@link AutoScalingConfig}.
*
* @param watcher optional {@link Watcher} to set on a znode to watch for config changes. * @param watcher optional {@link Watcher} to set on a znode to watch for config changes.
* @return current configuration from <code>autoscaling.json</code>. NOTE: * @return current configuration from <code>autoscaling.json</code>. NOTE:
* this data is retrieved from ZK on each call. * this data is retrieved from ZK on each call.
@ -359,7 +380,7 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Forcibly refresh cluster state from ZK. Do this only to avoid race conditions because it's expensive. * Forcibly refresh cluster state from ZK. Do this only to avoid race conditions because it's expensive.
* * <p>
* It is cheaper to call {@link #forceUpdateCollection(String)} on a single collection if you must. * It is cheaper to call {@link #forceUpdateCollection(String)} on a single collection if you must.
* *
* @lucene.internal * @lucene.internal
@ -438,7 +459,9 @@ public class ZkStateReader implements SolrCloseable {
} }
/** Refresh the set of live nodes. */ /**
* Refresh the set of live nodes.
*/
public void updateLiveNodes() throws KeeperException, InterruptedException { public void updateLiveNodes() throws KeeperException, InterruptedException {
refreshLiveNodes(null); refreshLiveNodes(null);
} }
@ -652,7 +675,7 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Search for any lazy-loadable state format2 collections. * Search for any lazy-loadable state format2 collections.
* * <p>
* A stateFormat=1 collection which is not interesting to us can also * A stateFormat=1 collection which is not interesting to us can also
* be put into the {@link #lazyCollectionStates} map here. But that is okay * be put into the {@link #lazyCollectionStates} map here. But that is okay
* because {@link #constructState(Set)} will give priority to collections in the * because {@link #constructState(Set)} will give priority to collections in the
@ -761,7 +784,8 @@ public class ZkStateReader implements SolrCloseable {
Stat exists = null; Stat exists = null;
try { try {
exists = zkClient.exists(getCollectionPath(collName), null, true); exists = zkClient.exists(getCollectionPath(collName), null, true);
} catch (Exception e) {} } catch (Exception e) {
}
if (exists != null && exists.getVersion() == cachedDocCollection.getZNodeVersion()) { if (exists != null && exists.getVersion() == cachedDocCollection.getZNodeVersion()) {
shouldFetch = false; shouldFetch = false;
} }
@ -877,7 +901,9 @@ public class ZkStateReader implements SolrCloseable {
notifications.shutdownNow(); notifications.shutdownNow();
waitLatches.parallelStream().forEach(c -> { c.countDown(); }); waitLatches.parallelStream().forEach(c -> {
c.countDown();
});
ExecutorUtil.shutdownAndAwaitTermination(notifications); ExecutorUtil.shutdownAndAwaitTermination(notifications);
ExecutorUtil.shutdownAndAwaitTermination(collectionPropsNotifications); ExecutorUtil.shutdownAndAwaitTermination(collectionPropsNotifications);
@ -904,6 +930,7 @@ public class ZkStateReader implements SolrCloseable {
} }
return null; return null;
} }
public Replica getLeader(String collection, String shard) { public Replica getLeader(String collection, String shard) {
if (clusterState != null) { if (clusterState != null) {
DocCollection docCollection = clusterState.getCollectionOrNull(collection); DocCollection docCollection = clusterState.getCollectionOrNull(collection);
@ -1029,7 +1056,7 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Get a cluster property * Get a cluster property
* * <p>
* N.B. Cluster properties are updated via ZK watchers, and so may not necessarily * N.B. Cluster properties are updated via ZK watchers, and so may not necessarily
* be completely up-to-date. If you need to get the latest version, then use a * be completely up-to-date. If you need to get the latest version, then use a
* {@link ClusterProperties} instance. * {@link ClusterProperties} instance.
@ -1047,7 +1074,8 @@ public class ZkStateReader implements SolrCloseable {
return value; return value;
} }
/**Same as the above but allows a full json path as a list of parts /**
* Same as the above but allows a full json path as a list of parts
* *
* @param keyPath path to the property example ["collectionDefauls", "numShards"] * @param keyPath path to the property example ["collectionDefauls", "numShards"]
* @param defaultValue a default value to use if no such property exists * @param defaultValue a default value to use if no such property exists
@ -1062,7 +1090,7 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Get all cluster properties for this cluster * Get all cluster properties for this cluster
* * <p>
* N.B. Cluster properties are updated via ZK watchers, and so may not necessarily * N.B. Cluster properties are updated via ZK watchers, and so may not necessarily
* be completely up-to-date. If you need to get the latest version, then use a * be completely up-to-date. If you need to get the latest version, then use a
* {@link ClusterProperties} instance. * {@link ClusterProperties} instance.
@ -1250,13 +1278,16 @@ public class ZkStateReader implements SolrCloseable {
* Returns the baseURL corresponding to a given node's nodeName -- * Returns the baseURL corresponding to a given node's nodeName --
* NOTE: does not (currently) imply that the nodeName (or resulting * NOTE: does not (currently) imply that the nodeName (or resulting
* baseURL) exists in the cluster. * baseURL) exists in the cluster.
*
* @lucene.experimental * @lucene.experimental
*/ */
public String getBaseUrlForNodeName(final String nodeName) { public String getBaseUrlForNodeName(final String nodeName) {
return Utils.getBaseUrlForNodeName(nodeName, getClusterProperty(URL_SCHEME, "http")); return Utils.getBaseUrlForNodeName(nodeName, getClusterProperty(URL_SCHEME, "http"));
} }
/** Watches a single collection's format2 state.json. */ /**
* Watches a single collection's format2 state.json.
*/
class StateWatcher implements Watcher { class StateWatcher implements Watcher {
private final String coll; private final String coll;
@ -1310,7 +1341,9 @@ public class ZkStateReader implements SolrCloseable {
} }
} }
/** Watches the legacy clusterstate.json. */ /**
* Watches the legacy clusterstate.json.
*/
class LegacyClusterStateWatcher implements Watcher { class LegacyClusterStateWatcher implements Watcher {
@Override @Override
@ -1324,7 +1357,9 @@ public class ZkStateReader implements SolrCloseable {
refreshAndWatch(); refreshAndWatch();
} }
/** Must hold {@link #getUpdateLock()} before calling this method. */ /**
* Must hold {@link #getUpdateLock()} before calling this method.
*/
public void refreshAndWatch() { public void refreshAndWatch() {
try { try {
refreshLegacyClusterState(this); refreshLegacyClusterState(this);
@ -1344,7 +1379,9 @@ public class ZkStateReader implements SolrCloseable {
} }
} }
/** Watches collection properties */ /**
* Watches collection properties
*/
class PropsWatcher implements Watcher { class PropsWatcher implements Watcher {
private final String coll; private final String coll;
private long watchUntilNs; private long watchUntilNs;
@ -1428,7 +1465,9 @@ public class ZkStateReader implements SolrCloseable {
} }
} }
/** Watches /collections children . */ /**
* Watches /collections children .
*/
class CollectionsChildWatcher implements Watcher { class CollectionsChildWatcher implements Watcher {
@Override @Override
@ -1448,7 +1487,9 @@ public class ZkStateReader implements SolrCloseable {
} }
} }
/** Must hold {@link #getUpdateLock()} before calling this method. */ /**
* Must hold {@link #getUpdateLock()} before calling this method.
*/
public void refreshAndWatch() { public void refreshAndWatch() {
try { try {
refreshCollectionList(this); refreshCollectionList(this);
@ -1465,7 +1506,9 @@ public class ZkStateReader implements SolrCloseable {
} }
} }
/** Watches the live_nodes and syncs changes. */ /**
* Watches the live_nodes and syncs changes.
*/
class LiveNodeWatcher implements Watcher { class LiveNodeWatcher implements Watcher {
@Override @Override
@ -1541,14 +1584,13 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Notify this reader that a local Core is a member of a collection, and so that collection * Notify this reader that a local Core is a member of a collection, and so that collection
* state should be watched. * state should be watched.
* * <p>
* Not a public API. This method should only be called from ZkController. * Not a public API. This method should only be called from ZkController.
* * <p>
* The number of cores per-collection is tracked, and adding multiple cores from the same * The number of cores per-collection is tracked, and adding multiple cores from the same
* collection does not increase the number of watches. * collection does not increase the number of watches.
* *
* @param collection the collection that the core is a member of * @param collection the collection that the core is a member of
*
* @see ZkStateReader#unregisterCore(String) * @see ZkStateReader#unregisterCore(String)
*/ */
public void registerCore(String collection) { public void registerCore(String collection) {
@ -1568,9 +1610,9 @@ public class ZkStateReader implements SolrCloseable {
/** /**
* Notify this reader that a local core that is a member of a collection has been closed. * Notify this reader that a local core that is a member of a collection has been closed.
* * <p>
* Not a public API. This method should only be called from ZkController. * Not a public API. This method should only be called from ZkController.
* * <p>
* If no cores are registered for a collection, and there are no {@link CollectionStateWatcher}s * If no cores are registered for a collection, and there are no {@link CollectionStateWatcher}s
* for that collection either, the collection watch will be removed. * for that collection either, the collection watch will be removed.
* *
@ -1673,14 +1715,14 @@ public class ZkStateReader implements SolrCloseable {
* instead * instead
* </p> * </p>
* *
* @see #waitForState(String, long, TimeUnit, Predicate)
* @see #registerCollectionStateWatcher
* @param collection the collection to watch * @param collection the collection to watch
* @param wait how long to wait * @param wait how long to wait
* @param unit the units of the wait parameter * @param unit the units of the wait parameter
* @param predicate the predicate to call on state changes * @param predicate the predicate to call on state changes
* @throws InterruptedException on interrupt * @throws InterruptedException on interrupt
* @throws TimeoutException on timeout * @throws TimeoutException on timeout
* @see #waitForState(String, long, TimeUnit, Predicate)
* @see #registerCollectionStateWatcher
*/ */
public void waitForState(final String collection, long wait, TimeUnit unit, CollectionStatePredicate predicate) public void waitForState(final String collection, long wait, TimeUnit unit, CollectionStatePredicate predicate)
throws InterruptedException, TimeoutException { throws InterruptedException, TimeoutException {
@ -1707,8 +1749,7 @@ public class ZkStateReader implements SolrCloseable {
if (!latch.await(wait, unit)) if (!latch.await(wait, unit))
throw new TimeoutException("Timeout waiting to see state for collection=" + collection + " :" + docCollection.get()); throw new TimeoutException("Timeout waiting to see state for collection=" + collection + " :" + docCollection.get());
} } finally {
finally {
removeCollectionStateWatcher(collection, watcher); removeCollectionStateWatcher(collection, watcher);
waitLatches.remove(latch); waitLatches.remove(latch);
} }
@ -1754,8 +1795,7 @@ public class ZkStateReader implements SolrCloseable {
if (!latch.await(wait, unit)) if (!latch.await(wait, unit))
throw new TimeoutException("Timeout waiting to see state for collection=" + collection + " :" + docCollection.get()); throw new TimeoutException("Timeout waiting to see state for collection=" + collection + " :" + docCollection.get());
} } finally {
finally {
removeDocCollectionWatcher(collection, watcher); removeDocCollectionWatcher(collection, watcher);
waitLatches.remove(latch); waitLatches.remove(latch);
} }
@ -1767,6 +1807,7 @@ public class ZkStateReader implements SolrCloseable {
* Note that the predicate may be called again even after it has returned true, so * Note that the predicate may be called again even after it has returned true, so
* implementors should avoid changing state within the predicate call itself. * implementors should avoid changing state within the predicate call itself.
* </p> * </p>
*
* @param wait how long to wait * @param wait how long to wait
* @param unit the units of the wait parameter * @param unit the units of the wait parameter
* @param predicate the predicate to call on state changes * @param predicate the predicate to call on state changes
@ -1798,8 +1839,7 @@ public class ZkStateReader implements SolrCloseable {
if (!latch.await(wait, unit)) if (!latch.await(wait, unit))
throw new TimeoutException("Timeout waiting for live nodes, currently they are: " + getClusterState().getLiveNodes()); throw new TimeoutException("Timeout waiting for live nodes, currently they are: " + getClusterState().getLiveNodes());
} } finally {
finally {
removeLiveNodesListener(listener); removeLiveNodesListener(listener);
waitLatches.remove(latch); waitLatches.remove(latch);
} }
@ -1813,9 +1853,9 @@ public class ZkStateReader implements SolrCloseable {
* collection. * collection.
* </p> * </p>
* *
* @see #registerCollectionStateWatcher
* @param collection the collection * @param collection the collection
* @param watcher the watcher * @param watcher the watcher
* @see #registerCollectionStateWatcher
*/ */
public void removeCollectionStateWatcher(String collection, CollectionStateWatcher watcher) { public void removeCollectionStateWatcher(String collection, CollectionStateWatcher watcher) {
final DocCollectionAndLiveNodesWatcherWrapper wrapper final DocCollectionAndLiveNodesWatcherWrapper wrapper
@ -1832,9 +1872,9 @@ public class ZkStateReader implements SolrCloseable {
* collection. * collection.
* </p> * </p>
* *
* @see #registerDocCollectionWatcher
* @param collection the collection * @param collection the collection
* @param watcher the watcher * @param watcher the watcher
* @see #registerDocCollectionWatcher
*/ */
public void removeDocCollectionWatcher(String collection, DocCollectionWatcher watcher) { public void removeDocCollectionWatcher(String collection, DocCollectionWatcher watcher) {
AtomicBoolean reconstructState = new AtomicBoolean(false); AtomicBoolean reconstructState = new AtomicBoolean(false);
@ -1967,8 +2007,7 @@ public class ZkStateReader implements SolrCloseable {
} }
try { try {
notifications.submit(new Notification(collection, collectionState)); notifications.submit(new Notification(collection, collectionState));
} } catch (RejectedExecutionException e) {
catch (RejectedExecutionException e) {
if (closed == false) { if (closed == false) {
log.error("Couldn't run collection notifications for {}", collection, e); log.error("Couldn't run collection notifications for {}", collection, e);
} }
@ -2011,7 +2050,9 @@ public class ZkStateReader implements SolrCloseable {
// Aliases related // Aliases related
// //
/** Access to the {@link Aliases}. */ /**
* Access to the {@link Aliases}.
*/
public final AliasesManager aliasesManager = new AliasesManager(); public final AliasesManager aliasesManager = new AliasesManager();
/** /**