You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rj...@apache.org on 2015/03/31 07:22:50 UTC

svn commit: r1670257 [23/39] - in /lucene/dev/branches/lucene6271: ./ dev-tools/ dev-tools/idea/.idea/libraries/ dev-tools/scripts/ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneou...

Modified: lucene/dev/branches/lucene6271/solr/core/src/java/org/apache/solr/core/SolrConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/solr/core/src/java/org/apache/solr/core/SolrConfig.java?rev=1670257&r1=1670256&r2=1670257&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/solr/core/src/java/org/apache/solr/core/SolrConfig.java (original)
+++ lucene/dev/branches/lucene6271/solr/core/src/java/org/apache/solr/core/SolrConfig.java Tue Mar 31 05:22:40 2015
@@ -42,11 +42,10 @@ import org.apache.solr.spelling.QueryCon
 import org.apache.solr.update.SolrIndexConfig;
 import org.apache.solr.update.UpdateLog;
 import org.apache.solr.update.processor.UpdateRequestProcessorChain;
+import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
 import org.apache.solr.util.DOMUtil;
 import org.apache.solr.util.FileUtils;
 import org.apache.solr.util.RegexFileFilter;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.data.Stat;
 import org.noggit.JSONParser;
 import org.noggit.ObjectBuilder;
 import org.slf4j.Logger;
@@ -74,13 +73,16 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static org.apache.solr.core.SolrConfig.PluginOpts.LAZY;
 import static org.apache.solr.core.SolrConfig.PluginOpts.MULTI_OK;
 import static org.apache.solr.core.SolrConfig.PluginOpts.NOOP;
 import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_CLASS;
 import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_NAME;
+import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_NAME_IN_OVERLAY;
 
 
 /**
@@ -88,21 +90,23 @@ import static org.apache.solr.core.SolrC
  * configuration data for a a Solr instance -- typically found in
  * "solrconfig.xml".
  */
-public class SolrConfig extends Config implements MapSerializable{
+public class SolrConfig extends Config implements MapSerializable {
 
   public static final Logger log = LoggerFactory.getLogger(SolrConfig.class);
-  
+
   public static final String DEFAULT_CONF_FILE = "solrconfig.xml";
   private RequestParams requestParams;
 
   public static enum PluginOpts {
-    MULTI_OK, 
+    MULTI_OK,
     REQUIRE_NAME,
+    REQUIRE_NAME_IN_OVERLAY,
     REQUIRE_CLASS,
+    LAZY,
     // EnumSet.of and/or EnumSet.copyOf(Collection) are anoying
     // because of type determination
     NOOP
-    }
+  }
 
   private int multipartUploadLimitKB;
 
@@ -115,49 +119,56 @@ public class SolrConfig extends Config i
   private boolean addHttpRequestToContext;
 
   private final SolrRequestParsers solrRequestParsers;
-  
-  /** Creates a default instance from the solrconfig.xml. */
+
+  /**
+   * Creates a default instance from the solrconfig.xml.
+   */
   public SolrConfig()
-  throws ParserConfigurationException, IOException, SAXException {
-    this( (SolrResourceLoader) null, DEFAULT_CONF_FILE, null );
+      throws ParserConfigurationException, IOException, SAXException {
+    this((SolrResourceLoader) null, DEFAULT_CONF_FILE, null);
   }
-  
-  /** Creates a configuration instance from a configuration name.
+
+  /**
+   * Creates a configuration instance from a configuration name.
    * A default resource loader will be created (@see SolrResourceLoader)
-   *@param name the configuration name used by the loader
+   *
+   * @param name the configuration name used by the loader
    */
   public SolrConfig(String name)
-  throws ParserConfigurationException, IOException, SAXException {
-    this( (SolrResourceLoader) null, name, null);
+      throws ParserConfigurationException, IOException, SAXException {
+    this((SolrResourceLoader) null, name, null);
   }
 
-  /** Creates a configuration instance from a configuration name and stream.
+  /**
+   * Creates a configuration instance from a configuration name and stream.
    * A default resource loader will be created (@see SolrResourceLoader).
    * If the stream is null, the resource loader will open the configuration stream.
    * If the stream is not null, no attempt to load the resource will occur (the name is not used).
-   *@param name the configuration name
-   *@param is the configuration stream
+   *
+   * @param name the configuration name
+   * @param is   the configuration stream
    */
   public SolrConfig(String name, InputSource is)
-  throws ParserConfigurationException, IOException, SAXException {
-    this( (SolrResourceLoader) null, name, is );
+      throws ParserConfigurationException, IOException, SAXException {
+    this((SolrResourceLoader) null, name, is);
   }
-  
-  /** Creates a configuration instance from an instance directory, configuration name and stream.
-   *@param instanceDir the directory used to create the resource loader
-   *@param name the configuration name used by the loader if the stream is null
-   *@param is the configuration stream 
+
+  /**
+   * Creates a configuration instance from an instance directory, configuration name and stream.
+   *
+   * @param instanceDir the directory used to create the resource loader
+   * @param name        the configuration name used by the loader if the stream is null
+   * @param is          the configuration stream
    */
   public SolrConfig(String instanceDir, String name, InputSource is)
-  throws ParserConfigurationException, IOException, SAXException {
+      throws ParserConfigurationException, IOException, SAXException {
     this(new SolrResourceLoader(instanceDir), name, is);
   }
 
   public static SolrConfig readFromResourceLoader(SolrResourceLoader loader, String name) {
     try {
       return new SolrConfig(loader, name, null);
-    }
-    catch (Exception e) {
+    } catch (Exception e) {
       String resource;
       if (loader instanceof ZkSolrResourceLoader) {
         resource = name;
@@ -167,16 +178,18 @@ public class SolrConfig extends Config i
       throw new SolrException(ErrorCode.SERVER_ERROR, "Error loading solr config from " + resource, e);
     }
   }
-  
-   /** Creates a configuration instance from a resource loader, a configuration name and a stream.
+
+  /**
+   * Creates a configuration instance from a resource loader, a configuration name and a stream.
    * If the stream is null, the resource loader will open the configuration stream.
    * If the stream is not null, no attempt to load the resource will occur (the name is not used).
-   *@param loader the resource loader
-   *@param name the configuration name
-   *@param is the configuration stream
+   *
+   * @param loader the resource loader
+   * @param name   the configuration name
+   * @param is     the configuration stream
    */
   public SolrConfig(SolrResourceLoader loader, String name, InputSource is)
-  throws ParserConfigurationException, IOException, SAXException {
+      throws ParserConfigurationException, IOException, SAXException {
     super(loader, name, is, "/config/");
     getOverlay();//just in case it is not initialized
     getRequestParams();
@@ -187,7 +200,7 @@ public class SolrConfig extends Config i
     // Old indexDefaults and mainIndex sections are deprecated and fails fast for luceneMatchVersion=>LUCENE_4_0_0.
     // For older solrconfig.xml's we allow the old sections, but never mixed with the new <indexConfig>
     boolean hasDeprecatedIndexConfig = (getNode("indexDefaults", false) != null) || (getNode("mainIndex", false) != null);
-    if(hasDeprecatedIndexConfig){
+    if (hasDeprecatedIndexConfig) {
       throw new SolrException(ErrorCode.FORBIDDEN, "<indexDefaults> and <mainIndex> configuration sections are discontinued. Use <indexConfig> instead.");
     } else {
       defaultIndexConfig = mainIndexConfig = null;
@@ -206,9 +219,9 @@ public class SolrConfig extends Config i
 
     // Warn about deprecated / discontinued parameters
     // boolToFilterOptimizer has had no effect since 3.1
-    if(get("query/boolTofilterOptimizer", null) != null)
+    if (get("query/boolTofilterOptimizer", null) != null)
       log.warn("solrconfig.xml: <boolTofilterOptimizer> is currently not implemented and has no effect.");
-    if(get("query/HashDocSet", null) != null)
+    if (get("query/HashDocSet", null) != null)
       log.warn("solrconfig.xml: <HashDocSet> is deprecated and no longer recommended used.");
 
 // TODO: Old code - in case somebody wants to re-enable. Also see SolrIndexSearcher#search()
@@ -227,62 +240,62 @@ public class SolrConfig extends Config i
     documentCacheConfig = CacheConfig.getConfig(this, "query/documentCache");
     CacheConfig conf = CacheConfig.getConfig(this, "query/fieldValueCache");
     if (conf == null) {
-      Map<String,String> args = new HashMap<>();
-      args.put("name","fieldValueCache");
-      args.put("size","10000");
-      args.put("initialSize","10");
-      args.put("showItems","-1");
+      Map<String, String> args = new HashMap<>();
+      args.put("name", "fieldValueCache");
+      args.put("size", "10000");
+      args.put("initialSize", "10");
+      args.put("showItems", "-1");
       conf = new CacheConfig(FastLRUCache.class, args, null);
     }
     fieldValueCacheConfig = conf;
-    unlockOnStartup = getBool(indexConfigPrefix+"/unlockOnStartup", false);
-    useColdSearcher = getBool("query/useColdSearcher",false);
+    unlockOnStartup = getBool(indexConfigPrefix + "/unlockOnStartup", false);
+    useColdSearcher = getBool("query/useColdSearcher", false);
     dataDir = get("dataDir", null);
-    if (dataDir != null && dataDir.length()==0) dataDir=null;
+    if (dataDir != null && dataDir.length() == 0) dataDir = null;
 
     userCacheConfigs = CacheConfig.getMultipleConfigs(this, "query/cache");
 
     org.apache.solr.search.SolrIndexSearcher.initRegenerators(this);
 
-    hashSetInverseLoadFactor = 1.0f / getFloat("//HashDocSet/@loadFactor",0.75f);
-    hashDocSetMaxSize= getInt("//HashDocSet/@maxSize",3000);
+    hashSetInverseLoadFactor = 1.0f / getFloat("//HashDocSet/@loadFactor", 0.75f);
+    hashDocSetMaxSize = getInt("//HashDocSet/@maxSize", 3000);
 
     httpCachingConfig = new HttpCachingConfig(this);
 
     Node jmx = getNode("jmx", false);
     if (jmx != null) {
       jmxConfig = new JmxConfiguration(true,
-                                       get("jmx/@agentId", null),
-                                       get("jmx/@serviceUrl", null),
-                                       get("jmx/@rootName", null));
+          get("jmx/@agentId", null),
+          get("jmx/@serviceUrl", null),
+          get("jmx/@rootName", null));
 
     } else {
       jmxConfig = new JmxConfiguration(false, null, null, null);
     }
-     maxWarmingSearchers = getInt("query/maxWarmingSearchers",Integer.MAX_VALUE);
+    maxWarmingSearchers = getInt("query/maxWarmingSearchers", Integer.MAX_VALUE);
     slowQueryThresholdMillis = getInt("query/slowQueryThresholdMillis", -1);
     for (SolrPluginInfo plugin : plugins) loadPluginInfo(plugin);
-     updateHandlerInfo = loadUpdatehandlerInfo();
-     
-     multipartUploadLimitKB = getInt( 
-         "requestDispatcher/requestParsers/@multipartUploadLimitInKB", 2048 );
-     
-     formUploadLimitKB = getInt( 
-         "requestDispatcher/requestParsers/@formdataUploadLimitInKB", 2048 );
-     
-     enableRemoteStreams = getBool( 
-         "requestDispatcher/requestParsers/@enableRemoteStreaming", false ); 
- 
-     // Let this filter take care of /select?xxx format
-     handleSelect = getBool( 
-         "requestDispatcher/@handleSelect", true ); 
-     
-     addHttpRequestToContext = getBool( 
-         "requestDispatcher/requestParsers/@addHttpRequestToContext", false );
-
-    List<PluginInfo> argsInfos =  pluginStore.get(InitParams.class.getName()) ;
-    if(argsInfos!=null){
-      Map<String,InitParams> argsMap = new HashMap<>();
+    updateHandlerInfo = loadUpdatehandlerInfo();
+
+    multipartUploadLimitKB = getInt(
+        "requestDispatcher/requestParsers/@multipartUploadLimitInKB", 2048);
+
+    formUploadLimitKB = getInt(
+        "requestDispatcher/requestParsers/@formdataUploadLimitInKB", 2048);
+
+    enableRemoteStreams = getBool(
+        "requestDispatcher/requestParsers/@enableRemoteStreaming", false);
+
+    // Let this filter take care of /select?xxx format
+    handleSelect = getBool(
+        "requestDispatcher/@handleSelect", true);
+
+    addHttpRequestToContext = getBool(
+        "requestDispatcher/requestParsers/@addHttpRequestToContext", false);
+
+    List<PluginInfo> argsInfos = getPluginInfos(InitParams.class.getName());
+    if (argsInfos != null) {
+      Map<String, InitParams> argsMap = new HashMap<>();
       for (PluginInfo p : argsInfos) {
         InitParams args = new InitParams(p);
         argsMap.put(args.name == null ? String.valueOf(args.hashCode()) : args.name, args);
@@ -295,41 +308,46 @@ public class SolrConfig extends Config i
     Config.log.info("Loaded SolrConfig: " + name);
   }
 
-  public static final  List<SolrPluginInfo> plugins = ImmutableList.<SolrPluginInfo>builder()
-      .add(new SolrPluginInfo(SolrRequestHandler.class, SolrRequestHandler.TYPE, REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
+  public static final List<SolrPluginInfo> plugins = ImmutableList.<SolrPluginInfo>builder()
+      .add(new SolrPluginInfo(SolrRequestHandler.class, SolrRequestHandler.TYPE, REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK, LAZY))
       .add(new SolrPluginInfo(QParserPlugin.class, "queryParser", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
-      .add(new SolrPluginInfo(QueryResponseWriter.class, "queryResponseWriter", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
+      .add(new SolrPluginInfo(QueryResponseWriter.class, "queryResponseWriter", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK, LAZY))
       .add(new SolrPluginInfo(ValueSourceParser.class, "valueSourceParser", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
       .add(new SolrPluginInfo(TransformerFactory.class, "transformer", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
       .add(new SolrPluginInfo(SearchComponent.class, "searchComponent", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
-      // TODO: WTF is up with queryConverter???
-      // it aparently *only* works as a singleton? - SOLR-4304
-      // and even then -- only if there is a single SpellCheckComponent
-      // because of queryConverter.setIndexAnalyzer
+      .add(new SolrPluginInfo(UpdateRequestProcessorFactory.class, "updateProcessor", REQUIRE_NAME, REQUIRE_CLASS, MULTI_OK))
+          // TODO: WTF is up with queryConverter???
+          // it aparently *only* works as a singleton? - SOLR-4304
+          // and even then -- only if there is a single SpellCheckComponent
+          // because of queryConverter.setIndexAnalyzer
       .add(new SolrPluginInfo(QueryConverter.class, "queryConverter", REQUIRE_NAME, REQUIRE_CLASS))
-      // this is hackish, since it picks up all SolrEventListeners,
-      // regardless of when/how/why they are used (or even if they are
-      // declared outside of the appropriate context) but there's no nice
-      // way around that in the PluginInfo framework
-      .add(new SolrPluginInfo(SolrEventListener.class, "//listener", REQUIRE_CLASS, MULTI_OK))
+      .add(new SolrPluginInfo(PluginBag.RuntimeLib.class, "runtimeLib", REQUIRE_NAME, MULTI_OK))
+          // this is hackish, since it picks up all SolrEventListeners,
+          // regardless of when/how/why they are used (or even if they are
+          // declared outside of the appropriate context) but there's no nice
+          // way around that in the PluginInfo framework
+      .add(new SolrPluginInfo(InitParams.class, InitParams.TYPE, MULTI_OK, REQUIRE_NAME_IN_OVERLAY))
+      .add(new SolrPluginInfo(SolrEventListener.class, "//listener", REQUIRE_CLASS, MULTI_OK, REQUIRE_NAME_IN_OVERLAY))
+
       .add(new SolrPluginInfo(DirectoryFactory.class, "directoryFactory", REQUIRE_CLASS))
       .add(new SolrPluginInfo(IndexDeletionPolicy.class, "indexConfig/deletionPolicy", REQUIRE_CLASS))
       .add(new SolrPluginInfo(CodecFactory.class, "codecFactory", REQUIRE_CLASS))
       .add(new SolrPluginInfo(IndexReaderFactory.class, "indexReaderFactory", REQUIRE_CLASS))
-      .add(new SolrPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain", MULTI_OK))
-      .add(new SolrPluginInfo(UpdateLog.class,"updateHandler/updateLog"))
+      .add(new SolrPluginInfo(UpdateRequestProcessorChain.class, "updateRequestProcessorChain", MULTI_OK))
+      .add(new SolrPluginInfo(UpdateLog.class, "updateHandler/updateLog"))
       .add(new SolrPluginInfo(IndexSchemaFactory.class, "schemaFactory", REQUIRE_CLASS))
       .add(new SolrPluginInfo(RestManager.class, "restManager"))
-      .add(new SolrPluginInfo(InitParams.class, InitParams.TYPE, MULTI_OK))
       .add(new SolrPluginInfo(StatsCache.class, "statsCache", REQUIRE_CLASS))
       .build();
-  private static final Map<String, SolrPluginInfo> clsVsInfo = new HashMap<>();
+  public static final Map<String, SolrPluginInfo> classVsSolrPluginInfo;
 
   static {
-    for (SolrPluginInfo plugin : plugins) clsVsInfo.put(plugin.clazz.getName(), plugin);
+    Map<String, SolrPluginInfo> map = new HashMap<>();
+    for (SolrPluginInfo plugin : plugins) map.put(plugin.clazz.getName(), plugin);
+    classVsSolrPluginInfo = Collections.unmodifiableMap(map);
   }
 
-  public static class SolrPluginInfo{
+  public static class SolrPluginInfo {
 
     public final Class clazz;
     public final String tag;
@@ -339,17 +357,26 @@ public class SolrConfig extends Config i
     private SolrPluginInfo(Class clz, String tag, PluginOpts... opts) {
       this.clazz = clz;
       this.tag = tag;
-      this.options=  opts == null? Collections.EMPTY_SET :  EnumSet.of(NOOP, opts);
+      this.options = opts == null ? Collections.EMPTY_SET : EnumSet.of(NOOP, opts);
+    }
+
+    public String getCleanTag() {
+      return tag.replaceAll("/", "");
+    }
+
+    public String getTagCleanLower() {
+      return getCleanTag().toLowerCase(Locale.ROOT);
+
     }
   }
 
-  public static  ConfigOverlay getConfigOverlay(SolrResourceLoader loader) {
+  public static ConfigOverlay getConfigOverlay(SolrResourceLoader loader) {
     InputStream in = null;
     try {
       in = loader.openResource(ConfigOverlay.RESOURCE_NAME);
     } catch (IOException e) {
       //no problem no overlay.json file
-      return new ConfigOverlay(Collections.EMPTY_MAP,-1);
+      return new ConfigOverlay(Collections.EMPTY_MAP, -1);
     }
 
     try {
@@ -359,27 +386,29 @@ public class SolrConfig extends Config i
         log.info("config overlay loaded . version : {} ", version);
       }
       Map m = (Map) ObjectBuilder.getVal(new JSONParser(new InputStreamReader(in, StandardCharsets.UTF_8)));
-      return new ConfigOverlay(m,version);
+      return new ConfigOverlay(m, version);
     } catch (Exception e) {
-      throw new SolrException(ErrorCode.SERVER_ERROR,"Error reading config overlay",e);
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error reading config overlay", e);
     }
 
   }
 
-  private Map<String,InitParams> initParams = Collections.emptyMap();
+  private Map<String, InitParams> initParams = Collections.emptyMap();
+
   public Map<String, InitParams> getInitParams() {
     return initParams;
   }
+
   protected UpdateHandlerInfo loadUpdatehandlerInfo() {
-    return new UpdateHandlerInfo(get("updateHandler/@class",null),
-            getInt("updateHandler/autoCommit/maxDocs",-1),
-            getInt("updateHandler/autoCommit/maxTime",-1),
-            getBool("updateHandler/indexWriter/closeWaitsForMerges",true),
-            getBool("updateHandler/autoCommit/openSearcher",true),
-            getInt("updateHandler/commitIntervalLowerBound",-1),
-            getInt("updateHandler/autoSoftCommit/maxDocs",-1),
-            getInt("updateHandler/autoSoftCommit/maxTime",-1),
-            getBool("updateHandler/commitWithin/softCommit",true));
+    return new UpdateHandlerInfo(get("updateHandler/@class", null),
+        getInt("updateHandler/autoCommit/maxDocs", -1),
+        getInt("updateHandler/autoCommit/maxTime", -1),
+        getBool("updateHandler/indexWriter/closeWaitsForMerges", true),
+        getBool("updateHandler/autoCommit/openSearcher", true),
+        getInt("updateHandler/commitIntervalLowerBound", -1),
+        getInt("updateHandler/autoSoftCommit/maxDocs", -1),
+        getInt("updateHandler/autoSoftCommit/maxTime", -1),
+        getBool("updateHandler/commitWithin/softCommit", true));
   }
 
   private void loadPluginInfo(SolrPluginInfo pluginInfo) {
@@ -388,37 +417,37 @@ public class SolrConfig extends Config i
 
     List<PluginInfo> result = readPluginInfos(pluginInfo.tag, requireName, requireClass);
 
-    if (1 < result.size() && ! pluginInfo.options.contains(MULTI_OK)) {
-        throw new SolrException
+    if (1 < result.size() && !pluginInfo.options.contains(MULTI_OK)) {
+      throw new SolrException
           (SolrException.ErrorCode.SERVER_ERROR,
-           "Found " + result.size() + " configuration sections when at most "
-           + "1 is allowed matching expression: " + pluginInfo.tag);
+              "Found " + result.size() + " configuration sections when at most "
+                  + "1 is allowed matching expression: " + pluginInfo.getCleanTag());
     }
-    if(!result.isEmpty()) pluginStore.put(pluginInfo.clazz.getName(),result);
+    if (!result.isEmpty()) pluginStore.put(pluginInfo.clazz.getName(), result);
   }
 
   public List<PluginInfo> readPluginInfos(String tag, boolean requireName, boolean requireClass) {
     ArrayList<PluginInfo> result = new ArrayList<>();
     NodeList nodes = (NodeList) evaluate(tag, XPathConstants.NODESET);
-    for (int i=0; i<nodes.getLength(); i++) {
+    for (int i = 0; i < nodes.getLength(); i++) {
       PluginInfo pluginInfo = new PluginInfo(nodes.item(i), "[solrconfig.xml] " + tag, requireName, requireClass);
-      if(pluginInfo.isEnabled()) result.add(pluginInfo);
+      if (pluginInfo.isEnabled()) result.add(pluginInfo);
     }
     return result;
   }
-  
+
   public SolrRequestParsers getRequestParsers() {
     return solrRequestParsers;
   }
 
   /* The set of materialized parameters: */
   public final int booleanQueryMaxClauseCount;
-// SolrIndexSearcher - nutch optimizer -- Disabled since 3.1
+  // SolrIndexSearcher - nutch optimizer -- Disabled since 3.1
 //  public final boolean filtOptEnabled;
 //  public final int filtOptCacheSize;
 //  public final float filtOptThreshold;
   // SolrIndexSearcher - caches configurations
-  public final CacheConfig filterCacheConfig ;
+  public final CacheConfig filterCacheConfig;
   public final CacheConfig queryResultCacheConfig;
   public final CacheConfig documentCacheConfig;
   public final CacheConfig fieldValueCacheConfig;
@@ -439,7 +468,7 @@ public class SolrConfig extends Config i
   // IndexConfig settings
   public final SolrIndexConfig indexConfig;
 
-  protected UpdateHandlerInfo updateHandlerInfo ;
+  protected UpdateHandlerInfo updateHandlerInfo;
 
   private Map<String, List<PluginInfo>> pluginStore = new LinkedHashMap<>();
 
@@ -449,23 +478,24 @@ public class SolrConfig extends Config i
   public final Version luceneMatchVersion;
   protected String dataDir;
   public final int slowQueryThresholdMillis;  // threshold above which a query is considered slow
-  
+
   //JMX configuration
   public final JmxConfiguration jmxConfig;
-  
+
   private final HttpCachingConfig httpCachingConfig;
+
   public HttpCachingConfig getHttpCachingConfig() {
     return httpCachingConfig;
   }
 
-  public static class JmxConfiguration implements MapSerializable{
+  public static class JmxConfiguration implements MapSerializable {
     public boolean enabled = false;
     public String agentId;
     public String serviceUrl;
     public String rootName;
 
-    public JmxConfiguration(boolean enabled, 
-                            String agentId, 
+    public JmxConfiguration(boolean enabled,
+                            String agentId,
                             String serviceUrl,
                             String rootName) {
       this.enabled = enabled;
@@ -475,180 +505,217 @@ public class SolrConfig extends Config i
 
       if (agentId != null && serviceUrl != null) {
         throw new SolrException
-          (SolrException.ErrorCode.SERVER_ERROR,
-           "Incorrect JMX Configuration in solrconfig.xml, "+
-           "both agentId and serviceUrl cannot be specified at the same time");
+            (SolrException.ErrorCode.SERVER_ERROR,
+                "Incorrect JMX Configuration in solrconfig.xml, " +
+                    "both agentId and serviceUrl cannot be specified at the same time");
       }
-      
+
     }
 
     @Override
     public Map<String, Object> toMap() {
       LinkedHashMap map = new LinkedHashMap();
-      map.put("agentId",agentId);
-      map.put("serviceUrl",serviceUrl);
-      map.put("rootName",rootName);
+      map.put("agentId", agentId);
+      map.put("serviceUrl", serviceUrl);
+      map.put("rootName", rootName);
       return map;
     }
   }
 
-  public static class HttpCachingConfig implements MapSerializable{
+  public static class HttpCachingConfig implements MapSerializable {
 
-    /** config xpath prefix for getting HTTP Caching options */
+    /**
+     * config xpath prefix for getting HTTP Caching options
+     */
     private final static String CACHE_PRE
-      = "requestDispatcher/httpCaching/";
-    
-    /** For extracting Expires "ttl" from <cacheControl> config */
+        = "requestDispatcher/httpCaching/";
+
+    /**
+     * For extracting Expires "ttl" from <cacheControl> config
+     */
     private final static Pattern MAX_AGE
-      = Pattern.compile("\\bmax-age=(\\d+)");
+        = Pattern.compile("\\bmax-age=(\\d+)");
 
     @Override
     public Map<String, Object> toMap() {
-      return ZkNodeProps.makeMap("never304",never304,
-          "etagSeed",etagSeed,
-          "lastModFrom",lastModFrom.name().toLowerCase(Locale.ROOT),
-          "cacheControl",cacheControlHeader);
+      return ZkNodeProps.makeMap("never304", never304,
+          "etagSeed", etagSeed,
+          "lastModFrom", lastModFrom.name().toLowerCase(Locale.ROOT),
+          "cacheControl", cacheControlHeader);
     }
 
     public static enum LastModFrom {
       OPENTIME, DIRLASTMOD, BOGUS;
 
-      /** Input must not be null */
+      /**
+       * Input must not be null
+       */
       public static LastModFrom parse(final String s) {
         try {
           return valueOf(s.toUpperCase(Locale.ROOT));
         } catch (Exception e) {
-          log.warn( "Unrecognized value for lastModFrom: " + s, e);
+          log.warn("Unrecognized value for lastModFrom: " + s, e);
           return BOGUS;
         }
       }
     }
-    
+
     private final boolean never304;
     private final String etagSeed;
     private final String cacheControlHeader;
     private final Long maxAge;
     private final LastModFrom lastModFrom;
-    
+
     private HttpCachingConfig(SolrConfig conf) {
 
-      never304 = conf.getBool(CACHE_PRE+"@never304", false);
-      
-      etagSeed = conf.get(CACHE_PRE+"@etagSeed", "Solr");
-      
-
-      lastModFrom = LastModFrom.parse(conf.get(CACHE_PRE+"@lastModFrom",
-                                               "openTime"));
-      
-      cacheControlHeader = conf.get(CACHE_PRE+"cacheControl",null);
+      never304 = conf.getBool(CACHE_PRE + "@never304", false);
+
+      etagSeed = conf.get(CACHE_PRE + "@etagSeed", "Solr");
+
+
+      lastModFrom = LastModFrom.parse(conf.get(CACHE_PRE + "@lastModFrom",
+          "openTime"));
+
+      cacheControlHeader = conf.get(CACHE_PRE + "cacheControl", null);
 
       Long tmp = null; // maxAge
       if (null != cacheControlHeader) {
-        try { 
+        try {
           final Matcher ttlMatcher = MAX_AGE.matcher(cacheControlHeader);
           final String ttlStr = ttlMatcher.find() ? ttlMatcher.group(1) : null;
           tmp = (null != ttlStr && !"".equals(ttlStr))
-            ? Long.valueOf(ttlStr)
-            : null;
+              ? Long.valueOf(ttlStr)
+              : null;
         } catch (Exception e) {
-          log.warn( "Ignoring exception while attempting to " +
-                    "extract max-age from cacheControl config: " +
-                    cacheControlHeader, e);
+          log.warn("Ignoring exception while attempting to " +
+              "extract max-age from cacheControl config: " +
+              cacheControlHeader, e);
         }
       }
       maxAge = tmp;
 
     }
-    
-    public boolean isNever304() { return never304; }
-    public String getEtagSeed() { return etagSeed; }
-    /** null if no Cache-Control header */
-    public String getCacheControlHeader() { return cacheControlHeader; }
-    /** null if no max age limitation */
-    public Long getMaxAge() { return maxAge; }
-    public LastModFrom getLastModFrom() { return lastModFrom; }
+
+    public boolean isNever304() {
+      return never304;
+    }
+
+    public String getEtagSeed() {
+      return etagSeed;
+    }
+
+    /**
+     * null if no Cache-Control header
+     */
+    public String getCacheControlHeader() {
+      return cacheControlHeader;
+    }
+
+    /**
+     * null if no max age limitation
+     */
+    public Long getMaxAge() {
+      return maxAge;
+    }
+
+    public LastModFrom getLastModFrom() {
+      return lastModFrom;
+    }
   }
 
-  public static class UpdateHandlerInfo implements MapSerializable{
+  public static class UpdateHandlerInfo implements MapSerializable {
     public final String className;
-    public final int autoCommmitMaxDocs,autoCommmitMaxTime,commitIntervalLowerBound,
-        autoSoftCommmitMaxDocs,autoSoftCommmitMaxTime;
+    public final int autoCommmitMaxDocs, autoCommmitMaxTime, commitIntervalLowerBound,
+        autoSoftCommmitMaxDocs, autoSoftCommmitMaxTime;
     public final boolean indexWriterCloseWaitsForMerges;
     public final boolean openSearcher;  // is opening a new searcher part of hard autocommit?
     public final boolean commitWithinSoftCommit;
 
     /**
-     * @param autoCommmitMaxDocs set -1 as default
-     * @param autoCommmitMaxTime set -1 as default
+     * @param autoCommmitMaxDocs       set -1 as default
+     * @param autoCommmitMaxTime       set -1 as default
      * @param commitIntervalLowerBound set -1 as default
      */
     public UpdateHandlerInfo(String className, int autoCommmitMaxDocs, int autoCommmitMaxTime, boolean indexWriterCloseWaitsForMerges, boolean openSearcher, int commitIntervalLowerBound,
-        int autoSoftCommmitMaxDocs, int autoSoftCommmitMaxTime, boolean commitWithinSoftCommit) {
+                             int autoSoftCommmitMaxDocs, int autoSoftCommmitMaxTime, boolean commitWithinSoftCommit) {
       this.className = className;
       this.autoCommmitMaxDocs = autoCommmitMaxDocs;
       this.autoCommmitMaxTime = autoCommmitMaxTime;
       this.indexWriterCloseWaitsForMerges = indexWriterCloseWaitsForMerges;
       this.openSearcher = openSearcher;
       this.commitIntervalLowerBound = commitIntervalLowerBound;
-      
+
       this.autoSoftCommmitMaxDocs = autoSoftCommmitMaxDocs;
       this.autoSoftCommmitMaxTime = autoSoftCommmitMaxTime;
-      
+
       this.commitWithinSoftCommit = commitWithinSoftCommit;
     }
 
 
-
     @Override
     public Map<String, Object> toMap() {
       LinkedHashMap result = new LinkedHashMap();
-      result.put("class",className);
-      result.put("autoCommmitMaxDocs",autoCommmitMaxDocs);
-      result.put("indexWriterCloseWaitsForMerges",indexWriterCloseWaitsForMerges);
-      result.put("openSearcher",openSearcher);
-      result.put("commitIntervalLowerBound",commitIntervalLowerBound);
-      result.put("commitWithinSoftCommit",commitWithinSoftCommit);
+      result.put("class", className);
+      result.put("autoCommmitMaxDocs", autoCommmitMaxDocs);
+      result.put("indexWriterCloseWaitsForMerges", indexWriterCloseWaitsForMerges);
+      result.put("openSearcher", openSearcher);
+      result.put("commitIntervalLowerBound", commitIntervalLowerBound);
+      result.put("commitWithinSoftCommit", commitWithinSoftCommit);
       result.put("autoCommit", ZkNodeProps.makeMap(
           "maxDocs", autoCommmitMaxDocs,
-          "maxTime",autoCommmitMaxTime,
+          "maxTime", autoCommmitMaxTime,
           "commitIntervalLowerBound", commitIntervalLowerBound
       ));
-      result.put("autoSoftCommit" ,
+      result.put("autoSoftCommit",
           ZkNodeProps.makeMap("maxDocs", autoSoftCommmitMaxDocs,
-              "maxTime",autoSoftCommmitMaxTime));
+              "maxTime", autoSoftCommmitMaxTime));
       return result;
     }
   }
 
 //  public Map<String, List<PluginInfo>> getUpdateProcessorChainInfo() { return updateProcessorChainInfo; }
 
-  public UpdateHandlerInfo getUpdateHandlerInfo() { return updateHandlerInfo; }
+  public UpdateHandlerInfo getUpdateHandlerInfo() {
+    return updateHandlerInfo;
+  }
 
-  public String getDataDir() { return dataDir; }
+  public String getDataDir() {
+    return dataDir;
+  }
 
-  /**SolrConfig keeps a repository of plugins by the type. The known interfaces are the types.
+  /**
+   * SolrConfig keeps a repository of plugins by the type. The known interfaces are the types.
+   *
    * @param type The key is FQN of the plugin class there are a few  known types : SolrFormatter, SolrFragmenter
-   * SolrRequestHandler,QParserPlugin, QueryResponseWriter,ValueSourceParser,
-   * SearchComponent, QueryConverter, SolrEventListener, DirectoryFactory,
-   * IndexDeletionPolicy, IndexReaderFactory, {@link TransformerFactory}
+   *             SolrRequestHandler,QParserPlugin, QueryResponseWriter,ValueSourceParser,
+   *             SearchComponent, QueryConverter, SolrEventListener, DirectoryFactory,
+   *             IndexDeletionPolicy, IndexReaderFactory, {@link TransformerFactory}
    */
   public List<PluginInfo> getPluginInfos(String type) {
     List<PluginInfo> result = pluginStore.get(type);
-    SolrPluginInfo info = clsVsInfo.get(type);
-    if (info != null && info.options.contains(REQUIRE_NAME)) {
-      Map<String, Map> infos = overlay.getNamedPlugins(info.tag);
+    SolrPluginInfo info = classVsSolrPluginInfo.get(type);
+    if (info != null &&
+        (info.options.contains(REQUIRE_NAME) || info.options.contains(REQUIRE_NAME_IN_OVERLAY))) {
+      Map<String, Map> infos = overlay.getNamedPlugins(info.getCleanTag());
       if (!infos.isEmpty()) {
         LinkedHashMap<String, PluginInfo> map = new LinkedHashMap<>();
-        if (result != null) for (PluginInfo pluginInfo : result) map.put(pluginInfo.name, pluginInfo);
+        if (result != null) for (PluginInfo pluginInfo : result) {
+          //just create a UUID for the time being so that map key is not null
+          String name = pluginInfo.name == null ?
+              UUID.randomUUID().toString().toLowerCase(Locale.ROOT) :
+              pluginInfo.name;
+          map.put(name, pluginInfo);
+        }
         for (Map.Entry<String, Map> e : infos.entrySet()) {
-          map.put(e.getKey(), new PluginInfo(info.tag, e.getValue()));
+          map.put(e.getKey(), new PluginInfo(info.getCleanTag(), e.getValue()));
         }
         result = new ArrayList<>(map.values());
       }
     }
     return result == null ? Collections.<PluginInfo>emptyList() : result;
   }
-  public PluginInfo getPluginInfo(String  type){
+
+  public PluginInfo getPluginInfo(String type) {
     List<PluginInfo> result = pluginStore.get(type);
     if (result == null || result.isEmpty()) {
       return null;
@@ -658,20 +725,20 @@ public class SolrConfig extends Config i
     }
 
     throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
-                            "Multiple plugins configured for type: " + type);
+        "Multiple plugins configured for type: " + type);
   }
-  
+
   private void initLibs() {
     NodeList nodes = (NodeList) evaluate("lib", XPathConstants.NODESET);
     if (nodes == null || nodes.getLength() == 0) return;
-    
+
     log.info("Adding specified lib dirs to ClassLoader");
     SolrResourceLoader loader = getResourceLoader();
-    
+
     try {
       for (int i = 0; i < nodes.getLength(); i++) {
         Node node = nodes.item(i);
-        
+
         String baseDir = DOMUtil.getAttr(node, "dir");
         String path = DOMUtil.getAttr(node, "path");
         if (null != baseDir) {
@@ -696,7 +763,7 @@ public class SolrConfig extends Config i
       loader.reloadLuceneSPI();
     }
   }
-  
+
   public int getMultipartUploadLimitKB() {
     return multipartUploadLimitKB;
   }
@@ -724,23 +791,36 @@ public class SolrConfig extends Config i
 
   @Override
   public int getInt(String path, int def) {
-    Object v = overlay.getXPathProperty(path);
-
     Object val = overlay.getXPathProperty(path);
     if (val != null) return Integer.parseInt(val.toString());
     return super.getInt(path, def);
   }
+
   @Override
   public boolean getBool(String path, boolean def) {
     Object val = overlay.getXPathProperty(path);
     if (val != null) return Boolean.parseBoolean(val.toString());
     return super.getBool(path, def);
   }
+
+  @Override
+  public String get(String path) {
+    Object val = overlay.getXPathProperty(path, true);
+    return val != null ? val.toString() : super.get(path);
+  }
+
+  @Override
+  public String get(String path, String def) {
+    Object val = overlay.getXPathProperty(path, true);
+    return val != null ? val.toString() : super.get(path, def);
+
+  }
+
   @Override
   public Map<String, Object> toMap() {
     LinkedHashMap result = new LinkedHashMap();
-    if(getZnodeVersion() > -1) result.put("znodeVersion",getZnodeVersion());
-    result.put("luceneMatchVersion",luceneMatchVersion);
+    if (getZnodeVersion() > -1) result.put("znodeVersion", getZnodeVersion());
+    result.put("luceneMatchVersion", luceneMatchVersion);
     result.put("updateHandler", getUpdateHandlerInfo().toMap());
     Map m = new LinkedHashMap();
     result.put("query", m);
@@ -749,22 +829,22 @@ public class SolrConfig extends Config i
     m.put("queryResultMaxDocsCached", queryResultMaxDocsCached);
     m.put("enableLazyFieldLoading", enableLazyFieldLoading);
     m.put("maxBooleanClauses", booleanQueryMaxClauseCount);
-
+    if (jmxConfig != null) result.put("jmx", jmxConfig.toMap());
     for (SolrPluginInfo plugin : plugins) {
       List<PluginInfo> infos = getPluginInfos(plugin.clazz.getName());
-      if(infos == null || infos.isEmpty()) continue;
-      String tag = plugin.tag;
-      tag = tag.replace("/","");
-      if(plugin.options.contains(PluginOpts.REQUIRE_NAME)){
+      if (infos == null || infos.isEmpty()) continue;
+      String tag = plugin.getCleanTag();
+      tag = tag.replace("/", "");
+      if (plugin.options.contains(PluginOpts.REQUIRE_NAME)) {
         LinkedHashMap items = new LinkedHashMap();
         for (PluginInfo info : infos) items.put(info.name, info.toMap());
         for (Map.Entry e : overlay.getNamedPlugins(plugin.tag).entrySet()) items.put(e.getKey(), e.getValue());
         result.put(tag, items);
       } else {
-        if(plugin.options.contains(MULTI_OK)){
+        if (plugin.options.contains(MULTI_OK)) {
           ArrayList<Map> l = new ArrayList<>();
           for (PluginInfo info : infos) l.add(info.toMap());
-          result.put(tag,l);
+          result.put(tag, l);
         } else {
           result.put(tag, infos.get(0).toMap());
         }
@@ -774,16 +854,16 @@ public class SolrConfig extends Config i
     }
 
 
-    addCacheConfig(m,filterCacheConfig,queryResultCacheConfig,documentCacheConfig,fieldValueCacheConfig);
-    if(jmxConfig != null) result.put("jmx",jmxConfig.toMap());
+    addCacheConfig(m, filterCacheConfig, queryResultCacheConfig, documentCacheConfig, fieldValueCacheConfig);
+    if (jmxConfig != null) result.put("jmx", jmxConfig.toMap());
     m = new LinkedHashMap();
     result.put("requestDispatcher", m);
-    m.put("handleSelect",handleSelect);
-    if(httpCachingConfig!=null) m.put("httpCaching", httpCachingConfig.toMap());
-    m.put("requestParsers", ZkNodeProps.makeMap("multipartUploadLimitKB",multipartUploadLimitKB,
-        "formUploadLimitKB",formUploadLimitKB,
-        "addHttpRequestToContext",addHttpRequestToContext));
-    if(indexConfig != null) result.put("indexConfig",indexConfig.toMap());
+    m.put("handleSelect", handleSelect);
+    if (httpCachingConfig != null) m.put("httpCaching", httpCachingConfig.toMap());
+    m.put("requestParsers", ZkNodeProps.makeMap("multipartUploadLimitKB", multipartUploadLimitKB,
+        "formUploadLimitKB", formUploadLimitKB,
+        "addHttpRequestToContext", addHttpRequestToContext));
+    if (indexConfig != null) result.put("indexConfig", indexConfig.toMap());
 
     //TODO there is more to add
 
@@ -791,38 +871,39 @@ public class SolrConfig extends Config i
   }
 
   private void addCacheConfig(Map queryMap, CacheConfig... cache) {
-    if(cache==null)return;
-    for (CacheConfig config : cache) if(config !=null) queryMap.put(config.getNodeName(),config.toMap());
+    if (cache == null) return;
+    for (CacheConfig config : cache) if (config != null) queryMap.put(config.getNodeName(), config.toMap());
 
   }
 
   @Override
   protected Properties getSubstituteProperties() {
     Map<String, Object> p = getOverlay().getUserProps();
-    if(p==null || p.isEmpty()) return super.getSubstituteProperties();
+    if (p == null || p.isEmpty()) return super.getSubstituteProperties();
     Properties result = new Properties(super.getSubstituteProperties());
     result.putAll(p);
     return result;
   }
+
   private ConfigOverlay overlay;
 
   public ConfigOverlay getOverlay() {
-    if(overlay ==null) {
+    if (overlay == null) {
       overlay = getConfigOverlay(getResourceLoader());
     }
     return overlay;
   }
 
   public RequestParams getRequestParams() {
-    if(requestParams == null){
+    if (requestParams == null) {
       return refreshRequestParams();
     }
     return requestParams;
   }
 
 
-  public RequestParams refreshRequestParams(){
-    requestParams = RequestParams.getFreshRequestParams(getResourceLoader(),requestParams);
+  public RequestParams refreshRequestParams() {
+    requestParams = RequestParams.getFreshRequestParams(getResourceLoader(), requestParams);
     log.info("current version of requestparams : {}", requestParams.getZnodeVersion());
     return requestParams;
   }