You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2019/12/18 16:38:38 UTC

[lucene-solr] branch jira/solr-13579 created (now 27ef7cc)

This is an automated email from the ASF dual-hosted git repository.

ab pushed a change to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


      at 27ef7cc  SOLR-13579: Soft optimization, unit tests.

This branch includes the following new commits:

     new d589383  Initial patch.
     new 51da363  Refactoring. Plugins for management of speficic types of resources.
     new ad6eafb  Merge branch 'master' into star-123
     new 2f7bdfe  Small refactorings.
     new 129a602  Merge branch 'master' into star-123
     new 23fceca  Merge branch 'master' into star-123
     new 682f72d  Merge branch 'master' into star-123
     new adde6ba  Next iteration.
     new 6f2ccb2  Refactoring + updates.
     new d38973f  Merge branch 'master' into jira/solr-13579
     new 56309ce  Support generic limits (eg. boolean, enum, etc).
     new 3d735b6  More refactoring. Add ResourceManagerHandler.
     new 386ee2d  Merge branch 'master' into jira/solr-13579
     new 0876676  Small fixes and improvements.
     new b576520  Merge branch 'master' into jira/solr-13579
     new 1f74268  Initial integration with SolrIndexSearcher caches.
     new 32e2cad  More refactoring.
     new 0a14b23  Merge branch 'master' into jira/solr-13579
     new 55c0060  Renaming and refactoring.
     new f06fae4  Rename ResourceContext to ManagedContext.
     new 4890c43  Minor edits.
     new 56b2509  Merge branch 'master' into jira/solr-13579
     new cd040a1  First round of refactoring for better type safety.
     new 2a0c575  Add unit test.
     new e8a45ca  Merge branch 'master' into jira/solr-13579
     new fb32394  Merge branch 'master' into jira/solr-13579
     new e44e822  Fix a bug in component registration.
     new 25972bf  Merge branch 'master' into jira/solr-13579
     new b103faa  Update the API to the current master.
     new 9bd5ebb  Broken, interim check-in.
     new f336d7c  Interim check-in, mostly fixed.
     new 5860e3d  SOLR-13579: Simplify the API, add more tests.
     new 5932e53  Merge branch 'master' into jira/solr-13579
     new f1ebfdc  Merge branch 'master' into jira/solr-13579
     new cb7d835  Merge branch 'master' into jira/solr-13579
     new 27ef7cc  SOLR-13579: Soft optimization, unit tests.

The 36 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[lucene-solr] 29/36: Update the API to the current master.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit b103faa866e6339b7a79a3196947e98a6cdf62c0
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Mon Nov 18 16:29:01 2019 +0100

    Update the API to the current master.
---
 .../java/org/apache/solr/core/CoreContainer.java   |  1 -
 .../DefaultResourceManagerPluginFactory.java       |  4 +--
 .../solr/managed/DefaultResourceManagerPool.java   | 38 ++++------------------
 .../apache/solr/managed/ManagedComponentId.java    | 19 ++++++++---
 .../apache/solr/managed/NoOpResourceManager.java   |  7 +++-
 .../apache/solr/managed/ResourceManagerPlugin.java | 28 ++++++++++++++++
 .../apache/solr/managed/ResourceManagerPool.java   |  4 +--
 .../solr/managed/types/CacheManagerPlugin.java     | 30 ++++++++---------
 .../solr/managed/types/ManagedCacheComponent.java  | 22 -------------
 .../apache/solr/managed/types/package-info.java    |  3 +-
 .../java/org/apache/solr/search/CaffeineCache.java | 14 +++++++-
 .../src/java/org/apache/solr/search/SolrCache.java | 18 ++++++++--
 .../org/apache/solr/search/SolrCacheHolder.java    | 10 ------
 .../managed/TestDefaultResourceManagerPool.java    | 16 ++++-----
 14 files changed, 113 insertions(+), 101 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 20a6914..e969f11 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -234,7 +234,6 @@ public class CoreContainer {
 
   protected volatile ResourceManagerHandler resourceManagerHandler;
 
-  private final LibListener clusterPropertiesListener = new LibListener(this);
   private PackageStoreAPI packageStoreAPI;
   private PackageLoader packageLoader;
 
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
index 07eb5ad..0f5cf79 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
@@ -23,7 +23,7 @@ import java.util.Map;
 
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.managed.types.CacheManagerPlugin;
-import org.apache.solr.managed.types.ManagedCacheComponent;
+import org.apache.solr.search.SolrCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,7 +41,7 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
 
   static {
     typeToPluginClass.put(CacheManagerPlugin.TYPE, CacheManagerPlugin.class);
-    typeToComponentClass.put(CacheManagerPlugin.TYPE, ManagedCacheComponent.class);
+    typeToComponentClass.put(CacheManagerPlugin.TYPE, SolrCache.class);
   }
 
   private final SolrResourceLoader loader;
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 1f1e6d2..07eb5bf 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
 
 /**
  * This class manages a pool of resources of the same type, which use the same
- * {@link ResourceManagerPlugin} for managing their resource limits.
+ * {@link ResourceManagerPlugin} implementation for managing their resource limits.
  */
 public class DefaultResourceManagerPool implements ResourceManagerPool {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -44,7 +44,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
   private final ManagedContext poolContext = new ManagedContext();
-  private Map<String, Float> totalValues = null;
+  private Map<String, Map<String, Object>> currentValues = null;
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
   ScheduledFuture<?> scheduledFuture;
@@ -119,34 +119,15 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
     updateLock.lockInterruptibly();
     try {
       // collect the current values
-      Map<String, Map<String, Object>> currentValues = new HashMap<>();
+      Map<String, Map<String, Object>> newCurrentValues = new HashMap<>();
       for (ManagedComponent managedComponent : components.values()) {
         try {
-          currentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
+          newCurrentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
         } catch (Exception e) {
           log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
         }
       }
-      // calculate the totals
-      Map<String, Float> newTotalValues = new HashMap<>();
-      currentValues.values().forEach(map -> map.forEach((k, v) -> {
-        // only calculate totals for numbers
-        if (!(v instanceof Number)) {
-          return;
-        }
-        Float val = ((Number)v).floatValue();
-        // -1 and MAX_VALUE are our special guard values
-        if (val < 0 || val.longValue() == Long.MAX_VALUE || val.longValue() == Integer.MAX_VALUE) {
-          return;
-        }
-        Float total = newTotalValues.get(k);
-        if (total == null) {
-          newTotalValues.put(k, val);
-        } else {
-          newTotalValues.put(k, total + val);
-        }
-      }));
-      totalValues = newTotalValues;
+      this.currentValues = newCurrentValues;
       return Collections.unmodifiableMap(currentValues);
     } finally {
       updateLock.unlock();
@@ -154,13 +135,8 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public Map<String, Number> getTotalValues() throws InterruptedException {
-    updateLock.lockInterruptibly();
-    try {
-      return Collections.unmodifiableMap(totalValues);
-    } finally {
-      updateLock.unlock();
-    }
+  public Map<String, Object> getTotalValues() throws InterruptedException {
+    return Collections.unmodifiableMap(resourceManagerPlugin.aggregateTotalValues(currentValues));
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index d5feda2..bd09080 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -19,8 +19,6 @@ package org.apache.solr.managed;
 
 import java.util.Arrays;
 
-import org.apache.solr.metrics.SolrMetricManager;
-
 /**
  * Hierarchical component id.
  */
@@ -32,7 +30,20 @@ public class ManagedComponentId {
   public ManagedComponentId(String name, String... path) {
     this.name = name;
     this.path = path;
-    this.id = SolrMetricManager.mkName(name, path);
+    StringBuilder sb = new StringBuilder();
+    if (path != null) {
+      for (String pathEl : path) {
+        if (sb.length() > 0) {
+          sb.append(':');
+        }
+        sb.append(pathEl);
+      }
+    }
+    if (sb.length() > 0) {
+      sb.append(':');
+    }
+    sb.append(name);
+    id = sb.toString();
   }
 
   public String getName() {
@@ -51,7 +62,7 @@ public class ManagedComponentId {
     if (fullName == null || fullName.isEmpty()) {
       return null;
     }
-    String[] parts = fullName.split("\\.");
+    String[] parts = fullName.split(":");
     if (parts.length > 1) {
       String name = parts[parts.length - 1];
       String[] path = Arrays.copyOfRange(parts, 0, parts.length - 1);
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index bf43cb1..d828a4f 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -103,6 +103,11 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
+    public boolean isRegistered(String componentId) {
+      return false;
+    }
+
+    @Override
     public Map<String, ManagedComponent> getComponents() {
       return Collections.emptyMap();
     }
@@ -113,7 +118,7 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public Map<String, Number> getTotalValues() throws InterruptedException {
+    public Map<String, Object> getTotalValues() throws InterruptedException {
       return Collections.emptyMap();
     }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index 592ba03..1fbeaf0 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -17,6 +17,7 @@
 package org.apache.solr.managed;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -40,6 +41,11 @@ public interface ResourceManagerPlugin<T extends ManagedComponent> {
    */
   Collection<String> getControlledParams();
 
+  /**
+   * Return current values of monitored parameters. Note: the resulting map may contain also
+   * other implementation-specific parameter values.
+   * @param component monitored component
+   */
   Map<String, Object> getMonitoredValues(T component) throws Exception;
 
   default void setResourceLimits(T component, Map<String, Object> limits) throws Exception {
@@ -62,4 +68,26 @@ public interface ResourceManagerPlugin<T extends ManagedComponent> {
    */
   void manage(ResourceManagerPool pool) throws Exception;
 
+  /**
+   * Aggregated current monitored values.
+   * <p>Default implementation of this method simply sums up all non-negative numeric values across
+   * components and ignores any non-numeric values.</p>
+   */
+  default Map<String, Object> aggregateTotalValues(Map<String, Map<String, Object>> perComponentValues) {
+    // calculate the totals
+    Map<String, Object> newTotalValues = new HashMap<>();
+    perComponentValues.values().forEach(map -> map.forEach((k, v) -> {
+      // only calculate totals for numbers
+      if (!(v instanceof Number)) {
+        return;
+      }
+      Double val = ((Number)v).doubleValue();
+      // -1 and MAX_VALUE are our special guard values
+      if (val < 0 || val.longValue() == Long.MAX_VALUE || val.longValue() == Integer.MAX_VALUE) {
+        return;
+      }
+      newTotalValues.merge(k, val, (v1, v2) -> ((Number)v1).doubleValue() + ((Number)v2).doubleValue());
+    }));
+    return newTotalValues;
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 0761442..2bf4db7 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -40,9 +40,9 @@ public interface ResourceManagerPool extends Runnable, Closeable {
 
   /**
    * This returns cumulative monitored values of all components.
-   * <p>NOTE: you must call {@link #getCurrentValues()} first!</p>
+   * <p>NOTE: you MUST call {@link #getCurrentValues()} first!</p>
    */
-  Map<String, Number> getTotalValues() throws InterruptedException;
+  Map<String, Object> getTotalValues() throws InterruptedException;
 
   /** Get current pool limits. */
   Map<String, Object> getPoolLimits();
diff --git a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
index 6cd581b..4956c58 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
  * which can be adjusted using configuration parameter {@link #DEAD_BAND}. If monitored values don't
  * exceed the limits +/- the dead band then no action is taken.</p>
  */
-public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheComponent> {
+public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static String TYPE = "cache";
@@ -76,7 +76,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
   }
 
   @Override
-  public void setResourceLimit(ManagedCacheComponent component, String limitName, Object val) {
+  public void setResourceLimit(SolrCache component, String limitName, Object val) {
     if (!(val instanceof Number)) {
       try {
         val = Long.parseLong(String.valueOf(val));
@@ -101,7 +101,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
   }
 
   @Override
-  public Map<String, Object> getResourceLimits(ManagedCacheComponent component) {
+  public Map<String, Object> getResourceLimits(SolrCache component) {
     Map<String, Object> limits = new HashMap<>();
     limits.put(SolrCache.MAX_SIZE_PARAM, component.getMaxSize());
     limits.put(SolrCache.MAX_RAM_MB_PARAM, component.getMaxRamMB());
@@ -109,12 +109,8 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
   }
 
   @Override
-  public Map<String, Object> getMonitoredValues(ManagedCacheComponent component) throws Exception {
-    Map<String, Object> values = new HashMap<>();
-    values.put(SolrCache.HIT_RATIO_PARAM, component.getHitRatio());
-    values.put(SolrCache.RAM_BYTES_USED_PARAM, component.ramBytesUsed());
-    values.put(SolrCache.SIZE_PARAM, component.getSize());
-    return values;
+  public Map<String, Object> getMonitoredValues(SolrCache component) throws Exception {
+    return component.getSolrMetricsContext().getMetricsSnapshot();
   }
 
   @Override
@@ -135,7 +131,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
   @Override
   public void manage(ResourceManagerPool pool) throws Exception {
     Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-    Map<String, Number> totalValues = pool.getTotalValues();
+    Map<String, Object> totalValues = pool.getTotalValues();
     // pool limits are defined using controlled tags
     pool.getPoolLimits().forEach((poolLimitName, value) -> {
       // only numeric limits are supported
@@ -150,8 +146,12 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
       if (monitoredTag == null) {
         return;
       }
-      Number totalValue = totalValues.get(monitoredTag);
-      if (totalValue == null || totalValue.floatValue() <= 0.0f) {
+      Object tv = totalValues.get(monitoredTag);
+      if (tv == null || !(tv instanceof Number)) {
+        return;
+      }
+      Number totalValue = (Number) tv;
+      if (totalValue.floatValue() <= 0.0f) {
         return;
       }
       float totalDelta = poolLimitValue - totalValue.floatValue();
@@ -164,7 +164,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
       float changeRatio = poolLimitValue / totalValue.floatValue();
       // modify current limits by the changeRatio
       pool.getComponents().forEach((name, component) -> {
-        Map<String, Object> resourceLimits = getResourceLimits((ManagedCacheComponent)component);
+        Map<String, Object> resourceLimits = getResourceLimits((SolrCache) component);
         Object limit = resourceLimits.get(poolLimitName);
         // XXX we could attempt here to control eg. ramBytesUsed by adjusting maxSize limit
         // XXX and vice versa if the current limit is undefined or unsupported
@@ -172,12 +172,12 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
           return;
         }
         float currentResourceLimit = ((Number)limit).floatValue();
-        if (currentResourceLimit <= 0) {
+        if (currentResourceLimit <= 0) { // undefined or unsupported
           return;
         }
         float newLimit = currentResourceLimit * changeRatio;
         try {
-          setResourceLimit((ManagedCacheComponent)component, poolLimitName, newLimit);
+          setResourceLimit((SolrCache) component, poolLimitName, newLimit);
         } catch (Exception e) {
           log.warn("Failed to set managed limit " + poolLimitName +
               " from " + currentResourceLimit + " to " + newLimit + " on " + component.getManagedComponentId(), e);
diff --git a/solr/core/src/java/org/apache/solr/managed/types/ManagedCacheComponent.java b/solr/core/src/java/org/apache/solr/managed/types/ManagedCacheComponent.java
deleted file mode 100644
index d36a842..0000000
--- a/solr/core/src/java/org/apache/solr/managed/types/ManagedCacheComponent.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.apache.solr.managed.types;
-
-import org.apache.lucene.util.Accountable;
-import org.apache.solr.managed.ManagedComponent;
-
-/**
- *
- */
-public interface ManagedCacheComponent extends ManagedComponent, Accountable {
-  /** Set maximum cache size limit (number of items). */
-  void setMaxSize(int size);
-  /** Set maximum cache size limit (in MB of RAM). */
-  void setMaxRamMB(int maxRamMB);
-  /** Get the configured maximum size limit (number of items). */
-  int getMaxSize();
-  /** Get the configured maximym size limit (in MB of RAM). */
-  int getMaxRamMB();
-  /** Get the current number of items in cache. */
-  int getSize();
-  /** Get the ratio of hits to lookups. */
-  float getHitRatio();
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/types/package-info.java b/solr/core/src/java/org/apache/solr/managed/types/package-info.java
index 5dd0a71..a7dde4d 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/package-info.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/package-info.java
@@ -16,6 +16,7 @@
  */
 
 /**
- * Implementations of {@link org.apache.solr.managed.ResourceManagerPlugin}.
+ * Implementations of {@link org.apache.solr.managed.ResourceManagerPlugin} specialized for
+ * particular types of objects.
  */
 package org.apache.solr.managed.types;
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index 82271ad..32837f6 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -37,6 +37,8 @@ import com.github.benmanes.caffeine.cache.RemovalListener;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.managed.ManagedComponentId;
+import org.apache.solr.managed.ManagedContext;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.slf4j.Logger;
@@ -103,7 +105,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
     super.init(args, regenerator);
     String str = (String) args.get(SIZE_PARAM);
     maxSize = (str == null) ? 1024 : Integer.parseInt(str);
-    str = (String) args.get("initialSize");
+    str = (String) args.get(INITIAL_SIZE_PARAM);
     initialSize = Math.min((str == null) ? 1024 : Integer.parseInt(str), maxSize);
     str = (String) args.get(MAX_IDLE_TIME_PARAM);
     if (str == null) {
@@ -386,4 +388,14 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
     });
     solrMetricsContext.gauge(cacheMap, true, scope, getCategory().toString());
   }
+
+  @Override
+  public ManagedComponentId getManagedComponentId() {
+    return null;
+  }
+
+  @Override
+  public ManagedContext getManagedContext() {
+    return null;
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index a714155..3744895 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -16,9 +16,9 @@
  */
 package org.apache.solr.search;
 
+import org.apache.lucene.util.Accountable;
 import org.apache.solr.core.SolrInfoBean;
 import org.apache.solr.managed.ManagedComponent;
-import org.apache.solr.managed.types.ManagedCacheComponent;
 
 import java.util.Map;
 import java.util.function.Function;
@@ -27,21 +27,33 @@ import java.util.function.Function;
 /**
  * Primary API for dealing with Solr's internal caches.
  */
-public interface SolrCache<K,V> extends SolrInfoBean, ManagedCacheComponent {
+public interface SolrCache<K,V> extends SolrInfoBean, ManagedComponent, Accountable {
 
+  // current cache properties
+  /** Hit ratio. */
   String HIT_RATIO_PARAM = "hitratio";
+  /** Number of hits. */
   String HITS_PARAM = "hits";
+  /** Number of inserts. */
   String INSERTS_PARAM = "inserts";
+  /** Number of eevictions. */
   String EVICTIONS_PARAM = "evictions";
+  /** Number of lookups. */
   String LOOKUPS_PARAM = "lookups";
+  /** Current cache size. */
   String SIZE_PARAM = "size";
+  /** Maximum allowed size. */
   String MAX_SIZE_PARAM = "maxSize";
+  /** Current RAM bytes used. */
   String RAM_BYTES_USED_PARAM = "ramBytesUsed";
+  /** Maximum allowed RAM use in MB. */
   String MAX_RAM_MB_PARAM = "maxRamMB";
+  /** Maximum idle time allowed in seconds. */
   String MAX_IDLE_TIME_PARAM = "maxIdleTime";
+  /** Initial cache size. */
   String INITIAL_SIZE_PARAM = "initialSize";
+  /** Use a background thread for cache evictions and cleanup. */
   String CLEANUP_THREAD_PARAM = "cleanupThread";
-  String SHOW_ITEMS_PARAM = "showItems";
 
   /**
    * The initialization routine. Instance specific arguments are passed in
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index 2e0ea9f..88a821d 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -150,16 +150,6 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
   }
 
   @Override
-  public int getSize() {
-    return delegate.getSize();
-  }
-
-  @Override
-  public float getHitRatio() {
-    return delegate.getHitRatio();
-  }
-
-  @Override
   public long ramBytesUsed() {
     return delegate.ramBytesUsed();
   }
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
index 566fc52..4f2fbd8 100644
--- a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
@@ -139,12 +139,12 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
       manageStartLatch.countDown();
       log.info("-- managing");
       pool.getCurrentValues();
-      Map<String, Number> totalValues = pool.getTotalValues();
+      Map<String, Object> totalValues = pool.getTotalValues();
       Map<String, Object> poolLimits = pool.getPoolLimits();
       if (poolLimits.containsKey("foo")) {
         // manage
         if (totalValues.containsKey("bar")) {
-          int totalValue = totalValues.get("bar").intValue();
+          int totalValue = ((Number)totalValues.get("bar")).intValue();
           int poolLimit = ((Number)poolLimits.get("foo")).intValue();
           if (totalValue > poolLimit) {
             for (ManagedComponent cmp : pool.getComponents().values()) {
@@ -193,18 +193,18 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     resourceManager.createPool("test", "mock", Collections.singletonMap("foo", 10), Collections.emptyMap());
     assertNotNull(resourceManager.getPool("test"));
     for (int i = 0; i < 10; i++) {
-      TestComponent component = new TestComponent("test.component." + i);
+      TestComponent component = new TestComponent("test:component:" + i);
       component.setFoo(i);
       resourceManager.registerComponent("test", component);
     }
     ResourceManagerPool pool = resourceManager.getPool("test");
     assertEquals(10, pool.getComponents().size());
     pool.getCurrentValues();
-    Map<String, Number> totalValues = pool.getTotalValues();
+    Map<String, Object> totalValues = pool.getTotalValues();
     assertNotNull(totalValues.get("bar"));
-    assertEquals(55, totalValues.get("bar").intValue());
+    assertEquals(55, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
-    assertEquals(65, totalValues.get("baz").intValue());
+    assertEquals(65, ((Number)totalValues.get("baz")).intValue());
     for (ManagedComponent cmp : pool.getComponents().values()) {
       TestComponent component = (TestComponent)cmp;
       Map<String, Object> limits = pool.getResourceManagerPlugin().getResourceLimits(component);
@@ -225,9 +225,9 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     pool.getCurrentValues();
     totalValues = pool.getTotalValues();
     assertNotNull(totalValues.get("bar"));
-    assertEquals(46, totalValues.get("bar").intValue());
+    assertEquals(46, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
-    assertEquals(56, totalValues.get("baz").intValue());
+    assertEquals(56, ((Number)totalValues.get("baz")).intValue());
     int changed = 0;
     for (ManagedComponent cmp : pool.getComponents().values()) {
       TestComponent component = (TestComponent)cmp;


[lucene-solr] 06/36: Merge branch 'master' into star-123

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 23fcecaa4b914d94dec07d6cdc266d9d0b82eb02
Merge: 129a602 7ec41d1
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jul 2 16:46:42 2019 +0200

    Merge branch 'master' into star-123

 README.md                                          |    4 +
 dev-tools/scripts/jenkins.build.ref.guide.sh       |    2 +-
 lucene/CHANGES.txt                                 |   61 +-
 lucene/MIGRATE.txt                                 |    4 +
 .../lucene/analysis/et/EstonianAnalyzer.java       |  127 ++
 .../apache/lucene/analysis/et/package-info.java}   |   17 +-
 .../analysis/util/AbstractAnalysisFactory.java     |   22 +
 .../lucene/analysis/util/AnalysisSPILoader.java    |   22 +-
 .../lucene/analysis/util/CharFilterFactory.java    |    9 +
 .../lucene/analysis/util/TokenFilterFactory.java   |   11 +-
 .../lucene/analysis/util/TokenizerFactory.java     |   11 +-
 .../org/tartarus/snowball/ext/EstonianStemmer.java | 1904 ++++++++++++++++++++
 .../org/apache/lucene/analysis/et/stopwords.txt    | 1603 ++++++++++++++++
 .../lucene/analysis/et/TestEstonianAnalyzer.java   |   62 +
 .../analysis/util/TestAbstractAnalysisFactory.java |   41 +
 lucene/analysis/kuromoji/build.xml                 |   51 +-
 .../analysis/ja/dict/TokenInfoDictionary.java      |   14 +-
 .../analysis/ja/util/BinaryDictionaryWriter.java   |   72 +-
 .../ja/util/CharacterDefinitionWriter.java         |   25 +-
 .../analysis/ja/util/ConnectionCostsBuilder.java   |   62 +
 .../analysis/ja/util/ConnectionCostsWriter.java    |   30 +-
 .../lucene/analysis/ja/util/DictionaryBuilder.java |   62 +
 .../ja/util/TokenInfoDictionaryBuilder.java        |  129 +-
 .../ja/util/TokenInfoDictionaryWriter.java         |   18 +-
 .../analysis/ja/util/UnknownDictionaryBuilder.java |  119 ++
 .../analysis/ja/util/UnknownDictionaryWriter.java  |    5 +-
 .../analysis/ja/dict/TokenInfoDictionary$fst.dat   |  Bin 1698570 -> 1698570 bytes
 ...ictionary.java => TokenInfoDictionaryTest.java} |   94 +-
 .../analysis/ja/util}/UnknownDictionaryTest.java   |    5 +-
 .../analysis/ja/util/ConnectionCostsBuilder.java   |   68 -
 .../lucene/analysis/ja/util/DictionaryBuilder.java |   85 -
 .../analysis/ja/util/UnknownDictionaryBuilder.java |  135 --
 .../analysis/ja/dict/TokenInfoDictionaryTest.java  |   85 -
 .../lucene/document/LatLonPointDistanceQuery.java  |  154 +-
 .../lucene/document/LatLonPointInPolygonQuery.java |   14 +-
 .../apache/lucene/document/RangeFieldQuery.java    |   16 +-
 .../java/org/apache/lucene/index/PointValues.java  |   10 +
 .../src/java/org/apache/lucene/index/Term.java     |   14 +-
 .../org/apache/lucene/search/AutomatonQuery.java   |   15 +-
 .../org/apache/lucene/search/BlendedTermQuery.java |    4 +-
 .../org/apache/lucene/search/BooleanQuery.java     |   42 +-
 .../org/apache/lucene/search/BooleanWeight.java    |   63 +-
 .../java/org/apache/lucene/search/FuzzyQuery.java  |    2 +-
 .../org/apache/lucene/search/IndexSearcher.java    |  102 +-
 .../org/apache/lucene/search/LRUQueryCache.java    |    2 +-
 .../org/apache/lucene/search/MatchesUtils.java     |   11 +
 .../org/apache/lucene/search/MultiTermQuery.java   |   26 +-
 .../search/MultiTermQueryConstantScoreWrapper.java |    2 +-
 .../org/apache/lucene/search/PointInSetQuery.java  |   51 +-
 .../org/apache/lucene/search/PointRangeQuery.java  |  132 +-
 .../org/apache/lucene/search/ScoringRewrite.java   |   12 +-
 .../org/apache/lucene/search/SynonymQuery.java     |    4 +-
 .../org/apache/lucene/search/TermInSetQuery.java   |    4 +-
 .../org/apache/lucene/search/TopTermsRewrite.java  |    2 +-
 .../org/apache/lucene/search/package-info.java     |    4 +-
 .../java/org/apache/lucene/util/ByteBlockPool.java |   18 +-
 .../src/java/org/apache/lucene/util/BytesRef.java  |    4 +-
 .../java/org/apache/lucene/util/BytesRefHash.java  |   16 +-
 .../src/java/org/apache/lucene/util/IntsRef.java   |    2 +-
 .../java/org/apache/lucene/util/LongBitSet.java    |    9 +-
 .../java/org/apache/lucene/util/QueryBuilder.java  |    9 +-
 .../org/apache/lucene/util/RamUsageEstimator.java  |  284 ++-
 .../lucene/util/automaton/CompiledAutomaton.java   |   17 +-
 .../apache/lucene/util/automaton/RunAutomaton.java |   17 +-
 .../java/org/apache/lucene/util/bkd/BKDReader.java |  166 +-
 .../java/org/apache/lucene/util/bkd/BKDWriter.java |  148 +-
 .../apache/lucene/util/bkd/HeapPointWriter.java    |   19 +
 .../java/org/apache/lucene/util/fst/FSTStore.java  |    1 +
 .../apache/lucene/util/fst/OffHeapFSTStore.java    |    5 +
 .../org/apache/lucene/util/fst/OnHeapFSTStore.java |   12 +-
 .../lucene/document/TestFeatureDoubleValues.java   |   16 +-
 .../org/apache/lucene/search/TestBooleanQuery.java |    2 +-
 .../apache/lucene/search/TestMaxClauseLimit.java   |  132 ++
 .../lucene/search/TestMultiTermQueryRewrites.java  |   14 +-
 .../org/apache/lucene/search/TestPointQueries.java |   94 +
 .../apache/lucene/search/TestTermRangeQuery.java   |    6 +-
 .../org/apache/lucene/util/TestQueryBuilder.java   |    7 +-
 .../apache/lucene/util/TestRamUsageEstimator.java  |   96 +-
 .../test/org/apache/lucene/util/bkd/TestBKD.java   |   48 +-
 .../lucene/util/bkd/TestBKDRadixSelector.java      |   65 +-
 .../apache/lucene/util/bkd/TestBKDRadixSort.java   |  163 ++
 .../util/bkd/TestMutablePointsReaderUtils.java     |    1 +
 .../search/uhighlight/TestUnifiedHighlighter.java  |    4 +-
 .../lucene/search/join/GlobalOrdinalsQuery.java    |   19 +-
 .../search/join/GlobalOrdinalsWithScoreQuery.java  |   18 +-
 .../search/join/PointInSetIncludingScoreQuery.java |   17 +-
 .../search/join/TermsIncludingScoreQuery.java      |   20 +-
 .../org/apache/lucene/search/join/TermsQuery.java  |   18 +-
 .../analysis/AnalysisChainDialogFactory.java       |    9 +-
 .../lucene/luke/models/analysis/AnalysisImpl.java  |    7 +-
 .../luke/models/analysis/AnalysisImplTest.java     |    6 +-
 .../apache/lucene/misc/CollectorMemoryTracker.java |   55 +
 .../search/MemoryAccountingBitsetCollector.java    |   58 +
 .../org/apache/lucene/util/MemoryTracker.java}     |   18 +-
 .../src/java/org/apache/lucene/util/package.html   |   23 +
 .../TestMemoryAccountingBitsetCollector.java       |   69 +
 .../lucene/util/TestCollectorMemoryTracker.java    |   42 +
 .../function/valuesource/MultiBoolFunction.java    |   10 +-
 .../queries}/intervals/BlockIntervalsSource.java   |    2 +-
 .../queries}/intervals/CachingMatchesIterator.java |    2 +-
 .../lucene/queries}/intervals/ConjunctionDISI.java |    2 +-
 .../intervals/ConjunctionIntervalIterator.java     |    2 +-
 .../intervals/ConjunctionIntervalsSource.java      |    2 +-
 .../intervals/ContainedByIntervalsSource.java      |    2 +-
 .../intervals/ContainingIntervalsSource.java       |    2 +-
 .../intervals/DifferenceIntervalsSource.java       |    2 +-
 .../queries}/intervals/DisiPriorityQueue.java      |    2 +-
 .../lucene/queries}/intervals/DisiWrapper.java     |    2 +-
 .../intervals/DisjunctionDISIApproximation.java    |    2 +-
 .../intervals/DisjunctionIntervalsSource.java      |    2 +-
 .../lucene/queries}/intervals/Disjunctions.java    |    6 +-
 .../intervals/ExtendedIntervalIterator.java        |    2 +-
 .../intervals/ExtendedIntervalsSource.java         |    2 +-
 .../intervals/FilteredIntervalsSource.java         |    2 +-
 .../intervals/FilteringIntervalIterator.java       |    2 +-
 .../intervals/FixedFieldIntervalsSource.java       |    2 +-
 .../lucene/queries}/intervals/IntervalFilter.java  |    2 +-
 .../queries}/intervals/IntervalIterator.java       |    2 +-
 .../lucene/queries}/intervals/IntervalMatches.java |    2 +-
 .../intervals/IntervalMatchesIterator.java         |    2 +-
 .../lucene/queries}/intervals/IntervalQuery.java   |    2 +-
 .../queries}/intervals/IntervalScoreFunction.java  |    2 +-
 .../lucene/queries}/intervals/IntervalScorer.java  |    2 +-
 .../lucene/queries}/intervals/Intervals.java       |   16 +-
 .../lucene/queries}/intervals/IntervalsSource.java |    2 +-
 .../MinimizingConjunctionMatchesIterator.java      |    2 +-
 .../MinimumShouldMatchIntervalsSource.java         |    2 +-
 .../intervals/MultiTermIntervalsSource.java        |    8 +-
 .../intervals/NonOverlappingIntervalsSource.java   |    2 +-
 .../intervals/NotContainedByIntervalsSource.java   |    2 +-
 .../intervals/NotContainingIntervalsSource.java    |    2 +-
 .../queries}/intervals/OffsetIntervalsSource.java  |    2 +-
 .../queries}/intervals/OrderedIntervalsSource.java |    2 +-
 .../intervals/OverlappingIntervalsSource.java      |    2 +-
 .../PayloadFilteredTermIntervalsSource.java        |    2 +-
 .../queries}/intervals/RelativeIterator.java       |    2 +-
 .../queries}/intervals/TermIntervalsSource.java    |    2 +-
 .../intervals/UnorderedIntervalsSource.java        |    2 +-
 .../lucene/queries/intervals/package-info.java     |   68 +
 .../apache/lucene/queries/mlt/MoreLikeThis.java    |    5 +-
 .../lucene/queries/function/TestValueSources.java  |   26 +
 .../intervals/TestDisjunctionRewrites.java         |    4 +-
 .../queries}/intervals/TestIntervalQuery.java      |    2 +-
 .../lucene/queries}/intervals/TestIntervals.java   |   13 +-
 .../intervals/TestPayloadFilteredInterval.java     |    2 +-
 .../queries}/intervals/TestSimplifications.java    |    2 +-
 .../queryparser/classic/QueryParserBase.java       |    4 +-
 .../standard/builders/AnyQueryNodeBuilder.java     |    2 +-
 .../standard/builders/BooleanQueryNodeBuilder.java |    5 +-
 .../precedence/TestPrecedenceQueryParser.java      |    7 +-
 .../flexible/standard/TestQPHelper.java            |    6 +-
 .../queryparser/util/QueryParserTestBase.java      |    6 +-
 .../apache/lucene/document/LatLonShapeQuery.java   |   39 +-
 .../java/org/apache/lucene/search/BM25FQuery.java  |   29 +-
 .../org/apache/lucene/search/CoveringQuery.java    |   18 +-
 .../lucene/search/DocValuesNumbersQuery.java       |   12 +-
 .../apache/lucene/search/DocValuesTermsQuery.java  |   12 +-
 .../IndexSortSortedNumericDocValuesRangeQuery.java |  301 ++++
 .../java/org/apache/lucene/search/LongHashSet.java |   11 +-
 .../apache/lucene/search/TermAutomatonQuery.java   |   16 +-
 .../lucene/search/intervals/package-info.java      |   68 -
 .../lucene/document/BaseLatLonShapeTestCase.java   |   19 +
 ...tIndexSortSortedNumericDocValuesRangeQuery.java |  446 +++++
 .../lucene/spatial3d/PointInGeo3DShapeQuery.java   |   14 +-
 .../document/Completion50PostingsFormat.java       |   15 +-
 .../suggest/document/CompletionFieldsProducer.java |    5 +-
 .../suggest/document/CompletionPostingsFormat.java |   34 +-
 .../suggest/document/CompletionsTermsReader.java   |    8 +-
 .../search/suggest/document/ContextQuery.java      |   20 +-
 .../search/suggest/document/NRTSuggester.java      |   36 +-
 .../suggest/document/NRTSuggesterBuilder.java      |    5 +-
 .../search/suggest/document/TestSuggestField.java  |    5 +-
 .../apache/lucene/geo/BaseGeoPointTestCase.java    |   23 +
 .../lucene/search/BaseRangeFieldQueryTestCase.java |   29 +
 .../util/TestRuleSetupAndRestoreInstanceEnv.java   |    6 +-
 solr/CHANGES.txt                                   |   37 +
 solr/bin/solr.in.cmd                               |    5 +
 solr/bin/solr.in.sh                                |    5 +
 .../function/field/AbstractAnalyticsFieldTest.java |    5 +-
 .../legacy/LegacyAbstractAnalyticsCloudTest.java   |    1 -
 .../dataimport/TestContentStreamDataSource.java    |    5 +-
 .../dataimport/TestHierarchicalDocBuilder.java     |    5 +-
 .../handler/dataimport/TestJdbcDataSource.java     |    4 +-
 .../TestSolrEntityProcessorEndToEnd.java           |   10 +-
 .../handler/dataimport/TestZKPropertiesWriter.java |   14 +-
 .../org/apache/solr/ltr/TestLTROnSolrCloud.java    |    5 +-
 .../test/org/apache/solr/ltr/TestRerankBase.java   |   17 +-
 .../prometheus/scraper/SolrCloudScraperTest.java   |    5 +-
 .../scraper/SolrStandaloneScraperTest.java         |   10 +-
 .../solr/cloud/autoscaling/ScheduledTrigger.java   |    9 +-
 .../java/org/apache/solr/core/BlobRepository.java  |   54 +-
 .../apache/solr/core/CachingDirectoryFactory.java  |  106 +-
 .../src/java/org/apache/solr/core/CloudConfig.java |   20 +-
 .../org/apache/solr/core/ConfigSetProperties.java  |    4 +-
 .../java/org/apache/solr/core/CoreContainer.java   |  213 +--
 .../src/java/org/apache/solr/core/NodeConfig.java  |    3 +-
 .../src/java/org/apache/solr/core/SolrConfig.java  |    8 +-
 .../src/java/org/apache/solr/core/SolrCore.java    |  591 +++---
 .../solr/handler/admin/CollectionsHandler.java     |  124 +-
 .../apache/solr/handler/admin/SolrEnvironment.java |   94 +
 .../solr/handler/admin/SystemInfoHandler.java      |   11 +
 .../solr/handler/component/QueryComponent.java     |   29 +-
 .../apache/solr/handler/component/StatsField.java  |   12 +-
 .../apache/solr/parser/SolrQueryParserBase.java    |    3 +-
 .../java/org/apache/solr/query/SolrRangeQuery.java |   17 +-
 .../org/apache/solr/schema/AbstractEnumField.java  |   14 +-
 .../java/org/apache/solr/schema/BinaryField.java   |    8 +
 .../src/java/org/apache/solr/schema/BoolField.java |    7 +
 .../src/java/org/apache/solr/schema/UUIDField.java |    8 +
 .../solr/search/CollapsingQParserPlugin.java       |   41 +-
 .../src/java/org/apache/solr/search/QParser.java   |    9 +-
 .../java/org/apache/solr/search/QueryUtils.java    |    3 +-
 .../TopGroupsShardResponseProcessor.java           |   29 +-
 .../MainEndResultTransformer.java                  |   45 +-
 .../SimpleEndResultTransformer.java                |   35 +-
 .../org/apache/solr/update/SolrIndexConfig.java    |   10 +
 .../conf/solrconfig.snippet.randomindexconfig.xml  |    1 +
 .../solr/configsets/_default/conf/solrconfig.xml   |    9 +
 .../org/apache/solr/TestDistributedGrouping.java   |   42 +-
 .../test/org/apache/solr/TestGroupingSearch.java   |   15 +-
 .../test/org/apache/solr/TestTolerantSearch.java   |   18 +-
 .../embedded/TestEmbeddedSolrServerSchemaAPI.java  |    6 +-
 .../org/apache/solr/cloud/CleanupOldIndexTest.java |    2 +-
 .../apache/solr/cloud/CreateRoutedAliasTest.java   |    5 +-
 .../apache/solr/cloud/DistributedQueueTest.java    |    9 +-
 .../solr/cloud/LeaderVoteWaitTimeoutTest.java      |    6 +-
 .../solr/cloud/MissingSegmentRecoveryTest.java     |    4 +
 .../OverseerCollectionConfigSetProcessorTest.java  |   12 +-
 .../test/org/apache/solr/cloud/RecoveryZkTest.java |   23 +-
 .../apache/solr/cloud/ReindexCollectionTest.java   |    5 +-
 .../org/apache/solr/cloud/SolrCLIZkUtilsTest.java  |    6 +-
 .../solr/cloud/SystemCollectionCompatTest.java     |    5 +-
 .../apache/solr/cloud/TestCloudConsistency.java    |    8 +-
 .../apache/solr/cloud/TestCloudDeleteByQuery.java  |   30 +-
 .../TestCloudPhrasesIdentificationComponent.java   |    5 +-
 .../solr/cloud/TestCloudPseudoReturnFields.java    |    5 +-
 .../solr/cloud/TestCloudSearcherWarming.java       |    9 +-
 .../org/apache/solr/cloud/TestConfigSetsAPI.java   |    5 +-
 .../solr/cloud/TestConfigSetsAPIExclusivity.java   |    5 +-
 .../solr/cloud/TestConfigSetsAPIZkFailure.java     |   10 +-
 .../org/apache/solr/cloud/TestDistributedMap.java  |    6 +-
 .../solr/cloud/TestMiniSolrCloudClusterSSL.java    |    2 -
 .../solr/cloud/TestPullReplicaErrorHandling.java   |    8 +-
 .../apache/solr/cloud/TestRandomFlRTGCloud.java    |    5 +-
 .../apache/solr/cloud/TestSSLRandomization.java    |    2 -
 .../cloud/TestSolrCloudWithDelegationTokens.java   |   14 +-
 .../cloud/TestStressCloudBlindAtomicUpdates.java   |   12 +-
 .../org/apache/solr/cloud/TestStressLiveNodes.java |    6 +-
 .../test/org/apache/solr/cloud/TestZkChroot.java   |    7 +-
 .../test/org/apache/solr/cloud/ZkFailoverTest.java |   11 -
 .../ConcurrentDeleteAndCreateCollectionTest.java   |    5 +-
 .../collections/TestHdfsCloudBackupRestore.java    |    3 -
 .../cloud/autoscaling/IndexSizeTriggerTest.java    |    2 +-
 .../autoscaling/sim/TestSimComputePlanAction.java  |    5 +
 .../autoscaling/sim/TestSimExecutePlanAction.java  |    5 +
 .../solr/cloud/cdcr/CdcrOpsAndBoundariesTest.java  |   12 +-
 .../solr/cloud/cdcr/CdcrWithNodesRestartsTest.java |   12 +-
 .../src/test/org/apache/solr/core/TestConfig.java  |    7 +-
 .../org/apache/solr/handler/TestCSVLoader.java     |    5 +-
 .../solr/handler/TestReplicationHandler.java       |   74 +-
 .../solr/handler/TestReplicationHandlerBackup.java |   12 +-
 .../TestReplicationHandlerDiskOverFlow.java        |   22 +-
 .../org/apache/solr/handler/TestRestoreCore.java   |   12 +-
 .../solr/handler/admin/DaemonStreamApiTest.java    |    5 +-
 .../solr/handler/admin/MetricsHandlerTest.java     |    8 +-
 .../solr/handler/admin/SolrEnvironmentTest.java    |   73 +
 .../component/DistributedDebugComponentTest.java   |   18 +-
 .../solr/highlight/TestUnifiedSolrHighlighter.java |    5 +
 .../apache/solr/index/hdfs/CheckHdfsIndexTest.java |    4 +-
 .../solr/legacy/TestNumericRangeQuery32.java       |   15 +-
 .../solr/legacy/TestNumericRangeQuery64.java       |   15 +-
 .../solr/metrics/SolrCoreMetricManagerTest.java    |    8 +-
 .../solr/metrics/SolrMetricsIntegrationTest.java   |    4 +
 .../metrics/reporters/SolrJmxReporterTest.java     |    3 +
 .../analysis/TestManagedStopFilterFactory.java     |    6 +-
 .../analysis/TestManagedSynonymFilterFactory.java  |   11 +-
 .../TestManagedSynonymGraphFilterFactory.java      |   10 +-
 .../solr/schema/TestManagedSchemaThreadSafety.java |    6 +-
 .../solr/schema/TestUseDocValuesAsStored.java      |    1 -
 .../org/apache/solr/search/QueryParsingTest.java   |   46 +-
 .../solr/search/TestCollapseQParserPlugin.java     |   51 +-
 .../solr/search/TestExtendedDismaxParser.java      |   76 +-
 .../apache/solr/search/TestSolrQueryParser.java    |    5 +-
 .../search/facet/TestCloudJSONFacetJoinDomain.java |    5 +-
 .../solr/search/facet/TestCloudJSONFacetSKG.java   |    5 +-
 .../apache/solr/search/function/TestOrdValues.java |    4 +-
 .../solr/search/join/BlockJoinFacetRandomTest.java |    8 +-
 .../solr/search/mlt/CloudMLTQParserTest.java       |    4 +-
 .../solr/security/AuditLoggerIntegrationTest.java  |    4 +-
 .../solr/security/AuditLoggerPluginTest.java       |    7 +-
 .../solr/security/BasicAuthIntegrationTest.java    |   15 +-
 .../solr/security/BasicAuthStandaloneTest.java     |    5 +-
 .../apache/solr/security/JWTAuthPluginTest.java    |    5 +-
 .../security/SolrLogAuditLoggerPluginTest.java     |    7 +-
 .../apache/solr/servlet/ResponseHeaderTest.java    |    4 +-
 .../solr/store/blockcache/BlockDirectoryTest.java  |    5 +-
 .../apache/solr/uninverting/TestFieldCache.java    |   12 +-
 .../solr/uninverting/TestLegacyFieldCache.java     |   12 +-
 .../solr/uninverting/TestNumericTerms32.java       |   14 +-
 .../solr/uninverting/TestNumericTerms64.java       |   14 +-
 .../org/apache/solr/update/AddBlockUpdateTest.java |    7 +-
 .../apache/solr/update/MaxSizeAutoCommitTest.java  |    6 +-
 .../apache/solr/update/SolrIndexConfigTest.java    |    2 +
 .../CategoryRoutedAliasUpdateProcessorTest.java    |   10 +-
 .../ClassificationUpdateProcessorTest.java         |   15 +-
 .../ParsingFieldUpdateProcessorsTest.java          |  189 +-
 .../TimeRoutedAliasUpdateProcessorTest.java        |    4 +-
 .../test/org/apache/solr/util/AuthToolTest.java    |    5 +-
 .../test/org/apache/solr/util/UtilsToolTest.java   |    5 +-
 .../solr/configsets/_default/conf/solrconfig.xml   |    9 +
 .../conf/solrconfig.xml                            |    9 +
 solr/solr-ref-guide/src/highlighting.adoc          |   11 +-
 .../src/indexconfig-in-solrconfig.adoc             |   11 +
 solr/solr-ref-guide/src/json-facet-api.adoc        |    2 +-
 .../src/rule-based-authorization-plugin.adoc       |   21 +-
 .../src/stream-decorator-reference.adoc            |    2 +-
 .../src/taking-solr-to-production.adoc             |    9 +
 .../java/org/apache/solr/client/solrj/io/Lang.java |    1 +
 .../solr/client/solrj/io/eval/KmeansEvaluator.java |    6 +-
 .../solrj/io/eval/ProjectToBorderEvaluator.java    |   65 +
 .../solr/client/solrj/io/stream/DaemonStream.java  |   38 +-
 .../solr/client/solrj/io/stream/ZplotStream.java   |   28 +-
 .../apache/solr/common/cloud/ZkStateReader.java    |  258 +--
 .../solr/autoscaling/testEmptyCollection.json      |   27 +
 .../client/solrj/cloud/autoscaling/TestPolicy.java |   68 +
 .../solrj/impl/HttpSolrClientConPoolTest.java      |    6 +-
 .../impl/HttpSolrClientSSLAuthConPoolTest.java     |    3 -
 .../org/apache/solr/client/solrj/io/TestLang.java  |    2 +-
 .../client/solrj/io/stream/MathExpressionTest.java |   40 +-
 .../common/cloud/TestCollectionStateWatchers.java  |    4 +-
 .../common/cloud/TestDocCollectionWatcher.java     |    4 +-
 .../solr/common/cloud/TestZkConfigManager.java     |    4 +-
 .../src/java/org/apache/solr/SolrTestCase.java     |   30 +
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |   10 +-
 .../java/org/apache/solr/util/SSLTestConfig.java   |   60 +-
 .../org/apache/solr/util/TestSSLTestConfig.java    |   87 +
 solr/webapp/web/css/angular/common.css             |    8 +-
 solr/webapp/web/index.html                         |    4 +-
 solr/webapp/web/js/angular/app.js                  |   12 +
 339 files changed, 10174 insertions(+), 2373 deletions(-)


[lucene-solr] 07/36: Merge branch 'master' into star-123

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 682f72d1011dbbf4b2d42f7485604c29da4e389d
Merge: 23fceca 66812b2
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 4 11:41:50 2019 +0200

    Merge branch 'master' into star-123

 lucene/CHANGES.txt                                 |    7 +
 lucene/MIGRATE.txt                                 |    8 +
 .../ja/util/TokenInfoDictionaryBuilder.java        |    2 +-
 .../ko/util/TokenInfoDictionaryBuilder.java        |    2 +-
 .../blocktreeords/OrdsBlockTreeTermsWriter.java    |    2 +-
 .../codecs/blocktreeords/OrdsSegmentTermsEnum.java |    2 +-
 .../codecs/blocktree/BlockTreeTermsWriter.java     |    2 +-
 .../codecs/lucene50/Lucene50PostingsReader.java    |  130 +-
 .../org/apache/lucene/search/IndexSearcher.java    |    4 +-
 .../org/apache/lucene/search/LRUQueryCache.java    |   17 +-
 .../org/apache/lucene/search/TermInSetQuery.java   |    2 +-
 .../src/java/org/apache/lucene/search/TopDocs.java |  140 +-
 .../org/apache/lucene/util/RamUsageEstimator.java  |   10 +
 .../java/org/apache/lucene/util/fst/Builder.java   |    9 +-
 .../src/java/org/apache/lucene/util/fst/FST.java   |    3 +-
 .../src/java/org/apache/lucene/util/fst/Util.java  |    1 +
 .../apache/lucene/search/TestLRUQueryCache.java    |   14 +-
 .../apache/lucene/search/TestMultiSliceMerge.java  |  129 ++
 .../org/apache/lucene/search/TestTopDocsMerge.java |   24 +-
 .../test/org/apache/lucene/util/fst/Test2BFST.java |    6 +-
 .../test/org/apache/lucene/util/fst/TestFSTs.java  |    8 +-
 .../org/apache/lucene/util/fst/TestFstDirect.java  |  133 +-
 .../apache/lucene/search/grouping/TopGroups.java   |    5 +
 .../idversion/VersionBlockTreeTermsWriter.java     |    2 +-
 .../search/suggest/fst/FSTCompletionBuilder.java   |    2 +-
 .../lucene/search/ShardSearchingTestBase.java      |   12 +
 .../java/org/apache/lucene/util/fst/FSTTester.java |    2 +-
 solr/CHANGES.txt                                   |   26 +
 .../solr/handler/dataimport/DataImportHandler.java |   11 +-
 .../AbstractDataImportHandlerTestCase.java         |   13 +-
 .../java/org/apache/solr/ltr/LTRScoringQuery.java  |   14 +-
 .../java/org/apache/solr/ltr/feature/Feature.java  |   12 +-
 .../org/apache/solr/ltr/model/LTRScoringModel.java |   16 +-
 .../org/apache/solr/ltr/model/WrapperModel.java    |    5 +
 .../apache/solr/ltr/model/TestWrapperModel.java    |    6 +
 .../solr/cloud/api/collections/AddReplicaCmd.java  |    9 +-
 .../solr/cloud/api/collections/BackupCmd.java      |    9 +-
 .../cloud/api/collections/CreateCollectionCmd.java |    2 +-
 .../solr/cloud/api/collections/CreateShardCmd.java |    9 +-
 .../cloud/api/collections/CreateSnapshotCmd.java   |   10 +-
 .../cloud/api/collections/DeleteCollectionCmd.java |   26 +-
 .../cloud/api/collections/DeleteReplicaCmd.java    |    9 +-
 .../solr/cloud/api/collections/DeleteShardCmd.java |    9 +-
 .../cloud/api/collections/DeleteSnapshotCmd.java   |    9 +-
 .../solr/cloud/api/collections/MigrateCmd.java     |   13 +-
 .../solr/cloud/api/collections/MoveReplicaCmd.java |    9 +-
 .../api/collections/ReindexCollectionCmd.java      |   18 +-
 .../solr/cloud/api/collections/RenameCmd.java      |   11 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |    9 +-
 .../src/java/org/apache/solr/core/PluginBag.java   |    2 +-
 .../solr/handler/admin/CollectionsHandler.java     |   66 +-
 .../solr/handler/admin/ZookeeperInfoHandler.java   |   51 +-
 .../solr/handler/component/QueryComponent.java     |   19 +-
 .../java/org/apache/solr/request/SimpleFacets.java |    2 +-
 .../src/java/org/apache/solr/search/DocSlice.java  |    4 +-
 .../java/org/apache/solr/search/FastLRUCache.java  |   18 +-
 .../solr/search/GraphTermsQParserPlugin.java       |   14 +-
 .../src/java/org/apache/solr/search/LFUCache.java  |   20 +-
 .../src/java/org/apache/solr/search/LRUCache.java  |   49 +-
 .../org/apache/solr/search/QueryResultKey.java     |   21 +-
 .../search/grouping/GroupingSpecification.java     |   45 -
 .../SearchGroupShardResponseProcessor.java         |    4 +-
 .../TopGroupsShardResponseProcessor.java           |   18 +-
 .../TopGroupsResultTransformer.java                |    4 +-
 .../GroupedEndResultTransformer.java               |    6 +-
 .../MainEndResultTransformer.java                  |    4 +-
 .../SimpleEndResultTransformer.java                |    4 +-
 .../org/apache/solr/util/ConcurrentLFUCache.java   |   54 +-
 .../org/apache/solr/util/ConcurrentLRUCache.java   |   78 +-
 .../configsets/_default/conf/lang/stopwords_et.txt | 1603 ++++++++++++++++++++
 .../solr/configsets/_default/conf/managed-schema   |   13 +-
 .../apache/solr/cloud/CollectionsAPISolrJTest.java |  166 +-
 .../apache/solr/cloud/ReindexCollectionTest.java   |   19 +-
 .../apache/solr/cloud/ReplicationFactorTest.java   |   63 +-
 .../org/apache/solr/core/QueryResultKeyTest.java   |    1 +
 .../org/apache/solr/search/TestFastLRUCache.java   |   32 +
 .../test/org/apache/solr/search/TestLFUCache.java  |   49 +
 .../test/org/apache/solr/search/TestLRUCache.java  |   11 +-
 .../configsets/_default/conf/lang/stopwords_et.txt | 1603 ++++++++++++++++++++
 .../solr/configsets/_default/conf/managed-schema   |   13 +-
 .../conf/lang/stopwords_et.txt                     | 1603 ++++++++++++++++++++
 .../conf/managed-schema                            |   12 +-
 solr/solr-ref-guide/src/aliases.adoc               |    8 +-
 solr/solr-ref-guide/src/language-analysis.adoc     |   28 +
 ...ta-store-data-with-the-data-import-handler.adoc |    2 +-
 .../solrj/request/CollectionAdminRequest.java      |    6 +
 .../solr/common/params/CollectionAdminParams.java  |    3 +
 87 files changed, 6053 insertions(+), 598 deletions(-)



[lucene-solr] 13/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 386ee2d24dcb782b90f55265dfd166ef3fc3976e
Merge: 3d735b6 15b08f9
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 18 15:06:02 2019 +0200

    Merge branch 'master' into jira/solr-13579

 .github/PULL_REQUEST_TEMPLATE.md                   |  14 +-
 lucene/CHANGES.txt                                 |  42 +-
 .../java/org/apache/lucene/index/FieldInfos.java   |  10 +-
 .../java/org/apache/lucene/index/IndexWriter.java  |  16 -
 .../org/apache/lucene/search/BooleanQuery.java     |  28 +
 .../java/org/apache/lucene/search/PhraseQuery.java |   7 +
 .../org/apache/lucene/search/TestPhraseQuery.java  |  11 +
 .../lucene/document/FloatPointNearestNeighbor.java |  31 +-
 .../lucene/document/BaseLatLonShapeTestCase.java   |   2 +-
 solr/CHANGES.txt                                   |  29 +
 .../org/apache/solr/cloud/OverseerTaskQueue.java   |  59 +-
 .../solr/cloud/api/collections/AliasCmd.java       |  29 +-
 .../cloud/api/collections/CategoryRoutedAlias.java | 142 ++--
 .../solr/cloud/api/collections/CreateAliasCmd.java |   3 +-
 .../cloud/api/collections/DeleteCollectionCmd.java |  18 +-
 .../api/collections/DimensionalRoutedAlias.java    | 365 +++++++++++
 .../MaintainCategoryRoutedAliasCmd.java            | 183 ------
 .../api/collections/MaintainRoutedAliasCmd.java    | 182 ++++++
 .../collections/MaintainTimeRoutedAliasCmd.java    | 257 --------
 .../OverseerCollectionMessageHandler.java          |  37 +-
 .../solr/cloud/api/collections/RoutedAlias.java    | 392 +++++++++--
 .../cloud/api/collections/TimeRoutedAlias.java     | 468 ++++++-------
 .../java/org/apache/solr/core/CoreContainer.java   |   7 +
 .../solr/handler/admin/BaseHandlerApiSupport.java  |  29 +
 .../solr/handler/admin/CollectionsHandler.java     |  27 +-
 .../java/org/apache/solr/request/SimpleFacets.java |   4 +-
 .../processor/AtomicUpdateDocumentMerger.java      |   5 -
 .../processor/RoutedAliasUpdateProcessor.java      |   6 +-
 .../collection1/conf/schema-inplace-updates.xml    |   1 +
 .../apache/solr/cloud/AliasIntegrationTest.java    |  30 +-
 .../apache/solr/cloud/CreateRoutedAliasTest.java   |   5 +-
 .../apache/solr/core/TestDynamicLoadingUrl.java    | 154 ++---
 .../{ => component}/ResponseBuilderTest.java       |   3 +-
 .../org/apache/solr/request/SimpleFacetsTest.java  |  33 +
 .../solr/update/TestInPlaceUpdatesDistrib.java     |  41 +-
 .../solr/update/TestInPlaceUpdatesStandalone.java  |  97 ++-
 .../CategoryRoutedAliasUpdateProcessorTest.java    |   6 +
 .../DimensionalRoutedAliasUpdateProcessorTest.java | 726 +++++++++++++++++++++
 .../processor/RoutedAliasUpdateProcessorTest.java  |  68 +-
 .../TimeRoutedAliasUpdateProcessorTest.java        | 175 +++--
 solr/solr-ref-guide/src/aliases.adoc               | 126 +++-
 solr/solr-ref-guide/src/collection-aliasing.adoc   | 209 +++++-
 .../apache/solr/client/solrj/RoutedAliasTypes.java |  47 ++
 .../solrj/request/CollectionAdminRequest.java      | 174 ++++-
 .../solr/common/cloud/ConnectionManager.java       |  41 +-
 .../common/cloud/ZkClientConnectionStrategy.java   |  36 +-
 .../solr/common/params/CollectionParams.java       |   3 +-
 .../resources/apispec/collections.Commands.json    |   8 +
 solr/webapp/build.xml                              |   4 +-
 solr/webapp/web/index.html                         |   4 +-
 50 files changed, 3160 insertions(+), 1234 deletions(-)



[lucene-solr] 20/36: Rename ResourceContext to ManagedContext.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit f06fae4d1819787277b3cb7fdb5f156d9170e515
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 25 18:09:13 2019 +0200

    Rename ResourceContext to ManagedContext.
---
 .../java/org/apache/solr/managed/DefaultResourceManagerPool.java   | 4 ++--
 solr/core/src/java/org/apache/solr/managed/ManagedComponent.java   | 2 +-
 .../solr/managed/{ResourceContext.java => ManagedContext.java}     | 2 +-
 .../core/src/java/org/apache/solr/managed/NoOpResourceManager.java | 2 +-
 .../core/src/java/org/apache/solr/managed/ResourceManagerPool.java | 2 +-
 solr/core/src/java/org/apache/solr/search/FastLRUCache.java        | 7 +++++++
 solr/core/src/java/org/apache/solr/search/LFUCache.java            | 7 +++++++
 solr/core/src/java/org/apache/solr/search/LRUCache.java            | 7 +++++++
 8 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index b966336..efe892d 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -43,7 +43,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
-  private final ResourceContext poolContext = new ResourceContext();
+  private final ManagedContext poolContext = new ManagedContext();
   private Map<String, Float> totalValues = null;
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
@@ -164,7 +164,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public ResourceContext getPoolContext() {
+  public ManagedContext getPoolContext() {
     return poolContext;
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index c8d3dba..2b9e6b8 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -83,5 +83,5 @@ public interface ManagedComponent {
    * Component context used for managing additional component state.
    * @return component's context
    */
-  ResourceContext getManagedContext();
+  ManagedContext getManagedContext();
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceContext.java b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
similarity index 92%
rename from solr/core/src/java/org/apache/solr/managed/ResourceContext.java
rename to solr/core/src/java/org/apache/solr/managed/ManagedContext.java
index 0c8e5a3..74919ee 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceContext.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
@@ -21,6 +21,6 @@ import java.util.concurrent.ConcurrentHashMap;
 /**
  *
  */
-public class ResourceContext extends ConcurrentHashMap<String, Object> {
+public class ManagedContext extends ConcurrentHashMap<String, Object> {
 
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index cd94afe..e2e12eb 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -84,7 +84,7 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public ResourceContext getPoolContext() {
+    public ManagedContext getPoolContext() {
       return null;
     }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 3a3bd78..783dc99 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -49,5 +49,5 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   /**
    * Pool context used for managing additional pool state.
    */
-  ResourceContext getPoolContext();
+  ManagedContext getPoolContext();
 }
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 3f40135..2fb9ada 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -21,6 +21,7 @@ import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
+import org.apache.solr.managed.ManagedContext;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -83,6 +84,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
   private ManagedComponentId managedComponentId;
+  private final ManagedContext managedContext = new ManagedContext();
 
   @Override
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
@@ -354,6 +356,11 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   }
 
   @Override
+  public ManagedContext getManagedContext() {
+    return managedContext;
+  }
+
+  @Override
   public ManagedComponentId getManagedComponentId() {
     return managedComponentId;
   }
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index a4dd8ff..28decac 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -32,6 +32,7 @@ import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
+import org.apache.solr.managed.ManagedContext;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -84,6 +85,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
   private ManagedComponentId managedComponentId;
+  private final ManagedContext managedContext = new ManagedContext();
 
   private int maxSize;
   private int minSize;
@@ -353,6 +355,11 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   @Override
+  public ManagedContext getManagedContext() {
+    return managedContext;
+  }
+
+  @Override
   public ManagedComponentId getManagedComponentId() {
     return managedComponentId;
   }
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index c62d4fd..b4669bc 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -34,6 +34,7 @@ import org.apache.lucene.util.Accountables;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
+import org.apache.solr.managed.ManagedContext;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -82,6 +83,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   private int maxSize;
   private int initialSize;
   private ManagedComponentId managedComponentId;
+  private final ManagedContext managedContext = new ManagedContext();
 
   private long maxRamBytes = Long.MAX_VALUE;
   // The synchronization used for the map will be used to update this,
@@ -386,6 +388,11 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   }
 
   @Override
+  public ManagedContext getManagedContext() {
+    return managedContext;
+  }
+
+  @Override
   public ManagedComponentId getManagedComponentId() {
     return managedComponentId;
   }


[lucene-solr] 08/36: Next iteration.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit adde6ba2b4dd6e91a72aec891d929a481155b897
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 4 13:18:48 2019 +0200

    Next iteration.
---
 .../solr/managed/DefaultResourceManager.java       |  21 ++++-
 .../apache/solr/managed/ManagedMetricProducer.java |  36 +++++++
 .../org/apache/solr/managed/ManagedResource.java   |   6 +-
 .../org/apache/solr/managed/ResourceManager.java   |  12 ++-
 .../apache/solr/managed/ResourceManagerPlugin.java |   2 +-
 .../apache/solr/managed/ResourceManagerPool.java   | 103 +++++++++++++++------
 .../solr/managed/plugins/CacheManagerPlugin.java   |  47 ++++++----
 7 files changed, 166 insertions(+), 61 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index 743b1d9..3f51897 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -18,7 +18,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- *
+ * Default implementation of {@link ResourceManager}.
  */
 public class DefaultResourceManager extends ResourceManager {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -75,7 +75,7 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void createPool(String name, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception {
+  public void createPool(String name, String type, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception {
     ensureNotClosed();
     if (resourcePools.containsKey(name)) {
       throw new IllegalArgumentException("Pool '" + name + "' already exists.");
@@ -83,7 +83,7 @@ public class DefaultResourceManager extends ResourceManager {
     if (resourcePools.size() >= maxNumPools) {
       throw new IllegalArgumentException("Maximum number of pools (" + maxNumPools + ") reached.");
     }
-    ResourceManagerPool newPool = new ResourceManagerPool(name, type, resourceManagerPluginFactory, limits, params);
+    ResourceManagerPool newPool = new ResourceManagerPool(name, type, resourceManagerPluginFactory, poolLimits, params);
     newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(params.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, DEFAULT_SCHEDULE_DELAY_SECONDS)));
     resourcePools.putIfAbsent(name, newPool);
     newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(newPool, 0,
@@ -92,13 +92,13 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void modifyPoolLimits(String name, Map<String, Float> limits) throws Exception {
+  public void modifyPoolLimits(String name, Map<String, Float> poolLimits) throws Exception {
     ensureNotClosed();
     ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
-    pool.setLimits(limits);
+    pool.setPoolLimits(poolLimits);
   }
 
   @Override
@@ -118,6 +118,17 @@ public class DefaultResourceManager extends ResourceManager {
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
+    String type = pool.getType();
+    resourcePools.forEach((poolName, otherPool) -> {
+      if (otherPool == pool) {
+        return;
+      }
+      if (otherPool.getType().equals(type)) {
+        throw new IllegalArgumentException("Resource " + managedResource.getResourceName() +
+            " is already managed in another pool (" +
+            otherPool.getName() + ") of the same type " + type);
+      }
+    });
     pool.addResource(managedResource);
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
new file mode 100644
index 0000000..9f48702
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
@@ -0,0 +1,36 @@
+package org.apache.solr.managed;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.core.SolrInfoBean;
+
+/**
+ *
+ */
+public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
+
+  @Override
+  default Map<String, Float> getManagedValues(Collection<String> tags) {
+    Map<String, Object> metrics = getMetricsSnapshot();
+    if (metrics == null) {
+      return Collections.emptyMap();
+    }
+    Map<String, Float> result = new HashMap<>();
+    tags.forEach(tag -> {
+      Object value = metrics.get(tag);
+      if (value == null || !(value instanceof Number)) {
+        return;
+      }
+      result.put(tag, ((Number)value).floatValue());
+    });
+    return result;
+  }
+
+  @Override
+  default String getResourceName() {
+    return getName();
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
index 04d5207..1351a76 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -16,7 +16,7 @@ public interface ManagedResource {
   /**
    * Unique name of this resource.
    */
-  String getName();
+  String getResourceName();
 
   /**
    * Returns types of management schemes supported by this resource. This always
@@ -37,7 +37,7 @@ public interface ManagedResource {
         setManagedLimit(key, value);
       } catch (Exception e) {
         log.warn("Exception setting managed limit on {}: key={}, value={}, exception={}",
-            getName(), key, value, e);
+            getResourceName(), key, value, e);
       }
     });
   }
@@ -59,5 +59,5 @@ public interface ManagedResource {
    * @param tags value names
    * @return map of names to current values.
    */
-  Map<String, Float> getManagedValues(Collection<String> tags);
+  Map<String, Float> getManagedValues(Collection<String> tags) throws Exception;
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index e808bdb..a49f5d7 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -17,7 +17,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- *
+ * Base class for resource management. It represents a flat model where there are named
+ * resource pools of a given type, each pool with its own defined limits. Resources can be added
+ * to a pool for management of a specific aspect of that resource using {@link ResourceManagerPlugin}.
  */
 public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -63,20 +65,20 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
 
   protected abstract void doInit() throws Exception;
 
-  public abstract void createPool(String name, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception;
+  public abstract void createPool(String name, String type, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception;
 
-  public abstract void modifyPoolLimits(String name, Map<String, Float> limits) throws Exception;
+  public abstract void modifyPoolLimits(String name, Map<String, Float> poolLimits) throws Exception;
 
   public abstract void removePool(String name) throws Exception;
 
-  public void addResources(String pool, Collection<ManagedResource> managedResource) {
+  public void addResources(String pool, Collection<ManagedResource> managedResource) throws Exception {
     ensureNotClosed();
     for (ManagedResource resource : managedResource) {
       addResource(pool, resource);
     }
   }
 
-  public abstract void addResource(String pool, ManagedResource managedResource);
+  public abstract void addResource(String pool, ManagedResource managedResource) throws Exception;
 
   protected void ensureNotClosed() {
     if (isClosed()) {
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index a73cdcb..0b00198 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -15,6 +15,6 @@ public interface ResourceManagerPlugin {
   Collection<String> getMonitoredTags();
   Collection<String> getControlledTags();
 
-  void manage(ResourceManagerPool pool);
+  void manage(ResourceManagerPool pool) throws Exception;
 
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 952dbb5..a1c437a 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -7,33 +7,46 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- *
+ * A pool of resources of the same type, which use the same {@link ResourceManagerPlugin} for managing their
+ * resource use.
  */
 public class ResourceManagerPool implements Runnable, Closeable {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
-  private Map<String, Float> limits;
+  private Map<String, Float> poolLimits;
   private final String type;
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> params;
   private Map<String, Float> totalValues = null;
+  private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
   ScheduledFuture<?> scheduledFuture;
 
-  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Float> limits, Map<String, Object> params) throws Exception {
+  /**
+   * Create a pool of resources to manage.
+   * @param name unique name of the pool
+   * @param type one of the supported pool types (see {@link ResourceManagerPluginFactory})
+   * @param factory factory of {@link ResourceManagerPlugin}-s of the specified type
+   * @param poolLimits pool limits (keys are controlled tags)
+   * @param params parameters for the {@link ResourceManagerPlugin}
+   * @throws Exception
+   */
+  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception {
     this.name = name;
     this.type = type;
     this.resourceManagerPlugin = factory.create(type, params);
-    this.limits = new HashMap<>(limits);
+    this.poolLimits = new TreeMap<>(poolLimits);
     this.params = new HashMap<>(params);
   }
 
@@ -41,15 +54,19 @@ public class ResourceManagerPool implements Runnable, Closeable {
     return name;
   }
 
+  public String getType() {
+    return type;
+  }
+
   public void addResource(ManagedResource managedResource) {
     Collection<String> types = managedResource.getManagedResourceTypes();
     if (!types.contains(type)) {
-      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getName());
+      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getResourceName());
       return;
     }
-    ManagedResource existing = resources.putIfAbsent(managedResource.getName(), managedResource);
+    ManagedResource existing = resources.putIfAbsent(managedResource.getResourceName(), managedResource);
     if (existing != null) {
-      throw new IllegalArgumentException("Resource '" + managedResource.getName() + "' already exists in pool '" + name + "' !");
+      throw new IllegalArgumentException("Resource '" + managedResource.getResourceName() + "' already exists in pool '" + name + "' !");
     }
   }
 
@@ -57,44 +74,70 @@ public class ResourceManagerPool implements Runnable, Closeable {
     return Collections.unmodifiableMap(resources);
   }
 
-  public Map<String, Map<String, Float>> getCurrentValues() {
-    // collect current values
-    Map<String, Map<String, Float>> currentValues = new HashMap<>();
-    for (ManagedResource resource : resources.values()) {
-      currentValues.put(resource.getName(), resource.getManagedValues(resourceManagerPlugin.getMonitoredTags()));
-    }
-    // calculate totals
-    totalValues = new HashMap<>();
-    currentValues.values().forEach(map -> map.forEach((k, v) -> {
-      Float total = totalValues.get(k);
-      if (total == null) {
-        totalValues.put(k, v);
-      } else {
-        totalValues.put(k, total + v);
+  /**
+   * Get the current values from all resources. Result is a map with resource names as keys,
+   * and tag/value maps as values.
+   */
+  public Map<String, Map<String, Float>> getCurrentValues() throws InterruptedException {
+    updateLock.lockInterruptibly();
+    try {
+      // collect current values
+      Map<String, Map<String, Float>> currentValues = new HashMap<>();
+      for (ManagedResource resource : resources.values()) {
+        try {
+          currentValues.put(resource.getResourceName(), resource.getManagedValues(resourceManagerPlugin.getMonitoredTags()));
+        } catch (Exception e) {
+          log.warn("Error getting managed values from " + resource.getResourceName(), e);
+        }
       }
-    }));
-    return Collections.unmodifiableMap(currentValues);
+      // calculate totals
+      Map<String, Float> newTotalValues = new HashMap<>();
+      currentValues.values().forEach(map -> map.forEach((k, v) -> {
+        Float total = newTotalValues.get(k);
+        if (total == null) {
+          newTotalValues.put(k, v);
+        } else {
+          newTotalValues.put(k, total + v);
+        }
+      }));
+      totalValues = newTotalValues;
+      return Collections.unmodifiableMap(currentValues);
+    } finally {
+      updateLock.unlock();
+    }
   }
 
   /**
    * This returns cumulative values of all resources. NOTE:
    * you must call {@link #getCurrentValues()} first!
    */
-  public Map<String, Float> getTotalValues() {
-    return Collections.unmodifiableMap(totalValues);
+  public Map<String, Float> getTotalValues() throws InterruptedException {
+    updateLock.lockInterruptibly();
+    try {
+      return Collections.unmodifiableMap(totalValues);
+    } finally {
+      updateLock.unlock();
+    }
   }
 
-  public Map<String, Float> getLimits() {
-    return limits;
+  public Map<String, Float> getPoolLimits() {
+    return poolLimits;
   }
 
-  public void setLimits(Map<String, Float> limits) {
-    this.limits = new HashMap(limits);
+  /**
+   * Pool limits are defined using controlled tags.
+   */
+  public void setPoolLimits(Map<String, Float> poolLimits) {
+    this.poolLimits = new HashMap(poolLimits);
   }
 
   @Override
   public void run() {
-    resourceManagerPlugin.manage(this);
+    try {
+      resourceManagerPlugin.manage(this);
+    } catch (Exception e) {
+      log.warn("Error running management plugin " + getName(), e);
+    }
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index 7f2f5cd..345dae4 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -1,5 +1,6 @@
 package org.apache.solr.managed.plugins;
 
+import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
@@ -7,11 +8,15 @@ import java.util.Map;
 
 import org.apache.solr.managed.AbstractResourceManagerPlugin;
 import org.apache.solr.managed.ResourceManagerPool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
  */
 public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   public static String TYPE = "cache";
 
   public static final String SIZE_TAG = "size";
@@ -58,36 +63,44 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   }
 
   @Override
-  public void manage(ResourceManagerPool pool) {
+  public void manage(ResourceManagerPool pool) throws Exception {
     Map<String, Map<String, Float>> currentValues = pool.getCurrentValues();
     Map<String, Float> totalValues = pool.getTotalValues();
-    pool.getLimits().forEach((poolLimitName, poolLimitValue) -> {
+    // pool limits are defined using controlled tags
+    pool.getPoolLimits().forEach((poolLimitName, poolLimitValue) -> {
+      if (poolLimitValue == null || poolLimitValue <= 0) {
+        return;
+      }
       String monitoredTag = controlledToMonitored.get(poolLimitName);
       if (monitoredTag == null) {
         return;
       }
       Float totalValue = totalValues.get(monitoredTag);
-      if (totalValue == null) {
+      if (totalValue == null || totalValue <= 0.0f) {
         return;
       }
       float totalDelta = poolLimitValue - totalValue;
+
+      // 10% hysteresis to avoid thrashing
+      // TODO: make the threshold configurable
+      if (Math.abs(totalDelta / poolLimitValue) < 0.1f) {
+        return;
+      }
+
+      float changeRatio = poolLimitValue / totalValue;
+      // modify current limits by the changeRatio
       pool.getResources().forEach((name, resource) -> {
-        Map<String, Float> current = currentValues.get(name);
-        if (current == null) {
+        Map<String, Float> resourceLimits = resource.getManagedLimits();
+        Float currentResourceLimit = resourceLimits.get(poolLimitName);
+        if (currentResourceLimit == null || currentResourceLimit <= 0) {
           return;
         }
-        Map<String, Float> limits = resource.getManagedLimits();
-        Float managedSize = limits.get(SIZE_TAG);
-        Float resMaxRamMB = limits.get(MAX_RAM_MB_TAG);
-        Float currentSize = current.get(SIZE_TAG);
-        Float currentHitratio = current.get(HIT_RATIO_TAG);
-        Float ramBytesUsed = current.get(RAM_BYTES_USED_TAG);
-
-        // logic to adjust per-resource controlled limits
-        if (poolLimitName.equals(MAX_RAM_MB_TAG)) {
-          // adjust per-resource maxRamMB
-        } else if (poolLimitName.equals(SIZE_TAG)) {
-          // adjust per-resource size
+        float newLimit = currentResourceLimit * changeRatio;
+        try {
+          resource.setManagedLimit(poolLimitName, newLimit);
+        } catch (Exception e) {
+          log.warn("Failed to set managed limit " + poolLimitName +
+              " from " + currentResourceLimit + " to " + newLimit + " on " + resource.getResourceName(), e);
         }
       });
     });


[lucene-solr] 12/36: More refactoring. Add ResourceManagerHandler.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 3d735b6187f1330b501f5976707d1b6e9b4473eb
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 18 15:05:11 2019 +0200

    More refactoring. Add ResourceManagerHandler.
---
 .../java/org/apache/solr/core/CoreContainer.java   |  25 ++
 .../solr/handler/admin/ResourceManagerHandler.java | 311 +++++++++++++++++++++
 .../solr/managed/DefaultResourceManager.java       |  38 ++-
 ...erPool.java => DefaultResourceManagerPool.java} |  44 +--
 .../org/apache/solr/managed/ManagedResource.java   |   2 +-
 .../org/apache/solr/managed/ResourceManager.java   |  25 +-
 .../apache/solr/managed/ResourceManagerPool.java   | 161 ++---------
 .../solr/security/PermissionNameProvider.java      |   2 +
 .../apache/solr/common/params/CommonParams.java    |   2 +
 9 files changed, 432 insertions(+), 178 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 6471d66..6c7f547 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -72,6 +72,7 @@ import org.apache.solr.common.params.CollectionAdminParams;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.SolrjNamedThreadFactory;
+import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.core.DirectoryFactory.DirContext;
 import org.apache.solr.core.backup.repository.BackupRepository;
@@ -87,6 +88,7 @@ import org.apache.solr.handler.admin.InfoHandler;
 import org.apache.solr.handler.admin.MetricsCollectorHandler;
 import org.apache.solr.handler.admin.MetricsHandler;
 import org.apache.solr.handler.admin.MetricsHistoryHandler;
+import org.apache.solr.handler.admin.ResourceManagerHandler;
 import org.apache.solr.handler.admin.SecurityConfHandler;
 import org.apache.solr.handler.admin.SecurityConfHandlerLocal;
 import org.apache.solr.handler.admin.SecurityConfHandlerZk;
@@ -95,6 +97,8 @@ import org.apache.solr.handler.admin.ZookeeperStatusHandler;
 import org.apache.solr.handler.component.ShardHandlerFactory;
 import org.apache.solr.logging.LogWatcher;
 import org.apache.solr.logging.MDCLoggingContext;
+import org.apache.solr.managed.DefaultResourceManager;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.metrics.SolrCoreMetricManager;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricProducer;
@@ -128,6 +132,7 @@ import static org.apache.solr.common.params.CommonParams.CORES_HANDLER_PATH;
 import static org.apache.solr.common.params.CommonParams.INFO_HANDLER_PATH;
 import static org.apache.solr.common.params.CommonParams.METRICS_HISTORY_PATH;
 import static org.apache.solr.common.params.CommonParams.METRICS_PATH;
+import static org.apache.solr.common.params.CommonParams.RESOURCE_MANAGER_PATH;
 import static org.apache.solr.common.params.CommonParams.ZK_PATH;
 import static org.apache.solr.common.params.CommonParams.ZK_STATUS_PATH;
 import static org.apache.solr.core.CorePropertiesLocator.PROPERTIES_FILENAME;
@@ -218,6 +223,10 @@ public class CoreContainer {
 
   protected volatile AutoscalingHistoryHandler autoscalingHistoryHandler;
 
+  protected volatile ResourceManager resourceManager;
+
+  protected volatile ResourceManagerHandler resourceManagerHandler;
+
 
   // Bits for the state variable.
   public final static long LOAD_COMPLETE = 0x1L;
@@ -569,6 +578,10 @@ public class CoreContainer {
     return metricsHistoryHandler;
   }
 
+  public ResourceManager getResourceManager() {
+    return resourceManager;
+  }
+
   public OrderedExecutor getReplayUpdatesExecutor() {
     return replayUpdatesExecutor;
   }
@@ -599,6 +612,10 @@ public class CoreContainer {
 
     metricManager = new SolrMetricManager(loader, cfg.getMetricsConfig());
 
+    resourceManager = new DefaultResourceManager(loader, TimeSource.NANO_TIME);
+    // TODO: get the config from solr.xml?
+    resourceManager.init(new PluginInfo("resourceManager", Collections.emptyMap()));
+
     coreContainerWorkExecutor = MetricUtils.instrumentedExecutorService(
         coreContainerWorkExecutor, null,
         metricManager.registry(SolrMetricManager.getRegistryName(SolrInfoBean.Group.node)),
@@ -647,6 +664,10 @@ public class CoreContainer {
 
     createMetricsHistoryHandler();
 
+    resourceManagerHandler = new ResourceManagerHandler(resourceManager);
+    containerHandlers.put(RESOURCE_MANAGER_PATH, resourceManagerHandler);
+    resourceManagerHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, RESOURCE_MANAGER_PATH);
+
     autoscalingHistoryHandler = createHandler(AUTOSCALING_HISTORY_PATH, AutoscalingHistoryHandler.class.getName(), AutoscalingHistoryHandler.class);
     metricsCollectorHandler = createHandler(MetricsCollectorHandler.HANDLER_PATH, MetricsCollectorHandler.class.getName(), MetricsCollectorHandler.class);
     // may want to add some configuration here in the future
@@ -970,6 +991,10 @@ public class CoreContainer {
         }
       }
 
+      if (resourceManager != null) {
+        IOUtils.closeQuietly(resourceManager);
+      }
+
       try {
         if (coreAdminHandler != null) {
           customThreadPool.submit(() -> {
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
new file mode 100644
index 0000000..bd65132
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.handler.admin;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.handler.RequestHandlerBase;
+import org.apache.solr.managed.ManagedResource;
+import org.apache.solr.managed.ResourceManager;
+import org.apache.solr.managed.ResourceManagerPool;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.security.AuthorizationContext;
+import org.apache.solr.security.PermissionNameProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Request handler to access and modify pools and their resource limits.
+ */
+public class ResourceManagerHandler extends RequestHandlerBase implements PermissionNameProvider {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public static final String POOL_PARAM = "pool";
+  public static final String RESOURCE_PARAM = "resource";
+  public static final String LIMIT_PREFIX_PARAM = "limit.";
+  public static final String ARG_PREFIX_PARAM = "arg.";
+  public static final String POOL_ACTION_PARAM = "poolAction";
+  public static final String RES_ACTION_PARAM = "resAction";
+
+  public enum PoolOp {
+    LIST,
+    STATUS,
+    CREATE,
+    DELETE,
+    SETLIMITS;
+
+    public static PoolOp get(String p) {
+      if (p != null) {
+        try {
+          return PoolOp.valueOf(p.toUpperCase(Locale.ROOT));
+        } catch (Exception e) {
+          return null;
+        }
+      }
+      return null;
+    }
+  }
+
+  public enum ResOp {
+    LIST,
+    STATUS,
+    DELETE,
+    GETLIMITS,
+    SETLIMITS;
+
+    public static ResOp get(String p) {
+      if (p != null) {
+        try {
+          return ResOp.valueOf(p.toUpperCase(Locale.ROOT));
+        } catch (Exception e) {
+          return null;
+        }
+      }
+      return null;
+    }
+  }
+
+  private final ResourceManager resourceManager;
+
+  public ResourceManagerHandler(ResourceManager resourceManager) {
+    this.resourceManager = resourceManager;
+  }
+
+  @Override
+  public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
+    if (resourceManager == null) {
+      throw new SolrException(SolrException.ErrorCode.INVALID_STATE, "ResourceManager instance not initialized.");
+    }
+    String poolAction = req.getParams().get(POOL_ACTION_PARAM);
+    String resAction = req.getParams().get(RES_ACTION_PARAM);
+    if (poolAction != null) {
+      handlePoolRequest(req, rsp);
+    } else if (resAction != null) {
+      handleResourceRequest(req, rsp);
+    } else {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Missing " + POOL_ACTION_PARAM + " and " + RES_ACTION_PARAM + ": " + req.getParams());
+    }
+  }
+
+  private void handlePoolRequest(SolrQueryRequest req, SolrQueryResponse rsp) {
+    SolrParams params = req.getParams();
+    PoolOp op = PoolOp.get(params.get(POOL_ACTION_PARAM));
+    if (op == null) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unsupported pool operation: " + params.get(POOL_ACTION_PARAM));
+    }
+    String name = null;
+    if (op != PoolOp.LIST) {
+      name = params.get(CommonParams.NAME);
+      if (name == null) {
+        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Required parameter " + CommonParams.NAME + " missing: " + params);
+      }
+    }
+    NamedList<Object> result = new SimpleOrderedMap<>();
+    switch (op) {
+      case LIST:
+        resourceManager.listPools().forEach(p -> {
+          ResourceManagerPool pool = resourceManager.getPool(p);
+          if (pool == null) {
+            return;
+          }
+          NamedList<Object> perPool = new SimpleOrderedMap<>();
+          result.add(p, perPool);
+          perPool.add("type", pool.getType());
+          perPool.add("size", pool.getResources().size());
+          perPool.add("limits", pool.getPoolLimits());
+          perPool.add("args", pool.getArgs());
+        });
+        break;
+      case STATUS:
+        ResourceManagerPool pool = resourceManager.getPool(name);
+        if (pool == null) {
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Pool '" + name + "' not found.");
+        }
+        result.add("type", pool.getType());
+        result.add("size", pool.getResources().size());
+        result.add("limits", pool.getPoolLimits());
+        result.add("args", pool.getArgs());
+        result.add("resources", pool.getResources().keySet());
+        try {
+          result.add("currentValues", pool.getCurrentValues());
+          result.add("totalValues", pool.getTotalValues());
+        } catch (Exception e) {
+          log.warn("Error getting current values from pool " + name, e);
+          result.add("error", "Error getting current values: " + e.toString());
+        }
+        break;
+      case CREATE:
+        String type = params.get(CommonParams.TYPE);
+        if (type == null || type.isBlank()) {
+          throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Required parameter " + CommonParams.TYPE + " missing or empty: " + params);
+        }
+        Map<String, Object> limits = getMap(params, LIMIT_PREFIX_PARAM);
+        Map<String, Object> args = getMap(params, ARG_PREFIX_PARAM);
+        try {
+          resourceManager.createPool(name, type, limits, args);
+          result.add("success", "created");
+        } catch (Exception e) {
+          throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Pool '" + name + "' creation failed: " + e.toString(), e);
+        }
+        break;
+      case DELETE:
+        try {
+          resourceManager.removePool(name);
+          result.add("success", "removed");
+        } catch (Exception e) {
+          throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Pool '" + name + "' deletion failed: " + e.toString(), e);
+        }
+        break;
+      case SETLIMITS:
+        ResourceManagerPool pool1 = resourceManager.getPool(name);
+        if (pool1 == null) {
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Pool '" + name + "' not found.");
+        }
+        Map<String, Object> currentLimits = new HashMap<>(pool1.getPoolLimits());
+        Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
+        newLimits.forEach((k, v) -> {
+          if (v == null) {
+            currentLimits.remove(k);
+          } else {
+            currentLimits.put(k, v);
+          }
+        });
+        pool1.setPoolLimits(newLimits);
+        result.add("success", newLimits);
+        break;
+    }
+    rsp.getValues().add("result", result);
+  }
+
+  private Map<String, Object> getMap(SolrParams params, String prefix) {
+    Map<String, Object> result = new HashMap<>();
+    params.forEach(entry -> {
+      if (!entry.getKey().startsWith(prefix)) {
+        return;
+      }
+      String val = params.get(entry.getKey());
+      if (val.isBlank()) {
+        val = null;
+      }
+      result.put(entry.getKey().substring(prefix.length()), val);
+    });
+    return result;
+  }
+
+  private void handleResourceRequest(SolrQueryRequest req, SolrQueryResponse rsp) {
+    SolrParams params = req.getParams();
+    ResOp op = ResOp.get(params.get(RES_ACTION_PARAM));
+    if (op == null) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unsupported resource operation: " + params.get(RES_ACTION_PARAM));
+    }
+    String poolName = params.get(POOL_PARAM);
+    if (poolName == null || poolName.isBlank()) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Resource operation requires '" + POOL_PARAM + "' parameter.");
+    }
+    ResourceManagerPool pool = resourceManager.getPool(poolName);
+    if (pool == null) {
+      throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Pool '" + poolName + "' not found.");
+    }
+    String resName = params.get(RESOURCE_PARAM);
+    if ((resName == null || resName.isBlank()) && op != ResOp.LIST) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Missing '" + RESOURCE_PARAM + "' parameter.");
+    }
+    NamedList<Object> result = new SimpleOrderedMap<>();
+    switch (op) {
+      case LIST:
+        pool.getResources().forEach((n, resource) -> {
+          NamedList<Object> perRes = new SimpleOrderedMap<>();
+          result.add(n, perRes);
+          perRes.add("class", resource.getClass().getName());
+          perRes.add("types", resource.getManagedResourceTypes());
+          perRes.add("managedLimits", resource.getManagedLimits());
+        });
+        break;
+      case STATUS:
+        ManagedResource resource = pool.getResources().get(resName);
+        if (resource == null) {
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
+        }
+        result.add("class", resource.getClass().getName());
+        result.add("types", resource.getManagedResourceTypes());
+        result.add("managedLimits", resource.getManagedLimits());
+        try {
+          result.add("monitoredValues", resource.getMonitoredValues(Collections.emptySet()));
+        } catch (Exception e) {
+          log.warn("Error getting monitored values of " + resName + "/" + poolName + " : " + e.toString(), e);
+          result.add("error", "Error getting monitored values of " + resName + ": " + e.toString());
+        }
+        break;
+      case GETLIMITS:
+        ManagedResource resource1 = pool.getResources().get(resName);
+        if (resource1 == null) {
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
+        }
+        result.add("managedLimits", resource1.getManagedLimits());
+        break;
+      case SETLIMITS:
+        ManagedResource resource2 = pool.getResources().get(resName);
+        if (resource2 == null) {
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
+        }
+        Map<String, Object> currentLimits = new HashMap<>(resource2.getManagedLimits());
+        Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
+        newLimits.forEach((k, v) -> {
+          if (v == null) {
+            currentLimits.remove(k);
+          } else {
+            currentLimits.put(k, v);
+          }
+        });
+        resource2.setManagedLimits(newLimits);
+        result.add("success", newLimits);
+        break;
+      case DELETE:
+        result.add("success", pool.removeResource(resName) ? "removed" : "not found");
+    }
+    rsp.getValues().add("result", result);
+  }
+
+  @Override
+  public String getDescription() {
+    return "ResourceManager handler";
+  }
+
+  @Override
+  public Name getPermissionName(AuthorizationContext request) {
+    if ("GET".equals(request.getHttpMethod())) {
+      return Name.RESOURCE_READ_PERM;
+    } else {
+      return Name.RESOURCE_WRITE_PERM;
+    }
+  }
+
+  @Override
+  public Category getCategory() {
+    return Category.ADMIN;
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index 5e708b7..e8c9c99 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -18,6 +18,8 @@ package org.apache.solr.managed;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
@@ -45,7 +47,7 @@ public class DefaultResourceManager extends ResourceManager {
   public static final String MAX_NUM_POOLS_PARAM = "maxNumPools";
 
   public static final int DEFAULT_MAX_POOLS = 100;
-  public static final int DEFAULT_SCHEDULE_DELAY_SECONDS = 60;
+  public static final int DEFAULT_SCHEDULE_DELAY_SECONDS = 30;
 
   protected int maxNumPools = DEFAULT_MAX_POOLS;
 
@@ -77,6 +79,7 @@ public class DefaultResourceManager extends ResourceManager {
     scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
     // TODO: make configurable
     resourceManagerPluginFactory = new DefaultResourceManagerPluginFactory(loader);
+    log.info("Resource manager initialized.");
   }
 
   public void setMaxNumPools(Integer maxNumPools) {
@@ -93,45 +96,62 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception {
-    ensureNotClosed();
+  public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
+    ensureActive();
     if (resourcePools.containsKey(name)) {
       throw new IllegalArgumentException("Pool '" + name + "' already exists.");
     }
     if (resourcePools.size() >= maxNumPools) {
       throw new IllegalArgumentException("Maximum number of pools (" + maxNumPools + ") reached.");
     }
-    ResourceManagerPool newPool = new ResourceManagerPool(name, type, resourceManagerPluginFactory, poolLimits, params);
-    newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(params.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, DEFAULT_SCHEDULE_DELAY_SECONDS)));
+    DefaultResourceManagerPool newPool = new DefaultResourceManagerPool(name, type, resourceManagerPluginFactory, poolLimits, args);
+    newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(args.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, DEFAULT_SCHEDULE_DELAY_SECONDS)));
     resourcePools.putIfAbsent(name, newPool);
-    newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(newPool, 0,
+    newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
+          log.info("- running pool " + newPool.getName() + " / " + newPool.getType());
+          newPool.run();
+        }, 0,
         timeSource.convertDelay(TimeUnit.SECONDS, newPool.scheduleDelaySeconds, TimeUnit.MILLISECONDS),
         TimeUnit.MILLISECONDS);
+    log.info("- created pool " + newPool.getName() + " / " + newPool.getType());
+  }
+
+  @Override
+  public Collection<String> listPools() {
+    return Collections.unmodifiableSet(resourcePools.keySet());
+  }
+
+  @Override
+  public ResourceManagerPool getPool(String name) {
+    return resourcePools.get(name);
   }
 
   @Override
   public void modifyPoolLimits(String name, Map<String, Object> poolLimits) throws Exception {
-    ensureNotClosed();
+    ensureActive();
     ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
     pool.setPoolLimits(poolLimits);
+    log.info("- modified pool limits " + pool.getName() + " / " + pool.getType() + ": " + poolLimits);
+
   }
 
   @Override
   public void removePool(String name) throws Exception {
-    ensureNotClosed();
+    ensureActive();
     ResourceManagerPool pool = resourcePools.remove(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
     IOUtils.closeQuietly(pool);
+    log.info("- removed pool " + pool.getName() + " / " + pool.getType());
   }
 
   @Override
   public void addResource(String name, ManagedResource managedResource) {
-    ensureNotClosed();
+    ensureActive();
     ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
similarity index 85%
copy from solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
copy to solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 79ecbb0..aada8c2 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -16,7 +16,6 @@
  */
 package org.apache.solr.managed;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
@@ -35,7 +34,7 @@ import org.slf4j.LoggerFactory;
  * This class manages a pool of resources of the same type, which use the same
  * {@link ResourceManagerPlugin} for managing their resource limits.
  */
-public class ResourceManagerPool implements Runnable, Closeable {
+public class DefaultResourceManagerPool implements ResourceManagerPool {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
@@ -43,7 +42,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
   private final String type;
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
-  private final Map<String, Object> params;
+  private final Map<String, Object> args;
   private Map<String, Float> totalValues = null;
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
@@ -55,25 +54,33 @@ public class ResourceManagerPool implements Runnable, Closeable {
    * @param type one of the supported pool types (see {@link ResourceManagerPluginFactory})
    * @param factory factory of {@link ResourceManagerPlugin}-s of the specified type
    * @param poolLimits pool limits (keys are controlled tags)
-   * @param params parameters for the {@link ResourceManagerPlugin}
-   * @throws Exception
+   * @param args parameters for the {@link ResourceManagerPlugin}
+   * @throws Exception when initialization of the management plugin fails.
    */
-  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception {
+  public DefaultResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
     this.name = name;
     this.type = type;
-    this.resourceManagerPlugin = factory.create(type, params);
+    this.resourceManagerPlugin = factory.create(type, args);
     this.poolLimits = new TreeMap<>(poolLimits);
-    this.params = new HashMap<>(params);
+    this.args = new HashMap<>(args);
   }
 
+  @Override
   public String getName() {
     return name;
   }
 
+  @Override
   public String getType() {
     return type;
   }
 
+  @Override
+  public Map<String, Object> getArgs() {
+    return args;
+  }
+
+  @Override
   public void addResource(ManagedResource managedResource) {
     Collection<String> types = managedResource.getManagedResourceTypes();
     if (!types.contains(type)) {
@@ -86,14 +93,17 @@ public class ResourceManagerPool implements Runnable, Closeable {
     }
   }
 
+  @Override
+  public boolean removeResource(String name) {
+    return resources.remove(name) != null;
+  }
+
+  @Override
   public Map<String, ManagedResource> getResources() {
     return Collections.unmodifiableMap(resources);
   }
 
-  /**
-   * Get the current monitored values from all resources. Result is a map with resource names as keys,
-   * and tag/value maps as values.
-   */
+  @Override
   public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
     updateLock.lockInterruptibly();
     try {
@@ -127,10 +137,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
     }
   }
 
-  /**
-   * This returns cumulative monitored values of all resources.
-   * <p>NOTE: you must call {@link #getCurrentValues()} first!</p>
-   */
+  @Override
   public Map<String, Float> getTotalValues() throws InterruptedException {
     updateLock.lockInterruptibly();
     try {
@@ -140,13 +147,12 @@ public class ResourceManagerPool implements Runnable, Closeable {
     }
   }
 
+  @Override
   public Map<String, Object> getPoolLimits() {
     return poolLimits;
   }
 
-  /**
-   * Pool limits are defined using controlled tags.
-   */
+  @Override
   public void setPoolLimits(Map<String, Object> poolLimits) {
     this.poolLimits = new HashMap(poolLimits);
   }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
index 261d857..7ace1e1 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -73,7 +73,7 @@ public interface ManagedResource {
 
   /**
    * Returns monitored values that are used for calculating optimal settings of managed limits.
-   * @param tags monitored tags
+   * @param tags selected monitored tags, empty collection to return all monitored values
    * @return map of tags to current values.
    */
   Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception;
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index 41dd690..aaeedbf 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -19,14 +19,10 @@ package org.apache.solr.managed;
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 import org.apache.solr.common.SolrCloseable;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.core.PluginInfo;
-import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.solr.util.SolrPluginUtils;
 import org.apache.solr.util.plugin.PluginInfoInitialized;
 import org.slf4j.Logger;
@@ -43,6 +39,7 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
   protected PluginInfo pluginInfo;
   protected boolean isClosed = false;
   protected boolean enabled = true;
+  protected boolean initialized = false;
 
   @Override
   public void init(PluginInfo info) {
@@ -58,6 +55,7 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
     }
     try {
       doInit();
+      initialized = true;
     } catch (Exception e) {
       log.warn("Exception initializing resource manager " + getClass().getSimpleName() + ", disabling!");
       IOUtils.closeQuietly(this);
@@ -86,9 +84,17 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    * @param name pool name
    * @param type pool type (one of the supported {@link ResourceManagerPlugin} types)
    * @param poolLimits pool limits
-   * @param params other parameters. These are also used for creating a {@link ResourceManagerPlugin}
+   * @param args other parameters. These are also used for creating a {@link ResourceManagerPlugin}
    */
-  public abstract void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception;
+  public abstract void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception;
+
+  /**
+   * List all currently existing pool names.
+   */
+  public abstract Collection<String> listPools();
+
+  /** Get a named pool. */
+  public abstract ResourceManagerPool getPool(String name);
 
   /**
    * Modify pool limits.
@@ -109,7 +115,7 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    * @param managedResources resources to add
    */
   public void addResources(String pool, Collection<ManagedResource> managedResources) throws Exception {
-    ensureNotClosed();
+    ensureActive();
     for (ManagedResource resource : managedResources) {
       addResource(pool, resource);
     }
@@ -125,10 +131,13 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    */
   public abstract void addResource(String pool, ManagedResource managedResource) throws Exception;
 
-  protected void ensureNotClosed() {
+  protected void ensureActive() {
     if (isClosed()) {
       throw new IllegalStateException("Already closed.");
     }
+    if (!initialized) {
+      throw new IllegalStateException("Not initialized.");
+    }
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 79ecbb0..453e293 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -1,170 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
 package org.apache.solr.managed;
 
 import java.io.Closeable;
 import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
-import java.util.TreeMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
- * This class manages a pool of resources of the same type, which use the same
- * {@link ResourceManagerPlugin} for managing their resource limits.
+ *
  */
-public class ResourceManagerPool implements Runnable, Closeable {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+public interface ResourceManagerPool extends Runnable, Closeable {
 
-  private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
-  private Map<String, Object> poolLimits;
-  private final String type;
-  private final String name;
-  private final ResourceManagerPlugin resourceManagerPlugin;
-  private final Map<String, Object> params;
-  private Map<String, Float> totalValues = null;
-  private final ReentrantLock updateLock = new ReentrantLock();
-  int scheduleDelaySeconds;
-  ScheduledFuture<?> scheduledFuture;
+  /** Unique pool name. */
+  String getName();
 
-  /**
-   * Create a pool of resources to manage.
-   * @param name unique name of the pool
-   * @param type one of the supported pool types (see {@link ResourceManagerPluginFactory})
-   * @param factory factory of {@link ResourceManagerPlugin}-s of the specified type
-   * @param poolLimits pool limits (keys are controlled tags)
-   * @param params parameters for the {@link ResourceManagerPlugin}
-   * @throws Exception
-   */
-  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception {
-    this.name = name;
-    this.type = type;
-    this.resourceManagerPlugin = factory.create(type, params);
-    this.poolLimits = new TreeMap<>(poolLimits);
-    this.params = new HashMap<>(params);
-  }
-
-  public String getName() {
-    return name;
-  }
+  /** Pool type. */
+  String getType();
 
-  public String getType() {
-    return type;
-  }
+  /** Add resource to this pool. */
+  void addResource(ManagedResource managedResource);
 
-  public void addResource(ManagedResource managedResource) {
-    Collection<String> types = managedResource.getManagedResourceTypes();
-    if (!types.contains(type)) {
-      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getResourceName());
-      return;
-    }
-    ManagedResource existing = resources.putIfAbsent(managedResource.getResourceName(), managedResource);
-    if (existing != null) {
-      throw new IllegalArgumentException("Resource '" + managedResource.getResourceName() + "' already exists in pool '" + name + "' !");
-    }
-  }
+  /** Remove named resource from this pool. */
+  boolean removeResource(String name);
 
-  public Map<String, ManagedResource> getResources() {
-    return Collections.unmodifiableMap(resources);
-  }
+  /** Get resources managed by this pool. */
+  Map<String, ManagedResource> getResources();
 
   /**
    * Get the current monitored values from all resources. Result is a map with resource names as keys,
    * and tag/value maps as values.
    */
-  public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
-    updateLock.lockInterruptibly();
-    try {
-      // collect current values
-      Map<String, Map<String, Object>> currentValues = new HashMap<>();
-      for (ManagedResource resource : resources.values()) {
-        try {
-          currentValues.put(resource.getResourceName(), resource.getMonitoredValues(resourceManagerPlugin.getMonitoredTags()));
-        } catch (Exception e) {
-          log.warn("Error getting managed values from " + resource.getResourceName(), e);
-        }
-      }
-      // calculate totals
-      Map<String, Float> newTotalValues = new HashMap<>();
-      currentValues.values().forEach(map -> map.forEach((k, v) -> {
-        // only calculate totals for numbers
-        if (!(v instanceof Number)) {
-          return;
-        }
-        Float total = newTotalValues.get(k);
-        if (total == null) {
-          newTotalValues.put(k, ((Number)v).floatValue());
-        } else {
-          newTotalValues.put(k, total + ((Number)v).floatValue());
-        }
-      }));
-      totalValues = newTotalValues;
-      return Collections.unmodifiableMap(currentValues);
-    } finally {
-      updateLock.unlock();
-    }
-  }
+  Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException;
 
   /**
    * This returns cumulative monitored values of all resources.
    * <p>NOTE: you must call {@link #getCurrentValues()} first!</p>
    */
-  public Map<String, Float> getTotalValues() throws InterruptedException {
-    updateLock.lockInterruptibly();
-    try {
-      return Collections.unmodifiableMap(totalValues);
-    } finally {
-      updateLock.unlock();
-    }
-  }
+  Map<String, Float> getTotalValues() throws InterruptedException;
+
+  /** Get current pool limits. */
+  Map<String, Object> getPoolLimits();
 
-  public Map<String, Object> getPoolLimits() {
-    return poolLimits;
-  }
+  /** Get parameters specified during creation. */
+  Map<String, Object> getArgs();
 
   /**
    * Pool limits are defined using controlled tags.
    */
-  public void setPoolLimits(Map<String, Object> poolLimits) {
-    this.poolLimits = new HashMap(poolLimits);
-  }
-
-  @Override
-  public void run() {
-    try {
-      resourceManagerPlugin.manage(this);
-    } catch (Exception e) {
-      log.warn("Error running management plugin " + getName(), e);
-    }
-  }
-
-  @Override
-  public void close() throws IOException {
-    if (scheduledFuture != null) {
-      scheduledFuture.cancel(true);
-      scheduledFuture = null;
-    }
-  }
+  void setPoolLimits(Map<String, Object> poolLimits);
 }
diff --git a/solr/core/src/java/org/apache/solr/security/PermissionNameProvider.java b/solr/core/src/java/org/apache/solr/security/PermissionNameProvider.java
index 79b4d29..b750af9 100644
--- a/solr/core/src/java/org/apache/solr/security/PermissionNameProvider.java
+++ b/solr/core/src/java/org/apache/solr/security/PermissionNameProvider.java
@@ -47,6 +47,8 @@ public interface PermissionNameProvider {
     SECURITY_EDIT_PERM("security-edit", null),
     SECURITY_READ_PERM("security-read", null),
     METRICS_READ_PERM("metrics-read", null),
+    RESOURCE_READ_PERM("resource-read", null),
+    RESOURCE_WRITE_PERM("resource-write", null),
     AUTOSCALING_READ_PERM("autoscaling-read", null),
     AUTOSCALING_WRITE_PERM("autoscaling-write", null),
     AUTOSCALING_HISTORY_READ_PERM("autoscaling-history-read", null),
diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
index 39a0242..334dd1a 100644
--- a/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
+++ b/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
@@ -186,6 +186,7 @@ public interface CommonParams {
   String SYSTEM_INFO_PATH = "/admin/info/system";
   String METRICS_PATH = "/admin/metrics";
   String METRICS_HISTORY_PATH = "/admin/metrics/history";
+  String RESOURCE_MANAGER_PATH = "/admin/resources";
   String AUTOSCALING_PATH = "/admin/autoscaling";
   String AUTOSCALING_HISTORY_PATH = "/admin/autoscaling/history";
   String AUTOSCALING_DIAGNOSTICS_PATH = "/admin/autoscaling/diagnostics";
@@ -206,6 +207,7 @@ public interface CommonParams {
       AUTHZ_PATH,
       METRICS_PATH,
       METRICS_HISTORY_PATH,
+      RESOURCE_MANAGER_PATH,
       AUTOSCALING_PATH,
       AUTOSCALING_HISTORY_PATH,
       AUTOSCALING_DIAGNOSTICS_PATH,


[lucene-solr] 02/36: Refactoring. Plugins for management of speficic types of resources.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 51da363d37807666f593472220cf75fc1ecdd089
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Jun 19 13:02:36 2019 +0200

    Refactoring. Plugins for management of speficic types of resources.
---
 .../managed/AbstractResourceManagerPlugin.java     |   7 ++
 ...rceManager.java => DefaultResourceManager.java} | 132 ++++-----------------
 .../DefaultResourceManagerPluginFactory.java       |  36 ++++++
 .../src/java/org/apache/solr/managed/Limit.java    |  35 ------
 .../src/java/org/apache/solr/managed/Limits.java   |  75 ------------
 .../org/apache/solr/managed/ManagedResource.java   |  63 ++++++++++
 .../solr/managed/ProportionalResourceManager.java  |  48 --------
 .../org/apache/solr/managed/ResourceManaged.java   |  23 ----
 .../org/apache/solr/managed/ResourceManager.java   |  10 +-
 .../apache/solr/managed/ResourceManagerPlugin.java |  20 ++++
 .../solr/managed/ResourceManagerPluginFactory.java |  11 ++
 .../apache/solr/managed/ResourceManagerPool.java   |  95 +++++++++++++++
 .../solr/managed/plugins/CacheManagerPlugin.java   |  95 +++++++++++++++
 .../src/java/org/apache/solr/search/LRUCache.java  |   8 +-
 14 files changed, 356 insertions(+), 302 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
new file mode 100644
index 0000000..f75d104
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
@@ -0,0 +1,7 @@
+package org.apache.solr.managed;
+
+/**
+ *
+ */
+public abstract class AbstractResourceManagerPlugin implements ResourceManagerPlugin {
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
similarity index 52%
rename from solr/core/src/java/org/apache/solr/managed/AbstractResourceManager.java
rename to solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index 41cb185..c509e2b 100644
--- a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -1,15 +1,11 @@
 package org.apache.solr.managed;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
@@ -17,6 +13,7 @@ import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
+import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.solr.util.SolrPluginUtils;
 import org.slf4j.Logger;
@@ -25,7 +22,7 @@ import org.slf4j.LoggerFactory;
 /**
  *
  */
-public abstract class AbstractResourceManager implements ResourceManager {
+public class DefaultResourceManager implements ResourceManager {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static final String SCHEDULE_DELAY_SECONDS_PARAM = "scheduleDelaySeconds";
@@ -33,99 +30,8 @@ public abstract class AbstractResourceManager implements ResourceManager {
 
   public static final int DEFAULT_MAX_POOLS = 20;
 
-  public static class Pool implements Runnable, Closeable {
-    private final AbstractResourceManager resourceManager;
-    private final Map<String, ResourceManaged> resources = new ConcurrentHashMap<>();
-    private Limits limits;
-    private final Map<String, Object> params;
-    private final Map<String, Float> totalCosts = new ConcurrentHashMap<>();
-    private Map<String, Map<String, Float>> currentValues = null;
-    private Map<String, Float> totalValues = null;
-    int scheduleDelaySeconds;
-    ScheduledFuture<?> scheduledFuture;
 
-    public Pool(AbstractResourceManager resourceManager, Limits limits, Map<String, Object> params) {
-      this.resourceManager = resourceManager;
-      this.limits = limits.copy();
-      this.params = new HashMap<>(params);
-    }
-
-    public synchronized void addResource(ResourceManaged resourceManaged) {
-      if (resources.containsKey(resourceManaged.getName())) {
-        throw new IllegalArgumentException("Pool already has resource '" + resourceManaged.getName() + "'.");
-      }
-      resources.put(resourceManaged.getName(), resourceManaged);
-      Limits managedLimits = resourceManaged.getManagedLimits();
-      managedLimits.forEach(entry -> {
-        Float total = totalCosts.get(entry.getKey());
-        if (total == null) {
-          totalCosts.put(entry.getKey(), entry.getValue().cost);
-        } else {
-          totalCosts.put(entry.getKey(), entry.getValue().cost + total);
-        }
-      });
-    }
-
-    public Map<String, ResourceManaged> getResources() {
-      return Collections.unmodifiableMap(resources);
-    }
-
-    public Map<String, Map<String, Float>> getCurrentValues() {
-      // collect current values
-      currentValues = new HashMap<>();
-      for (ResourceManaged resource : resources.values()) {
-        currentValues.put(resource.getName(), resource.getManagedValues());
-      }
-      // calculate totals
-      totalValues = new HashMap<>();
-      currentValues.values().forEach(map -> map.forEach((k, v) -> {
-        Float total = totalValues.get(k);
-        if (total == null) {
-          totalValues.put(k, v);
-        } else {
-          totalValues.put(k, total + v);
-        }
-      }));
-      return Collections.unmodifiableMap(currentValues);
-    }
-
-    /**
-     * This returns cumulative values of all resources. NOTE:
-     * you must call {@link #getCurrentValues()} first!
-     * @return
-     */
-    public Map<String, Float> getTotalValues() {
-      return Collections.unmodifiableMap(totalValues);
-    }
-
-    public Map<String, Float> getTotalCosts() {
-      return Collections.unmodifiableMap(totalCosts);
-    }
-
-    public Limits getLimits() {
-      return limits;
-    }
-
-    public void setLimits(Limits limits) {
-      this.limits = limits.copy();
-    }
-
-    @Override
-    public void run() {
-      resourceManager.managePool(this);
-    }
-
-    @Override
-    public void close() throws IOException {
-      if (scheduledFuture != null) {
-        scheduledFuture.cancel(true);
-        scheduledFuture = null;
-      }
-    }
-  }
-
-
-  private Map<String, Pool> resourcePools = new ConcurrentHashMap<>();
+  private Map<String, ResourceManagerPool> resourcePools = new ConcurrentHashMap<>();
   private PluginInfo pluginInfo;
   private int maxNumPools = DEFAULT_MAX_POOLS;
   private TimeSource timeSource;
@@ -138,7 +44,11 @@ public abstract class AbstractResourceManager implements ResourceManager {
   protected boolean isClosed = false;
   protected boolean enabled = true;
 
-  public AbstractResourceManager(TimeSource timeSource) {
+  protected ResourceManagerPluginFactory resourceManagerPluginFactory;
+  protected SolrResourceLoader loader;
+
+  public DefaultResourceManager(SolrResourceLoader loader, TimeSource timeSource) {
+    this.loader = loader;
     this.timeSource = timeSource;
   }
 
@@ -158,6 +68,8 @@ public abstract class AbstractResourceManager implements ResourceManager {
         new DefaultSolrThreadFactory(getClass().getSimpleName()));
     scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
     scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+    // TODO: make configurable
+    resourceManagerPluginFactory = new DefaultResourceManagerPluginFactory(loader);
   }
 
   public void setMaxNumPools(Integer maxNumPools) {
@@ -180,10 +92,8 @@ public abstract class AbstractResourceManager implements ResourceManager {
     return pluginInfo;
   }
 
-  protected abstract void managePool(Pool pool);
-
   @Override
-  public void createPool(String name, Limits limits, Map<String, Object> params) throws Exception {
+  public void createPool(String name, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception {
     ensureNotClosed();
     if (resourcePools.containsKey(name)) {
       throw new IllegalArgumentException("Pool '" + name + "' already exists.");
@@ -191,7 +101,7 @@ public abstract class AbstractResourceManager implements ResourceManager {
     if (resourcePools.size() >= maxNumPools) {
       throw new IllegalArgumentException("Maximum number of pools (" + maxNumPools + ") reached.");
     }
-    Pool newPool = new Pool(this, limits, params);
+    ResourceManagerPool newPool = new ResourceManagerPool(resourceManagerPluginFactory, type, limits, params);
     newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(params.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, 10)));
     resourcePools.putIfAbsent(name, newPool);
     newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(newPool, 0,
@@ -200,9 +110,9 @@ public abstract class AbstractResourceManager implements ResourceManager {
   }
 
   @Override
-  public void modifyPoolLimits(String name, Limits limits) throws Exception {
+  public void modifyPoolLimits(String name, Map<String, Float> limits) throws Exception {
     ensureNotClosed();
-    Pool pool = resourcePools.get(name);
+    ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
@@ -212,7 +122,7 @@ public abstract class AbstractResourceManager implements ResourceManager {
   @Override
   public void removePool(String name) throws Exception {
     ensureNotClosed();
-    Pool pool = resourcePools.remove(name);
+    ResourceManagerPool pool = resourcePools.remove(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
@@ -222,21 +132,21 @@ public abstract class AbstractResourceManager implements ResourceManager {
   }
 
   @Override
-  public void addResources(String name, Collection<ResourceManaged> resourceManaged) {
+  public void addResources(String name, Collection<ManagedResource> managedResource) {
     ensureNotClosed();
-    for (ResourceManaged resource : resourceManaged) {
+    for (ManagedResource resource : managedResource) {
       addResource(name, resource);
     }
   }
 
   @Override
-  public void addResource(String name, ResourceManaged resourceManaged) {
+  public void addResource(String name, ManagedResource managedResource) {
     ensureNotClosed();
-    Pool pool = resourcePools.get(name);
+    ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
-    pool.addResource(resourceManaged);
+    pool.addResource(managedResource);
   }
 
   @Override
@@ -244,7 +154,7 @@ public abstract class AbstractResourceManager implements ResourceManager {
     synchronized (this) {
       isClosed = true;
       log.debug("Closing all pools.");
-      for (Pool pool : resourcePools.values()) {
+      for (ResourceManagerPool pool : resourcePools.values()) {
         IOUtils.closeQuietly(pool);
       }
       resourcePools.clear();
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
new file mode 100644
index 0000000..3967c87
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
@@ -0,0 +1,36 @@
+package org.apache.solr.managed;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.managed.plugins.CacheManagerPlugin;
+
+/**
+ *
+ */
+public class DefaultResourceManagerPluginFactory implements ResourceManagerPluginFactory {
+
+  private static final Map<String, String> typeToClass = new HashMap<>();
+
+  static {
+    typeToClass.put(CacheManagerPlugin.TYPE, CacheManagerPlugin.class.getName());
+  }
+
+  private final SolrResourceLoader loader;
+
+  public DefaultResourceManagerPluginFactory(SolrResourceLoader loader) {
+    this.loader = loader;
+  }
+
+  @Override
+  public ResourceManagerPlugin create(String type, Map<String, Object> params) throws Exception {
+    String pluginClazz = typeToClass.get(type);
+    if (pluginClazz == null) {
+      throw new IllegalArgumentException("Unsupported plugin type '" + type + "'");
+    }
+    ResourceManagerPlugin resourceManagerPlugin = loader.newInstance(pluginClazz, ResourceManagerPlugin.class);
+    resourceManagerPlugin.init(params);
+    return resourceManagerPlugin;
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/Limit.java b/solr/core/src/java/org/apache/solr/managed/Limit.java
deleted file mode 100644
index 0eee67d..0000000
--- a/solr/core/src/java/org/apache/solr/managed/Limit.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.apache.solr.managed;
-
-/**
- *
- */
-public class Limit {
-  public final float min, max, cost;
-
-  public Limit() {
-    this(Float.MIN_VALUE, Float.MAX_VALUE, 1.0f);
-  }
-
-  public Limit(float min, float max) {
-    this(min, max, 1.0f);
-  }
-
-  public Limit(float min, float max, float cost) {
-    if (cost <= 0.0f) {
-      throw new IllegalArgumentException("cost must be > 0.0f");
-    }
-    this.min = min;
-    this.max = max;
-    this.cost = cost;
-  }
-
-  public float deltaOutsideLimit(float currentValue) {
-    if (currentValue < min) {
-      return currentValue - min;
-    } else if (currentValue > max) {
-      return currentValue - max;
-    } else {
-      return 0;
-    }
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/Limits.java b/solr/core/src/java/org/apache/solr/managed/Limits.java
deleted file mode 100644
index d817be9..0000000
--- a/solr/core/src/java/org/apache/solr/managed/Limits.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.apache.solr.managed;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- *
- */
-public class Limits implements Iterable<Map.Entry<String, Limit>> {
-
-  public static final Limit UNLIMITED = new Limit(Float.MIN_VALUE, Float.MAX_VALUE);
-
-  private Map<String, Limit> values = new HashMap<>();
-
-  public void setLimit(String key, Limit value) {
-    if (value != null) {
-      values.put(key, value);
-    } else {
-      values.remove(key);
-    }
-  }
-
-  public void setLimitMax(String key, float max) {
-    Limit limit = values.computeIfAbsent(key, k -> new Limit(Float.MIN_VALUE, max));
-    if (limit.max == max) {
-      return;
-    } else {
-      values.put(key, new Limit(limit.min, max));
-    }
-  }
-
-  public void setLimitMin(String key, float min) {
-    Limit limit = values.computeIfAbsent(key, k -> new Limit(min, Float.MAX_VALUE));
-    if (limit.min == min) {
-      return;
-    } else {
-      values.put(key, new Limit(min, limit.max));
-    }
-  }
-
-  public Limit getLimit(String key) {
-    return getLimit(key, UNLIMITED);
-  }
-
-  public Limit getLimit(String key, Limit defValue) {
-    Limit value = values.get(key);
-    if (value != null) {
-      return value;
-    } else {
-      return defValue;
-    }
-  }
-
-  public Set<String> getKeys() {
-    return Collections.unmodifiableSet(values.keySet());
-  }
-
-  public void removeLimit(String key) {
-    values.remove(key);
-  }
-
-  public Limits copy() {
-    Limits cloned = new Limits();
-    cloned.values.putAll(values);
-    return cloned;
-  }
-
-  @Override
-  public Iterator<Map.Entry<String, Limit>> iterator() {
-    return Collections.unmodifiableMap(values).entrySet().iterator();
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
new file mode 100644
index 0000000..04d5207
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -0,0 +1,63 @@
+package org.apache.solr.managed;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public interface ManagedResource {
+  Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  /**
+   * Unique name of this resource.
+   */
+  String getName();
+
+  /**
+   * Returns types of management schemes supported by this resource. This always
+   * returns a non-null collection with at least one entry.
+   */
+  Collection<String> getManagedResourceTypes();
+
+  /**
+   * Set current managed limits.
+   * @param limits map of limit names and values
+   */
+  default void setManagedLimits(Map<String, Float> limits) {
+    if (limits == null) {
+      return;
+    }
+    limits.forEach((key, value) -> {
+      try {
+        setManagedLimit(key, value);
+      } catch (Exception e) {
+        log.warn("Exception setting managed limit on {}: key={}, value={}, exception={}",
+            getName(), key, value, e);
+      }
+    });
+  }
+
+  /**
+   * Set a managed limit.
+   * @param key limit name
+   * @param value limit value
+   */
+  void setManagedLimit(String key, float value) throws Exception;
+
+  /**
+   * Returns current managed limits.
+   */
+  Map<String, Float> getManagedLimits();
+
+  /**
+   * Returns monitored values that are used for calculating optimal setting of managed limits.
+   * @param tags value names
+   * @return map of names to current values.
+   */
+  Map<String, Float> getManagedValues(Collection<String> tags);
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ProportionalResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ProportionalResourceManager.java
deleted file mode 100644
index f2edf65..0000000
--- a/solr/core/src/java/org/apache/solr/managed/ProportionalResourceManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.apache.solr.managed;
-
-import java.util.Map;
-
-import org.apache.solr.common.util.TimeSource;
-
-/**
- *
- */
-public class ProportionalResourceManager extends AbstractResourceManager {
-  public ProportionalResourceManager(TimeSource timeSource) {
-    super(timeSource);
-  }
-
-  @Override
-  protected void managePool(Pool pool) {
-    Map<String, Map<String, Float>> currentValues = pool.getCurrentValues();
-    Map<String, Float> totalValues = pool.getTotalValues();
-    Map<String, Float> totalCosts = pool.getTotalCosts();
-    pool.getLimits().forEach(entry -> {
-      Limit poolLimit = entry.getValue();
-      Float totalValue = totalValues.get(entry.getKey());
-      if (totalValue == null) {
-        return;
-      }
-      float delta = poolLimit.deltaOutsideLimit(totalValue);
-      Float totalCost = totalCosts.get(entry.getKey());
-      if (totalCost == null || totalCost == 0) {
-        return;
-      }
-      // re-adjust the limits based on relative costs
-      pool.getResources().forEach((name, resource) -> {
-        Map<String, Float> current = currentValues.get(name);
-        if (current == null) {
-          return;
-        }
-        Limits limits = resource.getManagedLimits();
-        Limit limit = limits.getLimit(entry.getKey());
-        if (limit == null) {
-          return;
-        }
-        float newMax = limit.max - delta * limit.cost / totalCost;
-        resource.setManagedLimitMax(entry.getKey(), newMax);
-      });
-    });
-  }
-
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManaged.java b/solr/core/src/java/org/apache/solr/managed/ResourceManaged.java
deleted file mode 100644
index 889bc85..0000000
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManaged.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.apache.solr.managed;
-
-import java.util.Map;
-
-/**
- *
- */
-public interface ResourceManaged {
-
-  String getName();
-
-  void setManagedLimits(Limits limits);
-
-  void setManagedLimit(String key, Limit limit);
-
-  void setManagedLimitMax(String key, float max);
-
-  void setManagedLimitMin(String key, float min);
-
-  Limits getManagedLimits();
-
-  Map<String, Float> getManagedValues();
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index cd9e87d..a2e3fe3 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -16,20 +16,20 @@ public interface ResourceManager extends SolrCloseable, PluginInfoInitialized {
 
   PluginInfo getPluginInfo();
 
-  void createPool(String name, Limits limits, Map<String, Object> params) throws Exception;
+  void createPool(String name, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception;
 
-  void modifyPoolLimits(String name, Limits limits) throws Exception;
+  void modifyPoolLimits(String name, Map<String, Float> limits) throws Exception;
 
   void removePool(String name) throws Exception;
 
-  default void addResources(String pool, Collection<ResourceManaged> resourceManaged) {
+  default void addResources(String pool, Collection<ManagedResource> managedResource) {
     ensureNotClosed();
-    for (ResourceManaged resource : resourceManaged) {
+    for (ManagedResource resource : managedResource) {
       addResource(pool, resource);
     }
   }
 
-  void addResource(String pool, ResourceManaged resourceManaged);
+  void addResource(String pool, ManagedResource managedResource);
 
   default void ensureNotClosed() {
     if (isClosed()) {
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
new file mode 100644
index 0000000..a73cdcb
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -0,0 +1,20 @@
+package org.apache.solr.managed;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ *
+ */
+public interface ResourceManagerPlugin {
+
+  String getType();
+
+  void init(Map<String, Object> params);
+
+  Collection<String> getMonitoredTags();
+  Collection<String> getControlledTags();
+
+  void manage(ResourceManagerPool pool);
+
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
new file mode 100644
index 0000000..b4e1a54
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
@@ -0,0 +1,11 @@
+package org.apache.solr.managed;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface ResourceManagerPluginFactory {
+
+  ResourceManagerPlugin create(String type, Map<String, Object> params) throws Exception;
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
new file mode 100644
index 0000000..88b4c06
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -0,0 +1,95 @@
+package org.apache.solr.managed;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+
+/**
+ *
+ */
+public class ResourceManagerPool implements Runnable, Closeable {
+  private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
+  private Map<String, Float> limits;
+  private final String type;
+  private final ResourceManagerPlugin resourceManagerPlugin;
+  private final Map<String, Object> params;
+  private Map<String, Map<String, Float>> currentValues = null;
+  private Map<String, Float> totalValues = null;
+  int scheduleDelaySeconds;
+  ScheduledFuture<?> scheduledFuture;
+
+  public ResourceManagerPool(ResourceManagerPluginFactory factory, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception {
+    this.type = type;
+    this.resourceManagerPlugin = factory.create(type, params);
+    this.limits = new HashMap<>(limits);
+    this.params = new HashMap<>(params);
+  }
+
+  public synchronized void addResource(ManagedResource managedResource) {
+    if (resources.containsKey(managedResource.getName())) {
+      throw new IllegalArgumentException("Pool already has resource '" + managedResource.getName() + "'.");
+    }
+    Collection<String> types = managedResource.getManagedResourceTypes();
+    if (!types.contains(type)) {
+      throw new IllegalArgumentException("Pool type '" + type + "' is not supported by the resource " + managedResource.getName());
+    }
+    resources.put(managedResource.getName(), managedResource);
+  }
+
+  public Map<String, ManagedResource> getResources() {
+    return Collections.unmodifiableMap(resources);
+  }
+
+  public Map<String, Map<String, Float>> getCurrentValues() {
+    // collect current values
+    currentValues = new HashMap<>();
+    for (ManagedResource resource : resources.values()) {
+      currentValues.put(resource.getName(), resource.getManagedValues(resourceManagerPlugin.getMonitoredTags()));
+    }
+    // calculate totals
+    totalValues = new HashMap<>();
+    currentValues.values().forEach(map -> map.forEach((k, v) -> {
+      Float total = totalValues.get(k);
+      if (total == null) {
+        totalValues.put(k, v);
+      } else {
+        totalValues.put(k, total + v);
+      }
+    }));
+    return Collections.unmodifiableMap(currentValues);
+  }
+
+  /**
+   * This returns cumulative values of all resources. NOTE:
+   * you must call {@link #getCurrentValues()} first!
+   */
+  public Map<String, Float> getTotalValues() {
+    return Collections.unmodifiableMap(totalValues);
+  }
+
+  public Map<String, Float> getLimits() {
+    return limits;
+  }
+
+  public void setLimits(Map<String, Float> limits) {
+    this.limits = new HashMap(limits);
+  }
+
+  @Override
+  public void run() {
+    resourceManagerPlugin.manage(this);
+  }
+
+  @Override
+  public void close() throws IOException {
+    if (scheduledFuture != null) {
+      scheduledFuture.cancel(true);
+      scheduledFuture = null;
+    }
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
new file mode 100644
index 0000000..7f2f5cd
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -0,0 +1,95 @@
+package org.apache.solr.managed.plugins;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.managed.AbstractResourceManagerPlugin;
+import org.apache.solr.managed.ResourceManagerPool;
+
+/**
+ *
+ */
+public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
+  public static String TYPE = "cache";
+
+  public static final String SIZE_TAG = "size";
+  public static final String HIT_RATIO_TAG = "hitratio";
+  public static final String RAM_BYTES_USED_TAG = "ramBytesUsed";
+  public static final String MAX_RAM_MB_TAG = "maxRamMB";
+
+  private static final Map<String, String> controlledToMonitored = new HashMap<>();
+
+  static {
+    controlledToMonitored.put(MAX_RAM_MB_TAG, RAM_BYTES_USED_TAG);
+    controlledToMonitored.put(SIZE_TAG, SIZE_TAG);
+  }
+
+  private static final Collection<String> MONITORED_TAGS = Arrays.asList(
+      SIZE_TAG,
+      HIT_RATIO_TAG,
+      RAM_BYTES_USED_TAG
+  );
+
+  @Override
+  public Collection<String> getMonitoredTags() {
+    return MONITORED_TAGS;
+  }
+
+  private static final Collection<String> CONTROLLED_TAGS = Arrays.asList(
+      MAX_RAM_MB_TAG,
+      SIZE_TAG
+  );
+
+  @Override
+  public Collection<String> getControlledTags() {
+    return CONTROLLED_TAGS;
+  }
+
+  @Override
+  public String getType() {
+    return TYPE;
+  }
+
+  @Override
+  public void init(Map<String, Object> params) {
+
+  }
+
+  @Override
+  public void manage(ResourceManagerPool pool) {
+    Map<String, Map<String, Float>> currentValues = pool.getCurrentValues();
+    Map<String, Float> totalValues = pool.getTotalValues();
+    pool.getLimits().forEach((poolLimitName, poolLimitValue) -> {
+      String monitoredTag = controlledToMonitored.get(poolLimitName);
+      if (monitoredTag == null) {
+        return;
+      }
+      Float totalValue = totalValues.get(monitoredTag);
+      if (totalValue == null) {
+        return;
+      }
+      float totalDelta = poolLimitValue - totalValue;
+      pool.getResources().forEach((name, resource) -> {
+        Map<String, Float> current = currentValues.get(name);
+        if (current == null) {
+          return;
+        }
+        Map<String, Float> limits = resource.getManagedLimits();
+        Float managedSize = limits.get(SIZE_TAG);
+        Float resMaxRamMB = limits.get(MAX_RAM_MB_TAG);
+        Float currentSize = current.get(SIZE_TAG);
+        Float currentHitratio = current.get(HIT_RATIO_TAG);
+        Float ramBytesUsed = current.get(RAM_BYTES_USED_TAG);
+
+        // logic to adjust per-resource controlled limits
+        if (poolLimitName.equals(MAX_RAM_MB_TAG)) {
+          // adjust per-resource maxRamMB
+        } else if (poolLimitName.equals(SIZE_TAG)) {
+          // adjust per-resource size
+        }
+      });
+    });
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index 8f53b45..0e0ff6c 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -345,11 +345,9 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
         res.put("inserts", inserts);
         res.put("evictions", evictions);
         res.put("size", map.size());
-        if (maxRamBytes != Long.MAX_VALUE)  {
-          res.put("maxRamMB", maxRamBytes / 1024L / 1024L);
-          res.put("ramBytesUsed", ramBytesUsed());
-          res.put("evictionsRamUsage", evictionsRamUsage);
-        }
+        res.put("maxRamMB", maxRamBytes / 1024L / 1024L);
+        res.put("ramBytesUsed", ramBytesUsed());
+        res.put("evictionsRamUsage", evictionsRamUsage);
       }
       res.put("warmupTime", warmupTime);
 


[lucene-solr] 27/36: Fix a bug in component registration.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit e44e82255ebbe2e15215c344ad7ea973747fffa5
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Mon Aug 12 09:52:47 2019 +0200

    Fix a bug in component registration.
---
 .../src/java/org/apache/solr/managed/DefaultResourceManager.java   | 7 ++++---
 .../java/org/apache/solr/managed/DefaultResourceManagerPool.java   | 5 +++++
 .../core/src/java/org/apache/solr/managed/ResourceManagerPool.java | 7 +++++++
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index e6eb55c..069628d 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -178,15 +178,16 @@ public class DefaultResourceManager extends ResourceManager {
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
-    String type = pool.getType();
+    String poolType = pool.getType();
     resourcePools.forEach((poolName, otherPool) -> {
       if (otherPool == pool) {
         return;
       }
-      if (otherPool.getType().equals(type)) {
+      if (otherPool.isRegistered(managedComponent.getManagedComponentId().toString()) &&
+          otherPool.getType().equals(poolType)) {
         throw new IllegalArgumentException("Resource " + managedComponent.getManagedComponentId() +
             " is already managed in another pool (" +
-            otherPool.getName() + ") of the same type " + type);
+            otherPool.getName() + ") of the same type " + poolType);
       }
     });
     pool.registerComponent(managedComponent);
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 07de310..1f1e6d2 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -105,6 +105,11 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
+  public boolean isRegistered(String componentId) {
+    return components.containsKey(componentId);
+  }
+
+  @Override
   public Map<String, ManagedComponent> getComponents() {
     return Collections.unmodifiableMap(components);
   }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index dc2ddac..0761442 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -22,6 +22,13 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   /** Remove named component from this pool. */
   boolean unregisterComponent(String componentId);
 
+  /**
+   * Check whether a named component is registered in this pool.
+   * @param componentId component id
+   * @return true if the component with this name is registered, false otherwise.
+   */
+  boolean isRegistered(String componentId);
+
   /** Get components managed by this pool. */
   Map<String, ManagedComponent> getComponents();
 


[lucene-solr] 28/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 25972bfaf9f33139a999e23a7a1c15d0e7f7ced7
Merge: e44e822 0857bb6
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Mon Nov 18 13:19:30 2019 +0100

    Merge branch 'master' into jira/solr-13579

 .asf.yaml                                          |   19 +
 .github/PULL_REQUEST_TEMPLATE.md                   |    1 +
 .github/workflows/ant.yml                          |   22 +
 README.md                                          |    2 +-
 dev-tools/doap/lucene.rdf                          |    7 +
 dev-tools/doap/solr.rdf                            |    7 +
 dev-tools/maven/README.maven                       |    8 +-
 dev-tools/maven/pom.xml.template                   |   24 +-
 dev-tools/maven/solr/pom.xml.template              |   10 +-
 dev-tools/scripts/jenkins.build.ref.guide.sh       |    9 +-
 lucene/CHANGES.txt                                 |  175 +-
 lucene/MIGRATE.txt                                 |   23 +
 .../lucene/analysis/custom/CustomAnalyzer.java     |   12 +-
 .../analysis/el/GreekLowerCaseFilterFactory.java   |    2 +-
 .../analysis/ga/IrishLowerCaseFilterFactory.java   |    2 +-
 .../miscellaneous/ConcatenateGraphFilter.java      |   37 +-
 .../ConcatenateGraphFilterFactory.java             |   35 +-
 .../miscellaneous/WordDelimiterGraphFilter.java    |   14 +-
 .../analysis/query/QueryAutoStopWordAnalyzer.java  |    8 +-
 .../standard/UAX29URLEmailTokenizerFactory.java    |    2 +-
 .../analysis/synonym/WordnetSynonymParser.java     |    6 +-
 .../analysis/tr/TurkishLowerCaseFilterFactory.java |    2 +-
 .../analysis/util/AbstractAnalysisFactory.java     |    3 +
 .../miscellaneous/TestConcatenateGraphFilter.java  |   56 +-
 .../TestConcatenateGraphFilterFactory.java         |   36 +-
 .../TestWordDelimiterGraphFilter.java              |   31 +
 .../analysis/synonym/TestSolrSynonymParser.java    |   23 +
 .../analysis/synonym/TestWordnetSynonymParser.java |    5 +
 lucene/analysis/icu/src/data/utr30/nfc.txt         |   17 +-
 lucene/analysis/icu/src/data/utr30/nfkc.txt        |    2 +-
 lucene/analysis/icu/src/data/utr30/nfkc_cf.txt     |   81 +-
 .../icu/ICUNormalizer2CharFilterFactory.java       |    6 +-
 .../analysis/icu/ICUNormalizer2FilterFactory.java  |    6 +-
 .../org/apache/lucene/analysis/icu/utr30.nrm       |  Bin 59232 -> 59664 bytes
 .../icu/TestICUNormalizer2CharFilterFactory.java   |   14 +-
 .../icu/TestICUNormalizer2FilterFactory.java       |   12 +
 .../analysis/icu/GenerateUTR30DataFiles.java       |    2 +-
 .../lucene/analysis/ja/JapaneseTokenizer.java      |   40 +-
 .../lucene/analysis/ja/dict/BinaryDictionary.java  |   13 +-
 .../lucene/analysis/ja/dict/ConnectionCosts.java   |   14 +-
 .../analysis/ja/dict/TokenInfoDictionary.java      |    2 +-
 .../lucene/analysis/ja/dict/UnknownDictionary.java |    9 +
 .../lucene/analysis/ja/dict/UserDictionary.java    |   14 +-
 .../lucene/analysis/ja/util/DictionaryBuilder.java |   12 +-
 .../analysis/ja/dict/TokenInfoDictionary$fst.dat   |  Bin 1698570 -> 1707541 bytes
 .../lucene/analysis/ja/TestJapaneseTokenizer.java  |   20 +
 .../analysis/ja/dict/UserDictionaryTest.java       |   22 +
 .../lucene/analysis/ko/GraphvizFormatter.java      |   19 +-
 .../apache/lucene/analysis/ko/KoreanAnalyzer.java  |    3 +-
 .../lucene/analysis/ko/KoreanNumberFilter.java     |    9 +-
 .../analysis/ko/KoreanPartOfSpeechStopFilter.java  |    6 +-
 .../apache/lucene/analysis/ko/KoreanTokenizer.java |   36 +-
 .../lucene/analysis/ko/dict/BinaryDictionary.java  |   18 +-
 .../analysis/ko/dict/CharacterDefinition.java      |    8 +-
 .../lucene/analysis/ko/dict/ConnectionCosts.java   |    2 +-
 .../lucene/analysis/ko/dict/TokenInfoFST.java      |    4 +-
 .../lucene/analysis/ko/dict/UserDictionary.java    |   16 +-
 .../analysis/ko/util/BinaryDictionaryWriter.java   |    4 +-
 .../apache/lucene/analysis/ko/util/CSVUtil.java    |    4 +-
 .../ko/util/TokenInfoDictionaryBuilder.java        |    2 +-
 .../analysis/ko/dict/TokenInfoDictionary$fst.dat   |  Bin 5641400 -> 6009053 bytes
 .../analysis/ko/StringMockResourceLoader.java      |    2 +-
 .../lucene/analysis/ko/TestKoreanAnalyzer.java     |    4 +-
 .../analysis/ko/TestKoreanNumberFilterFactory.java |   12 +-
 .../TestKoreanPartOfSpeechStopFilterFactory.java   |   16 +-
 .../ko/TestKoreanReadingFormFilterFactory.java     |   17 +-
 .../lucene/analysis/ko/TestKoreanTokenizer.java    |   16 +
 .../analysis/ko/TestKoreanTokenizerFactory.java    |   41 +-
 .../analysis/ko/dict/TokenInfoDictionaryTest.java  |    6 +-
 .../analysis/ko/dict/UserDictionaryTest.java       |    5 +-
 .../lucene/index/TestBackwardsCompatibility.java   |    7 +-
 .../org/apache/lucene/index/index.8.3.0-cfs.zip    |  Bin 0 -> 15684 bytes
 .../org/apache/lucene/index/index.8.3.0-nocfs.zip  |  Bin 0 -> 15690 bytes
 .../test/org/apache/lucene/index/sorted.8.3.0.zip  |  Bin 0 -> 62474 bytes
 .../lucene/benchmark/byTask/utils/Config.java      |   19 +-
 .../blocktreeords/OrdsBlockTreeTermsReader.java    |    3 +-
 .../codecs/blocktreeords/OrdsSegmentTermsEnum.java |    2 +-
 .../codecs/bloom/BloomFilteringPostingsFormat.java |    3 +-
 .../codecs/memory/DirectDocValuesConsumer.java     |  350 --
 .../codecs/memory/DirectDocValuesFormat.java       |   83 -
 .../codecs/memory/DirectDocValuesProducer.java     |  780 ----
 .../lucene/codecs/memory/FSTOrdTermsReader.java    |    3 +-
 .../lucene/codecs/memory/FSTTermsReader.java       |    3 +-
 .../lucene/codecs/uniformsplit/BlockDecoder.java   |   48 +
 .../lucene/codecs/uniformsplit/BlockEncoder.java   |   59 +
 .../lucene/codecs/uniformsplit/BlockHeader.java    |  167 +
 .../lucene/codecs/uniformsplit/BlockLine.java      |  260 ++
 .../lucene/codecs/uniformsplit/BlockReader.java    |  537 +++
 .../lucene/codecs/uniformsplit/BlockWriter.java    |  258 ++
 .../uniformsplit/DeltaBaseTermStateSerializer.java |  219 ++
 .../uniformsplit/DictionaryBrowserSupplier.java    |   81 +
 .../lucene/codecs/uniformsplit/FSTDictionary.java  |  234 ++
 .../lucene/codecs/uniformsplit/FieldMetadata.java  |  256 ++
 .../codecs/uniformsplit/IndexDictionary.java       |  127 +
 .../codecs/uniformsplit/IntersectBlockReader.java  |  558 +++
 .../lucene/codecs/uniformsplit/RamUsageUtil.java   |   87 +
 .../lucene/codecs/uniformsplit/TermBytes.java      |  123 +
 .../uniformsplit/UniformSplitPostingsFormat.java   |  136 +
 .../codecs/uniformsplit/UniformSplitTerms.java     |  153 +
 .../uniformsplit/UniformSplitTermsReader.java      |  204 +
 .../uniformsplit/UniformSplitTermsWriter.java      |  315 ++
 .../lucene/codecs/uniformsplit/package-info.java   |   33 +
 .../sharedterms/FieldMetadataTermState.java        |   37 +
 .../uniformsplit/sharedterms/STBlockLine.java      |  194 +
 .../uniformsplit/sharedterms/STBlockReader.java    |  139 +
 .../uniformsplit/sharedterms/STBlockWriter.java    |  105 +
 .../sharedterms/STIntersectBlockReader.java        |  112 +
 .../sharedterms/STMergingBlockReader.java          |  111 +
 .../sharedterms/STMergingTermsEnum.java            |  243 ++
 .../sharedterms/STUniformSplitPostingsFormat.java  |   84 +
 .../sharedterms/STUniformSplitTerms.java           |   65 +
 .../sharedterms/STUniformSplitTermsReader.java     |   98 +
 .../sharedterms/STUniformSplitTermsWriter.java     |  477 +++
 .../sharedterms/UnionFieldMetadataBuilder.java     |   60 +
 .../uniformsplit/sharedterms/package-info.java     |   30 +
 .../org.apache.lucene.codecs.DocValuesFormat       |   16 -
 .../org.apache.lucene.codecs.PostingsFormat        |    3 +-
 .../codecs/lucene50/MockTermStateFactory.java      |   31 +
 .../codecs/memory/TestDirectDocValuesFormat.java   |   34 -
 .../codecs/uniformsplit/TestBlockWriter.java       |  126 +
 .../codecs/uniformsplit/TestFSTDictionary.java     |  145 +
 .../lucene/codecs/uniformsplit/TestTermBytes.java  |  217 ++
 .../uniformsplit/TestTermBytesComparator.java      |  189 +
 .../TestUniformSplitPostingFormat.java             |   59 +
 .../sharedterms/STBlockReaderTest.java             |  352 ++
 .../TestSTUniformSplitPostingFormat.java           |   35 +
 lucene/common-build.xml                            |   26 +-
 .../codecs/blocktree/BlockTreeTermsReader.java     |    3 +-
 .../lucene/codecs/blocktree/SegmentTermsEnum.java  |    4 +
 .../org/apache/lucene/document/DoublePoint.java    |    9 +-
 .../org/apache/lucene/document/FeatureField.java   |    2 +-
 .../org/apache/lucene/document/FloatPoint.java     |    9 +-
 .../java/org/apache/lucene/document/IntPoint.java  |    9 +-
 .../lucene/document/LatLonDocValuesField.java      |   16 +
 .../LatLonDocValuesPointInPolygonQuery.java        |  147 +
 .../lucene/document/LatLonPointDistanceQuery.java  |    2 +-
 .../lucene/document/LatLonPointInPolygonQuery.java |  167 +-
 .../java/org/apache/lucene/document/LongPoint.java |    9 +-
 .../apache/lucene/document/RangeFieldQuery.java    |    2 +-
 .../java/org/apache/lucene/geo/Component2D.java    |   96 +
 .../java/org/apache/lucene/geo/ComponentTree.java  |  206 +
 .../src/java/org/apache/lucene/geo/EdgeTree.java   |  503 +--
 .../org/apache/lucene/geo/GeoEncodingUtils.java    |   17 +-
 .../src/java/org/apache/lucene/geo/GeoUtils.java   |    9 +-
 .../src/java/org/apache/lucene/geo/Polygon2D.java  |  224 +-
 .../src/java/org/apache/lucene/geo/Rectangle.java  |   15 +-
 .../lucene/geo/SimpleGeoJSONPolygonParser.java     |    2 +
 .../apache/lucene/index/BaseCompositeReader.java   |   24 +-
 .../org/apache/lucene/index/DirectoryReader.java   |    1 -
 .../org/apache/lucene/index/IndexFileDeleter.java  |    4 +-
 .../org/apache/lucene/index/IndexFileNames.java    |    3 -
 .../java/org/apache/lucene/index/IndexReader.java  |    7 +-
 .../java/org/apache/lucene/index/PointValues.java  |   28 +-
 .../java/org/apache/lucene/index/SegmentInfos.java |   11 +-
 .../org/apache/lucene/search/BooleanQuery.java     |   14 +-
 .../apache/lucene/search/HitsThresholdChecker.java |  119 +
 .../org/apache/lucene/search/IndexSearcher.java    |   51 +-
 .../org/apache/lucene/search/LRUQueryCache.java    |   61 +-
 .../apache/lucene/search/MaxScoreAccumulator.java  |   90 +
 .../org/apache/lucene/search/MultiPhraseQuery.java |    7 +-
 .../java/org/apache/lucene/search/PhraseQuery.java |    6 +-
 .../org/apache/lucene/search/PointRangeQuery.java  |    2 +-
 .../org/apache/lucene/search/QueryRescorer.java    |   39 +-
 .../org/apache/lucene/search/SynonymQuery.java     |    7 +-
 .../org/apache/lucene/search/TermInSetQuery.java   |    4 +-
 .../java/org/apache/lucene/search/TermQuery.java   |    2 +-
 .../org/apache/lucene/search/TopDocsCollector.java |   15 +-
 .../apache/lucene/search/TopFieldCollector.java    |  152 +-
 .../apache/lucene/search/TopScoreDocCollector.java |  132 +-
 .../org/apache/lucene/search/spans/SpanWeight.java |    8 +-
 .../src/java/org/apache/lucene/util/ArrayUtil.java |   23 +-
 .../src/java/org/apache/lucene/util/BitUtil.java   |  125 +
 .../java/org/apache/lucene/util/IntroSelector.java |   97 +-
 .../src/java/org/apache/lucene/util/SetOnce.java   |   36 +-
 .../java/org/apache/lucene/util/SloppyMath.java    |   31 +-
 .../src/java/org/apache/lucene/util/Version.java   |    7 +
 .../java/org/apache/lucene/util/bkd/BKDReader.java |  236 +-
 .../java/org/apache/lucene/util/bkd/BKDWriter.java |   97 +-
 .../java/org/apache/lucene/util/fst/Builder.java   |  115 +-
 .../org/apache/lucene/util/fst/BytesStore.java     |   21 +
 .../src/java/org/apache/lucene/util/fst/FST.java   |  771 ++--
 .../java/org/apache/lucene/util/fst/FSTEnum.java   |  236 +-
 .../java/org/apache/lucene/util/fst/NodeHash.java  |   17 +-
 .../src/java/org/apache/lucene/util/fst/Util.java  |   29 +-
 .../org/apache/lucene/util/packed/Direct16.java    |  106 -
 .../org/apache/lucene/util/packed/Direct32.java    |  106 -
 .../org/apache/lucene/util/packed/Direct64.java    |   96 -
 .../org/apache/lucene/util/packed/Direct8.java     |  104 -
 .../lucene/util/packed/Packed16ThreeBlocks.java    |  125 -
 .../lucene/util/packed/Packed8ThreeBlocks.java     |  123 -
 .../org/apache/lucene/util/packed/PackedInts.java  |   65 +-
 .../codecs/lucene60/TestLucene60PointsFormat.java  |  310 +-
 .../perfield/TestPerFieldDocValuesFormat.java      |    2 +-
 .../apache/lucene/document/TestFeatureSort.java    |    2 +-
 .../test/org/apache/lucene/geo/TestPolygon.java    |   17 +
 .../test/org/apache/lucene/geo/TestPolygon2D.java  |   88 +-
 .../lucene/index/TestFilterDirectoryReader.java    |   72 +
 .../lucene/search/TestIndexOrDocValuesQuery.java   |   67 +
 .../apache/lucene/search/TestIndexSearcher.java    |   82 +
 .../apache/lucene/search/TestLRUQueryCache.java    |  190 +-
 .../lucene/search/TestLatLonDocValuesQueries.java  |    5 +-
 .../lucene/search/TestMaxScoreAccumulator.java     |   57 +
 .../apache/lucene/search/TestMinShouldMatch2.java  |    4 +-
 .../apache/lucene/search/TestQueryRescorer.java    |   92 +
 .../org/apache/lucene/search/TestQueryVisitor.java |   18 +
 .../apache/lucene/search/TestTopDocsCollector.java |  308 +-
 .../lucene/search/TestTopFieldCollector.java       |  231 ++
 .../TestUsageTrackingFilterCachingPolicy.java      |    2 +-
 .../test/org/apache/lucene/util/TestBitUtil.java   |   85 +
 .../org/apache/lucene/util/TestIntroSelector.java  |    2 +-
 .../test/org/apache/lucene/util/TestSetOnce.java   |    9 +
 .../test/org/apache/lucene/util/bkd/TestBKD.java   |   18 +-
 .../test/org/apache/lucene/util/fst/TestFSTs.java  |   33 +-
 .../org/apache/lucene/util/fst/TestFstDirect.java  |  106 -
 .../lucene/util/fst/TestFstDirectAddressing.java   |  212 +
 .../test/org/apache/lucene/util/fst/TestUtil.java  |   21 +-
 .../apache/lucene/util/packed/TestPackedInts.java  |   55 +-
 lucene/default-nested-ivy-settings.xml             |    2 +-
 .../lucene/demo/facet/DistanceFacetsExample.java   |   27 +-
 .../lucene/search/grouping/TopGroupsTest.java      |  235 ++
 lucene/ivy-versions.properties                     |   32 +-
 .../search/join/GlobalOrdinalsWithScoreQuery.java  |    7 +
 .../app/desktop/components/MenuBarProvider.java    |    2 +-
 .../dialog/menubar/ExportTermsDialogFactory.java   |   54 +-
 .../lucene/luke/models/tools/IndexTools.java       |    3 +-
 .../lucene/luke/models/tools/IndexToolsImpl.java   |    4 +-
 .../luke/models/overview/OverviewTestBase.java     |    6 +-
 .../search/TestDiversifiedTopDocsCollector.java    |   12 +-
 .../monitor/MultipassTermFilteredPresearcher.java  |    4 +-
 .../lucene/monitor/TermFilteredPresearcher.java    |    4 +-
 .../apache/lucene/queries/intervals/Intervals.java |   30 +
 .../apache/lucene/queries/mlt/MoreLikeThis.java    |    6 +-
 .../lucene/queries/intervals/TestIntervals.java    |   52 +-
 .../lucene/queries/mlt/TestMoreLikeThis.java       |   59 +
 .../builders/MultiPhraseQueryNodeBuilder.java      |   10 +-
 .../apache/lucene/queryparser/xml/CoreParser.java  |    4 +
 .../xml/builders/SpanPositionRangeBuilder.java     |   50 +
 .../queryparser/xml/SpanPositionRangeQuery.xml     |   21 +
 .../lucene/queryparser/xml/TestCoreParser.java     |    9 +
 .../lucene/replicator/IndexReplicationHandler.java |    5 +-
 .../idversion/VersionBlockTreeTermsReader.java     |    3 +-
 .../document/DoublePointMultiRangeBuilder.java     |   54 +
 .../document/FloatPointMultiRangeBuilder.java      |   55 +
 .../lucene/document/FloatPointNearestNeighbor.java |  186 +-
 .../lucene/document/IntPointMultiRangeBuilder.java |   53 +
 .../document/LatLonShapeBoundingBoxQuery.java      |   25 +-
 .../lucene/document/LatLonShapeLineQuery.java      |   28 +-
 .../lucene/document/LatLonShapePolygonQuery.java   |   28 +-
 .../document/LongPointMultiRangeBuilder.java       |   53 +
 .../org/apache/lucene/document/ShapeField.java     |  198 +-
 .../org/apache/lucene/document/ShapeQuery.java     |  488 ++-
 .../lucene/document/XYShapeBoundingBoxQuery.java   |   25 +-
 .../apache/lucene/document/XYShapeLineQuery.java   |   36 +-
 .../lucene/document/XYShapePolygonQuery.java       |   31 +-
 .../src/java/org/apache/lucene/geo/Line2D.java     |  134 +-
 .../java/org/apache/lucene/geo/Rectangle2D.java    |   77 +-
 .../java/org/apache/lucene/geo/Tessellator.java    |  210 +-
 .../java/org/apache/lucene/geo/XYPolygon2D.java    |   10 +-
 .../java/org/apache/lucene/search/BM25FQuery.java  |    7 +-
 .../apache/lucene/search/DocValuesTermsQuery.java  |   14 +
 .../lucene/search/LatLonPointPrototypeQueries.java |    4 +-
 .../org/apache/lucene/search/MultiRangeQuery.java  |  389 ++
 .../org/apache/lucene/search/NearestNeighbor.java  |   75 +-
 .../apache/lucene/search/TermAutomatonQuery.java   |    6 +-
 .../lucene/document/BaseLatLonShapeTestCase.java   |   21 +-
 .../lucene/document/BaseShapeEncodingTestCase.java |  384 +-
 .../apache/lucene/document/BaseShapeTestCase.java  |   21 +-
 .../lucene/document/BaseXYShapeTestCase.java       |   21 +-
 .../document/TestFloatPointNearestNeighbor.java    |   11 +-
 .../document/TestLatLonLineShapeQueries.java       |   27 +-
 .../document/TestLatLonMultiLineShapeQueries.java  |   22 +-
 .../document/TestLatLonMultiPointShapeQueries.java |   22 +-
 .../TestLatLonMultiPolygonShapeQueries.java        |   22 +-
 .../document/TestLatLonPointShapeQueries.java      |   18 +-
 .../document/TestLatLonPolygonShapeQueries.java    |   30 +-
 .../apache/lucene/document/TestLatLonShape.java    |   20 +-
 .../lucene/document/TestLatLonShapeEncoding.java   |    3 +-
 .../lucene/document/TestXYLineShapeQueries.java    |   27 +-
 .../document/TestXYMultiLineShapeQueries.java      |   22 +-
 .../document/TestXYMultiPointShapeQueries.java     |   22 +-
 .../document/TestXYMultiPolygonShapeQueries.java   |   22 +-
 .../lucene/document/TestXYPointShapeQueries.java   |   18 +-
 .../lucene/document/TestXYPolygonShapeQueries.java |   30 +-
 .../lucene/document/TestXYShapeEncoding.java       |    3 +-
 .../test/org/apache/lucene/geo/ShapeTestUtil.java  |    5 +-
 .../src/test/org/apache/lucene/geo/TestLine2D.java |   18 +-
 .../org/apache/lucene/geo/TestRectangle2D.java     |   58 +-
 .../org/apache/lucene/geo/TestTessellator.java     |   76 +
 .../lucene/search/TestMultiRangeQueries.java       |  590 +++
 .../test/org/apache/lucene/search/TestNearest.java |   29 +-
 .../spatial/prefix/tree/PackedQuadPrefixTree.java  |   68 +-
 .../lucene/spatial/prefix/tree/QuadPrefixTree.java |  104 +-
 .../prefix/tree/SpatialPrefixTreeFactory.java      |   33 +-
 .../lucene/spatial3d/geom/StandardObjects.java     |    4 +-
 .../apache/lucene/spatial3d/geom/GeoPathTest.java  |   16 +-
 .../search/suggest/document/ContextQuery.java      |    6 +-
 .../lucene/analysis/BaseTokenStreamTestCase.java   |   17 +-
 .../codecs/uniformsplit/Rot13CypherTestUtil.java   |   72 +
 .../UniformSplitRot13PostingsFormat.java           |  147 +
 .../apache/lucene/codecs/uniformsplit/package.html |   43 +
 .../STUniformSplitRot13PostingsFormat.java         |   59 +
 .../codecs/uniformsplit/sharedterms/package.html   |   43 +
 .../java/org/apache/lucene/geo/EarthDebugger.java  |    4 +-
 .../java/org/apache/lucene/geo/GeoTestUtil.java    |    8 +-
 .../java/org/apache/lucene/index/RandomCodec.java  |    4 +-
 .../lucene/search/ShardSearchingTestBase.java      |   35 +-
 .../org/apache/lucene/util/LuceneTestCase.java     |  154 +-
 .../org.apache.lucene.codecs.PostingsFormat        |    2 +
 .../org/apache/lucene/util/TestExpectThrows.java   |  155 +
 lucene/tools/forbiddenApis/lucene.txt              |    4 -
 lucene/tools/forbiddenApis/solr.txt                |    4 +
 .../tools/src/groovy/check-source-patterns.groovy  |   12 +
 .../dependencies/GetMavenDependenciesTask.java     |   22 +-
 solr/CHANGES.txt                                   |  312 +-
 solr/bin/solr                                      |   86 +-
 solr/bin/solr.cmd                                  | 4070 ++++++++++----------
 solr/bin/solr.in.cmd                               |    2 +
 solr/bin/solr.in.sh                                |    4 +-
 solr/cloud-dev/clean.sh                            |   20 -
 solr/cloud-dev/cli-test-solrcloud-start.sh         |   53 -
 solr/cloud-dev/cloud.sh                            |  383 ++
 solr/cloud-dev/control.sh                          |   37 -
 solr/cloud-dev/example1.sh                         |   26 -
 solr/cloud-dev/example2.sh                         |   36 -
 solr/cloud-dev/example3.sh                         |   35 -
 solr/cloud-dev/functions.sh                        |   77 -
 solr/cloud-dev/solrcloud-start-existing.sh         |   39 -
 solr/cloud-dev/solrcloud-start.sh                  |   74 -
 solr/cloud-dev/stop.sh                             |   64 -
 .../solr/collection1/conf/schema-folding-extra.xml |    2 +-
 .../solr/analytics/AnalyticsRequestManager.java    |    6 +-
 .../org/apache/solr/analytics/facet/PivotNode.java |    6 +-
 solr/contrib/clustering/ivy.xml                    |    2 +-
 .../solr/collection1/conf/solrconfig.xml           |   12 +-
 .../collection1/conf/dataimport-solrconfig.xml     |   12 +-
 .../solr/handler/dataimport/DataImportHandler.java |    8 +-
 .../solr/handler/dataimport/RegexTransformer.java  |    3 +-
 .../dataimport/config/ConfigNameConstants.java     |    9 +-
 .../collection1/conf/contentstream-solrconfig.xml  |   12 +-
 .../conf/dataimport-nodatasource-solrconfig.xml    |   12 +-
 .../collection1/conf/dataimport-solrconfig.xml     |   12 +-
 .../solr/collection1/conf/solrconfig.xml           |    8 +-
 .../apache/solr/ltr/model/DefaultWrapperModel.java |    2 +-
 .../solr/collection1/conf/solrconfig-ltr.xml       |    4 +-
 .../collection1/conf/solrconfig-ltr_Th10_10.xml    |    4 +-
 .../solr/collection1/conf/solrconfig-multiseg.xml  |    4 +-
 .../org/apache/solr/ltr/TestLTRQParserExplain.java |   12 +-
 .../test/org/apache/solr/ltr/TestLTRWithFacet.java |   21 +-
 .../test/org/apache/solr/ltr/TestLTRWithSort.java  |   20 +-
 .../test/org/apache/solr/ltr/TestRerankBase.java   |   11 +-
 .../solr/ltr/feature/TestEdisMaxSolrFeature.java   |   12 +-
 .../solr/ltr/feature/TestFeatureLogging.java       |   12 +-
 .../solr/ltr/feature/TestFieldLengthFeature.java   |   12 +-
 .../solr/ltr/feature/TestFieldValueFeature.java    |   12 +-
 .../solr/ltr/feature/TestFilterSolrFeature.java    |   12 +-
 .../solr/ltr/feature/TestNoMatchSolrFeature.java   |   12 +-
 .../solr/ltr/feature/TestOriginalScoreFeature.java |   12 +-
 .../solr/ltr/feature/TestRankingFeature.java       |   13 +-
 .../solr/ltr/feature/TestUserTermScoreWithQ.java   |   12 +-
 .../solr/ltr/feature/TestUserTermScorerQuery.java  |   12 +-
 .../solr/ltr/feature/TestUserTermScorereQDF.java   |   12 +-
 .../apache/solr/ltr/feature/TestValueFeature.java  |   12 +-
 .../apache/solr/ltr/model/TestAdapterModel.java    |   15 +-
 .../solr/ltr/model/TestDefaultWrapperModel.java    |   17 +-
 .../org/apache/solr/ltr/model/TestLinearModel.java |   15 +-
 .../ltr/model/TestMultipleAdditiveTreesModel.java  |   13 +-
 .../solr/ltr/model/TestNeuralNetworkModel.java     |   12 +-
 .../ltr/store/rest/TestManagedFeatureStore.java    |   15 +-
 .../store/rest/TestModelManagerPersistence.java    |   11 +-
 solr/contrib/prometheus-exporter/bin/solr-exporter |   23 +-
 .../prometheus-exporter/bin/solr-exporter.cmd      |    7 +-
 .../solr/prometheus/collector/MetricSamples.java   |    7 +-
 .../solr/collection1/conf/solrconfig.xml           |    8 +-
 .../exporter/SolrExporterIntegrationTest.java      |    1 +
 .../prometheus/exporter/SolrExporterTestBase.java  |    2 +-
 .../solr/response/VelocityResponseWriter.java      |    5 +-
 solr/core/ivy.xml                                  |    4 +-
 .../src/java/org/apache/solr/api/AnnotatedApi.java |  272 ++
 solr/core/src/java/org/apache/solr/api/ApiBag.java |   26 +-
 .../core/src/java/org/apache/solr/api/Command.java |   35 +
 .../src/java/org/apache/solr/api/EndPoint.java     |   36 +
 .../src/java/org/apache/solr/api/PayloadObj.java   |   35 +
 .../client/solrj/embedded/EmbeddedSolrServer.java  |  101 +-
 .../solr/client/solrj/embedded/JettyConfig.java    |   14 +-
 .../client/solrj/embedded/JettySolrRunner.java     |   25 +-
 .../src/java/org/apache/solr/cloud/CloudUtil.java  |    6 +-
 .../org/apache/solr/cloud/NodesSysPropsCacher.java |  204 -
 .../apache/solr/cloud/OverseerTaskProcessor.java   |    6 +-
 .../org/apache/solr/cloud/RecoveryStrategy.java    |    5 +-
 .../org/apache/solr/cloud/ReplicateFromLeader.java |    2 +-
 .../java/org/apache/solr/cloud/ZkController.java   |    8 +-
 .../java/org/apache/solr/cloud/ZkShardTerms.java   |   38 +-
 .../cloud/api/collections/CategoryRoutedAlias.java |   10 +-
 .../cloud/api/collections/CreateCollectionCmd.java |    5 +-
 .../solr/cloud/api/collections/CreateShardCmd.java |   10 +-
 .../cloud/api/collections/DeleteReplicaCmd.java    |    5 +-
 .../solr/cloud/api/collections/MoveReplicaCmd.java |    8 +-
 .../OverseerCollectionMessageHandler.java          |   10 +-
 .../api/collections/ReindexCollectionCmd.java      |    3 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |   46 +-
 .../cloud/api/collections/TimeRoutedAlias.java     |   29 +-
 .../solr/cloud/autoscaling/AutoScalingHandler.java |    2 +-
 .../solr/cloud/autoscaling/ExecutePlanAction.java  |   82 +-
 .../autoscaling/InactiveMarkersPlanAction.java     |   11 +-
 .../solr/cloud/autoscaling/IndexSizeTrigger.java   |   28 +-
 .../solr/cloud/autoscaling/NodeAddedTrigger.java   |   16 +
 .../solr/cloud/autoscaling/NodeLostTrigger.java    |   21 +-
 .../cloud/autoscaling/OverseerTriggerThread.java   |   30 +-
 .../solr/cloud/autoscaling/ScheduledTriggers.java  |   66 +-
 .../cloud/autoscaling/sim/FakeDocIterator.java     |   56 +
 .../cloud/autoscaling/sim/SimCloudManager.java     |   13 +-
 .../autoscaling/sim/SimClusterStateProvider.java   |  119 +-
 .../autoscaling/sim/SimNodeStateProvider.java      |   21 +-
 .../solr/cloud/autoscaling/sim/SimScenario.java    | 1091 ++++++
 .../solr/cloud/autoscaling/sim/SimUtils.java       |   64 +-
 .../autoscaling/sim/SnapshotCloudManager.java      |   44 +-
 .../sim/SnapshotClusterStateProvider.java          |    5 +-
 .../sim/SnapshotDistribStateManager.java           |   33 +-
 .../autoscaling/sim/SnapshotNodeStateProvider.java |   20 +-
 .../java/org/apache/solr/core/BlobRepository.java  |    9 +-
 .../java/org/apache/solr/core/CoreContainer.java   |  146 +-
 .../java/org/apache/solr/core/CoreDescriptor.java  |    6 +-
 .../org/apache/solr/core/HdfsDirectoryFactory.java |   20 +-
 .../solr/core/IndexDeletionPolicyWrapper.java      |  388 +-
 .../src/java/org/apache/solr/core/InitParams.java  |    3 +-
 .../src/java/org/apache/solr/core/LibListener.java |  273 --
 .../java/org/apache/solr/core/MemClassLoader.java  |   17 +-
 .../src/java/org/apache/solr/core/PluginBag.java   |  304 +-
 .../src/java/org/apache/solr/core/PluginInfo.java  |   51 +-
 .../java/org/apache/solr/core/RequestParams.java   |    9 +
 .../src/java/org/apache/solr/core/RuntimeLib.java  |  220 --
 .../src/java/org/apache/solr/core/SolrConfig.java  |   24 +-
 .../src/java/org/apache/solr/core/SolrCore.java    |  132 +-
 .../src/java/org/apache/solr/core/SolrCores.java   |   11 +-
 .../java/org/apache/solr/core/SolrInfoBean.java    |   52 +-
 .../org/apache/solr/core/SolrResourceLoader.java   |  348 +-
 .../apache/solr/filestore/DistribPackageStore.java |  489 +++
 .../org/apache/solr/filestore/PackageStore.java    |  124 +
 .../org/apache/solr/filestore/PackageStoreAPI.java |  360 ++
 .../org/apache/solr/filestore/package-info.java    |   21 +
 .../java/org/apache/solr/handler/BlobHandler.java  |    4 +-
 .../java/org/apache/solr/handler/CatStream.java    |   15 +-
 .../apache/solr/handler/CdcrReplicatorManager.java |   29 -
 .../apache/solr/handler/CdcrRequestHandler.java    |   15 +
 .../apache/solr/handler/ReplicationHandler.java    |  219 +-
 .../apache/solr/handler/RequestHandlerBase.java    |  102 +-
 .../java/org/apache/solr/handler/SnapShooter.java  |  117 +-
 .../org/apache/solr/handler/SolrConfigHandler.java |  544 ++-
 .../org/apache/solr/handler/admin/ColStatus.java   |    5 +
 .../solr/handler/admin/CollectionHandlerApi.java   |  300 +-
 .../solr/handler/admin/CollectionsHandler.java     |    7 +-
 .../solr/handler/admin/CoreAdminHandler.java       |   15 +-
 .../solr/handler/admin/CoreAdminOperation.java     |    2 +
 .../solr/handler/admin/CreateSnapshotOp.java       |   31 +-
 .../solr/handler/admin/IndexSizeEstimator.java     |    8 +-
 .../apache/solr/handler/admin/MetricsHandler.java  |    4 +-
 .../solr/handler/admin/PluginInfoHandler.java      |    4 +-
 .../handler/admin/SegmentsInfoRequestHandler.java  |    3 +-
 .../solr/handler/admin/SolrInfoMBeanHandler.java   |    4 +-
 .../org/apache/solr/handler/admin/SplitOp.java     |   14 +-
 .../solr/handler/admin/ZookeeperInfoHandler.java   |    8 +-
 .../solr/handler/component/DebugComponent.java     |   16 +-
 .../solr/handler/component/ExpandComponent.java    |   80 +-
 .../solr/handler/component/HttpShardHandler.java   |    1 +
 .../handler/component/HttpShardHandlerFactory.java |  327 +-
 .../solr/handler/component/QueryComponent.java     |   15 +-
 .../handler/component/ReplicaListTransformer.java  |   35 -
 .../solr/handler/component/ResponseBuilder.java    |   14 -
 .../solr/handler/component/SearchComponent.java    |   18 +-
 .../solr/handler/component/SearchHandler.java      |   63 +-
 .../component/ShufflingReplicaListTransformer.java |   39 -
 .../solr/handler/component/SuggestComponent.java   |   23 +-
 .../solr/handler/component/TermsComponent.java     |   35 +-
 .../apache/solr/handler/loader/CSVLoaderBase.java  |    6 +-
 .../solr/highlight/HighlightingPluginBase.java     |   27 +-
 .../apache/solr/logging/log4j2/Log4j2Watcher.java  |    4 +-
 .../solr/metrics/FilteringSolrMetricReporter.java  |    3 +
 .../apache/solr/metrics/SolrCoreMetricManager.java |   56 +-
 .../org/apache/solr/metrics/SolrMetricManager.java |  210 +-
 .../apache/solr/metrics/SolrMetricProducer.java    |   62 +-
 .../apache/solr/metrics/SolrMetricsContext.java    |  158 +
 .../solr/metrics/reporters/SolrJmxReporter.java    |    2 +-
 .../metrics/reporters/jmx/JmxMetricsReporter.java  |    7 +-
 .../solr/metrics/reporters/solr/SolrReporter.java  |    3 +
 .../packagemanager/DefaultPackageRepository.java   |  116 +
 .../apache/solr/packagemanager/PackageManager.java |  416 ++
 .../solr/packagemanager/PackageRepository.java     |   53 +
 .../apache/solr/packagemanager/PackageUtils.java   |  238 ++
 .../solr/packagemanager/RepositoryManager.java     |  317 ++
 .../apache/solr/packagemanager/SolrPackage.java    |  140 +
 .../solr/packagemanager/SolrPackageInstance.java   |   66 +
 .../apache/solr/packagemanager/package-info.java   |   21 +
 .../src/java/org/apache/solr/pkg/PackageAPI.java   |  410 ++
 .../java/org/apache/solr/pkg/PackageListeners.java |  111 +
 .../java/org/apache/solr/pkg/PackageLoader.java    |  303 ++
 .../org/apache/solr/pkg/PackagePluginHolder.java   |  123 +
 .../src/java/org/apache/solr/pkg/package-info.java |   23 +
 .../java/org/apache/solr/query/SolrRangeQuery.java |    3 +
 .../org/apache/solr/request/DocValuesFacets.java   |    4 +
 .../org/apache/solr/request/IntervalFacets.java    |    2 +-
 .../org/apache/solr/request/NumericFacets.java     |   20 +-
 .../request/PerSegmentSingleValuedFaceting.java    |   10 +
 .../java/org/apache/solr/request/SimpleFacets.java |   19 +-
 .../org/apache/solr/request/json/ObjectUtil.java   |    8 +-
 .../org/apache/solr/request/json/RequestUtil.java  |    9 +-
 .../solr/response/PHPSerializedResponseWriter.java |   11 +-
 .../org/apache/solr/response/SchemaXmlWriter.java  |    2 +
 .../java/org/apache/solr/rest/ManagedResource.java |    6 +-
 .../apache/solr/rest/ManagedResourceStorage.java   |   12 +-
 .../src/java/org/apache/solr/rest/RestManager.java |   10 +-
 .../solr/rest/schema/FieldTypeXmlAdapter.java      |    9 +-
 .../analysis/ManagedSynonymFilterFactory.java      |   23 +-
 .../analysis/ManagedSynonymGraphFilterFactory.java |   21 +-
 .../schema/AbstractSpatialPrefixTreeFieldType.java |    2 +
 .../java/org/apache/solr/schema/BinaryField.java   |    3 +
 .../src/java/org/apache/solr/schema/BoolField.java |    6 +-
 .../src/java/org/apache/solr/schema/FieldType.java |   47 +-
 .../apache/solr/schema/FieldTypePluginLoader.java  |   57 +-
 .../solr/schema/FileExchangeRateProvider.java      |    6 +-
 .../java/org/apache/solr/schema/IndexSchema.java   |  115 +-
 .../apache/solr/schema/JsonPreAnalyzedParser.java  |    2 +-
 .../org/apache/solr/schema/ManagedIndexSchema.java |   40 +-
 .../solr/schema/RptWithGeometrySpatialField.java   |   13 +-
 .../java/org/apache/solr/schema/SchemaManager.java |    1 +
 .../java/org/apache/solr/search/CacheConfig.java   |  168 +-
 .../java/org/apache/solr/search/CaffeineCache.java |  389 ++
 .../java/org/apache/solr/search/DisMaxQParser.java |    6 +-
 .../apache/solr/search/ExtendedDismaxQParser.java  |    6 +-
 .../java/org/apache/solr/search/FastLRUCache.java  |  412 --
 .../src/java/org/apache/solr/search/Grouping.java  |    5 +-
 .../src/java/org/apache/solr/search/LFUCache.java  |  414 --
 .../src/java/org/apache/solr/search/LRUCache.java  |  423 --
 .../java/org/apache/solr/search/PointMerger.java   |    4 +
 .../java/org/apache/solr/search/QParserPlugin.java |   11 +-
 .../src/java/org/apache/solr/search/SolrCache.java |   59 +-
 .../org/apache/solr/search/SolrCacheHolder.java    |   70 +-
 .../apache/solr/search/SolrDocumentFetcher.java    |   55 +-
 .../org/apache/solr/search/SolrFieldCacheBean.java |   27 +-
 .../org/apache/solr/search/SolrIndexSearcher.java  |  124 +-
 .../org/apache/solr/search/ValueSourceParser.java  |    8 +
 .../solr/search/facet/FacetFieldProcessor.java     |   12 +-
 .../org/apache/solr/search/facet/FacetRange.java   |  279 +-
 .../org/apache/solr/search/facet/FacetRequest.java |  119 +-
 .../org/apache/solr/search/facet/MissingAgg.java   |   81 +
 .../apache/solr/search/facet/UnInvertedField.java  |  117 +-
 .../distance/GeoDistValueSourceParser.java         |   15 +-
 .../distributed/command/GroupConverter.java        |   13 +-
 .../grouping/distributed/command/QueryCommand.java |   53 +-
 .../StoredFieldsShardRequestFactory.java           |   15 +-
 .../TopGroupsShardRequestFactory.java              |    3 +-
 .../SearchGroupShardResponseProcessor.java         |   10 +-
 .../TopGroupsShardResponseProcessor.java           |   18 +-
 .../TopGroupsResultTransformer.java                |    2 +-
 .../solr/search/join/BlockJoinChildQParser.java    |    2 +-
 .../solr/search/join/BlockJoinParentQParser.java   |   34 +-
 .../search/join/ChildFieldValueSourceParser.java   |    4 +-
 .../apache/solr/search/mlt/SimpleMLTQParser.java   |    8 +-
 .../solr/search/stats/ExactSharedStatsCache.java   |   24 +-
 .../apache/solr/search/stats/ExactStatsCache.java  |  194 +-
 .../apache/solr/search/stats/LRUStatsCache.java    |  173 +-
 .../apache/solr/search/stats/LocalStatsCache.java  |   31 +-
 .../apache/solr/search/stats/LocalStatsSource.java |   11 +-
 .../org/apache/solr/search/stats/StatsCache.java   |  196 +-
 .../org/apache/solr/search/stats/StatsSource.java  |    3 +-
 .../org/apache/solr/search/stats/StatsUtil.java    |  239 +-
 .../org/apache/solr/search/stats/TermStats.java    |    4 +-
 .../java/org/apache/solr/security/AuditEvent.java  |   22 +-
 .../apache/solr/security/AuditLoggerPlugin.java    |   52 +-
 .../apache/solr/security/AuthenticationPlugin.java |   65 +-
 .../apache/solr/security/AuthorizationContext.java |    5 +
 .../org/apache/solr/security/BasicAuthPlugin.java  |    2 +-
 .../org/apache/solr/security/JWTAuthPlugin.java    |  533 ++-
 .../org/apache/solr/security/JWTIssuerConfig.java  |  438 +++
 .../solr/security/JWTVerificationkeyResolver.java  |  153 +
 .../solr/security/MultiDestinationAuditLogger.java |   10 +-
 .../solr/security/PermissionNameProvider.java      |    6 +-
 .../security/RuleBasedAuthorizationPlugin.java     |   57 +-
 .../security/Sha256AuthenticationProvider.java     |   17 +-
 .../java/org/apache/solr/servlet/HttpSolrCall.java |   57 +-
 .../apache/solr/servlet/SolrDispatchFilter.java    |    3 +-
 .../apache/solr/servlet/SolrRequestParsers.java    |    9 +-
 .../org/apache/solr/store/blockcache/Metrics.java  |   28 +-
 .../solr/store/hdfs/HdfsLocalityReporter.java      |   27 +-
 .../apache/solr/update/DirectUpdateHandler2.java   |   66 +-
 .../org/apache/solr/update/DocumentBuilder.java    |    4 +-
 .../src/java/org/apache/solr/update/PeerSync.java  |   17 +-
 .../org/apache/solr/update/PeerSyncWithLeader.java |   17 +-
 .../org/apache/solr/update/SolrCmdDistributor.java |    5 -
 .../org/apache/solr/update/SolrIndexWriter.java    |   38 +-
 .../java/org/apache/solr/update/UpdateHandler.java |   17 +-
 .../src/java/org/apache/solr/update/UpdateLog.java |   29 +-
 .../org/apache/solr/update/UpdateShardHandler.java |   33 +-
 .../AddSchemaFieldsUpdateProcessorFactory.java     |   14 +-
 .../processor/AtomicUpdateDocumentMerger.java      |   11 +-
 .../CloneFieldUpdateProcessorFactory.java          |    4 +-
 .../processor/DistributedUpdateProcessor.java      |   21 +-
 .../processor/DistributedZkUpdateProcessor.java    |   56 +-
 .../processor/UpdateRequestProcessorChain.java     |   29 +-
 .../org/apache/solr/util/ConcurrentLFUCache.java   |  545 ---
 .../org/apache/solr/util/ConcurrentLRUCache.java   |  233 +-
 .../src/java/org/apache/solr/util/CryptoKeys.java  |   49 +-
 .../src/java/org/apache/solr/util/ExportTool.java  |  512 +++
 .../src/java/org/apache/solr/util/FileUtils.java   |   30 +-
 .../src/java/org/apache/solr/util/JmxUtil.java     |    9 +-
 .../src/java/org/apache/solr/util/PackageTool.java |  293 ++
 .../java/org/apache/solr/util/RedactionUtils.java  |   83 +-
 .../java/org/apache/solr/util/SimplePostTool.java  |    6 +-
 .../src/java/org/apache/solr/util/SolrCLI.java     |   93 +-
 .../solr/util/SolrJacksonAnnotationInspector.java  |   95 +
 .../java/org/apache/solr/util/SolrPluginUtils.java |   38 +-
 .../java/org/apache/solr/util/TestInjection.java   |   14 +-
 .../java/org/apache/solr/util/TimeZoneUtils.java   |   11 +-
 .../solr/util/plugin/AbstractPluginLoader.java     |   11 +-
 .../stats/InstrumentedHttpListenerFactory.java     |   22 +-
 .../stats/InstrumentedHttpRequestExecutor.java     |   22 +-
 ...rumentedPoolingHttpClientConnectionManager.java |   40 +-
 .../org/apache/solr/util/stats/MetricUtils.java    |   10 +-
 ....apache.lucene.analysis.util.TokenFilterFactory |   19 +
 .../src/test-files/cryptokeys/priv_key2048.pem     |   27 -
 .../core/src/test-files/cryptokeys/pub_key2048.der |  Bin 294 -> 0 bytes
 solr/core/src/test-files/runtimecode/sig.txt       |   44 +-
 .../conf/bad-schema-analyzer-by-name.xml           |   32 +
 .../conf/bad-schema-analyzer-class-and-name-cf.xml |   33 +
 .../conf/bad-schema-analyzer-class-and-name-tf.xml |   33 +
 .../bad-schema-analyzer-class-and-name-tok.xml     |   32 +
 .../collection1/conf/schema-analyzer-by-name.xml   |   78 +
 .../solr/collection1/conf/schema-spatial.xml       |    8 +-
 .../solr/collection1/conf/schema-tiny.xml          |    2 +
 .../test-files/solr/collection1/conf/schema.xml    |   39 +
 .../solr/collection1/conf/schema_codec.xml         |    5 +-
 .../conf/solrconfig-analytics-query.xml            |   10 +-
 .../conf/solrconfig-cache-enable-disable.xml       |    6 +-
 .../solr/collection1/conf/solrconfig-caching.xml   |    6 +-
 .../conf/solrconfig-collapseqparser.xml            |   10 +-
 .../collection1/conf/solrconfig-deeppaging.xml     |    4 +-
 .../conf/solrconfig-delaying-component.xml         |    6 +-
 .../solr/collection1/conf/solrconfig-elevate.xml   |    6 +-
 .../collection1/conf/solrconfig-managed-schema.xml |    6 +-
 .../solr/collection1/conf/solrconfig-minhash.xml   |   10 +-
 .../solr/collection1/conf/solrconfig-noopregen.xml |    2 +-
 .../collection1/conf/solrconfig-plugcollector.xml  |   10 +-
 .../conf/solrconfig-sortingresponse.xml            |    2 +-
 .../solr/collection1/conf/solrconfig-spatial.xml   |    4 +-
 .../solr/collection1/conf/solrconfig-tlog.xml      |    8 +-
 .../solr/collection1/conf/solrconfig.xml           |   10 +-
 .../solr/collection1/conf/solrconfig_perf.xml      |    6 +-
 .../solr/configsets/_default/conf/managed-schema   |  494 +--
 .../solr/configsets/_default/conf/solrconfig.xml   |   31 +-
 .../configsets/cloud-dynamic/conf/solrconfig.xml   |    2 +
 .../exitable-directory/conf/solrconfig.xml         |    8 +-
 .../question-answer-repository-private-key.pem     |    9 +
 .../solr/question-answer-repository/publickey.der  |  Bin 0 -> 94 bytes
 .../question-answer-request-handler-1.0.jar.tmp    |  Bin 0 -> 5652 bytes
 .../question-answer-request-handler-1.1.jar.tmp    |  Bin 0 -> 6324 bytes
 .../question-answer-repository/repository.json     |   56 +
 .../solr/security/auditlog_plugin_security.json    |    4 +-
 .../solr/security/jwt_plugin_jwk_security.json     |    6 +-
 .../solr/security/jwt_plugin_jwk_url_security.json |    2 +-
 .../solr/simSnapshot/autoscalingState.json         | 3923 +++++++++++++++++++
 .../test-files/solr/simSnapshot/clusterState.json  | 2854 ++++++++++++++
 .../test-files/solr/simSnapshot/distribState.json  |  206 +
 .../test-files/solr/simSnapshot/managerState.json  |    1 +
 .../src/test-files/solr/simSnapshot/nodeState.json | 3823 ++++++++++++++++++
 .../test-files/solr/simSnapshot/statistics.json    | 2045 ++++++++++
 .../src/test/org/apache/solr/SolrInfoBeanTest.java |   10 +-
 .../test/org/apache/solr/SolrTestCaseJ4Test.java   |   22 +
 .../org/apache/solr/TestDistributedGrouping.java   |  142 +-
 .../test/org/apache/solr/TestGroupingSearch.java   |   40 +
 .../test/org/apache/solr/TestRandomFaceting.java   |   19 +-
 .../apache/solr/cloud/AliasIntegrationTest.java    |   76 +-
 .../apache/solr/cloud/BasicDistributedZk2Test.java |   31 +-
 .../cloud/CloudExitableDirectoryReaderTest.java    |   52 +-
 .../apache/solr/cloud/CollectionsAPISolrJTest.java |   14 +
 .../org/apache/solr/cloud/MoveReplicaTest.java     |   49 +-
 .../apache/solr/cloud/PackageManagerCLITest.java   |  201 +
 .../cloud/RoutingToNodesWithPropertiesTest.java    |    9 +-
 .../test/org/apache/solr/cloud/SplitShardTest.java |  157 +
 .../apache/solr/cloud/TestBaseStatsCacheCloud.java |  221 ++
 .../apache/solr/cloud/TestClusterProperties.java   |    6 +-
 .../org/apache/solr/cloud/TestConfigSetsAPI.java   |    1 +
 .../test/org/apache/solr/cloud/TestCryptoKeys.java |    2 +-
 .../solr/cloud/TestExactSharedStatsCacheCloud.java |   34 +
 .../solr/cloud/TestExactStatsCacheCloud.java       |   36 +
 .../apache/solr/cloud/TestLRUStatsCacheCloud.java  |   35 +
 .../solr/cloud/TestLocalStatsCacheCloud.java       |   46 +
 .../solr/cloud/TestQueryingOnDownCollection.java   |  151 +
 .../cloud/TestSolrCloudWithDelegationTokens.java   |   64 +-
 .../org/apache/solr/cloud/TestTlogReplica.java     |  213 +-
 .../org/apache/solr/cloud/ZkShardTermsTest.java    |   22 +
 .../cloud/api/collections/SplitByPrefixTest.java   |   16 +-
 .../AutoAddReplicasIntegrationTest.java            |  339 +-
 .../autoscaling/AutoAddReplicasPlanActionTest.java |    2 +-
 .../cloud/autoscaling/ExecutePlanActionTest.java   |  144 +
 .../cloud/autoscaling/IndexSizeTriggerTest.java    |   53 +-
 .../autoscaling/NodeMarkersRegistrationTest.java   |   23 +-
 .../autoscaling/sim/TestSimExtremeIndexing.java    |   35 -
 .../cloud/autoscaling/sim/TestSimLargeCluster.java |   87 +
 .../cloud/autoscaling/sim/TestSimScenario.java     |  138 +
 .../autoscaling/sim/TestSimTriggerIntegration.java |  133 +-
 .../autoscaling/sim/TestSnapshotCloudManager.java  |   79 +-
 .../apache/solr/cloud/cdcr/CdcrBootstrapTest.java  |   52 +
 .../apache/solr/core/HdfsDirectoryFactoryTest.java |    3 +-
 .../test/org/apache/solr/core/MockInfoBean.java    |   24 +-
 .../core/MockQuerySenderListenerReqHandler.java    |    8 +-
 .../org/apache/solr/core/RequestHandlersTest.java  |    5 +-
 .../org/apache/solr/core/ResourceLoaderTest.java   |   19 +
 .../test/org/apache/solr/core/TestBadConfig.java   |    2 +-
 .../org/apache/solr/core/TestCodecSupport.java     |   10 +-
 .../org/apache/solr/core/TestCoreContainer.java    |   16 +-
 .../org/apache/solr/core/TestDynamicLoading.java   |   31 +-
 .../apache/solr/core/TestSolrConfigHandler.java    |   20 +-
 .../solr/filestore/TestDistribPackageStore.java    |  265 ++
 .../apache/solr/handler/BackupStatusChecker.java   |  294 ++
 .../org/apache/solr/handler/CheckBackupStatus.java |   69 -
 .../org/apache/solr/handler/TestBlobHandler.java   |   12 +-
 .../org/apache/solr/handler/TestCSVLoader.java     |   21 +-
 .../solr/handler/TestContainerReqHandler.java      |  565 ---
 .../org/apache/solr/handler/TestCoreBackup.java    |  331 +-
 .../solr/handler/TestHdfsBackupRestoreCore.java    |    8 +-
 .../solr/handler/TestReplicationHandler.java       |   84 +-
 .../solr/handler/TestReplicationHandlerBackup.java |  154 +-
 .../org/apache/solr/handler/TestReqParamsAPI.java  |   10 +
 .../org/apache/solr/handler/TestRestoreCore.java   |   40 +-
 .../solr/handler/TestSolrConfigHandlerCloud.java   |    9 +
 .../solr/handler/TestStressThreadBackup.java       |  381 ++
 .../solr/handler/admin/IndexSizeEstimatorTest.java |   25 +
 .../solr/handler/admin/MBeansHandlerTest.java      |   20 +-
 .../solr/handler/admin/MetricsHandlerTest.java     |  146 +-
 .../handler/admin/MetricsHistoryHandlerTest.java   |    7 +-
 .../handler/admin/SecurityConfHandlerTest.java     |    9 +-
 .../solr/handler/admin/SplitHandlerTest.java       |    6 +-
 .../solr/handler/admin/TestApiFramework.java       |  191 +-
 .../solr/handler/component/DebugComponentTest.java |    4 +-
 .../component/DistributedExpandComponentTest.java  |   17 +-
 .../component/DistributedFacetPivotLargeTest.java  |   36 +-
 .../component/DistributedTermsComponentTest.java   |   26 +-
 .../handler/component/FacetPivotSmallTest.java     |   12 +
 .../component/ReplicaListTransformerTest.java      |  164 -
 .../ShufflingReplicaListTransformerTest.java       |   76 -
 .../solr/handler/component/TermsComponentTest.java |  102 +-
 .../TestDistributedStatsComponentCardinality.java  |    1 -
 .../handler/component/TestExpandComponent.java     |  230 +-
 .../component/TestHttpShardHandlerFactory.java     |  110 -
 .../solr/handler/export/TestExportWriter.java      |    5 +-
 .../apache/solr/metrics/SolrMetricTestUtils.java   |   11 +-
 .../reporters/SolrJmxReporterCloudTest.java        |    7 +-
 .../metrics/reporters/SolrJmxReporterTest.java     |   66 +-
 .../src/test/org/apache/solr/pkg/TestPackages.java |  508 +++
 .../org/apache/solr/request/SimpleFacetsTest.java  |   83 +-
 .../apache/solr/rest/schema/TestBulkSchemaAPI.java |   81 +-
 .../solr/schema/ResolveAnalyzerByNameTest.java     |  135 +
 .../org/apache/solr/search/QueryEqualityTest.java  |    3 +
 .../org/apache/solr/search/TestCaffeineCache.java  |  288 ++
 .../solr/search/TestExtendedDismaxParser.java      |   11 +-
 .../org/apache/solr/search/TestFastLRUCache.java   |  512 ---
 .../test/org/apache/solr/search/TestLFUCache.java  |  637 ---
 .../test/org/apache/solr/search/TestLRUCache.java  |  258 --
 .../test/org/apache/solr/search/TestRecovery.java  |   53 +-
 .../org/apache/solr/search/TestSolr4Spatial2.java  |   20 +
 .../org/apache/solr/search/TestSolrCachePerf.java  |  150 +
 .../apache/solr/search/TestSolrFieldCacheBean.java |    7 +-
 ...stributedFacetSimpleRefinementLongTailTest.java |   36 +-
 .../solr/search/facet/RangeFacetCloudTest.java     |  164 +-
 .../solr/search/facet/TestJsonFacetRefinement.java |   38 +-
 .../apache/solr/search/facet/TestJsonFacets.java   |  389 +-
 .../solr/search/function/TestFunctionQuery.java    |    5 +-
 .../solr/search/join/TestCloudNestedDocsSort.java  |   16 +-
 .../solr/search/join/TestNestedDocsSort.java       |    4 +-
 .../join/another/BJQFilterAccessibleTest.java      |   52 +
 .../apache/solr/search/json/TestJsonRequest.java   |   12 +-
 .../solr/search/mlt/SimpleMLTQParserTest.java      |   39 +-
 .../solr/search/stats/TestDefaultStatsCache.java   |    1 +
 .../solr/security/AuditLoggerIntegrationTest.java  |  413 +-
 .../solr/security/BasicAuthIntegrationTest.java    |   41 +-
 .../solr/security/BasicAuthOnSingleNodeTest.java   |   18 +-
 .../solr/security/CallbackAuditLoggerPlugin.java   |   29 +-
 .../security/JWTAuthPluginIntegrationTest.java     |   59 +-
 .../apache/solr/security/JWTAuthPluginTest.java    |  239 +-
 .../apache/solr/security/JWTIssuerConfigTest.java  |  156 +
 .../security/JWTVerificationkeyResolverTest.java   |  156 +
 .../security/PKIAuthenticationIntegrationTest.java |   15 +-
 .../security/TestSha256AuthenticationProvider.java |   58 +-
 .../org/apache/solr/servlet/CacheHeaderTest.java   |   24 +-
 .../solr/store/blockcache/BlockCacheTest.java      |   85 +-
 .../solr/store/blockcache/BufferStoreTest.java     |    4 +-
 .../apache/solr/update/DocumentBuilderTest.java    |   25 +
 .../test/org/apache/solr/update/RootFieldTest.java |    4 +-
 .../apache/solr/update/SolrCmdDistributorTest.java |   19 +
 .../AbstractAtomicUpdatesMultivalueTestBase.java   |  427 ++
 .../AtomicUpdateProcessorFactoryTest.java          |  117 +-
 .../solr/update/processor/AtomicUpdatesTest.java   |  139 +-
 .../DimensionalRoutedAliasUpdateProcessorTest.java |    3 +-
 .../JavaBinAtomicUpdateMultivalueTest.java         |   28 +
 .../processor/TestNamedUpdateProcessors.java       |   21 +-
 .../TimeRoutedAliasUpdateProcessorTest.java        |   70 +
 .../UpdateRequestProcessorFactoryTest.java         |   10 +-
 .../processor/XMLAtomicUpdateMultivalueTest.java   |   28 +
 .../org/apache/solr/util/SolrPluginUtilsTest.java  |   20 +
 .../test/org/apache/solr/util/TestExportTool.java  |  231 ++
 .../solr/util/TestSolrJacksonAnnotation.java       |   82 +
 .../example-DIH/solr/atom/conf/managed-schema      |   36 +-
 .../example-DIH/solr/db/conf/managed-schema        |  488 +--
 .../example-DIH/solr/db/conf/solrconfig.xml        |   29 +-
 .../example-DIH/solr/mail/conf/managed-schema      |  490 +--
 .../example-DIH/solr/mail/conf/solrconfig.xml      |   29 +-
 .../example-DIH/solr/solr/conf/managed-schema      |  488 +--
 .../example-DIH/solr/solr/conf/solrconfig.xml      |   29 +-
 .../example-DIH/solr/tika/conf/managed-schema      |    4 +-
 solr/example/files/conf/managed-schema             |  438 +--
 solr/example/files/conf/solrconfig.xml             |   29 +-
 .../asciidoctor-ant-1.6.0-alpha.5.jar.sha1         |    1 -
 solr/licenses/asciidoctor-ant-1.6.2.jar.sha1       |    1 +
 solr/licenses/caffeine-2.4.0.jar.sha1              |    1 -
 solr/licenses/caffeine-2.8.0.jar.sha1              |    1 +
 solr/licenses/commons-beanutils-1.9.3.jar.sha1     |    1 -
 solr/licenses/commons-beanutils-NOTICE.txt         |    5 -
 solr/licenses/jackson-annotations-2.9.8.jar.sha1   |    1 -
 solr/licenses/jackson-annotations-2.9.9.jar.sha1   |    1 +
 solr/licenses/jackson-core-2.9.8.jar.sha1          |    1 -
 solr/licenses/jackson-core-2.9.9.jar.sha1          |    1 +
 solr/licenses/jackson-databind-2.9.8.jar.sha1      |    1 -
 solr/licenses/jackson-databind-2.9.9.3.jar.sha1    |    1 +
 .../jackson-dataformat-smile-2.9.8.jar.sha1        |    1 -
 .../jackson-dataformat-smile-2.9.9.jar.sha1        |    1 +
 solr/licenses/java-semver-0.9.0.jar.sha1           |    1 +
 solr/licenses/java-semver-LICENSE-MIT.txt          |   21 +
 solr/licenses/netty-all-4.0.52.Final.jar.sha1      |    1 -
 solr/licenses/netty-all-4.1.29.Final.jar.sha1      |    1 +
 solr/licenses/netty-buffer-4.1.29.Final.jar.sha1   |    1 +
 ...ICENSE-ASL.txt => netty-buffer-LICENSE-ASL.txt} |    0
 solr/licenses/netty-buffer-NOTICE.txt              |  223 ++
 solr/licenses/netty-codec-4.1.29.Final.jar.sha1    |    1 +
 ...LICENSE-ASL.txt => netty-codec-LICENSE-ASL.txt} |    0
 solr/licenses/netty-codec-NOTICE.txt               |  223 ++
 solr/licenses/netty-common-4.1.29.Final.jar.sha1   |    1 +
 ...ICENSE-ASL.txt => netty-common-LICENSE-ASL.txt} |    0
 solr/licenses/netty-common-NOTICE.txt              |  223 ++
 solr/licenses/netty-handler-4.1.29.Final.jar.sha1  |    1 +
 ...CENSE-ASL.txt => netty-handler-LICENSE-ASL.txt} |    0
 solr/licenses/netty-handler-NOTICE.txt             |  223 ++
 solr/licenses/netty-resolver-4.1.29.Final.jar.sha1 |    1 +
 ...ENSE-ASL.txt => netty-resolver-LICENSE-ASL.txt} |    0
 solr/licenses/netty-resolver-NOTICE.txt            |  223 ++
 .../licenses/netty-transport-4.1.29.Final.jar.sha1 |    1 +
 ...NSE-ASL.txt => netty-transport-LICENSE-ASL.txt} |    0
 solr/licenses/netty-transport-NOTICE.txt           |  223 ++
 ...ty-transport-native-epoll-4.1.29.Final.jar.sha1 |    1 +
 ...> netty-transport-native-epoll-LICENSE-ASL.txt} |    0
 .../netty-transport-native-epoll-NOTICE.txt        |  223 ++
 ...nsport-native-unix-common-4.1.29.Final.jar.sha1 |    1 +
 ...y-transport-native-unix-common-LICENSE-ASL.txt} |    0
 .../netty-transport-native-unix-common-NOTICE.txt  |  223 ++
 solr/licenses/simple-xml-2.7.1.jar.sha1            |    1 -
 solr/licenses/simple-xml-NOTICE.txt                |    2 -
 solr/licenses/simple-xml-safe-2.7.1.jar.sha1       |    1 +
 ...NSE-ASL.txt => simple-xml-safe-LICENSE-ASL.txt} |    0
 solr/licenses/simple-xml-safe-NOTICE.txt           |    2 +
 solr/server/etc/jetty-ssl.xml                      |    1 +
 .../solr/configsets/_default/conf/managed-schema   |  494 +--
 .../solr/configsets/_default/conf/solrconfig.xml   |   31 +-
 .../conf/managed-schema                            |  534 +--
 .../conf/solrconfig.xml                            |   33 +-
 solr/solr-ref-guide/README.adoc                    |   26 +-
 solr/solr-ref-guide/src/_config.yml.template       |    4 +-
 solr/solr-ref-guide/src/about-filters.adoc         |   21 +
 solr/solr-ref-guide/src/about-tokenizers.adoc      |   19 +
 .../adding-custom-plugins-in-solrcloud-mode.adoc   |   13 +-
 solr/solr-ref-guide/src/aliases.adoc               |    6 +-
 solr/solr-ref-guide/src/analyzers.adoc             |   64 +-
 .../authentication-and-authorization-plugins.adoc  |   10 +-
 .../src/basic-authentication-plugin.adoc           |    4 +-
 solr/solr-ref-guide/src/charfilterfactories.adoc   |   79 +-
 .../src/cluster-node-management.adoc               |    2 +-
 solr/solr-ref-guide/src/collection-management.adoc |    2 +-
 .../src/common-query-parameters.adoc               |    2 +-
 solr/solr-ref-guide/src/distributed-requests.adoc  |   20 +-
 solr/solr-ref-guide/src/enabling-ssl.adoc          |    8 +-
 solr/solr-ref-guide/src/filter-descriptions.adoc   |  963 ++++-
 solr/solr-ref-guide/src/format-of-solr-xml.adoc    |   14 +
 solr/solr-ref-guide/src/how-solrcloud-works.adoc   |    6 +
 solr/solr-ref-guide/src/json-facet-api.adoc        |   92 +-
 .../src/jwt-authentication-plugin.adoc             |  119 +-
 .../src/kerberos-authentication-plugin.adoc        |    2 +-
 solr/solr-ref-guide/src/language-analysis.adoc     | 1025 ++++-
 solr/solr-ref-guide/src/learning-to-rank.adoc      |    2 +-
 .../src/major-changes-in-solr-9.adoc               |   46 +
 .../src/making-and-restoring-backups.adoc          |    6 +
 solr/solr-ref-guide/src/metrics-reporting.adoc     |    6 +-
 ...onitoring-solr-with-prometheus-and-grafana.adoc |   24 +-
 solr/solr-ref-guide/src/other-parsers.adoc         |    1 +
 .../src/package-manager-internals.adoc             |  357 ++
 solr/solr-ref-guide/src/package-manager.adoc       |  159 +
 .../src/performance-statistics-reference.adoc      |    2 +-
 solr/solr-ref-guide/src/ping.adoc                  |   11 +-
 .../src/query-settings-in-solrconfig.adoc          |   37 +-
 .../solr-ref-guide/src/request-parameters-api.adoc |   29 +-
 .../src/resource-and-plugin-loading.adoc           |    2 +-
 .../src/rule-based-authorization-plugin.adoc       |  246 +-
 solr/solr-ref-guide/src/schema-api.adoc            |   24 +-
 .../setting-up-an-external-zookeeper-ensemble.adoc |    6 +-
 solr/solr-ref-guide/src/shard-management.adoc      |   29 +
 .../src/solr-control-script-reference.adoc         |   33 +-
 .../src/solr-system-requirements.adoc              |    2 +-
 solr/solr-ref-guide/src/solr-tracing.adoc          |    2 +-
 solr/solr-ref-guide/src/solr-tutorial.adoc         |    2 +-
 solr/solr-ref-guide/src/solr-upgrade-notes.adoc    |   67 +-
 .../src/solrcloud-autoscaling-api.adoc             |   12 +-
 .../solrcloud-autoscaling-policy-preferences.adoc  |  143 +-
 .../src/solrcloud-autoscaling-trigger-actions.adoc |   15 +-
 .../src/solrcloud-autoscaling-triggers.adoc        |   57 +-
 solr/solr-ref-guide/src/spatial-search.adoc        |    2 +-
 .../src/taking-solr-to-production.adoc             |   27 +-
 .../src/the-standard-query-parser.adoc             |    4 +-
 .../src/the-well-configured-solr-instance.adoc     |    4 +-
 solr/solr-ref-guide/src/tokenizers.adoc            |  368 +-
 .../src/transforming-result-documents.adoc         |    3 +-
 .../src/updating-parts-of-documents.adoc           |    2 +-
 ...ding-data-with-solr-cell-using-apache-tika.adoc |    6 +-
 ...ng-zookeeper-to-manage-configuration-files.adoc |    2 +-
 solr/solrj/ivy.xml                                 |    9 +
 .../org/apache/solr/client/solrj/SolrClient.java   |   16 +
 .../org/apache/solr/client/solrj/SolrRequest.java  |    8 +-
 .../cloud/autoscaling/MoveReplicaSuggester.java    |    9 +-
 .../client/solrj/cloud/autoscaling/Policy.java     |    2 +-
 .../solrj/cloud/autoscaling/ReplicaInfo.java       |    2 +-
 .../cloud/autoscaling/SplitShardSuggester.java     |    4 +
 .../client/solrj/cloud/autoscaling/Variable.java   |    8 +-
 .../client/solrj/impl/BaseCloudSolrClient.java     |    7 +-
 .../solr/client/solrj/impl/CloudSolrClient.java    |    9 +-
 .../impl/ConcurrentUpdateHttp2SolrClient.java      |   20 +-
 .../solrj/impl/DelegationTokenHttpSolrClient.java  |    4 +-
 .../solr/client/solrj/impl/Http2SolrClient.java    |   10 +-
 .../solr/client/solrj/impl/HttpSolrClient.java     |   11 +-
 .../solr/client/solrj/impl/PreferenceRule.java     |   47 -
 .../solrj/impl/SolrClientNodeStateProvider.java    |    2 +-
 .../java/org/apache/solr/client/solrj/io/Lang.java |    6 +-
 .../org/apache/solr/client/solrj/io/Tuple.java     |    3 +-
 .../solr/client/solrj/io/eval/ColumnEvaluator.java |    2 +-
 .../client/solrj/io/eval/ConversionEvaluator.java  |    2 +-
 .../client/solrj/io/eval/CorrelationEvaluator.java |   25 +
 .../solrj/io/eval/CosineDistanceEvaluator.java     |   60 +
 .../solrj/io/eval/CosineSimilarityEvaluator.java   |    6 +-
 .../client/solrj/io/eval/CovarianceEvaluator.java  |    6 +-
 .../solr/client/solrj/io/eval/DbscanEvaluator.java |  141 +
 .../client/solrj/io/eval/DerivativeEvaluator.java  |   14 +-
 .../client/solrj/io/eval/DistanceEvaluator.java    |    6 +-
 .../solr/client/solrj/io/eval/DoubleEvaluator.java |    6 +-
 .../client/solrj/io/eval/FuzzyKmeansEvaluator.java |    6 +
 .../client/solrj/io/eval/IntegrateEvaluator.java   |   52 +-
 .../solrj/io/eval/KolmogorovSmirnovEvaluator.java  |    8 +-
 .../solr/client/solrj/io/eval/LongEvaluator.java   |    6 +-
 .../client/solrj/io/eval/NormalizeEvaluator.java   |    5 +-
 .../solrj/io/eval/NormalizeSumEvaluator.java       |    5 +-
 .../client/solrj/io/eval/RecursiveEvaluator.java   |   21 +-
 .../client/solrj/io/eval/SetValueEvaluator.java    |    3 +-
 .../client/solrj/io/eval/TermVectorsEvaluator.java |    3 +-
 .../client/solrj/io/eval/TopFeaturesEvaluator.java |   22 +-
 .../solr/client/solrj/io/eval/TruncEvaluator.java  |   53 +
 .../solr/client/solrj/io/eval/UnitEvaluator.java   |    2 +-
 .../client/solrj/io/graph/ShortestPathStream.java  |    3 +-
 .../solr/client/solrj/io/ops/GroupOperation.java   |    6 +-
 .../client/solrj/io/stream/CloudSolrStream.java    |    6 +-
 .../client/solrj/io/stream/DeepRandomStream.java   |    6 +-
 .../solrj/io/stream/FeaturesSelectionStream.java   |    4 +-
 .../solr/client/solrj/io/stream/KnnStream.java     |   10 +-
 .../client/solrj/io/stream/RandomFacadeStream.java |    4 +-
 .../solr/client/solrj/io/stream/RandomStream.java  |   10 +-
 .../solr/client/solrj/io/stream/SearchStream.java  |    4 +-
 .../solrj/io/stream/SignificantTermsStream.java    |   10 +-
 .../solr/client/solrj/io/stream/StatsStream.java   |    6 +-
 .../client/solrj/io/stream/TextLogitStream.java    |    4 +-
 .../solr/client/solrj/io/stream/ZplotStream.java   |  146 +-
 .../client/solrj/request/CollectionApiMapping.java |   17 -
 .../solrj/request/JavaBinUpdateRequestCodec.java   |   40 +-
 .../solr/client/solrj/request/V2Request.java       |   54 +
 .../solr/client/solrj/request/beans/Package.java   |   50 +
 .../client/solrj/request/beans/package-info.java   |   23 +
 .../client/solrj/request/json/TermsFacetMap.java   |    7 +-
 .../solrj/response/json/NestableJsonFacet.java     |   25 +-
 .../solrj/response/schema/SchemaResponse.java      |    9 +-
 .../routing/AffinityReplicaListTransformer.java    |  105 +
 .../AffinityReplicaListTransformerFactory.java     |   91 +
 .../routing/NodePreferenceRulesComparator.java     |  179 +
 .../solr/client/solrj/routing/PreferenceRule.java  |   47 +
 .../solrj/routing/ReplicaListTransformer.java      |   35 +
 .../routing/ReplicaListTransformerFactory.java     |   34 +
 .../RequestReplicaListTransformerGenerator.java    |  168 +
 .../routing/ShufflingReplicaListTransformer.java   |   39 +
 .../solr/client/solrj/routing/package-info.java    |   23 +
 .../solr/common/ConditionalKeyMapWriter.java       |   88 +
 .../org/apache/solr/common/SolrInputDocument.java  |   53 +-
 .../solr/common/annotation/JsonProperty.java       |   39 +
 .../solr/common/annotation/package-info.java       |   23 +
 .../solr/common/cloud/ClusterProperties.java       |   14 +-
 .../solr/common/cloud/NodesSysPropsCacher.java     |  200 +
 .../org/apache/solr/common/cloud/SolrZkClient.java |    9 +-
 .../apache/solr/common/cloud/ZkStateReader.java    |   97 +-
 .../solr/common/cloud/rule/ImplicitSnitch.java     |    3 +-
 .../apache/solr/common/params/CommonParams.java    |   14 +-
 .../org/apache/solr/common/params/ShardParams.java |   20 +-
 .../apache/solr/common/util/CommandOperation.java  |   14 +-
 .../solr/common/util/CommonTestInjection.java      |   42 +
 .../org/apache/solr/common/util/ExecutorUtil.java  |    1 +
 .../org/apache/solr/common/util/JavaBinCodec.java  |   11 +-
 .../apache/solr/common/util/JsonSchemaCreator.java |   85 +
 .../org/apache/solr/common/util/NamedList.java     |   11 +-
 .../java/org/apache/solr/common/util/PathTrie.java |   44 +-
 .../apache/solr/common/util/ReflectMapWriter.java  |   59 +
 .../java/org/apache/solr/common/util/StrUtils.java |  207 +-
 .../java/org/apache/solr/common/util/Utils.java    |  394 +-
 .../apache/solr/common/util/ValidatingJsonMap.java |    3 +-
 solr/solrj/src/java/org/noggit/ObjectBuilder.java  |   43 +-
 .../src/resources/apispec/cluster.Commands.json    |   37 -
 .../cluster.Commands.runtimelib.properties.json    |   23 -
 ...nfig.Commands.addRequestHandler.properties.json |    2 +-
 .../apispec/core.config.Commands.generic.json      |    2 +-
 .../apispec/core.config.Params.Commands.json       |    2 +-
 solr/solrj/src/resources/apispec/node.ext.json     |   13 -
 .../ref_guide_examples/JsonRequestApiTest.java     |   26 +-
 .../org/apache/solr/client/solrj/GetByIdTest.java  |   34 +-
 .../solr/client/solrj/LargeVolumeTestBase.java     |   14 +-
 .../apache/solr/client/solrj/SolrExampleTests.java |   50 +-
 .../autoscaling/MoveReplicaSuggesterTest.java      |  104 +
 .../client/solrj/cloud/autoscaling/TestPolicy.java |  130 +-
 .../solrj/embedded/LargeVolumeBinaryJettyTest.java |    2 +-
 .../solrj/embedded/LargeVolumeJettyTest.java       |    2 +-
 .../solrj/embedded/MergeIndexesEmbeddedTest.java   |    2 +-
 .../solrj/embedded/SolrExampleEmbeddedTest.java    |    2 +-
 .../client/solrj/embedded/TestSolrProperties.java  |    6 +-
 .../client/solrj/impl/CloudSolrClientTest.java     |   13 +
 .../org/apache/solr/client/solrj/io/TestLang.java  |   19 +-
 .../client/solrj/io/stream/MathExpressionTest.java |  455 ++-
 .../solrj/io/stream/StreamExpressionTest.java      |   43 +
 .../io/stream/eval/AbsoluteValueEvaluatorTest.java |    9 +-
 .../solrj/io/stream/eval/AddEvaluatorTest.java     |   24 +-
 .../solrj/io/stream/eval/AppendEvaluatorTest.java  |    4 +-
 .../solrj/io/stream/eval/ArrayEvaluatorTest.java   |   12 +-
 .../solrj/io/stream/eval/AscEvaluatorTest.java     |    4 +-
 .../solrj/io/stream/eval/CeilingEvaluatorTest.java |    9 +-
 .../io/stream/eval/CoalesceEvaluatorTest.java      |    2 +-
 .../solrj/io/stream/eval/DivideEvaluatorTest.java  |    3 +-
 .../solrj/io/stream/eval/FloorEvaluatorTest.java   |    9 +-
 .../solrj/io/stream/eval/ModuloEvaluatorTest.java  |   11 +-
 .../io/stream/eval/MultiplyEvaluatorTest.java      |   12 +-
 .../io/stream/eval/RecursiveEvaluatorTest.java     |    3 +-
 .../io/stream/eval/SubtractEvaluatorTest.java      |   15 +-
 .../solr/client/solrj/request/SchemaTest.java      |    8 +-
 .../solr/client/solrj/request/SolrPingTest.java    |    8 +-
 .../solr/client/solrj/request/TestCoreAdmin.java   |    2 +-
 .../solrj/request/TestUpdateRequestCodec.java      |  125 +-
 .../solr/client/solrj/request/TestV2Request.java   |   29 +-
 ...DirectJsonQueryRequestFacetingEmbeddedTest.java |  592 +++
 ...ectJsonQueryRequestFacetingIntegrationTest.java |    4 +-
 .../JsonQueryRequestFacetingIntegrationTest.java   |    4 +-
 .../solrj/request/json/TermsFacetMapTest.java      |   15 +-
 .../solrj/response/NestableJsonFacetTest.java      |   85 +
 .../client/solrj/response/TermsResponseTest.java   |   20 +-
 .../solrj/response/TestSpellCheckResponse.java     |   33 +-
 .../solrj/response/TestSuggesterResponse.java      |    8 +-
 .../routing/NodePreferenceRulesComparatorTest.java |  155 +
 .../solrj/routing/ReplicaListTransformerTest.java  |  165 +
 ...RequestReplicaListTransformerGeneratorTest.java |  152 +
 .../ShufflingReplicaListTransformerTest.java       |   76 +
 .../org/apache/solr/common/util/NamedListTest.java |   10 +
 .../org/apache/solr/common/util/TestPathTrie.java  |   13 +
 .../src/test/org/noggit/TestObjectBuilder.java     |   33 +-
 .../apache/solr/EmbeddedSolrServerTestBase.java    |  160 +
 .../java/org/apache/solr/SolrJettyTestBase.java    |   54 +-
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |   63 +-
 .../solr/analysis/MockCharFilterFactory.java       |    4 +
 .../solr/analysis/MockTokenFilterFactory.java      |    4 +
 .../apache/solr/analysis/MockTokenizerFactory.java |    4 +
 .../solr/cloud/AbstractDistribZkTestBase.java      |    1 +
 .../solr/cloud/AbstractFullDistribZkTestBase.java  |   13 +-
 .../apache/solr/cloud/MiniSolrCloudCluster.java    |    6 +-
 .../apache/solr/cloud/SolrCloudAuthTestCase.java   |   50 +-
 .../org/apache/solr/cloud/SolrCloudTestCase.java   |   74 +-
 .../java/org/apache/solr/cloud/ZkTestServer.java   |    2 +
 .../org/apache/solr/util/TestSSLTestConfig.java    |   17 +
 solr/webapp/web/css/angular/collections.css        |   38 +-
 solr/webapp/web/css/angular/overview.css           |   42 +
 solr/webapp/web/index.html                         |   17 +-
 solr/webapp/web/js/angular/app.js                  |   59 +-
 .../web/js/angular/controllers/alias-overview.js   |   27 +
 .../web/js/angular/controllers/collections.js      |   43 +-
 solr/webapp/web/js/angular/services.js             |    6 +
 solr/webapp/web/partials/alias_overview.html       |   46 +
 solr/webapp/web/partials/collection_overview.html  |    2 +-
 solr/webapp/web/partials/collections.html          |  223 +-
 1089 files changed, 66974 insertions(+), 21681 deletions(-)

diff --cc solr/core/src/java/org/apache/solr/core/CoreContainer.java
index daff00f,62a0ce9..20a6914
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@@ -225,11 -224,8 +230,13 @@@ public class CoreContainer 
  
    protected volatile AutoscalingHistoryHandler autoscalingHistoryHandler;
  
 +  protected volatile ResourceManager resourceManager;
 +
 +  protected volatile ResourceManagerHandler resourceManagerHandler;
 +
 +  private final LibListener clusterPropertiesListener = new LibListener(this);
+   private PackageStoreAPI packageStoreAPI;
+   private PackageLoader packageLoader;
  
  
    // Bits for the state variable.
@@@ -666,25 -673,6 +688,25 @@@
  
      createMetricsHistoryHandler();
  
 +    Map<String, Object> resManConfig = new HashMap<>();
 +    Map<String, Object> poolConfigs = new HashMap<>(DefaultResourceManager.DEFAULT_NODE_POOLS);
 +    resManConfig.put(DefaultResourceManager.POOL_CONFIGS_PARAM, poolConfigs);
 +    if (isZooKeeperAware()) {
 +      Map<String, Object> clusterProps = getZkController().getZkStateReader().getClusterProperties();
 +      poolConfigs.putAll((Map<String, Object>)clusterProps.getOrDefault(DefaultResourceManager.POOL_CONFIGS_PARAM, Collections.emptyMap()));
 +    }
 +    try {
 +      resourceManager = ResourceManager.load(loader, TimeSource.NANO_TIME, DefaultResourceManager.class,
 +          new PluginInfo("resourceManager", Collections.emptyMap()), resManConfig);
 +    } catch (Exception e) {
 +      log.warn("Resource manager initialization error - disabling!", e);
 +      resourceManager = NoOpResourceManager.INSTANCE;
 +    }
 +
 +    resourceManagerHandler = new ResourceManagerHandler(resourceManager);
 +    containerHandlers.put(RESOURCE_MANAGER_PATH, resourceManagerHandler);
-     resourceManagerHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, RESOURCE_MANAGER_PATH);
++    resourceManagerHandler.initializeMetrics(solrMetricsContext, RESOURCE_MANAGER_PATH);
 +
      autoscalingHistoryHandler = createHandler(AUTOSCALING_HISTORY_PATH, AutoscalingHistoryHandler.class.getName(), AutoscalingHistoryHandler.class);
      metricsCollectorHandler = createHandler(MetricsCollectorHandler.HANDLER_PATH, MetricsCollectorHandler.class.getName(), MetricsCollectorHandler.class);
      // may want to add some configuration here in the future
diff --cc solr/core/src/java/org/apache/solr/search/SolrCache.java
index b1d090d,c37cf9e..a714155
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@@ -17,33 -17,29 +17,31 @@@
  package org.apache.solr.search;
  
  import org.apache.solr.core.SolrInfoBean;
 +import org.apache.solr.managed.ManagedComponent;
 +import org.apache.solr.managed.types.ManagedCacheComponent;
- import org.apache.solr.metrics.SolrMetricProducer;
  
  import java.util.Map;
+ import java.util.function.Function;
  
  
  /**
   * Primary API for dealing with Solr's internal caches.
   */
- public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedCacheComponent {
 -public interface SolrCache<K,V> extends SolrInfoBean {
++public interface SolrCache<K,V> extends SolrInfoBean, ManagedCacheComponent {
  
-   /** Current size of the cache. */
+   String HIT_RATIO_PARAM = "hitratio";
+   String HITS_PARAM = "hits";
+   String INSERTS_PARAM = "inserts";
+   String EVICTIONS_PARAM = "evictions";
+   String LOOKUPS_PARAM = "lookups";
    String SIZE_PARAM = "size";
-   /** Maximum size of the cache. */
    String MAX_SIZE_PARAM = "maxSize";
-   /** Minimum size of the cache. */
-   String MIN_SIZE_PARAM = "minSize";
-   /** Maximum RAM use in MB. */
-   String MAX_RAM_MB_PARAM = "maxRamMB";
-   /** Ram usage estimate. */
    String RAM_BYTES_USED_PARAM = "ramBytesUsed";
-   // not camelCase for back-compat
-   /** Cache hit ratio. */
-   String HIT_RATIO_PARAM = "hitratio";
- 
-   long MB = 1024L * 1024L;
+   String MAX_RAM_MB_PARAM = "maxRamMB";
+   String MAX_IDLE_TIME_PARAM = "maxIdleTime";
+   String INITIAL_SIZE_PARAM = "initialSize";
+   String CLEANUP_THREAD_PARAM = "cleanupThread";
+   String SHOW_ITEMS_PARAM = "showItems";
  
    /**
     * The initialization routine. Instance specific arguments are passed in
diff --cc solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index fb562a2,3d572c8..2e0ea9f
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@@ -19,12 -19,9 +19,11 @@@ package org.apache.solr.search
  
  import java.lang.invoke.MethodHandles;
  import java.util.Map;
- import java.util.Set;
+ import java.util.function.Function;
  
- import com.codahale.metrics.MetricRegistry;
 +import org.apache.solr.managed.ManagedComponentId;
 +import org.apache.solr.managed.ManagedContext;
- import org.apache.solr.metrics.SolrMetricManager;
+ import org.apache.solr.metrics.SolrMetricsContext;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
@@@ -140,37 -143,8 +145,32 @@@ public class SolrCacheHolder<K, V> impl
    }
  
    @Override
-   public int getMaxSize() {
-     return delegate.getMaxSize();
-   }
- 
-   @Override
-   public int getMaxRamMB() {
-     return delegate.getMaxRamMB();
+   public SolrMetricsContext getSolrMetricsContext() {
+     return delegate.getSolrMetricsContext();
    }
  
 +  @Override
 +  public int getSize() {
 +    return delegate.getSize();
 +  }
 +
 +  @Override
 +  public float getHitRatio() {
 +    return delegate.getHitRatio();
 +  }
 +
 +  @Override
 +  public long ramBytesUsed() {
 +    return delegate.ramBytesUsed();
 +  }
 +
 +  @Override
 +  public ManagedComponentId getManagedComponentId() {
 +    return delegate.getManagedComponentId();
 +  }
 +
 +  @Override
 +  public ManagedContext getManagedContext() {
 +    return delegate.getManagedContext();
 +  }
  }
diff --cc solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 143bf46,ae47aed..fba2aa1
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@@ -67,10 -65,9 +65,11 @@@ import org.apache.solr.core.SolrConfig
  import org.apache.solr.core.SolrCore;
  import org.apache.solr.core.SolrInfoBean;
  import org.apache.solr.index.SlowCompositeReaderWrapper;
 +import org.apache.solr.managed.DefaultResourceManager;
 +import org.apache.solr.managed.ResourceManager;
+ import org.apache.solr.metrics.MetricsMap;
  import org.apache.solr.metrics.SolrMetricManager;
- import org.apache.solr.metrics.SolrMetricProducer;
+ import org.apache.solr.metrics.SolrMetricsContext;
  import org.apache.solr.request.LocalSolrQueryRequest;
  import org.apache.solr.request.SolrQueryRequest;
  import org.apache.solr.request.SolrRequestInfo;
@@@ -425,18 -430,11 +432,17 @@@ public class SolrIndexSearcher extends 
        cache.setState(SolrCache.State.LIVE);
        infoRegistry.put(cache.name(), cache);
      }
-     metricManager = core.getCoreContainer().getMetricManager();
 +    ResourceManager resourceManager = core.getCoreContainer().getResourceManager();
-     registryName = core.getCoreMetricManager().getRegistryName();
+     this.solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
      for (SolrCache cache : cacheList) {
-       cache.initializeMetrics(metricManager, registryName, core.getMetricTag(), SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
+       cache.initializeMetrics(solrMetricsContext, SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
 +      try {
 +        resourceManager.registerComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache);
 +      } catch (Exception e) {
 +        log.warn("Exception adding cache '" + cache.getManagedComponentId() + "' to the resource manager pool", e);
 +      }
      }
-     initializeMetrics(metricManager, registryName, core.getMetricTag(), STATISTICS_KEY);
+     initializeMetrics(solrMetricsContext, STATISTICS_KEY);
      registerTime = new Date();
    }
  
@@@ -479,8 -477,11 +485,12 @@@
      }
  
      for (SolrCache cache : cacheList) {
-       core.getCoreContainer().getResourceManager().unregisterComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getManagedComponentId().toString());
-       cache.close();
+       try {
++        core.getCoreContainer().getResourceManager().unregisterComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getManagedComponentId().toString());
+         cache.close();
+       } catch (Exception e) {
+         SolrException.log(log, "Exception closing cache " + cache.name(), e);
+       }
      }
  
      if (releaseDirectory) {


[lucene-solr] 03/36: Merge branch 'master' into star-123

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit ad6eafb80c9195d2c0c01bdf21e78fd93da6f430
Merge: 51da363 2e468ab
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Jun 19 13:03:03 2019 +0200

    Merge branch 'master' into star-123

 lucene/CHANGES.txt                                 |  12 +
 .../org/apache/lucene/search/IndexSearcher.java    |  22 +-
 .../java/org/apache/lucene/store/Directory.java    |  10 +
 .../java/org/apache/lucene/store/FSDirectory.java  |   3 +-
 .../apache/lucene/store/FileSwitchDirectory.java   |  27 +-
 .../org/apache/lucene/util/IntArrayDocIdSet.java   |  13 +-
 .../lucene/store/TestFileSwitchDirectory.java      |  27 ++
 .../org/apache/lucene/util/LuceneTestCase.java     |  30 ++-
 solr/CHANGES.txt                                   |  12 +-
 solr/core/ivy.xml                                  |   1 +
 .../java/org/apache/solr/cloud/ZkController.java   |  14 +-
 .../cloud/api/collections/CreateCollectionCmd.java |   2 +-
 .../cloud/api/collections/DeleteCollectionCmd.java |   2 +-
 .../solr/cloud/api/collections/DeleteShardCmd.java |   2 +-
 .../OverseerCollectionMessageHandler.java          |   2 +-
 .../solr/handler/component/TermsComponent.java     |  15 +-
 .../org/apache/solr/cloud/DeleteReplicaTest.java   |   6 +-
 .../test/org/apache/solr/cloud/OverseerTest.java   |  36 +--
 .../solr/cloud/TestMiniSolrCloudClusterSSL.java    |   2 -
 .../apache/solr/cloud/TestSSLRandomization.java    |   2 -
 .../cloud/TestWaitForStateWithJettyShutdowns.java  | 154 +++++++++++
 .../cloud/autoscaling/AutoScalingHandlerTest.java  |   2 +-
 .../solr/common/cloud/ZkStateReaderAccessor.java   |   2 +-
 .../component/DistributedTermsComponentTest.java   |  60 ++++-
 .../solr/handler/component/TermsComponentTest.java |  30 +++
 .../src/solrcloud-autoscaling-api.adoc             |   2 +-
 .../solrcloud-autoscaling-policy-preferences.adoc  |   8 +-
 .../client/solrj/cloud/autoscaling/Clause.java     |  75 +++++-
 .../solrj/cloud/autoscaling/ReplicaVariable.java   |  17 +-
 .../client/solrj/impl/BaseCloudSolrClient.java     |  68 ++++-
 .../solr/client/solrj/impl/HttpClientUtil.java     |  34 ++-
 .../common/cloud/CollectionStatePredicate.java     |  10 +-
 .../solr/common/cloud/CollectionStateWatcher.java  |   9 +-
 ...StateWatcher.java => DocCollectionWatcher.java} |  17 +-
 .../apache/solr/common/cloud/ZkStateReader.java    | 202 ++++++++++++--
 .../solr/autoscaling/testSysPropSuggestions.json   |  14 +-
 .../client/solrj/cloud/autoscaling/TestPolicy.java |  31 ++-
 .../solrj/cloud/autoscaling/TestPolicy2.java       |  19 +-
 .../solr/client/solrj/impl/HttpClientUtilTest.java |  11 +
 .../common/cloud/TestCollectionStateWatchers.java  | 180 ++++++++-----
 .../common/cloud/TestDocCollectionWatcher.java     | 291 +++++++++++++++++++++
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |   2 +-
 .../solr/cloud/AbstractDistribZkTestBase.java      |   6 +-
 .../solr/cloud/AbstractFullDistribZkTestBase.java  |   4 +-
 .../apache/solr/cloud/MiniSolrCloudCluster.java    |   2 +-
 .../java/org/apache/solr/util/SSLTestConfig.java   |  15 +-
 46 files changed, 1267 insertions(+), 238 deletions(-)


[lucene-solr] 31/36: Interim check-in, mostly fixed.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit f336d7c6343c091fccaa605a9f4e565aba58bade
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Nov 20 12:29:44 2019 +0100

    Interim check-in, mostly fixed.
---
 .../java/org/apache/solr/core/CoreContainer.java   |  2 +-
 .../apache/solr/handler/RequestHandlerBase.java    | 20 ++++-----
 .../solr/handler/admin/ResourceManagerHandler.java |  7 ++-
 .../handler/component/HttpShardHandlerFactory.java |  2 +-
 .../solr/handler/component/SearchComponent.java    |  2 +-
 .../solr/handler/component/SuggestComponent.java   |  4 +-
 .../solr/highlight/HighlightingPluginBase.java     |  4 +-
 .../solr/managed/DefaultResourceManagerPool.java   |  4 +-
 .../org/apache/solr/managed/ManagedComponent.java  | 10 +++--
 .../apache/solr/managed/ManagedComponentId.java    | 25 ++++++++---
 .../org/apache/solr/managed/ManagedContext.java    | 33 ++++++++++----
 .../apache/solr/managed/NoOpResourceManager.java   |  9 +---
 .../java/org/apache/solr/managed/PoolContext.java  |  9 ++++
 .../apache/solr/managed/ResourceManagerPool.java   |  2 +-
 .../solr/managed/types/CacheManagerPlugin.java     |  2 +-
 .../apache/solr/metrics/SolrCoreMetricManager.java |  4 +-
 .../apache/solr/metrics/SolrMetricProducer.java    |  8 ++--
 .../apache/solr/metrics/SolrMetricsContext.java    | 45 +++++++++++++++----
 .../java/org/apache/solr/search/CaffeineCache.java | 12 ++++--
 .../src/java/org/apache/solr/search/SolrCache.java |  3 +-
 .../org/apache/solr/search/SolrCacheHolder.java    |  6 +++
 .../org/apache/solr/search/SolrIndexSearcher.java  |  5 +--
 .../apache/solr/security/AuditLoggerPlugin.java    | 20 ++++-----
 .../apache/solr/security/AuthenticationPlugin.java | 18 ++++----
 .../org/apache/solr/store/blockcache/Metrics.java  |  4 +-
 .../solr/store/hdfs/HdfsLocalityReporter.java      |  4 +-
 .../apache/solr/update/DirectUpdateHandler2.java   | 50 +++++++++++-----------
 .../src/java/org/apache/solr/update/PeerSync.java  |  2 +-
 .../org/apache/solr/update/PeerSyncWithLeader.java |  2 +-
 .../org/apache/solr/update/SolrIndexWriter.java    |  2 +-
 .../src/java/org/apache/solr/update/UpdateLog.java | 14 +++---
 .../org/apache/solr/update/UpdateShardHandler.java |  2 +-
 .../stats/InstrumentedHttpRequestExecutor.java     |  6 +--
 ...rumentedPoolingHttpClientConnectionManager.java | 14 +++---
 .../apache/solr/core/HdfsDirectoryFactoryTest.java |  2 +-
 .../test/org/apache/solr/core/MockInfoBean.java    |  4 +-
 .../solr/handler/admin/MBeansHandlerTest.java      |  2 +-
 .../managed/TestDefaultResourceManagerPool.java    | 19 +++++---
 .../apache/solr/metrics/SolrMetricTestUtils.java   |  2 +-
 .../org/apache/solr/search/TestSolrCachePerf.java  |  2 +-
 .../apache/solr/search/TestSolrFieldCacheBean.java |  4 +-
 41 files changed, 230 insertions(+), 161 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index e969f11..a4dea32 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -635,7 +635,7 @@ public class CoreContainer {
 
     metricManager = new SolrMetricManager(loader, cfg.getMetricsConfig());
     String registryName = SolrMetricManager.getRegistryName(SolrInfoBean.Group.node);
-    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, metricTag);
+    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "container", metricTag);
 
     coreContainerWorkExecutor = MetricUtils.instrumentedExecutorService(
         coreContainerWorkExecutor, null,
diff --git a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
index 7149821..cb53d41 100644
--- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
@@ -146,18 +146,18 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
-    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), scope);
-    numServerErrors = solrMetricsContext.meter("serverErrors", getCategory().toString(), scope);
-    numClientErrors = solrMetricsContext.meter("clientErrors", getCategory().toString(), scope);
-    numTimeouts = solrMetricsContext.meter("timeouts", getCategory().toString(), scope);
-    requests = solrMetricsContext.counter("requests", getCategory().toString(), scope);
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
+    numErrors = solrMetricsContext.meter("errors", getCategory().toString());
+    numServerErrors = solrMetricsContext.meter("serverErrors", getCategory().toString());
+    numClientErrors = solrMetricsContext.meter("clientErrors", getCategory().toString());
+    numTimeouts = solrMetricsContext.meter("timeouts", getCategory().toString());
+    requests = solrMetricsContext.counter("requests", getCategory().toString());
     MetricsMap metricsMap = new MetricsMap((detail, map) ->
         shardPurposes.forEach((k, v) -> map.put(k, v.getCount())));
-    solrMetricsContext.gauge(metricsMap, true, "shardRequests", getCategory().toString(), scope);
-    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope);
-    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> handlerStart, true, "handlerStart", getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, "shardRequests", getCategory().toString());
+    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString());
+    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString());
+    solrMetricsContext.gauge(() -> handlerStart, true, "handlerStart", getCategory().toString());
   }
 
   public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) {
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index 8c58dea..854da43 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -17,7 +17,6 @@
 package org.apache.solr.handler.admin;
 
 import java.lang.invoke.MethodHandles;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -151,8 +150,8 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         result.add("poolParams", pool.getParams());
         result.add("resources", pool.getComponents().keySet());
         try {
-          pool.getCurrentValues();
-          result.add("totalValues", pool.getTotalValues());
+          Map<String, Map<String, Object>> values = pool.getCurrentValues();
+          result.add("totalValues", pool.getResourceManagerPlugin().aggregateTotalValues(values));
         } catch (Exception e) {
           log.warn("Error getting current values from pool " + name, e);
           result.add("error", "Error getting current values: " + e.toString());
@@ -331,4 +330,4 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
   public Category getCategory() {
     return Category.ADMIN;
   }
-}
+}
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
index a091874..d4b58ff 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
@@ -452,7 +452,7 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     String expandedScope = SolrMetricManager.mkName(scope, SolrInfoBean.Category.QUERY.name());
     httpListenerFactory.initializeMetrics(solrMetricsContext, expandedScope);
     commExecutor = MetricUtils.instrumentedExecutorService(commExecutor, null,
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
index 5a524a9..7735b12 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
@@ -120,7 +120,7 @@ public abstract class SearchComponent implements SolrInfoBean, NamedListInitiali
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
     // By default don't register any metrics - but prepare a child context
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
   }
 
   public static final Map<String, Class<? extends SearchComponent>> standard_components;
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
index fe24f5e..a284f5d 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
@@ -356,7 +356,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.metricsContext = parentContext.getChildContext(this);
+    this.metricsContext = parentContext.getChildContext(this, scope);
 
     this.metricsContext.gauge(() -> ramBytesUsed(), true, "totalSizeInBytes", getCategory().toString());
     MetricsMap suggestersMap = new MetricsMap((detailed, map) -> {
@@ -365,7 +365,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
         map.put(entry.getKey(), suggester.toString());
       }
     });
-    this.metricsContext.gauge(suggestersMap, true, "suggesters", getCategory().toString(), scope);
+    this.metricsContext.gauge(suggestersMap, true, "suggesters", getCategory().toString());
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
index 5c41b13..afb3e91 100644
--- a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
+++ b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
@@ -68,8 +68,8 @@ public abstract class HighlightingPluginBase implements SolrInfoBean
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
-    numRequests = solrMetricsContext.counter("requests", getCategory().toString(), scope);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
+    numRequests = solrMetricsContext.counter("requests", getCategory().toString());
   }
 }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 98771b8..f00866c 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -43,7 +43,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
-  private final ManagedContext poolContext = new ManagedContext();
+  private final PoolContext poolContext = new PoolContext();
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
   ScheduledFuture<?> scheduledFuture;
@@ -143,7 +143,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public ManagedContext getPoolContext() {
+  public PoolContext getPoolContext() {
     return poolContext;
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index d8e6692..4ea5922 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -16,23 +16,25 @@
  */
 package org.apache.solr.managed;
 
-import org.apache.solr.core.SolrInfoBean;
-
 /**
  * A managed component.
  */
-public interface ManagedComponent extends SolrInfoBean {
+public interface ManagedComponent extends AutoCloseable {
   /**
    * Unique name of this component. By convention id-s form a colon-separated hierarchy.
    */
   ManagedComponentId getManagedComponentId();
 
+  void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools);
+
   /**
    * Component context used for managing additional component state for the purpose of resource management.
    */
   ManagedContext getManagedContext();
 
   default void close() throws Exception {
-    SolrInfoBean.super.close();
+    if (getManagedContext() != null) {
+      getManagedContext().close();
+    }
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index 7b5d908..9b80e2d 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -19,30 +19,41 @@ package org.apache.solr.managed;
 
 import java.util.Arrays;
 
+import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
+
 /**
  * Hierarchical component id.
  */
 public class ManagedComponentId {
+
+  public static final String SEPARATOR = ":";
+
   private final String type;
   private final String name;
   private final String[] path;
   private final String id;
 
-  public ManagedComponentId(String type, String name, String... path) {
+  public ManagedComponentId(String type, Object component, String... path) {
+    this(type, SolrMetricProducer.getUniqueMetricTag(component, null), path);
+  }
+
+  ManagedComponentId(String type, String name, String... path) {
     this.type = type;
     this.name = name;
     this.path = path;
     StringBuilder sb = new StringBuilder();
+    sb.append(type);
     if (path != null) {
       for (String pathEl : path) {
         if (sb.length() > 0) {
-          sb.append(':');
+          sb.append(SEPARATOR);
         }
         sb.append(pathEl);
       }
     }
     if (sb.length() > 0) {
-      sb.append(':');
+      sb.append(SEPARATOR);
     }
     sb.append(name);
     id = sb.toString();
@@ -68,14 +79,14 @@ public class ManagedComponentId {
     if (fullName == null || fullName.isEmpty()) {
       return null;
     }
-    String[] parts = fullName.split(":");
+    String[] parts = fullName.split(SEPARATOR);
     if (parts.length < 2) {
       throw new RuntimeException("at least 2 parts (type and name) must be present: " + fullName);
     }
     if (parts.length > 2) {
-      String type = parts[parts.length - 1];
-      String name = parts[parts.length - 2];
-      String[] path = Arrays.copyOfRange(parts, 0, parts.length - 2);
+      String type = parts[0];
+      String name = parts[parts.length - 1];
+      String[] path = Arrays.copyOfRange(parts, 1, parts.length - 1);
       return new ManagedComponentId(type, name, path);
     } else {
       return new ManagedComponentId(parts[0], parts[1]);
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
index 3cf6839..f426d7c 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
@@ -16,30 +16,45 @@
  */
 package org.apache.solr.managed;
 
+import java.io.Closeable;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 /**
  *
  */
-public class ManagedContext {
+public class ManagedContext implements Closeable {
   private final ResourceManager resourceManager;
-  private final String poolName;
+  private final String[] poolNames;
   private final ManagedComponent component;
 
-  public ManagedContext(ResourceManager resourceManager, String poolName, ManagedComponent component) {
+  public ManagedContext(ResourceManager resourceManager, ManagedComponent component, String poolName, String... otherPools) {
     this.resourceManager = resourceManager;
-    this.poolName = poolName;
+    Set<String> pools = new LinkedHashSet<>();
+    pools.add(poolName);
+    if (otherPools != null) {
+      Collections.addAll(pools, otherPools);
+    }
+    this.poolNames = (String[])pools.toArray(new String[pools.size()]);
     this.component = component;
-    this.resourceManager.registerComponent(poolName, component);
+    for (String pool : poolNames) {
+      this.resourceManager.registerComponent(pool, component);
+    }
   }
 
   public ResourceManager getResourceManager() {
     return resourceManager;
   }
 
-  public String getPoolName() {
-    return poolName;
+  public String[] getPoolNames() {
+    return poolNames;
   }
 
-  public void unregister() {
-    resourceManager.unregisterComponent(poolName, component.getManagedComponentId());
+  @Override
+  public void close() {
+    for (String poolName : poolNames) {
+      resourceManager.unregisterComponent(poolName, component.getManagedComponentId());
+    }
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index d828a4f..9dc0fc3 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -118,11 +118,6 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public Map<String, Object> getTotalValues() throws InterruptedException {
-      return Collections.emptyMap();
-    }
-
-    @Override
     public Map<String, Object> getPoolLimits() {
       return Collections.emptyMap();
     }
@@ -138,7 +133,7 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public ManagedContext getPoolContext() {
+    public PoolContext getPoolContext() {
       return null;
     }
 
@@ -184,7 +179,7 @@ public class NoOpResourceManager extends ResourceManager {
   }
 
   @Override
-  public void registerComponent(String pool, ManagedComponent managedComponent) throws Exception {
+  public void registerComponent(String pool, ManagedComponent managedComponent) {
     // no-op
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/PoolContext.java b/solr/core/src/java/org/apache/solr/managed/PoolContext.java
new file mode 100644
index 0000000..221e1d0
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/PoolContext.java
@@ -0,0 +1,9 @@
+package org.apache.solr.managed;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *
+ */
+public class PoolContext extends ConcurrentHashMap<String, Object> {
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 9f2b4ff..4f1a786 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -52,5 +52,5 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   /**
    * Pool context used for managing additional pool state.
    */
-  ManagedContext getPoolContext();
+  PoolContext getPoolContext();
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
index 4956c58..695b046 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
@@ -131,7 +131,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
   @Override
   public void manage(ResourceManagerPool pool) throws Exception {
     Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-    Map<String, Object> totalValues = pool.getTotalValues();
+    Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
     // pool limits are defined using controlled tags
     pool.getPoolLimits().forEach((poolLimitName, value) -> {
       // only numeric limits are supported
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
index 572c01c..7fb0944 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
@@ -53,7 +53,7 @@ public class SolrCoreMetricManager implements Closeable {
     initCloudMode();
     metricManager = core.getCoreContainer().getMetricManager();
     String registryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName());
-    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, core.getMetricTag());
+    solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "SolrCore", core.getMetricTag());
     leaderRegistryName = createLeaderRegistryName(cloudMode, collectionName, shardName);
   }
 
@@ -106,7 +106,7 @@ public class SolrCoreMetricManager implements Closeable {
     if (oldLeaderRegistryName != null) {
       metricManager.closeReporters(oldLeaderRegistryName, solrMetricsContext.getTag());
     }
-    solrMetricsContext = new SolrMetricsContext(metricManager, newRegistryName, solrMetricsContext.getTag());
+    solrMetricsContext = new SolrMetricsContext(metricManager, newRegistryName, "SolrCore", solrMetricsContext.getTag());
     // load reporters again, using the new core name
     loadReporters();
   }
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
index c321a11..69a356b 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
@@ -44,11 +44,11 @@ public interface SolrMetricProducer extends AutoCloseable {
    * Initialize metrics specific to this producer.
    * @param parentContext parent metrics context. If this component has the same life-cycle as the parent
    *                it can simply use the parent context, otherwise it should obtain a child context
-   *                using {@link SolrMetricsContext#getChildContext(Object)} passing <code>this</code>
-   *                as the child object.
-   * @param scope component scope
+   *                using {@link SolrMetricsContext#getChildContext(Object, String)} passing <code>this</code>
+   *                as the child object and <code>childScope</code> as the scope.
+   * @param childScope component scope
    */
-  void initializeMetrics(SolrMetricsContext parentContext, String scope);
+  void initializeMetrics(SolrMetricsContext parentContext, String childScope);
 
   /**
    * Implementations should return the context used in
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
index 6861457..66a3718 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
@@ -17,6 +17,8 @@
 
 package org.apache.solr.metrics;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -38,15 +40,28 @@ import org.apache.solr.util.stats.MetricUtils;
 public class SolrMetricsContext {
   private final String registryName;
   private final SolrMetricManager metricManager;
+  private final String scope;
   private final String tag;
   private final Set<String> metricNames = ConcurrentHashMap.newKeySet();
 
-  public SolrMetricsContext(SolrMetricManager metricManager, String registryName, String tag) {
+  public SolrMetricsContext(SolrMetricManager metricManager, String registryName, String scope, String tag) {
     this.registryName = registryName;
     this.metricManager = metricManager;
+    this.scope = scope;
     this.tag = tag;
   }
 
+  public SolrMetricsContext(SolrMetricManager metricManager, String registryName, String tag) {
+    this(metricManager, registryName, null, tag);
+  }
+
+  /**
+   * Scope of the component where this context is used.
+   */
+  public String getScope() {
+    return scope;
+  }
+
   /**
    * Metrics tag that represents objects with the same life-cycle.
    */
@@ -92,8 +107,8 @@ public class SolrMetricsContext {
    * and child are different.
    * @param child child object that produces metrics with a different life-cycle than the parent.
    */
-  public SolrMetricsContext getChildContext(Object child) {
-    SolrMetricsContext childContext = new SolrMetricsContext(metricManager, registryName, SolrMetricProducer.getUniqueMetricTag(child, tag));
+  public SolrMetricsContext getChildContext(Object child, String childScope) {
+    SolrMetricsContext childContext = new SolrMetricsContext(metricManager, registryName, childScope, SolrMetricProducer.getUniqueMetricTag(child, tag));
     return childContext;
   }
 
@@ -113,18 +128,32 @@ public class SolrMetricsContext {
     return MetricUtils.convertMetrics(getMetricRegistry(), metricNames);
   }
 
+  private String createName(String metricName, String... metricpath) {
+    ArrayList<String> l = new ArrayList<>();
+    if(metricpath != null ) {
+      Collections.addAll(l, metricpath);
+    }
+    if (scope != null) {
+      l.add(scope);
+    }
+    if (metricName != null) {
+      l.add(metricName);
+    }
+    return String.join(".", l);
+  }
+
   /**
    * Convenience method for {@link SolrMetricManager#meter(SolrMetricsContext, String, String, String...)}.
    */
   public Meter meter(String metricName, String... metricPath) {
-    return metricManager.meter(this, registryName, metricName, metricPath);
+    return metricManager.meter(this, registryName, createName(metricName, metricPath));
   }
 
   /**
    * Convenience method for {@link SolrMetricManager#counter(SolrMetricsContext, String, String, String...)}.
    */
   public Counter counter(String metricName, String... metricPath) {
-    return metricManager.counter(this, registryName, metricName, metricPath);
+    return metricManager.counter(this, registryName, createName(metricName, metricPath));
 
   }
 
@@ -132,21 +161,21 @@ public class SolrMetricsContext {
    * Convenience method for {@link SolrMetricManager#registerGauge(SolrMetricsContext, String, Gauge, String, boolean, String, String...)}.
    */
   public void gauge(Gauge<?> gauge, boolean force, String metricName, String... metricPath) {
-    metricManager.registerGauge(this, registryName, gauge, tag, force, metricName, metricPath);
+    metricManager.registerGauge(this, registryName, gauge, tag, force, createName(metricName, metricPath));
   }
 
   /**
    * Convenience method for {@link SolrMetricManager#meter(SolrMetricsContext, String, String, String...)}.
    */
   public Timer timer(String metricName, String... metricPath) {
-    return metricManager.timer(this, registryName, metricName, metricPath);
+    return metricManager.timer(this, registryName, createName(metricName, metricPath));
   }
 
   /**
    * Convenience method for {@link SolrMetricManager#histogram(SolrMetricsContext, String, String, String...)}.
    */
   public Histogram histogram(String metricName, String... metricPath) {
-    return metricManager.histogram(this, registryName, metricName, metricPath);
+    return metricManager.histogram(this, registryName, createName(metricName, metricPath));
   }
 
   /**
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index ea1db54..2002d4b 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -37,7 +37,7 @@ import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
-import org.apache.solr.managed.ResourceManagerPluginFactory;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricsContext;
@@ -364,7 +364,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     cacheMap = new MetricsMap((detailed, map) -> {
       if (cache != null) {
         CacheStats stats = cache.stats();
@@ -389,8 +389,12 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
       }
     });
     solrMetricsContext.gauge(cacheMap, true, scope, getCategory().toString());
-    managedComponentId = new ManagedComponentId(CacheManagerPlugin.TYPE, solrMetricsContext.getTag(), solrMetricsContext.getRegistryName(), getCategory().toString(), scope);
-    managedContext = new ManagedContext()
+  }
+
+  @Override
+  public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
+    managedComponentId = new ManagedComponentId(CacheManagerPlugin.TYPE, this, solrMetricsContext.getRegistryName(), getCategory().toString(), solrMetricsContext.getScope());
+    managedContext = new ManagedContext(resourceManager, this, poolName, otherPools);
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 3744895..a8ead8c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -163,9 +163,10 @@ public interface SolrCache<K,V> extends SolrInfoBean, ManagedComponent, Accounta
   // init and have the cache implementation save it.
 
 
-  /** Frees any non-memory resources */
+  /** Frees any non-memory resources and unregisters this instance from resource management. */
   default void close() throws Exception {
     SolrInfoBean.super.close();
+    ManagedComponent.super.close();
   }
 
   /** Returns maximum size limit (number of items) if set and supported, -1 otherwise. */
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index 88a821d..5f1dbf8 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -23,6 +23,7 @@ import java.util.function.Function;
 
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -160,6 +161,11 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
   }
 
   @Override
+  public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
+    delegate.initializeManagedComponent(resourceManager, poolName, otherPools);
+  }
+
+  @Override
   public ManagedContext getManagedContext() {
     return delegate.getManagedContext();
   }
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index fba2aa1..3994b2c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -433,11 +433,11 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
       infoRegistry.put(cache.name(), cache);
     }
     ResourceManager resourceManager = core.getCoreContainer().getResourceManager();
-    this.solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
+    this.solrMetricsContext = core.getSolrMetricsContext().getChildContext(this, null);
     for (SolrCache cache : cacheList) {
       cache.initializeMetrics(solrMetricsContext, SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
       try {
-        resourceManager.registerComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache);
+        cache.initializeManagedComponent(resourceManager, DefaultResourceManager.NODE_SEARCHER_CACHE_POOL);
       } catch (Exception e) {
         log.warn("Exception adding cache '" + cache.getManagedComponentId() + "' to the resource manager pool", e);
       }
@@ -486,7 +486,6 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
 
     for (SolrCache cache : cacheList) {
       try {
-        core.getCoreContainer().getResourceManager().unregisterComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getManagedComponentId().toString());
         cache.close();
       } catch (Exception e) {
         SolrException.log(log, "Exception closing cache " + cache.name(), e);
diff --git a/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java b/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
index c3ff254..2569118 100644
--- a/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
@@ -236,20 +236,20 @@ public abstract class AuditLoggerPlugin implements Closeable, Runnable, SolrInfo
   
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, final String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     String className = this.getClass().getSimpleName();
     log.debug("Initializing metrics for {}", className);
-    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), scope, className);
-    numLost = solrMetricsContext.meter("lost", getCategory().toString(), scope, className);
-    numLogged = solrMetricsContext.meter("count", getCategory().toString(), scope, className);
-    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope, className);
-    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope, className);
+    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), className);
+    numLost = solrMetricsContext.meter("lost", getCategory().toString(), className);
+    numLogged = solrMetricsContext.meter("count", getCategory().toString(), className);
+    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), className);
+    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), className);
     if (async) {
-      solrMetricsContext.gauge(() -> blockingQueueSize, true, "queueCapacity", getCategory().toString(), scope, className);
-      solrMetricsContext.gauge(() -> blockingQueueSize - queue.remainingCapacity(), true, "queueSize", getCategory().toString(), scope, className);
-      queuedTime = solrMetricsContext.timer("queuedTime", getCategory().toString(), scope, className);
+      solrMetricsContext.gauge(() -> blockingQueueSize, true, "queueCapacity", getCategory().toString(), className);
+      solrMetricsContext.gauge(() -> blockingQueueSize - queue.remainingCapacity(), true, "queueSize", getCategory().toString(), className);
+      queuedTime = solrMetricsContext.timer("queuedTime", getCategory().toString(), className);
     }
-    solrMetricsContext.gauge(() -> async, true, "async", getCategory().toString(), scope, className);
+    solrMetricsContext.gauge(() -> async, true, "async", getCategory().toString(), className);
   }
   
   @Override
diff --git a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
index f08651a..f083a31 100644
--- a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
@@ -144,16 +144,16 @@ public abstract class AuthenticationPlugin implements SolrInfoBean {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
     // Metrics
-    numErrors = this.solrMetricsContext.meter("errors", getCategory().toString(), scope);
-    requests = this.solrMetricsContext.counter("requests", getCategory().toString(), scope);
-    numAuthenticated = this.solrMetricsContext.counter("authenticated",getCategory().toString(), scope);
-    numPassThrough = this.solrMetricsContext.counter("passThrough",  getCategory().toString(), scope);
-    numWrongCredentials = this.solrMetricsContext.counter("failWrongCredentials",getCategory().toString(), scope);
-    numMissingCredentials = this.solrMetricsContext.counter("failMissingCredentials",getCategory().toString(), scope);
-    requestTimes = this.solrMetricsContext.timer("requestTimes", getCategory().toString(), scope);
-    totalTime = this.solrMetricsContext.counter("totalTime", getCategory().toString(), scope);
+    numErrors = this.solrMetricsContext.meter("errors", getCategory().toString());
+    requests = this.solrMetricsContext.counter("requests", getCategory().toString());
+    numAuthenticated = this.solrMetricsContext.counter("authenticated",getCategory().toString());
+    numPassThrough = this.solrMetricsContext.counter("passThrough",  getCategory().toString());
+    numWrongCredentials = this.solrMetricsContext.counter("failWrongCredentials",getCategory().toString());
+    numMissingCredentials = this.solrMetricsContext.counter("failMissingCredentials",getCategory().toString());
+    requestTimes = this.solrMetricsContext.timer("requestTimes", getCategory().toString());
+    totalTime = this.solrMetricsContext.counter("totalTime", getCategory().toString());
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
index 37d735e..809a31b 100644
--- a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
+++ b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
@@ -58,7 +58,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     metricsMap = new MetricsMap((detailed, map) -> {
       long now = System.nanoTime();
       long delta = Math.max(now - previous, 1);
@@ -102,7 +102,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean {
       previous = now;
 
     });
-    solrMetricsContext.gauge(metricsMap, true, getName(), getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, getName(), getCategory().toString());
   }
 
   private float getPerSecond(long value, double seconds) {
diff --git a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
index 4cf9090..2b8a1b7 100644
--- a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
+++ b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
@@ -88,7 +88,7 @@ public class HdfsLocalityReporter implements SolrInfoBean {
    */
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
       long totalBytes = 0;
       long localBytes = 0;
@@ -138,7 +138,7 @@ public class HdfsLocalityReporter implements SolrInfoBean {
         map.put(LOCALITY_BLOCKS_RATIO, localCount / (double) totalCount);
       }
     });
-    solrMetricsContext.gauge(metricsMap, true, "hdfsLocality", getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, "hdfsLocality", getCategory().toString());
   }
 
   /**
diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
index b6232ae..8cec555 100644
--- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
+++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
@@ -169,45 +169,45 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
-    commitCommands = solrMetricsContext.meter("commits", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> softCommitTracker.getCommitCount(), true, "softAutoCommits", getCategory().toString(), scope);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
+    commitCommands = solrMetricsContext.meter("commits", getCategory().toString());
+    solrMetricsContext.gauge(() -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString());
+    solrMetricsContext.gauge(() -> softCommitTracker.getCommitCount(), true, "softAutoCommits", getCategory().toString());
     if (commitTracker.getDocsUpperBound() > 0) {
       solrMetricsContext.gauge(() -> commitTracker.getDocsUpperBound(), true, "autoCommitMaxDocs",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (commitTracker.getTimeUpperBound() > 0) {
       solrMetricsContext.gauge(() -> "" + commitTracker.getTimeUpperBound() + "ms", true, "autoCommitMaxTime",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (commitTracker.getTLogFileSizeUpperBound() > 0) {
       solrMetricsContext.gauge(() -> commitTracker.getTLogFileSizeUpperBound(), true, "autoCommitMaxSize",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (softCommitTracker.getDocsUpperBound() > 0) {
       solrMetricsContext.gauge(() -> softCommitTracker.getDocsUpperBound(), true, "softAutoCommitMaxDocs",
-          getCategory().toString(), scope);
+          getCategory().toString());
     }
     if (softCommitTracker.getTimeUpperBound() > 0) {
       solrMetricsContext.gauge(() -> "" + softCommitTracker.getTimeUpperBound() + "ms", true, "softAutoCommitMaxTime",
-          getCategory().toString(), scope);
-    }
-    optimizeCommands = solrMetricsContext.meter("optimizes", getCategory().toString(), scope);
-    rollbackCommands = solrMetricsContext.meter("rollbacks", getCategory().toString(), scope);
-    splitCommands = solrMetricsContext.meter("splits", getCategory().toString(), scope);
-    mergeIndexesCommands = solrMetricsContext.meter("merges", getCategory().toString(), scope);
-    expungeDeleteCommands = solrMetricsContext.meter("expungeDeletes", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> numDocsPending.longValue(), true, "docsPending", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> addCommands.longValue(), true, "adds", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString(), scope);
-    solrMetricsContext.gauge(() -> numErrors.longValue(), true, "errors", getCategory().toString(), scope);
-
-    addCommandsCumulative = solrMetricsContext.meter("cumulativeAdds", getCategory().toString(), scope);
-    deleteByIdCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesById", getCategory().toString(), scope);
-    deleteByQueryCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesByQuery", getCategory().toString(), scope);
-    numErrorsCumulative = solrMetricsContext.meter("cumulativeErrors", getCategory().toString(), scope);
+          getCategory().toString());
+    }
+    optimizeCommands = solrMetricsContext.meter("optimizes", getCategory().toString());
+    rollbackCommands = solrMetricsContext.meter("rollbacks", getCategory().toString());
+    splitCommands = solrMetricsContext.meter("splits", getCategory().toString());
+    mergeIndexesCommands = solrMetricsContext.meter("merges", getCategory().toString());
+    expungeDeleteCommands = solrMetricsContext.meter("expungeDeletes", getCategory().toString());
+    solrMetricsContext.gauge(() -> numDocsPending.longValue(), true, "docsPending", getCategory().toString());
+    solrMetricsContext.gauge(() -> addCommands.longValue(), true, "adds", getCategory().toString());
+    solrMetricsContext.gauge(() -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString());
+    solrMetricsContext.gauge(() -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString());
+    solrMetricsContext.gauge(() -> numErrors.longValue(), true, "errors", getCategory().toString());
+
+    addCommandsCumulative = solrMetricsContext.meter("cumulativeAdds", getCategory().toString());
+    deleteByIdCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesById", getCategory().toString());
+    deleteByQueryCommandsCumulative = solrMetricsContext.meter("cumulativeDeletesByQuery", getCategory().toString());
+    numErrorsCumulative = solrMetricsContext.meter("cumulativeErrors", getCategory().toString());
   }
 
   private void deleteAll() throws IOException {
diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java
index 801e48f..a47a339 100644
--- a/solr/core/src/java/org/apache/solr/update/PeerSync.java
+++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java
@@ -140,7 +140,7 @@ public class PeerSync implements SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, null);
     syncTime = solrMetricsContext.timer("time", scope, METRIC_SCOPE);
     syncErrors = solrMetricsContext.counter("errors", scope, METRIC_SCOPE);
     syncSkipped = solrMetricsContext.counter("skipped", scope, METRIC_SCOPE);
diff --git a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
index fca105e..f03bd8d 100644
--- a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
+++ b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
@@ -97,7 +97,7 @@ public class PeerSyncWithLeader implements SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
+    this.solrMetricsContext = parentContext.getChildContext(this, null);
     syncTime = solrMetricsContext.timer("time", scope, METRIC_SCOPE);
     syncErrors = solrMetricsContext.counter("errors", scope, METRIC_SCOPE);
     syncSkipped = solrMetricsContext.counter("skipped", scope, METRIC_SCOPE);
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
index 4070ea9..4d92481 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
@@ -133,7 +133,7 @@ public class SolrIndexWriter extends IndexWriter {
     infoStream = getConfig().getInfoStream();
     this.directory = directory;
     numOpens.incrementAndGet();
-    solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
+    solrMetricsContext = core.getSolrMetricsContext().getChildContext(this, null);
     if (config.metricsInfo != null && config.metricsInfo.initArgs != null) {
       Object v = config.metricsInfo.initArgs.get("majorMergeDocs");
       if (v != null) {
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
index 9fd185d..03cfebe 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
@@ -432,7 +432,7 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     bufferedOpsGauge = () -> {
       if (state == State.BUFFERING) {
         if (bufferTlog == null) return  0;
@@ -449,13 +449,13 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer {
       }
     };
 
-    solrMetricsContext.gauge(bufferedOpsGauge, true, "ops", scope, "buffered");
-    solrMetricsContext.gauge(() -> logs.size(), true, "logs", scope, "replay", "remaining");
-    solrMetricsContext.gauge(() -> getTotalLogsSize(), true, "bytes", scope, "replay", "remaining");
-    applyingBufferedOpsMeter = solrMetricsContext.meter("ops", scope, "applyingBuffered");
+    solrMetricsContext.gauge(bufferedOpsGauge, true, "ops", "buffered");
+    solrMetricsContext.gauge(() -> logs.size(), true, "logs", "replay", "remaining");
+    solrMetricsContext.gauge(() -> getTotalLogsSize(), true, "bytes", "replay", "remaining");
+    applyingBufferedOpsMeter = solrMetricsContext.meter("ops", "applyingBuffered");
     replayOpsMeter = solrMetricsContext.meter("ops", scope, "replay");
-    copyOverOldUpdatesMeter = solrMetricsContext.meter("ops", scope, "copyOverOldUpdates");
-    solrMetricsContext.gauge(() -> state.getValue(), true, "state", scope);
+    copyOverOldUpdatesMeter = solrMetricsContext.meter("ops", "copyOverOldUpdates");
+    solrMetricsContext.gauge(() -> state.getValue(), true, "state");
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
index 2060978..9a56f12 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
@@ -179,7 +179,7 @@ public class UpdateShardHandler implements SolrInfoBean {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     String expandedScope = SolrMetricManager.mkName(scope, getCategory().name());
     updateHttpListenerFactory.initializeMetrics(solrMetricsContext, expandedScope);
     defaultConnectionManager.initializeMetrics(solrMetricsContext, expandedScope);
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java
index 4adbe68..501ee12 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java
@@ -90,7 +90,6 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme
     KNOWN_METRIC_NAME_STRATEGIES.put("methodOnly", METHOD_ONLY);
   }
 
-  protected String scope;
   protected HttpClientMetricNameStrategy nameStrategy;
   protected SolrMetricsContext solrMetricsContext;
 
@@ -128,12 +127,11 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme
   }
 
   private Timer timer(HttpRequest request) {
-    return solrMetricsContext.timer(null, nameStrategy.getNameFor(scope, request));
+    return solrMetricsContext.timer(null, nameStrategy.getNameFor(solrMetricsContext.getScope(), request));
   }
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
-    this.scope = scope;
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
index e9144df..c69738b 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
@@ -43,16 +43,12 @@ public class InstrumentedPoolingHttpClientConnectionManager extends PoolingHttpC
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    this.solrMetricsContext = parentContext.getChildContext(this);
-    solrMetricsContext.gauge(() -> getTotalStats().getAvailable(),
-        true, SolrMetricManager.mkName("availableConnections", scope));
+    this.solrMetricsContext = parentContext.getChildContext(this, scope);
+    solrMetricsContext.gauge(() -> getTotalStats().getAvailable(), true, "availableConnections");
     // this acquires a lock on the connection pool; remove if contention sucks
-    solrMetricsContext.gauge(() -> getTotalStats().getLeased(),
-        true, SolrMetricManager.mkName("leasedConnections", scope));
-    solrMetricsContext.gauge(() -> getTotalStats().getMax(),
-        true, SolrMetricManager.mkName("maxConnections", scope));
-    solrMetricsContext.gauge(() -> getTotalStats().getPending(),
-        true, SolrMetricManager.mkName("pendingConnections", scope));
+    solrMetricsContext.gauge(() -> getTotalStats().getLeased(), true, "leasedConnections");
+    solrMetricsContext.gauge(() -> getTotalStats().getMax(), true, "maxConnections");
+    solrMetricsContext.gauge(() -> getTotalStats().getPending(), true, "pendingConnections");
   }
 
   @Override
diff --git a/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java b/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java
index 632fcb6..bbffe90 100644
--- a/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java
+++ b/solr/core/src/test/org/apache/solr/core/HdfsDirectoryFactoryTest.java
@@ -194,7 +194,7 @@ public class HdfsDirectoryFactoryTest extends SolrTestCaseJ4 {
       props.put(HdfsDirectoryFactory.NRTCACHINGDIRECTORY_ENABLE, "false");
       props.put(HdfsDirectoryFactory.LOCALITYMETRICS_ENABLED, "true");
       factory.init(new NamedList<>(props));
-      factory.initializeMetrics(new SolrMetricsContext(metricManager, registry, "foo"), scope);
+      factory.initializeMetrics(new SolrMetricsContext(metricManager, registry, "foo", "foo"), scope);
 
       // get the metrics map for the locality bean
       MetricsMap metrics = (MetricsMap) ((SolrMetricManager.GaugeWrapper) metricManager.registry(registry).getMetrics().get("OTHER." + scope + ".hdfsLocality")).getGauge();
diff --git a/solr/core/src/test/org/apache/solr/core/MockInfoBean.java b/solr/core/src/test/org/apache/solr/core/MockInfoBean.java
index ce73a02..5c527b4 100644
--- a/solr/core/src/test/org/apache/solr/core/MockInfoBean.java
+++ b/solr/core/src/test/org/apache/solr/core/MockInfoBean.java
@@ -49,7 +49,7 @@ class MockInfoBean implements SolrInfoBean, SolrMetricProducer {
 
   @Override
   public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-    solrMetricsContext = parentContext.getChildContext(this);
+    solrMetricsContext = parentContext.getChildContext(this, scope);
     MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
       map.put("Integer", 123);
       map.put("Double",567.534);
@@ -60,6 +60,6 @@ class MockInfoBean implements SolrInfoBean, SolrMetricProducer {
       map.put("String","testing");
       map.put("Object", new Object());
     });
-    solrMetricsContext.gauge(metricsMap, true, getClass().getSimpleName(), getCategory().toString(), scope);
+    solrMetricsContext.gauge(metricsMap, true, getClass().getSimpleName(), getCategory().toString());
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java
index 5ec4b61..a8e45a2 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/MBeansHandlerTest.java
@@ -149,7 +149,7 @@ public class MBeansHandlerTest extends SolrTestCaseJ4 {
 
       @Override
       public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-        this.solrMetricsContext = parentContext.getChildContext(this);
+        this.solrMetricsContext = parentContext.getChildContext(this, scope);
       }
 
       @Override
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
index 4f2fbd8..ebb9129 100644
--- a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
@@ -41,7 +41,7 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
   }
 
   public static class TestComponent implements MockManagedComponent {
-    ManagedContext context = new ManagedContext();
+    ManagedContext context;
     ManagedComponentId id;
     int foo, bar, baz;
 
@@ -77,6 +77,11 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     }
 
     @Override
+    public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
+      context = new ManagedContext(resourceManager, this, poolName, otherPools);
+    }
+
+    @Override
     public ManagedContext getManagedContext() {
       return context;
     }
@@ -138,8 +143,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
       }
       manageStartLatch.countDown();
       log.info("-- managing");
-      pool.getCurrentValues();
-      Map<String, Object> totalValues = pool.getTotalValues();
+      Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
+      Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
       Map<String, Object> poolLimits = pool.getPoolLimits();
       if (poolLimits.containsKey("foo")) {
         // manage
@@ -199,8 +204,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     }
     ResourceManagerPool pool = resourceManager.getPool("test");
     assertEquals(10, pool.getComponents().size());
-    pool.getCurrentValues();
-    Map<String, Object> totalValues = pool.getTotalValues();
+    Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
+    Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
     assertNotNull(totalValues.get("bar"));
     assertEquals(55, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
@@ -222,8 +227,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     manageStartLatch = new CountDownLatch(1);
     boolean await = manageFinishLatch.await(30000 / SPEED, TimeUnit.MILLISECONDS);
     assertTrue("did not finish in time", await);
-    pool.getCurrentValues();
-    totalValues = pool.getTotalValues();
+    currentValues = pool.getCurrentValues();
+    totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
     assertNotNull(totalValues.get("bar"));
     assertEquals(46, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java b/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java
index 1f5f614..519cf04 100644
--- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java
+++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricTestUtils.java
@@ -80,7 +80,7 @@ public final class SolrMetricTestUtils {
       SolrMetricsContext solrMetricsContext;
       @Override
       public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
-        this.solrMetricsContext = parentContext.getChildContext(this);
+        this.solrMetricsContext = parentContext.getChildContext(this, scope);
         if (category == null) {
           throw new IllegalArgumentException("null category");
         }
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java b/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java
index cc9cf73..0210588 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrCachePerf.java
@@ -94,7 +94,7 @@ public class TestSolrCachePerf extends SolrTestCaseJ4 {
       CacheRegenerator cr = new NoOpRegenerator();
       Object o = cache.init(params, null, cr);
       cache.setState(SolrCache.State.LIVE);
-      cache.initializeMetrics(new SolrMetricsContext(metricManager, "foo", "bar"), "foo");
+      cache.initializeMetrics(new SolrMetricsContext(metricManager, "foo", "foo", "bar"), "foo");
       AtomicBoolean stop = new AtomicBoolean();
       SummaryStatistics perImplRatio = ratioStats.computeIfAbsent(clazz.getSimpleName(), c -> new SummaryStatistics());
       SummaryStatistics perImplTime = timeStats.computeIfAbsent(clazz.getSimpleName(), c -> new SummaryStatistics());
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java b/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java
index 49b754f..cbfc9ae 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrFieldCacheBean.java
@@ -75,7 +75,7 @@ public class TestSolrFieldCacheBean extends SolrTestCaseJ4 {
     Random r = random();
     String registryName = TestUtil.randomSimpleString(r, 1, 10);
     SolrMetricManager metricManager = h.getCoreContainer().getMetricManager();
-    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo");
+    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo", "foo");
     mbean.initializeMetrics(solrMetricsContext, null);
     MetricsMap metricsMap = (MetricsMap)((SolrMetricManager.GaugeWrapper)metricManager.registry(registryName).getMetrics().get("CACHE.fieldCache")).getGauge();
     Map<String, Object> metrics = checkJmx ? metricsMap.getValue(true) : metricsMap.getValue();
@@ -89,7 +89,7 @@ public class TestSolrFieldCacheBean extends SolrTestCaseJ4 {
     Random r = random();
     String registryName = TestUtil.randomSimpleString(r, 1, 10);
     SolrMetricManager metricManager = h.getCoreContainer().getMetricManager();
-    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo");
+    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, registryName, "foo", "foo");
     mbean.initializeMetrics(solrMetricsContext, null);
     MetricsMap metricsMap = (MetricsMap)((SolrMetricManager.GaugeWrapper)metricManager.registry(registryName).getMetrics().get("CACHE.fieldCache")).getGauge();
     Map<String, Object> metrics = checkJmx ? metricsMap.getValue(true) : metricsMap.getValue();


[lucene-solr] 05/36: Merge branch 'master' into star-123

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 129a60223d183b2625069f3e35d1645fdee5acdb
Merge: 2f7bdfe 54aff4a
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Mon Jun 24 20:15:15 2019 +0200

    Merge branch 'master' into star-123

 .gitignore                                         |    4 +-
 dev-tools/idea/dev-tools/scripts/scripts.iml       |    9 +
 dev-tools/scripts/README.md                        |  211 ++
 dev-tools/scripts/addBackcompatIndexes.py          |    2 +
 dev-tools/scripts/addVersion.py                    |    6 +-
 dev-tools/scripts/buildAndPushRelease.py           |    2 +
 dev-tools/scripts/releaseWizard.py                 | 2011 ++++++++++++++++++++
 dev-tools/scripts/releaseWizard.yaml               | 1735 +++++++++++++++++
 dev-tools/scripts/releasedJirasRegex.py            |    2 +
 dev-tools/scripts/requirements.txt                 |    6 +
 dev-tools/scripts/smokeTestRelease.py              |    2 +-
 lucene/CHANGES.txt                                 |   23 +-
 .../ar/ArabicNormalizationFilterFactory.java       |    4 +
 .../analysis/ar/ArabicStemFilterFactory.java       |    4 +
 .../analysis/bg/BulgarianStemFilterFactory.java    |    6 +-
 .../bn/BengaliNormalizationFilterFactory.java      |    4 +
 .../analysis/bn/BengaliStemFilterFactory.java      |    4 +
 .../analysis/br/BrazilianStemFilterFactory.java    |    4 +
 .../charfilter/HTMLStripCharFilterFactory.java     |    5 +
 .../charfilter/MappingCharFilterFactory.java       |    4 +
 .../analysis/cjk/CJKBigramFilterFactory.java       |    5 +
 .../lucene/analysis/cjk/CJKWidthFilterFactory.java |    4 +
 .../ckb/SoraniNormalizationFilterFactory.java      |    4 +
 .../analysis/ckb/SoraniStemFilterFactory.java      |    4 +
 .../commongrams/CommonGramsFilterFactory.java      |    7 +-
 .../commongrams/CommonGramsQueryFilterFactory.java |    3 +
 .../DictionaryCompoundWordTokenFilterFactory.java  |    5 +
 .../HyphenationCompoundWordTokenFilterFactory.java |    5 +
 .../analysis/core/DecimalDigitFilterFactory.java   |    4 +
 .../analysis/core/FlattenGraphFilterFactory.java   |    4 +
 .../analysis/core/KeywordTokenizerFactory.java     |    5 +
 .../analysis/core/LetterTokenizerFactory.java      |    5 +
 .../analysis/core/LowerCaseFilterFactory.java      |    4 +
 .../lucene/analysis/core/StopFilterFactory.java    |    5 +
 .../analysis/core/TypeTokenFilterFactory.java      |    5 +
 .../analysis/core/UpperCaseFilterFactory.java      |    4 +
 .../analysis/core/WhitespaceTokenizerFactory.java  |    5 +
 .../lucene/analysis/cz/CzechStemFilterFactory.java |    4 +
 .../analysis/de/GermanLightStemFilterFactory.java  |    4 +
 .../de/GermanMinimalStemFilterFactory.java         |    4 +
 .../de/GermanNormalizationFilterFactory.java       |    4 +
 .../analysis/de/GermanStemFilterFactory.java       |    4 +
 .../analysis/el/GreekLowerCaseFilterFactory.java   |    4 +
 .../lucene/analysis/el/GreekStemFilterFactory.java |    4 +
 .../en/EnglishMinimalStemFilterFactory.java        |    4 +
 .../en/EnglishPossessiveFilterFactory.java         |    4 +
 .../lucene/analysis/en/KStemFilterFactory.java     |    4 +
 .../analysis/en/PorterStemFilterFactory.java       |    4 +
 .../analysis/es/SpanishLightStemFilterFactory.java |    4 +
 .../analysis/fa/PersianCharFilterFactory.java      |    4 +
 .../fa/PersianNormalizationFilterFactory.java      |    4 +
 .../analysis/fi/FinnishLightStemFilterFactory.java |    4 +
 .../analysis/fr/FrenchLightStemFilterFactory.java  |    4 +
 .../fr/FrenchMinimalStemFilterFactory.java         |    4 +
 .../analysis/ga/IrishLowerCaseFilterFactory.java   |    4 +
 .../gl/GalicianMinimalStemFilterFactory.java       |    4 +
 .../analysis/gl/GalicianStemFilterFactory.java     |    4 +
 .../hi/HindiNormalizationFilterFactory.java        |    4 +
 .../lucene/analysis/hi/HindiStemFilterFactory.java |    4 +
 .../hu/HungarianLightStemFilterFactory.java        |    4 +
 .../hunspell/HunspellStemFilterFactory.java        |    5 +
 .../analysis/id/IndonesianStemFilterFactory.java   |    5 +
 .../in/IndicNormalizationFilterFactory.java        |    4 +
 .../analysis/it/ItalianLightStemFilterFactory.java |    4 +
 .../analysis/lv/LatvianStemFilterFactory.java      |    4 +
 .../analysis/minhash/MinHashFilterFactory.java     |    5 +
 .../miscellaneous/ASCIIFoldingFilterFactory.java   |    5 +
 .../miscellaneous/CapitalizationFilterFactory.java |    5 +
 .../miscellaneous/CodepointCountFilterFactory.java |    5 +
 .../ConcatenateGraphFilterFactory.java             |    4 +
 .../ConditionalTokenFilterFactory.java             |    4 +
 .../miscellaneous/DateRecognizerFilterFactory.java |    4 +
 .../DelimitedTermFrequencyTokenFilterFactory.java  |    5 +
 .../miscellaneous/FingerprintFilterFactory.java    |    4 +
 .../FixBrokenOffsetsFilterFactory.java             |    4 +
 .../HyphenatedWordsFilterFactory.java              |    4 +
 .../miscellaneous/KeepWordFilterFactory.java       |    5 +
 .../miscellaneous/KeywordMarkerFilterFactory.java  |    5 +
 .../miscellaneous/KeywordRepeatFilterFactory.java  |    4 +
 .../miscellaneous/LengthFilterFactory.java         |    5 +
 .../LimitTokenCountFilterFactory.java              |    4 +
 .../LimitTokenOffsetFilterFactory.java             |    4 +
 .../LimitTokenPositionFilterFactory.java           |    4 +
 .../miscellaneous/ProtectedTermFilterFactory.java  |    3 +
 .../RemoveDuplicatesTokenFilterFactory.java        |    4 +
 .../ScandinavianFoldingFilterFactory.java          |    4 +
 .../ScandinavianNormalizationFilterFactory.java    |    4 +
 .../StemmerOverrideFilterFactory.java              |    5 +
 .../analysis/miscellaneous/TrimFilterFactory.java  |    4 +
 .../miscellaneous/TruncateTokenFilterFactory.java  |    4 +
 .../miscellaneous/TypeAsSynonymFilterFactory.java  |    5 +
 .../miscellaneous/WordDelimiterFilterFactory.java  |    5 +
 .../WordDelimiterGraphFilterFactory.java           |    5 +
 .../analysis/ngram/EdgeNGramFilterFactory.java     |    5 +
 .../analysis/ngram/EdgeNGramTokenizerFactory.java  |    5 +
 .../lucene/analysis/ngram/NGramFilterFactory.java  |    5 +
 .../analysis/ngram/NGramTokenizerFactory.java      |    5 +
 .../no/NorwegianLightStemFilterFactory.java        |    4 +
 .../no/NorwegianMinimalStemFilterFactory.java      |    4 +
 .../path/PathHierarchyTokenizerFactory.java        |    5 +
 .../pattern/PatternCaptureGroupFilterFactory.java  |    5 +
 .../pattern/PatternReplaceCharFilterFactory.java   |    5 +
 .../pattern/PatternReplaceFilterFactory.java       |    5 +
 .../analysis/pattern/PatternTokenizerFactory.java  |    5 +
 .../SimplePatternSplitTokenizerFactory.java        |    5 +
 .../pattern/SimplePatternTokenizerFactory.java     |    5 +
 .../DelimitedPayloadTokenFilterFactory.java        |    5 +
 .../payloads/NumericPayloadTokenFilterFactory.java |    5 +
 .../TokenOffsetPayloadTokenFilterFactory.java      |    4 +
 .../payloads/TypeAsPayloadTokenFilterFactory.java  |    4 +
 .../pt/PortugueseLightStemFilterFactory.java       |    4 +
 .../pt/PortugueseMinimalStemFilterFactory.java     |    4 +
 .../analysis/pt/PortugueseStemFilterFactory.java   |    4 +
 .../reverse/ReverseStringFilterFactory.java        |    4 +
 .../analysis/ru/RussianLightStemFilterFactory.java |    4 +
 .../shingle/FixedShingleFilterFactory.java         |    4 +
 .../analysis/shingle/ShingleFilterFactory.java     |    5 +
 .../snowball/SnowballPorterFilterFactory.java      |    5 +
 .../sr/SerbianNormalizationFilterFactory.java      |    5 +
 .../analysis/standard/ClassicFilterFactory.java    |    4 +
 .../analysis/standard/ClassicTokenizerFactory.java |    5 +
 .../standard/StandardTokenizerFactory.java         |    5 +
 .../standard/UAX29URLEmailTokenizerFactory.java    |    5 +
 .../analysis/sv/SwedishLightStemFilterFactory.java |    4 +
 .../analysis/synonym/SynonymFilterFactory.java     |    5 +
 .../synonym/SynonymGraphFilterFactory.java         |    5 +
 .../lucene/analysis/th/ThaiTokenizerFactory.java   |    4 +
 .../analysis/tr/ApostropheFilterFactory.java       |    4 +
 .../analysis/tr/TurkishLowerCaseFilterFactory.java |    4 +
 .../lucene/analysis/util/AnalysisSPILoader.java    |   76 +-
 .../lucene/analysis/util/ElisionFilterFactory.java |    5 +
 .../lucene/analysis/util/TokenFilterFactory.java   |    5 +-
 .../wikipedia/WikipediaTokenizerFactory.java       |    5 +
 .../analysis/util/TestAnalysisSPILoader.java       |    6 +-
 .../analysis/icu/ICUFoldingFilterFactory.java      |    5 +
 .../icu/ICUNormalizer2CharFilterFactory.java       |    5 +
 .../analysis/icu/ICUNormalizer2FilterFactory.java  |    5 +
 .../analysis/icu/ICUTransformFilterFactory.java    |    5 +
 .../icu/segmentation/ICUTokenizerFactory.java      |    5 +
 lucene/analysis/kuromoji/build.xml                 |   18 +-
 .../analysis/ja/JapaneseBaseFormFilterFactory.java |    4 +
 .../ja/JapaneseIterationMarkCharFilterFactory.java |    4 +
 .../ja/JapaneseKatakanaStemFilterFactory.java      |    5 +
 .../analysis/ja/JapaneseNumberFilterFactory.java   |    4 +
 .../ja/JapanesePartOfSpeechStopFilterFactory.java  |    4 +
 .../ja/JapaneseReadingFormFilterFactory.java       |    5 +
 .../analysis/ja/JapaneseTokenizerFactory.java      |    5 +
 .../lucene/analysis/ja/dict/BinaryDictionary.java  |   57 +-
 .../analysis/ja/dict/TokenInfoDictionary.java      |   15 +-
 .../analysis/ja/util/BinaryDictionaryWriter.java   |   43 +-
 .../ja/util/TokenInfoDictionaryBuilder.java        |   18 +-
 .../analysis/ja/dict/TokenInfoDictionaryTest.java  |   85 +
 .../analysis/ja/dict/UnknownDictionaryTest.java    |   22 +-
 .../morfologik/MorfologikFilterFactory.java        |    5 +
 .../analysis/ko/KoreanNumberFilterFactory.java     |    4 +
 .../ko/KoreanPartOfSpeechStopFilterFactory.java    |    5 +
 .../ko/KoreanReadingFormFilterFactory.java         |    4 +
 .../lucene/analysis/ko/KoreanTokenizerFactory.java |    5 +
 .../opennlp/OpenNLPChunkerFilterFactory.java       |    5 +
 .../opennlp/OpenNLPLemmatizerFilterFactory.java    |    5 +
 .../analysis/opennlp/OpenNLPPOSFilterFactory.java  |    5 +
 .../analysis/opennlp/OpenNLPTokenizerFactory.java  |    5 +
 .../phonetic/BeiderMorseFilterFactory.java         |    5 +
 .../DaitchMokotoffSoundexFilterFactory.java        |    5 +
 .../phonetic/DoubleMetaphoneFilterFactory.java     |    5 +
 .../analysis/phonetic/PhoneticFilterFactory.java   |    5 +
 .../cn/smart/HMMChineseTokenizerFactory.java       |    4 +
 .../stempel/StempelPolishStemFilterFactory.java    |    6 +-
 lucene/common-build.xml                            |    2 +
 .../org/apache/lucene/search/IndexSearcher.java    |   38 +-
 .../org/apache/lucene/search/SearcherFactory.java  |    4 +-
 .../src/java/org/apache/lucene/util/fst/Util.java  |   16 +-
 .../apache/lucene/search/TestIndexSearcher.java    |   28 +
 .../uhighlight/MemoryIndexOffsetStrategy.java      |    9 +-
 .../search/uhighlight/MultiTermHighlighting.java   |    8 +
 .../search/uhighlight/NoOpOffsetStrategy.java      |    2 +-
 .../uhighlight/TokenStreamOffsetStrategy.java      |   16 +-
 .../lucene/search/uhighlight/UHComponents.java     |    8 +-
 .../search/uhighlight/UnifiedHighlighter.java      |   66 +-
 .../search/uhighlight/TestUnifiedHighlighter.java  |  103 +
 .../TestUnifiedHighlighterExtensibility.java       |   33 +-
 .../desktop/components/AnalysisPanelProvider.java  |  197 +-
 .../desktop/components/SearchPanelProvider.java    |    4 +-
 .../SimpleAnalyzeResultPanelOperator.java}         |   26 +-
 .../analysis/SimpleAnalyzeResultPanelProvider.java |  196 ++
 .../StepByStepAnalyzeResultPanelOperator.java}     |   25 +-
 .../StepByStepAnalyzeResultPanelProvider.java      |  415 ++++
 .../lucene/luke/models/analysis/Analysis.java      |   76 +
 .../lucene/luke/models/analysis/AnalysisImpl.java  |  191 +-
 .../luke/app/desktop/messages/messages.properties  |    2 +
 .../luke/models/analysis/AnalysisImplTest.java     |   40 +
 .../apache/lucene/monitor/TestCachePurging.java    |   17 +-
 .../java/org/apache/lucene/geo/Tessellator.java    |    7 +-
 .../org/apache/lucene/geo/TestTessellator.java     |    6 +-
 .../analyzing/SuggestStopFilterFactory.java        |    7 +-
 .../apache/lucene/search/ScorerIndexSearcher.java  |    8 +-
 .../tools/src/groovy/check-source-patterns.groovy  |   11 +
 solr/CHANGES.txt                                   |   23 +-
 .../solr/analysis/LowerCaseTokenizerFactory.java   |    4 +
 .../analysis/ReversedWildcardFilterFactory.java    |    4 +
 .../solr/cloud/api/collections/AliasCmd.java       |    4 +
 .../collections/MaintainTimeRoutedAliasCmd.java    |   27 +-
 .../solr/cloud/api/collections/RoutedAlias.java    |   19 +-
 .../cloud/api/collections/TimeRoutedAlias.java     |   14 +-
 .../schema/analysis/ManagedStopFilterFactory.java  |    4 +
 .../analysis/ManagedSynonymFilterFactory.java      |    4 +
 .../analysis/ManagedSynonymGraphFilterFactory.java |    4 +
 .../processor/AtomicUpdateDocumentMerger.java      |   12 +-
 .../processor/DistributedUpdateProcessor.java      |   17 +-
 .../solr/collection1/conf/schema-root.xml          |   34 +
 .../test-files/solr/collection1/conf/schema.xml    |    3 +-
 .../apache/solr/cloud/CreateRoutedAliasTest.java   |    8 +-
 .../solr/cloud/TestMiniSolrCloudClusterSSL.java    |    2 +
 .../apache/solr/cloud/TestSSLRandomization.java    |    2 +
 .../tagger/WordLengthTaggingFilterFactory.java     |    6 +
 .../solr/highlight/TestUnifiedSolrHighlighter.java |   12 +
 .../transform/TestChildDocTransformer.java         |   34 +-
 .../solr/update/TestInPlaceUpdatesDistrib.java     |   41 +
 .../solr/update/TestInPlaceUpdatesStandalone.java  |   21 +
 .../AtomicUpdateProcessorFactoryTest.java          |   10 +-
 .../solr/update/processor/AtomicUpdatesTest.java   |    9 -
 .../processor/RoutedAliasUpdateProcessorTest.java  |    5 +-
 .../TimeRoutedAliasUpdateProcessorTest.java        |  346 +++-
 .../UpdateRequestProcessorFactoryTest.java         |   33 +-
 .../solr-ref-guide/src/parallel-sql-interface.adoc |    6 +
 .../solrcloud-autoscaling-policy-preferences.adoc  |    6 +-
 solr/solr-ref-guide/src/the-terms-component.adoc   |   23 +-
 .../solrj/impl/BaseHttpClusterStateProvider.java   |    6 +-
 .../solr/client/solrj/impl/HttpClientUtil.java     |   34 +-
 .../java/org/apache/solr/client/solrj/io/Lang.java |    3 +
 .../client/solrj/io/eval/FieldValueEvaluator.java  |    6 +
 .../solr/client/solrj/io/eval/IsNullEvaluator.java |   54 +
 .../client/solrj/io/eval/MatchesEvaluator.java     |   61 +
 .../client/solrj/io/eval/NotNullEvaluator.java     |   54 +
 .../solr/client/solrj/io/stream/HavingStream.java  |    1 +
 .../solrj/request/CollectionAdminRequest.java      |   32 +-
 .../solrj/request/ContentStreamUpdateRequest.java  |    4 +-
 .../apache/solr/client/solrj/SolrExampleTests.java |   48 +-
 .../solr/client/solrj/impl/HttpClientUtilTest.java |   11 -
 .../org/apache/solr/client/solrj/io/TestLang.java  |    3 +-
 .../client/solrj/io/stream/MathExpressionTest.java |  105 +
 .../java/org/apache/solr/util/SSLTestConfig.java   |   13 +-
 242 files changed, 7200 insertions(+), 545 deletions(-)


[lucene-solr] 24/36: Add unit test.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 2a0c57560617f43f4a2d5a6b77a2c24e4e978541
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Aug 1 21:42:12 2019 +0200

    Add unit test.
---
 .../solr/managed/DefaultResourceManager.java       |   5 +-
 .../DefaultResourceManagerPluginFactory.java       |  42 +++-
 .../solr/managed/DefaultResourceManagerPool.java   |  17 +-
 .../apache/solr/managed/ManagedComponentId.java    |   2 +-
 .../apache/solr/managed/NoOpResourceManager.java   |  10 +
 .../org/apache/solr/managed/ResourceManager.java   |   3 -
 .../apache/solr/managed/ResourceManagerPlugin.java |  11 ++
 .../solr/managed/types/CacheManagerPlugin.java     |  10 +
 .../managed/TestDefaultResourceManagerPool.java    | 215 ++++++++++++++++++++-
 9 files changed, 297 insertions(+), 18 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index d485685..e6eb55c 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -97,7 +97,10 @@ public class DefaultResourceManager extends ResourceManager {
     scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
     scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
     // TODO: make configurable based on plugin info
-    resourceManagerPluginFactory = new DefaultResourceManagerPluginFactory(loader);
+    resourceManagerPluginFactory = new DefaultResourceManagerPluginFactory(loader,
+        pluginInfo != null ?
+            (Map<String, Object>)pluginInfo.initArgs.toMap(new HashMap<>()).getOrDefault("plugins", Collections.emptyMap()) :
+            Collections.emptyMap());
     log.info("Resource manager initialized.");
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
index 0b00e74..07eb5ad 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
@@ -16,21 +16,29 @@
  */
 package org.apache.solr.managed;
 
+import java.lang.invoke.MethodHandles;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.managed.types.ManagedCacheComponent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Default implementation of {@link ResourceManagerPluginFactory}.
  */
 public class DefaultResourceManagerPluginFactory implements ResourceManagerPluginFactory {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private static final Map<String, Class<? extends ResourceManagerPlugin>> typeToPluginClass = new HashMap<>();
   private static final Map<String, Class<? extends ManagedComponent>> typeToComponentClass = new HashMap<>();
 
+  public static final String TYPE_TO_PLUGIN = "typeToPlugin";
+  public static final String TYPE_TO_COMPONENT = "typeToComponent";
+
   static {
     typeToPluginClass.put(CacheManagerPlugin.TYPE, CacheManagerPlugin.class);
     typeToComponentClass.put(CacheManagerPlugin.TYPE, ManagedCacheComponent.class);
@@ -38,8 +46,40 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
 
   private final SolrResourceLoader loader;
 
-  public DefaultResourceManagerPluginFactory(SolrResourceLoader loader) {
+  public DefaultResourceManagerPluginFactory(SolrResourceLoader loader, Map<String, Object> config) {
     this.loader = loader;
+    Map<String, String> typeToPluginMap = (Map<String, String>)config.getOrDefault(TYPE_TO_PLUGIN, Collections.emptyMap());
+    Map<String, String> typeToComponentMap = (Map<String, String>)config.getOrDefault(TYPE_TO_COMPONENT, Collections.emptyMap());
+    Map<String, Class<? extends ResourceManagerPlugin>> newPlugins = new HashMap<>();
+    Map<String, Class<? extends ManagedComponent>> newComponents = new HashMap<>();
+    typeToPluginMap.forEach((type, className) -> {
+      try {
+        Class<? extends ResourceManagerPlugin> pluginClazz = loader.findClass(className, ResourceManagerPlugin.class);
+        newPlugins.put(type, pluginClazz);
+      } catch (Exception e) {
+        log.warn("Error finding plugin class", e);
+      }
+    });
+    typeToComponentMap.forEach((type, className) -> {
+      try {
+        Class<? extends ManagedComponent> componentClazz = loader.findClass(className, ManagedComponent.class);
+        if (typeToPluginClass.containsKey(type) || newPlugins.containsKey(type)) {
+          newComponents.put(type, componentClazz);
+        }
+      } catch (Exception e) {
+        log.warn("Error finding plugin class", e);
+        newPlugins.remove(type);
+      }
+    });
+    newPlugins.forEach((type, pluginClass) -> {
+      if (!newComponents.containsKey(type) && !typeToComponentClass.containsKey(type)) {
+        return;
+      }
+      typeToPluginClass.put(type, pluginClass);
+      if (newComponents.containsKey(type)) {
+        typeToComponentClass.put(type, newComponents.get(type));
+      }
+    });
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 1729789..07de310 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -18,7 +18,6 @@ package org.apache.solr.managed;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -37,7 +36,7 @@ import org.slf4j.LoggerFactory;
 public class DefaultResourceManagerPool implements ResourceManagerPool {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private final Map<String, ManagedComponent> resources = new ConcurrentHashMap<>();
+  private final Map<String, ManagedComponent> components = new ConcurrentHashMap<>();
   private Map<String, Object> poolLimits;
   private final String type;
   private final Class<? extends ManagedComponent> componentClass;
@@ -91,23 +90,23 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   @Override
   public void registerComponent(ManagedComponent managedComponent) {
     if (!componentClass.isAssignableFrom(managedComponent.getClass())) {
-      log.debug("Pool type '" + type + "' is not supported by the resource " + managedComponent.getManagedComponentId());
+      log.debug("Pool type '" + type + "' is not supported by the component " + managedComponent.getManagedComponentId());
       return;
     }
-    ManagedComponent existing = resources.putIfAbsent(managedComponent.getManagedComponentId().toString(), managedComponent);
+    ManagedComponent existing = components.putIfAbsent(managedComponent.getManagedComponentId().toString(), managedComponent);
     if (existing != null) {
-      throw new IllegalArgumentException("Resource '" + managedComponent.getManagedComponentId() + "' already exists in pool '" + name + "' !");
+      throw new IllegalArgumentException("Component '" + managedComponent.getManagedComponentId() + "' already exists in pool '" + name + "' !");
     }
   }
 
   @Override
   public boolean unregisterComponent(String name) {
-    return resources.remove(name) != null;
+    return components.remove(name) != null;
   }
 
   @Override
   public Map<String, ManagedComponent> getComponents() {
-    return Collections.unmodifiableMap(resources);
+    return Collections.unmodifiableMap(components);
   }
 
   @Override
@@ -116,7 +115,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
     try {
       // collect the current values
       Map<String, Map<String, Object>> currentValues = new HashMap<>();
-      for (ManagedComponent managedComponent : resources.values()) {
+      for (ManagedComponent managedComponent : components.values()) {
         try {
           currentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
         } catch (Exception e) {
@@ -189,7 +188,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
       scheduledFuture.cancel(true);
       scheduledFuture = null;
     }
-    resources.clear();
+    components.clear();
     poolContext.clear();
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index 064cbe5..d5feda2 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -47,7 +47,7 @@ public class ManagedComponentId {
     return id;
   }
 
-  public ManagedComponentId of(String fullName) {
+  public static ManagedComponentId of(String fullName) {
     if (fullName == null || fullName.isEmpty()) {
       return null;
     }
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index 282fd11..bf43cb1 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -39,6 +39,16 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
+    public Collection<String> getMonitoredParams() {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<String> getControlledParams() {
+      return Collections.emptySet();
+    }
+
+    @Override
     public Map<String, Object> getMonitoredValues(ManagedComponent component) throws Exception {
       return Collections.emptyMap();
     }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index d75cb37..24a6e44 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -109,9 +109,6 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
   public void init(PluginInfo info) {
     if (info != null) {
       this.pluginInfo = info.copy();
-      if (pluginInfo.initArgs != null) {
-        SolrPluginUtils.invokeSetters(this, this.pluginInfo.initArgs);
-      }
     }
     if (!enabled) {
       log.debug("Resource manager " + getClass().getSimpleName() + " disabled.");
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index 61ec2e8..592ba03 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -29,6 +29,17 @@ public interface ResourceManagerPlugin<T extends ManagedComponent> {
 
   void init(Map<String, Object> params);
 
+  /**
+   * Name of monitored parameters that {@link ManagedComponent}-s managed by this plugin
+   * are expected to support.
+   */
+  Collection<String> getMonitoredParams();
+  /**
+   * Name of controlled parameters that {@link ManagedComponent}-s managed by this plugin
+   * are expected to support.
+   */
+  Collection<String> getControlledParams();
+
   Map<String, Object> getMonitoredValues(T component) throws Exception;
 
   default void setResourceLimits(T component, Map<String, Object> limits) throws Exception {
diff --git a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
index 0ee888b..6cd581b 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
@@ -66,6 +66,16 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheCom
   protected float deadBand = DEFAULT_DEAD_BAND;
 
   @Override
+  public Collection<String> getMonitoredParams() {
+    return MONITORED_PARAMS;
+  }
+
+  @Override
+  public Collection<String> getControlledParams() {
+    return CONTROLLED_PARAMS;
+  }
+
+  @Override
   public void setResourceLimit(ManagedCacheComponent component, String limitName, Object val) {
     if (!(val instanceof Number)) {
       try {
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
index 9f65ec2..566fc52 100644
--- a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
@@ -1,24 +1,180 @@
 package org.apache.solr.managed;
 
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.TimeSource;
+import org.apache.solr.core.PluginInfo;
+import org.apache.solr.core.SolrResourceLoader;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
  */
 public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private final int SPEED = 50;
+  private static final int SPEED = 50;
+  private static CountDownLatch manageStartLatch = new CountDownLatch(1);
+  private static CountDownLatch manageFinishLatch = new CountDownLatch(1);
 
   private ResourceManager resourceManager;
+  private SolrResourceLoader loader;
+
+  public interface MockManagedComponent extends ManagedComponent {
+    int getFoo();
+    int getBar();
+    int getBaz();
+    void setFoo(int foo);
+  }
+
+  public static class TestComponent implements MockManagedComponent {
+    ManagedContext context = new ManagedContext();
+    ManagedComponentId id;
+    int foo, bar, baz;
+
+    public TestComponent(String id) {
+      this.id = ManagedComponentId.of(id);
+    }
+
+    @Override
+    public int getFoo() {
+      return foo;
+    }
+
+    @Override
+    public int getBar() {
+      return bar;
+    }
+
+    @Override
+    public int getBaz() {
+      return baz;
+    }
+
+    @Override
+    public void setFoo(int foo) {
+      this.foo = foo;
+      this.bar = foo + 1;
+      this.baz = foo + 2;
+    }
+
+    @Override
+    public ManagedComponentId getManagedComponentId() {
+      return id;
+    }
+
+    @Override
+    public ManagedContext getManagedContext() {
+      return context;
+    }
+  }
+
+  public static class MockManagerPlugin implements ResourceManagerPlugin<MockManagedComponent> {
+
+    public MockManagerPlugin() {
+
+    }
+
+    @Override
+    public String getType() {
+      return "foo";
+    }
+
+    @Override
+    public void init(Map<String, Object> params) {
+
+    }
+
+    @Override
+    public Collection<String> getMonitoredParams() {
+      return Arrays.asList("foo", "bar", "baz");
+    }
+
+    @Override
+    public Collection<String> getControlledParams() {
+      return Collections.singleton("foo");
+    }
+
+    @Override
+    public Map<String, Object> getMonitoredValues(MockManagedComponent component) throws Exception {
+      Map<String, Object> result = new HashMap<>();
+      result.put("bar", component.getBar());
+      result.put("baz", component.getBaz());
+      result.put("foo", component.getFoo());
+      return result;
+    }
+
+    @Override
+    public void setResourceLimit(MockManagedComponent component, String limitName, Object value) throws Exception {
+      if (limitName.equals("foo") && value instanceof Number) {
+        component.setFoo(((Number)value).intValue());
+      } else {
+        throw new Exception("invalid limit name or value");
+      }
+    }
+
+    @Override
+    public Map<String, Object> getResourceLimits(MockManagedComponent component) throws Exception {
+      return Collections.singletonMap("foo", component.getFoo());
+    }
+
+    @Override
+    public void manage(ResourceManagerPool pool) throws Exception {
+      if (manageStartLatch.getCount() == 0) { // already fired
+        return;
+      }
+      manageStartLatch.countDown();
+      log.info("-- managing");
+      pool.getCurrentValues();
+      Map<String, Number> totalValues = pool.getTotalValues();
+      Map<String, Object> poolLimits = pool.getPoolLimits();
+      if (poolLimits.containsKey("foo")) {
+        // manage
+        if (totalValues.containsKey("bar")) {
+          int totalValue = totalValues.get("bar").intValue();
+          int poolLimit = ((Number)poolLimits.get("foo")).intValue();
+          if (totalValue > poolLimit) {
+            for (ManagedComponent cmp : pool.getComponents().values()) {
+              TestComponent component = (TestComponent)cmp;
+              int foo = component.getFoo();
+              if (foo > 0) {
+                component.setFoo(--foo);
+              }
+            }
+          }
+        }
+      }
+      manageFinishLatch.countDown();
+    }
+  }
 
   @Before
   public void initManager() {
-    resourceManager = new DefaultResourceManager(h.getCoreContainer().getResourceLoader(), TimeSource.get("simTime:" + SPEED));
+    loader = new SolrResourceLoader(TEST_PATH());
+    resourceManager = new DefaultResourceManager(loader, TimeSource.get("simTime:" + SPEED));
+    Map<String, Object> initArgs = new HashMap<>();
+    Map<String, Object> config = new HashMap<>();
+    initArgs.put("plugins", config);
+    Map<String, String> plugins = new HashMap<>();
+    Map<String, String> components = new HashMap<>();
+    config.put(DefaultResourceManagerPluginFactory.TYPE_TO_PLUGIN, plugins);
+    config.put(DefaultResourceManagerPluginFactory.TYPE_TO_COMPONENT, components);
+    plugins.put("mock", MockManagerPlugin.class.getName());
+    components.put("mock", MockManagedComponent.class.getName());
+    resourceManager.init(new PluginInfo("resourceManager", initArgs));
   }
 
   @After
@@ -30,7 +186,60 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
   }
 
   @Test
-  public void testBasicRegistration() throws Exception {
+  public void testBasic() throws Exception {
+    // let it run
+    manageStartLatch.countDown();
 
+    resourceManager.createPool("test", "mock", Collections.singletonMap("foo", 10), Collections.emptyMap());
+    assertNotNull(resourceManager.getPool("test"));
+    for (int i = 0; i < 10; i++) {
+      TestComponent component = new TestComponent("test.component." + i);
+      component.setFoo(i);
+      resourceManager.registerComponent("test", component);
+    }
+    ResourceManagerPool pool = resourceManager.getPool("test");
+    assertEquals(10, pool.getComponents().size());
+    pool.getCurrentValues();
+    Map<String, Number> totalValues = pool.getTotalValues();
+    assertNotNull(totalValues.get("bar"));
+    assertEquals(55, totalValues.get("bar").intValue());
+    assertNotNull(totalValues.get("baz"));
+    assertEquals(65, totalValues.get("baz").intValue());
+    for (ManagedComponent cmp : pool.getComponents().values()) {
+      TestComponent component = (TestComponent)cmp;
+      Map<String, Object> limits = pool.getResourceManagerPlugin().getResourceLimits(component);
+      assertEquals(1, limits.size());
+      assertNotNull(limits.get("foo"));
+      String name = component.getManagedComponentId().getName();
+      int val = Integer.parseInt(name);
+      assertEquals("foo", val, component.getFoo());
+      assertEquals("bar", val + 1, component.getBar());
+      assertEquals("baz", val + 2, component.getBaz());
+    }
+    // set pool limits
+    resourceManager.setPoolLimits("test", Collections.singletonMap("foo", 50));
+    manageFinishLatch = new CountDownLatch(1);
+    manageStartLatch = new CountDownLatch(1);
+    boolean await = manageFinishLatch.await(30000 / SPEED, TimeUnit.MILLISECONDS);
+    assertTrue("did not finish in time", await);
+    pool.getCurrentValues();
+    totalValues = pool.getTotalValues();
+    assertNotNull(totalValues.get("bar"));
+    assertEquals(46, totalValues.get("bar").intValue());
+    assertNotNull(totalValues.get("baz"));
+    assertEquals(56, totalValues.get("baz").intValue());
+    int changed = 0;
+    for (ManagedComponent cmp : pool.getComponents().values()) {
+      TestComponent component = (TestComponent)cmp;
+      Map<String, Object> limits = pool.getResourceManagerPlugin().getResourceLimits(component);
+      assertEquals(1, limits.size());
+      assertNotNull(limits.get("foo"));
+      String name = component.getManagedComponentId().getName();
+      int val = Integer.parseInt(name);
+      if (val > component.getFoo()) {
+        changed++;
+      }
+    }
+    assertTrue(changed > 0);
   }
 }


[lucene-solr] 34/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit f1ebfdcbafb84373c103a3917ff2660ac2faa989
Merge: 5932e53 b5a2cfb
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Mon Dec 16 16:00:08 2019 +0100

    Merge branch 'master' into jira/solr-13579

 .github/PULL_REQUEST_TEMPLATE.md                   |    3 +-
 dev-tools/doap/lucene.rdf                          |    7 +
 dev-tools/doap/solr.rdf                            |    7 +
 lucene/CHANGES.txt                                 |   68 +-
 lucene/MIGRATE.txt                                 |    5 +
 .../analysis/charfilter/NormalizeCharMap.java      |    7 +-
 .../lucene/analysis/hunspell/Dictionary.java       |   22 +-
 .../miscellaneous/StemmerOverrideFilter.java       |    7 +-
 .../apache/lucene/analysis/synonym/SynonymMap.java |    9 +-
 .../lucene/analysis/hunspell/TestDictionary.java   |   14 +-
 .../org/apache/lucene/analysis/hunspell/broken.aff |    2 +-
 .../lucene/analysis/hunspell/complexprefix.aff     |    2 +-
 .../org/apache/lucene/analysis/hunspell/conv.aff   |    2 +-
 .../lucene/analysis/hunspell/dependencies.aff      |    2 +-
 .../apache/lucene/analysis/hunspell/homonyms.dic   |    2 +-
 .../org/apache/lucene/analysis/hunspell/ignore.aff |    2 +-
 .../org/apache/lucene/analysis/hunspell/ignore.dic |    2 +-
 .../apache/lucene/analysis/hunspell/keepcase.dic   |    2 +-
 .../apache/lucene/analysis/hunspell/needaffix.dic  |    2 +-
 .../analysis/hunspell/optional-condition.aff       |    2 +-
 .../org/apache/lucene/analysis/hunspell/simple.aff |    2 +-
 .../lucene/analysis/ja/dict/UserDictionary.java    |    8 +-
 .../ja/util/TokenInfoDictionaryBuilder.java        |    8 +-
 .../lucene/analysis/ko/dict/UserDictionary.java    |    8 +-
 .../ko/util/TokenInfoDictionaryBuilder.java        |    8 +-
 .../lucene/index/TestBackwardsCompatibility.java   |    7 +-
 .../org/apache/lucene/index/index.8.3.1-cfs.zip    |  Bin 0 -> 15677 bytes
 .../org/apache/lucene/index/index.8.3.1-nocfs.zip  |  Bin 0 -> 15696 bytes
 .../test/org/apache/lucene/index/sorted.8.3.1.zip  |  Bin 0 -> 87919 bytes
 lucene/build.xml                                   |    2 +-
 .../BooleanPerceptronClassifier.java               |    8 +-
 .../blockterms/VariableGapTermsIndexWriter.java    |   12 +-
 .../blocktreeords/OrdsBlockTreeTermsWriter.java    |   16 +-
 .../lucene/codecs/memory/DirectPostingsFormat.java |    2 +-
 .../lucene/codecs/memory/FSTOrdTermsWriter.java    |   10 +-
 .../lucene/codecs/memory/FSTTermsWriter.java       |   10 +-
 .../codecs/simpletext/SimpleTextFieldsReader.java  |   12 +-
 .../lucene/codecs/uniformsplit/FSTDictionary.java  |    9 +-
 lucene/common-build.xml                            |    1 -
 lucene/core/build.xml                              |    1 -
 .../org/apache/lucene/analysis/CharacterUtils.java |    4 +-
 .../tokenattributes/TermFrequencyAttribute.java    |    2 +-
 .../TermFrequencyAttributeImpl.java                |    2 +-
 .../codecs/CompetitiveImpactAccumulator.java       |    2 +-
 .../codecs/blocktree/BlockTreeTermsReader.java     |   25 +-
 .../codecs/blocktree/BlockTreeTermsWriter.java     |   16 +-
 .../codecs/blocktree/IntersectTermsEnum.java       |    2 +-
 .../apache/lucene/codecs/lucene80/IndexedDISI.java |    2 +-
 .../codecs/perfield/PerFieldPostingsFormat.java    |   65 +-
 .../java/org/apache/lucene/geo/Component2D.java    |   27 +
 .../java/org/apache/lucene/geo/ComponentTree.java  |    9 +
 .../src/java/org/apache/lucene/geo/EdgeTree.java   |   44 +-
 .../src/java/org/apache/lucene/geo/Polygon2D.java  |   65 +-
 .../lucene/geo/SimpleGeoJSONPolygonParser.java     |    2 +-
 .../org/apache/lucene/index/DocValuesIterator.java |    2 +-
 .../lucene/index/DocumentsWriterPerThread.java     |    2 +-
 .../java/org/apache/lucene/index/FieldInfos.java   |    2 +-
 .../apache/lucene/index/FieldUpdatesBuffer.java    |    4 +-
 .../org/apache/lucene/index/SegmentWriteState.java |    2 +-
 .../org/apache/lucene/search/AutomatonQuery.java   |    4 +-
 .../lucene/search/DocValuesFieldExistsQuery.java   |    2 +-
 .../java/org/apache/lucene/search/FuzzyQuery.java  |   13 +-
 .../org/apache/lucene/search/IndexSearcher.java    |   12 +-
 .../org/apache/lucene/search/LRUQueryCache.java    |   76 +-
 .../org/apache/lucene/search/MultiTermQuery.java   |   11 +-
 .../java/org/apache/lucene/search/PhraseQuery.java |   16 +
 .../java/org/apache/lucene/search/QueryCache.java  |    5 +-
 .../org/apache/lucene/search/QueryVisitor.java     |   15 +-
 .../org/apache/lucene/search/ReferenceManager.java |    2 +-
 .../lucene/search/similarities/BM25Similarity.java |   28 +-
 .../src/java/org/apache/lucene/util/Version.java   |   14 +
 .../apache/lucene/util/automaton/Automaton.java    |    2 +-
 .../lucene/util/automaton/ByteRunAutomaton.java    |    1 -
 .../util/automaton/CharacterRunAutomaton.java      |    2 +-
 .../lucene/util/automaton/CompiledAutomaton.java   |   28 +-
 .../TooComplexToDeterminizeException.java          |    2 +-
 .../src/java/org/apache/lucene/util/fst/FST.java   |  251 +--
 .../util/fst/{Builder.java => FSTCompiler.java}    |  289 ++--
 .../java/org/apache/lucene/util/fst/NodeHash.java  |   16 +-
 .../util/packed/MonotonicBlockPackedWriter.java    |    2 +-
 .../org/apache/lucene/util/packed/PackedInts.java  |    2 +-
 .../apache/lucene/analysis/TestCharacterUtils.java |   11 +
 .../test/org/apache/lucene/geo/TestPolygon.java    |    2 +-
 .../apache/lucene/search/TestIndexSearcher.java    |    7 +-
 .../apache/lucene/search/TestLRUQueryCache.java    |  607 +------
 .../test/org/apache/lucene/util/fst/Test2BFST.java |   35 +-
 ...ddressing.java => TestFSTDirectAddressing.java} |   53 +-
 .../test/org/apache/lucene/util/fst/TestFSTs.java  |  158 +-
 .../test/org/apache/lucene/util/fst/TestUtil.java  |   10 +-
 .../apache/lucene/search/grouping/TopGroups.java   |   21 +-
 .../lucene/search/grouping/TopGroupsTest.java      |   10 +-
 ...OpOffsetStrategy.java => CharArrayMatcher.java} |   39 +-
 .../search/uhighlight/FieldOffsetStrategy.java     |   13 +-
 .../uhighlight/LabelledCharArrayMatcher.java       |   88 ++
 .../uhighlight/MemoryIndexOffsetStrategy.java      |   32 +-
 .../search/uhighlight/MultiTermHighlighting.java   |   91 +-
 .../search/uhighlight/NoOpOffsetStrategy.java      |    4 +-
 .../uhighlight/TokenStreamOffsetStrategy.java      |   24 +-
 .../lucene/search/uhighlight/UHComponents.java     |    7 +-
 .../search/uhighlight/UnifiedHighlighter.java      |    7 +-
 .../lucene/search/highlight/TokenSourcesTest.java  |    2 +-
 .../TestUnifiedHighlighterExtensibility.java       |    6 +-
 lucene/ivy-versions.properties                     |   12 +-
 lucene/licenses/jcl-over-slf4j-LICENSE-MIT.txt     |   21 -
 lucene/licenses/jcl-over-slf4j-NOTICE.txt          |   25 -
 .../jetty-continuation-9.4.19.v20190610.jar.sha1   |    1 -
 .../jetty-continuation-9.4.24.v20191120.jar.sha1   |    1 +
 .../licenses/jetty-http-9.4.19.v20190610.jar.sha1  |    1 -
 .../licenses/jetty-http-9.4.24.v20191120.jar.sha1  |    1 +
 lucene/licenses/jetty-io-9.4.19.v20190610.jar.sha1 |    1 -
 lucene/licenses/jetty-io-9.4.24.v20191120.jar.sha1 |    1 +
 .../jetty-server-9.4.19.v20190610.jar.sha1         |    1 -
 .../jetty-server-9.4.24.v20191120.jar.sha1         |    1 +
 .../jetty-servlet-9.4.19.v20190610.jar.sha1        |    1 -
 .../jetty-servlet-9.4.24.v20191120.jar.sha1        |    1 +
 .../licenses/jetty-util-9.4.19.v20190610.jar.sha1  |    1 -
 .../licenses/jetty-util-9.4.24.v20191120.jar.sha1  |    1 +
 lucene/licenses/log4j-LICENSE-ASL.txt              |  202 ---
 lucene/licenses/log4j-NOTICE.txt                   |    5 -
 .../randomizedtesting-runner-2.7.2.jar.sha1        |    1 -
 .../randomizedtesting-runner-2.7.5.jar.sha1        |    1 +
 lucene/licenses/slf4j-LICENSE-MIT.txt              |   21 -
 lucene/licenses/slf4j-NOTICE.txt                   |   25 -
 lucene/licenses/slf4j-api-1.7.24.jar.sha1          |    1 -
 .../org/apache/lucene/util/fst/ListOfOutputs.java  |    4 +-
 .../lucene/util/fst/UpToTwoPositiveIntOutputs.java |    4 +-
 .../org/apache/lucene/util/fst/TestFSTsMisc.java   |   34 +-
 lucene/module-build.xml                            |    1 -
 .../lucene/queries/intervals/IntervalQuery.java    |    7 +-
 .../queries/intervals/IntervalScoreFunction.java   |    4 +-
 .../intervals/MultiTermIntervalsSource.java        |    2 +-
 .../queries/intervals/TestIntervalQuery.java       |   20 +
 lucene/replicator/build.xml                        |    2 +-
 .../idversion/VersionBlockTreeTermsWriter.java     |   17 +-
 .../org/apache/lucene/document/LatLonShape.java    |   23 +
 .../document/LatLonShapeBoundingBoxQuery.java      |   11 +
 .../lucene/document/LatLonShapeLineQuery.java      |   16 +-
 .../lucene/document/LatLonShapePolygonQuery.java   |   14 +
 .../org/apache/lucene/document/ShapeField.java     |    2 +-
 .../org/apache/lucene/document/ShapeQuery.java     |   72 +-
 .../java/org/apache/lucene/document/XYShape.java   |   16 +
 .../lucene/document/XYShapeBoundingBoxQuery.java   |   81 +-
 .../apache/lucene/document/XYShapeLineQuery.java   |   14 +
 .../lucene/document/XYShapePolygonQuery.java       |   14 +
 .../src/java/org/apache/lucene/geo/Line2D.java     |   51 +
 .../java/org/apache/lucene/geo/Rectangle2D.java    |   60 +
 .../java/org/apache/lucene/geo/XYRectangle2D.java  |  218 ++-
 .../apache/lucene/search/PhraseWildcardQuery.java  | 1045 +++++++++++++
 .../lucene/document/BaseLatLonShapeTestCase.java   |   10 +
 .../apache/lucene/document/BaseShapeTestCase.java  |   29 +-
 .../lucene/document/BaseXYShapeTestCase.java       |    9 +
 .../document/TestLatLonLineShapeQueries.java       |   28 +
 .../document/TestLatLonMultiLineShapeQueries.java  |    8 +-
 .../document/TestLatLonMultiPointShapeQueries.java |    8 +-
 .../TestLatLonMultiPolygonShapeQueries.java        |   39 +-
 .../document/TestLatLonPointShapeQueries.java      |    6 +
 .../document/TestLatLonPolygonShapeQueries.java    |   41 +-
 .../apache/lucene/document/TestLatLonShape.java    |  171 ++
 .../lucene/document/TestXYLineShapeQueries.java    |   34 +-
 .../document/TestXYMultiLineShapeQueries.java      |   22 +-
 .../document/TestXYMultiPointShapeQueries.java     |   22 +-
 .../document/TestXYMultiPolygonShapeQueries.java   |   53 +-
 .../lucene/document/TestXYPointShapeQueries.java   |   21 +-
 .../lucene/document/TestXYPolygonShapeQueries.java |   46 +-
 .../org/apache/lucene/document/TestXYShape.java    |   56 +
 .../src/test/org/apache/lucene/geo/TestLine2D.java |    8 +-
 .../org/apache/lucene/geo/TestRectangle2D.java     |   58 +-
 .../org/apache/lucene/geo/TestXYRectangle2D.java   |   88 ++
 .../lucene/search/TestPhraseWildcardQuery.java     |  583 +++++++
 lucene/spatial-extras/ivy.xml                      |    4 +-
 .../suggest/analyzing/AnalyzingSuggester.java      |   10 +-
 .../suggest/analyzing/FreeTextSuggester.java       |    8 +-
 .../suggest/document/NRTSuggesterBuilder.java      |   14 +-
 .../search/suggest/fst/FSTCompletionBuilder.java   |   13 +-
 .../search/suggest/fst/WFSTCompletionLookup.java   |    8 +-
 lucene/test-framework/build.xml                    |    1 -
 .../apache/lucene/util/TestSecurityManager.java    |    4 +-
 .../java/org/apache/lucene/util/fst/FSTTester.java |   29 +-
 lucene/tools/custom-tasks.xml                      |    2 +-
 lucene/tools/junit4/replicator-tests.policy        |   91 ++
 lucene/tools/junit4/solr-tests.policy              |  145 +-
 solr/CHANGES.txt                                   |  179 ++-
 solr/bin/solr                                      |    4 +-
 solr/bin/solr.cmd                                  |    2 +
 solr/build.xml                                     |    2 +-
 solr/common-build.xml                              |    9 +-
 .../solr/analytics/AnalyticsRequestManager.java    |   11 +
 .../solr/analytics/TimeExceededStubException.java} |   25 +-
 .../stream/AnalyticsShardRequestManager.java       |   10 +-
 .../org/apache/solr/handler/AnalyticsHandler.java  |   13 +
 .../solr/handler/component/AnalyticsComponent.java |    4 +
 .../solr/analytics/ExpressionFactoryTest.java      |    6 +
 .../function/field/AbstractAnalyticsFieldTest.java |    3 +
 .../legacy/LegacyAbstractAnalyticsCloudTest.java   |   32 +-
 .../legacy/LegacyAbstractAnalyticsTest.java        |    4 +
 .../analytics/legacy/LegacyNoFacetCloudTest.java   |    8 +-
 .../legacy/facet/LegacyFieldFacetCloudTest.java    |    7 +-
 .../facet/LegacyFieldFacetExtrasCloudTest.java     |    6 +-
 .../legacy/facet/LegacyFieldFacetTest.java         |   17 +
 .../TestSolrEntityProcessorEndToEnd.java           |    2 +-
 .../LanguageIdentifierUpdateProcessor.java         |   22 +-
 ...geIdentifierUpdateProcessorFactoryTestCase.java |   21 -
 .../solr/prometheus/scraper/SolrCloudScraper.java  |    7 +-
 .../scraper/SolrStandaloneScraperTest.java         |    2 +
 .../solr/response/SolrParamResourceLoader.java     |   73 -
 .../solr/response/VelocityResponseWriter.java      |  179 ++-
 .../velocity/solr/collection1/conf/solrconfig.xml  |    3 -
 .../solr/collection1/conf/velocity/custom_tool.vm  |    1 -
 .../solr/collection1/conf/velocity/foreach.vm      |    1 -
 .../collection1/conf/velocity/locale_number.vm     |    1 +
 .../collection1/conf/velocity/outside_the_box.vm   |    4 +
 .../conf/velocity/sandbox_intersection.vm          |    5 +
 solr/contrib/velocity/src/test/custom_tool.vm      |   19 +
 solr/contrib/velocity/src/test/foreach.vm          |   14 +
 .../solr/velocity/VelocityResponseWriterTest.java  |  172 +-
 solr/core/ivy.xml                                  |    1 +
 .../apache/solr/cloud/ExclusiveSliceProperty.java  |    2 +-
 .../solr/cloud/RecoveringCoreTermWatcher.java      |    3 +-
 .../java/org/apache/solr/cloud/ZkShardTerms.java   |  259 +--
 .../cloud/api/collections/CreateCollectionCmd.java |    2 +-
 .../solr/cloud/api/collections/RestoreCmd.java     |   30 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |   49 +-
 .../autoscaling/sim/SimClusterStateProvider.java   |   12 +-
 .../solr/cloud/autoscaling/sim/SimScenario.java    |   29 +-
 .../solr/cloud/overseer/ClusterStateMutator.java   |    4 +-
 .../solr/cloud/overseer/CollectionMutator.java     |    2 +-
 .../apache/solr/cloud/overseer/NodeMutator.java    |    4 +-
 .../apache/solr/cloud/overseer/ReplicaMutator.java |   25 +-
 .../apache/solr/cloud/overseer/SliceMutator.java   |   14 +-
 .../org/apache/solr/core/ConfigSetService.java     |    7 +-
 .../java/org/apache/solr/core/CoreContainer.java   |   17 +
 .../src/java/org/apache/solr/core/SolrConfig.java  |   59 +-
 .../org/apache/solr/filestore/PackageStoreAPI.java |    4 +
 .../apache/solr/handler/RequestHandlerBase.java    |   21 +-
 .../org/apache/solr/handler/StreamHandler.java     |   22 +
 .../solr/handler/admin/HealthCheckHandler.java     |    2 +-
 .../solr/handler/component/ExpandComponent.java    |   39 +-
 .../solr/handler/component/HttpShardHandler.java   |    9 +-
 .../solr/handler/component/SearchHandler.java      |    2 +-
 .../apache/solr/handler/loader/JavabinLoader.java  |    1 -
 .../solr/metrics/reporters/SolrSlf4jReporter.java  |    2 +-
 .../solr/metrics/reporters/solr/SolrReporter.java  |    8 +-
 .../packagemanager/DefaultPackageRepository.java   |    5 +-
 .../apache/solr/packagemanager/PackageManager.java |   85 +-
 .../apache/solr/packagemanager/PackageUtils.java   |    7 +
 .../solr/packagemanager/RepositoryManager.java     |   30 +-
 .../src/java/org/apache/solr/pkg/PackageAPI.java   |    8 +-
 .../org/apache/solr/response/DocsStreamer.java     |    7 +-
 .../org/apache/solr/schema/FieldProperties.java    |    7 +-
 .../src/java/org/apache/solr/schema/FieldType.java |    2 -
 .../java/org/apache/solr/schema/IndexSchema.java   |    5 +-
 .../solr/schema/LatLonPointSpatialField.java       |   11 +-
 .../java/org/apache/solr/schema/SchemaField.java   |   20 +-
 .../solr/search/CollapsingQParserPlugin.java       |    6 +
 .../org/apache/solr/search/ValueSourceParser.java  |   31 +-
 .../java/org/apache/solr/search/facet/AggUtil.java |   65 +
 .../java/org/apache/solr/search/facet/AvgAgg.java  |  200 ++-
 .../org/apache/solr/search/facet/DocValuesAcc.java |  245 ++-
 .../java/org/apache/solr/search/facet/HLLAgg.java  |   12 +-
 .../org/apache/solr/search/facet/MinMaxAgg.java    |  190 ++-
 .../apache/solr/search/facet/PercentileAgg.java    |  292 +++-
 .../java/org/apache/solr/search/facet/SlotAcc.java |   21 +-
 .../org/apache/solr/search/facet/StddevAgg.java    |   72 +-
 .../java/org/apache/solr/search/facet/SumAgg.java  |   86 +-
 .../org/apache/solr/search/facet/SumsqAgg.java     |   86 +-
 .../solr/search/facet/UnInvertedFieldAcc.java      |  113 ++
 .../org/apache/solr/search/facet/UniqueAgg.java    |   12 +-
 .../org/apache/solr/search/facet/VarianceAgg.java  |   72 +-
 .../java/org/apache/solr/security/AuditEvent.java  |  135 +-
 .../apache/solr/update/DirectUpdateHandler2.java   |    6 +
 .../org/apache/solr/update/DocumentBuilder.java    |    4 +-
 .../org/apache/solr/update/SolrCmdDistributor.java |   12 +-
 .../apache/solr/update/StreamingSolrClients.java   |    7 +-
 .../processor/AtomicUpdateDocumentMerger.java      |    2 +-
 .../src/java/org/apache/solr/util/FSHDFSUtils.java |    2 +-
 .../src/java/org/apache/solr/util/PackageTool.java |   18 +-
 .../java/org/apache/solr/util/SimplePostTool.java  |   64 +-
 .../java/org/apache/solr/util/TestInjection.java   |   15 +
 .../src/test-files/core-site.xml}                  |   16 +-
 .../test-files/runtimecode/TestVersionedURP.java   |    1 +
 .../solr/collection1/conf/schema-nest.xml          |    4 +
 .../test-files/solr/collection1/conf/schema.xml    |    1 +
 .../collection1/conf/schema_postingsformat.xml     |   41 +
 .../solr/configsets/_default/conf/params.json      |   20 -
 .../solr/configsets/_default/conf/solrconfig.xml   |  152 +-
 .../upload/with-lib-directive/managed-schema       |   25 +
 .../upload/with-lib-directive/solrconfig.xml       |   53 +
 .../src/test/org/apache/hadoop/fs/FileUtil.java    | 1653 ++++++++++++++++++++
 .../src/test/org/apache/hadoop/fs/HardLink.java    |  183 +++
 .../org/apache/hadoop/fs/RawLocalFileSystem.java   | 1046 +++++++++++++
 .../datanode/fsdataset/impl/BlockPoolSlice.java    |  117 +-
 .../server/namenode/NameNodeResourceChecker.java   |   56 +
 .../test/org/apache/hadoop/http/HttpServer2.java   |    7 +-
 .../src/test/org/apache/hadoop/package-info.java   |   39 +
 .../test/org/apache/hadoop/util/DiskChecker.java   |  372 +++++
 .../apache/solr/cloud/ClusterStateMockUtil.java    |   12 +-
 .../org/apache/solr/cloud/ClusterStateTest.java    |    8 +-
 .../solr/cloud/CreateCollectionCleanupTest.java    |   19 +-
 .../cloud/FullThrottleStoppableIndexingThread.java |    3 +
 .../solr/cloud/LegacyCloudClusterPropTest.java     |    3 +-
 .../OverseerCollectionConfigSetProcessorTest.java  |    5 +-
 .../test/org/apache/solr/cloud/OverseerTest.java   |    2 +
 .../apache/solr/cloud/PackageManagerCLITest.java   |    9 +-
 .../cloud/SharedFSAutoReplicaFailoverTest.java     |   10 +-
 .../test/org/apache/solr/cloud/SliceStateTest.java |   14 +-
 .../org/apache/solr/cloud/TestConfigSetsAPI.java   |   47 +-
 .../cloud/TestDynamicFieldNamesIndexCorrectly.java |    2 +-
 .../org/apache/solr/cloud/TestHashPartitioner.java |    2 +-
 .../TestSolrCloudWithSecureImpersonation.java      |   76 +-
 .../org/apache/solr/cloud/TestWithCollection.java  |    6 +
 .../org/apache/solr/cloud/ZkShardTermsTest.java    |    3 +-
 .../solr/cloud/api/collections/AssignTest.java     |   18 +-
 .../ConcurrentCreateCollectionTest.java            |  293 ++++
 .../cloud/api/collections/SplitByPrefixTest.java   |   19 +
 .../cloud/autoscaling/ComputePlanActionTest.java   |    6 +
 .../IndexSizeTriggerMixedBoundsTest.java           |  391 +++++
 .../IndexSizeTriggerSizeEstimationTest.java        |  320 ++++
 .../cloud/autoscaling/IndexSizeTriggerTest.java    |  474 +-----
 .../NodeAddedTriggerIntegrationTest.java           |    6 +
 .../NodeLostTriggerIntegrationTest.java            |    6 +
 .../SearchRateTriggerIntegrationTest.java          |    6 +
 .../cloud/autoscaling/TriggerIntegrationTest.java  |    6 +
 .../sim/TestSimClusterStateProvider.java           |    1 +
 .../cloud/autoscaling/sim/TestSimScenario.java     |   32 +-
 .../autoscaling/sim/TestSnapshotCloudManager.java  |   10 +
 .../apache/solr/cloud/hdfs/FakeGroupMapping.java}  |   23 +-
 .../solr/cloud/hdfs/HDFSCollectionsAPITest.java    |    4 +-
 .../cloud/hdfs/HdfsBasicDistributedZk2Test.java    |   11 +-
 .../solr/cloud/hdfs/HdfsRecoverLeaseTest.java      |    7 +-
 .../apache/solr/cloud/hdfs/HdfsSyncSliceTest.java  |    7 +-
 .../org/apache/solr/cloud/hdfs/HdfsTestUtil.java   |  122 +-
 .../hdfs/HdfsWriteToMultipleCollectionsTest.java   |    1 +
 .../test/org/apache/solr/cloud/rule/RulesTest.java |    9 +-
 .../test/org/apache/solr/core/CoreSorterTest.java  |    2 +-
 .../test/org/apache/solr/core/SolrCoreTest.java    |   12 +-
 .../src/test/org/apache/solr/core/TestConfig.java  |   12 +-
 .../org/apache/solr/core/TestJmxIntegration.java   |    1 +
 .../solr/filestore/TestDistribPackageStore.java    |   19 +-
 .../solr/handler/admin/CoreAdminHandlerTest.java   |   11 +-
 .../handler/admin/MetricsHistoryHandlerTest.java   |    5 +
 .../component/CustomTermsComponentTest.java        |    2 +-
 .../component/DistributedDebugComponentTest.java   |    2 +-
 .../solr/handler/component/StatsComponentTest.java |  143 +-
 .../handler/component/TestExpandComponent.java     |   22 +-
 .../tagger/EmbeddedSolrNoSerializeTest.java        |    6 +
 .../solr/handler/tagger/XmlInterpolationTest.java  |    6 +
 .../apache/solr/index/hdfs/CheckHdfsIndexTest.java |    1 +
 .../src/test/org/apache/solr/pkg/TestPackages.java |   13 +-
 .../test/org/apache/solr/schema/DateFieldTest.java |    3 +-
 .../apache/solr/schema/PrimitiveFieldTypeTest.java |    3 +-
 .../solr/schema/TestManagedSchemaThreadSafety.java |    2 +-
 .../org/apache/solr/schema/TestSchemaField.java    |   84 +
 .../solr/search/TestCollapseQParserPlugin.java     |   18 +-
 .../org/apache/solr/search/TestRecoveryHdfs.java   |   33 +-
 ...stributedFacetSimpleRefinementLongTailTest.java |   34 +-
 .../apache/solr/search/facet/TestJsonFacets.java   |  154 +-
 .../solr/search/join/TestCloudNestedDocsSort.java  |    6 +
 .../solr/security/AuditLoggerPluginTest.java       |   23 +-
 .../security/JWTAuthPluginIntegrationTest.java     |    3 +-
 .../hadoop/TestDelegationWithHadoopAuth.java       |    9 +-
 .../hadoop/TestImpersonationWithHadoopAuth.java    |    6 +-
 .../hadoop/TestSolrCloudWithHadoopAuthPlugin.java  |    4 +-
 .../security/hadoop/TestZkAclsWithHadoopAuth.java  |   26 +-
 .../apache/solr/store/hdfs/HdfsDirectoryTest.java  |    7 +-
 .../solr/store/hdfs/HdfsLockFactoryTest.java       |    7 +-
 .../apache/solr/update/SolrCmdDistributorTest.java |   39 +-
 .../apache/solr/update/SolrIndexConfigTest.java    |   12 +-
 .../org/apache/solr/update/TestHdfsUpdateLog.java  |    2 +-
 .../CategoryRoutedAliasUpdateProcessorTest.java    |    6 +
 .../DimensionalRoutedAliasUpdateProcessorTest.java |    1 +
 .../update/processor/NestedAtomicUpdateTest.java   |   23 +-
 .../org/apache/solr/util/SimplePostToolTest.java   |    7 +-
 .../org/apache/solr/util/TestSystemIdResolver.java |    1 +
 .../solr/solr/conf/solr-data-config.xml            |    2 +-
 solr/licenses/carrot2-mini-3.16.0.jar.sha1         |    1 -
 solr/licenses/carrot2-mini-3.16.2.jar.sha1         |    1 +
 .../http2-client-9.4.19.v20190610.jar.sha1         |    1 -
 .../http2-client-9.4.24.v20191120.jar.sha1         |    1 +
 .../http2-common-9.4.19.v20190610.jar.sha1         |    1 -
 .../http2-common-9.4.24.v20191120.jar.sha1         |    1 +
 .../licenses/http2-hpack-9.4.19.v20190610.jar.sha1 |    1 -
 .../licenses/http2-hpack-9.4.24.v20191120.jar.sha1 |    1 +
 ...http-client-transport-9.4.19.v20190610.jar.sha1 |    1 -
 ...http-client-transport-9.4.24.v20191120.jar.sha1 |    1 +
 .../http2-server-9.4.19.v20190610.jar.sha1         |    1 -
 .../http2-server-9.4.24.v20191120.jar.sha1         |    1 +
 solr/licenses/jackson-annotations-2.10.0.jar.sha1  |    1 +
 solr/licenses/jackson-annotations-2.9.9.jar.sha1   |    1 -
 solr/licenses/jackson-core-2.10.0.jar.sha1         |    1 +
 solr/licenses/jackson-core-2.9.9.jar.sha1          |    1 -
 solr/licenses/jackson-databind-2.10.0.jar.sha1     |    1 +
 solr/licenses/jackson-databind-2.9.9.3.jar.sha1    |    1 -
 .../jackson-dataformat-smile-2.10.0.jar.sha1       |    1 +
 .../jackson-dataformat-smile-2.9.9.jar.sha1        |    1 -
 .../jetty-alpn-client-9.4.19.v20190610.jar.sha1    |    1 -
 .../jetty-alpn-client-9.4.24.v20191120.jar.sha1    |    1 +
 ...etty-alpn-java-client-9.4.19.v20190610.jar.sha1 |    1 -
 ...etty-alpn-java-client-9.4.24.v20191120.jar.sha1 |    1 +
 ...etty-alpn-java-server-9.4.19.v20190610.jar.sha1 |    1 -
 ...etty-alpn-java-server-9.4.24.v20191120.jar.sha1 |    1 +
 .../jetty-alpn-server-9.4.19.v20190610.jar.sha1    |    1 -
 .../jetty-alpn-server-9.4.24.v20191120.jar.sha1    |    1 +
 .../jetty-client-9.4.19.v20190610.jar.sha1         |    1 -
 .../jetty-client-9.4.24.v20191120.jar.sha1         |    1 +
 .../jetty-continuation-9.4.19.v20190610.jar.sha1   |    1 -
 .../jetty-continuation-9.4.24.v20191120.jar.sha1   |    1 +
 .../jetty-deploy-9.4.19.v20190610.jar.sha1         |    1 -
 .../jetty-deploy-9.4.24.v20191120.jar.sha1         |    1 +
 solr/licenses/jetty-http-9.4.19.v20190610.jar.sha1 |    1 -
 solr/licenses/jetty-http-9.4.24.v20191120.jar.sha1 |    1 +
 solr/licenses/jetty-io-9.4.19.v20190610.jar.sha1   |    1 -
 solr/licenses/jetty-io-9.4.24.v20191120.jar.sha1   |    1 +
 solr/licenses/jetty-jmx-9.4.19.v20190610.jar.sha1  |    1 -
 solr/licenses/jetty-jmx-9.4.24.v20191120.jar.sha1  |    1 +
 .../jetty-rewrite-9.4.19.v20190610.jar.sha1        |    1 -
 .../jetty-rewrite-9.4.24.v20191120.jar.sha1        |    1 +
 .../jetty-security-9.4.19.v20190610.jar.sha1       |    1 -
 .../jetty-security-9.4.24.v20191120.jar.sha1       |    1 +
 .../jetty-server-9.4.19.v20190610.jar.sha1         |    1 -
 .../jetty-server-9.4.24.v20191120.jar.sha1         |    1 +
 .../jetty-servlet-9.4.19.v20190610.jar.sha1        |    1 -
 .../jetty-servlet-9.4.24.v20191120.jar.sha1        |    1 +
 .../jetty-servlets-9.4.19.v20190610.jar.sha1       |    1 -
 .../jetty-servlets-9.4.24.v20191120.jar.sha1       |    1 +
 solr/licenses/jetty-util-9.4.19.v20190610.jar.sha1 |    1 -
 solr/licenses/jetty-util-9.4.24.v20191120.jar.sha1 |    1 +
 .../jetty-webapp-9.4.19.v20190610.jar.sha1         |    1 -
 .../jetty-webapp-9.4.24.v20191120.jar.sha1         |    1 +
 solr/licenses/jetty-xml-9.4.19.v20190610.jar.sha1  |    1 -
 solr/licenses/jetty-xml-9.4.24.v20191120.jar.sha1  |    1 +
 solr/licenses/junit4-ant-2.7.2.jar.sha1            |    1 -
 solr/licenses/junit4-ant-2.7.5.jar.sha1            |    1 +
 ...CENSE-ASL.txt => log4j-1.2-api-LICENSE-ASL.txt} |    0
 .../{log4j-NOTICE.txt => log4j-1.2-api-NOTICE.txt} |    0
 solr/licenses/metrics-core-4.0.5.jar.sha1          |    1 -
 solr/licenses/metrics-core-4.1.2.jar.sha1          |    1 +
 solr/licenses/metrics-graphite-4.0.5.jar.sha1      |    1 -
 solr/licenses/metrics-graphite-4.1.2.jar.sha1      |    1 +
 solr/licenses/metrics-jetty9-4.0.5.jar.sha1        |    1 -
 solr/licenses/metrics-jetty9-4.1.2.jar.sha1        |    1 +
 ...ENSE-ASL.txt => metrics-jetty9-LICENSE-ASL.txt} |    0
 ...-jetty-NOTICE.txt => metrics-jetty9-NOTICE.txt} |    0
 solr/licenses/metrics-jmx-4.0.5.jar.sha1           |    1 -
 solr/licenses/metrics-jmx-4.1.2.jar.sha1           |    1 +
 solr/licenses/metrics-jvm-4.0.5.jar.sha1           |    1 -
 solr/licenses/metrics-jvm-4.1.2.jar.sha1           |    1 +
 .../randomizedtesting-runner-2.7.2.jar.sha1        |    1 -
 .../randomizedtesting-runner-2.7.5.jar.sha1        |    1 +
 solr/licenses/start.jar.sha1                       |    2 +-
 solr/server/etc/jetty.xml                          |   41 +-
 .../solr/configsets/_default/conf/params.json      |   20 -
 .../solr/configsets/_default/conf/solrconfig.xml   |  152 +-
 solr/server/solr/zoo.cfg                           |    3 +
 .../adding-custom-plugins-in-solrcloud-mode.adoc   |    6 +
 solr/solr-ref-guide/src/aliases.adoc               |    2 +-
 solr/solr-ref-guide/src/analytics.adoc             |    7 +-
 .../authentication-and-authorization-plugins.adoc  |    2 +-
 .../solr-ref-guide/src/aws-solrcloud-tutorial.adoc |    2 +-
 .../src/collapse-and-expand-results.adoc           |    2 +-
 .../src/common-query-parameters.adoc               |    5 +-
 solr/solr-ref-guide/src/config-sets.adoc           |   29 +-
 solr/solr-ref-guide/src/configsets-api.adoc        |    1 +
 .../src/configuring-solrconfig-xml.adoc            |   16 +-
 .../src/detecting-languages-during-indexing.adoc   |    2 +-
 solr/solr-ref-guide/src/distributed-requests.adoc  |    2 +-
 solr/solr-ref-guide/src/filter-descriptions.adoc   |    8 +-
 solr/solr-ref-guide/src/highlighting.adoc          |    2 +-
 solr/solr-ref-guide/src/index.adoc                 |   21 +-
 solr/solr-ref-guide/src/json-facet-api.adoc        |    2 +-
 .../src/json-faceting-domain-changes.adoc          |    2 +-
 solr/solr-ref-guide/src/language-analysis.adoc     |   32 +-
 solr/solr-ref-guide/src/learning-to-rank.adoc      |    2 +-
 solr/solr-ref-guide/src/libs.adoc                  |   78 +
 .../src/major-changes-in-solr-7.adoc               |    2 +-
 .../src/meta-docs/asciidoc-syntax.adoc             |    2 +-
 solr/solr-ref-guide/src/other-parsers.adoc         |   26 +-
 .../src/performance-statistics-reference.adoc      |   22 +-
 .../src/requestdispatcher-in-solrconfig.adoc       |    2 +-
 .../src/resource-and-plugin-loading.adoc           |   86 -
 solr/solr-ref-guide/src/resource-loading.adoc      |   44 +
 .../src/shards-and-indexing-data-in-solrcloud.adoc |    2 +-
 solr/solr-ref-guide/src/solr-plugins.adoc          |   40 +-
 .../solrcloud-autoscaling-policy-preferences.adoc  |    2 +-
 solr/solr-ref-guide/src/spatial-search.adoc        |    2 +-
 .../src/stream-decorator-reference.adoc            |    4 +-
 .../src/stream-source-reference.adoc               |    1 +
 solr/solr-ref-guide/src/streaming-expressions.adoc |   10 +-
 .../src/the-dismax-query-parser.adoc               |   53 +-
 .../src/the-extended-dismax-query-parser.adoc      |   22 +-
 .../src/the-well-configured-solr-instance.adoc     |   15 +-
 solr/solr-ref-guide/src/tokenizers.adoc            |    2 +-
 .../src/update-request-processors.adoc             |    2 +-
 solr/solr-ref-guide/src/using-jmx-with-solr.adoc   |    2 +-
 solr/solr-ref-guide/src/using-solrj.adoc           |   14 +
 .../src/velocity-response-writer.adoc              |   37 +-
 .../solr-ref-guide/tools/CheckLinksAndAnchors.java |    2 +-
 .../apache/solr/client/solrj/cloud/ShardTerms.java |  256 +++
 .../client/solrj/impl/BaseCloudSolrClient.java     |   82 +-
 .../impl/ConcurrentUpdateHttp2SolrClient.java      |   76 +-
 .../solrj/impl/ConcurrentUpdateSolrClient.java     |   80 +-
 .../client/solrj/io/eval/PrecisionEvaluator.java   |   13 +-
 .../client/solrj/io/stream/CloudSolrStream.java    |    3 +-
 .../client/solrj/io/stream/DeepRandomStream.java   |    6 +-
 .../solr/client/solrj/io/stream/Facet2DStream.java |    9 +-
 .../solr/client/solrj/io/stream/FacetStream.java   |   36 +-
 .../client/solrj/io/stream/RandomFacadeStream.java |   19 +-
 .../solr/client/solrj/io/stream/RandomStream.java  |   36 +-
 .../solr/client/solrj/io/stream/StatsStream.java   |   13 +-
 .../solr/client/solrj/io/stream/StreamContext.java |   20 +
 .../client/solrj/io/stream/TimeSeriesStream.java   |   37 +-
 .../solr/client/solrj/io/stream/TupleStream.java   |   50 +-
 .../solr/client/solrj/io/stream/UpdateStream.java  |    6 +-
 .../solr/client/solrj/request/UpdateRequest.java   |    1 +
 .../solr/client/solrj/response/QueryResponse.java  |    8 +-
 .../routing/NodePreferenceRulesComparator.java     |    2 +-
 .../RequestReplicaListTransformerGenerator.java    |   40 +-
 .../java/org/apache/solr/common/SolrDocument.java  |   10 +-
 .../org/apache/solr/common/SolrInputField.java     |   68 +-
 .../common/annotation/SolrSingleThreaded.java}     |   23 +-
 .../solr/common/annotation/SolrThreadSafe.java}    |   24 +-
 .../org/apache/solr/common/cloud/ClusterState.java |   10 +-
 .../solr/common/cloud/CompositeIdRouter.java       |   56 +-
 .../apache/solr/common/cloud/DistributedQueue.java |   42 -
 .../java/org/apache/solr/common/cloud/Replica.java |   14 +-
 .../java/org/apache/solr/common/cloud/Slice.java   |   17 +-
 .../apache/solr/common/cloud/ZkStateReader.java    |    5 +
 .../apache/solr/common/params/CommonParams.java    |    1 +
 .../org/apache/solr/common/util/JavaBinCodec.java  |    2 +-
 .../src/test-files/solrj/sampleDebugResponse.xml   |  206 +++
 .../src/test-files/solrj/solr/multicore/zoo.cfg    |    2 +
 .../solr/client/solrj/SolrExceptionTest.java       |    3 +-
 .../client/solrj/cloud/autoscaling/TestPolicy.java |   43 +-
 .../solrj/embedded/SolrExampleJettyTest.java       |   19 +
 .../solrj/impl/CloudHttp2SolrClientTest.java       |   78 +-
 .../client/solrj/impl/CloudSolrClientTest.java     |   79 +-
 .../client/solrj/io/stream/MathExpressionTest.java |   26 +
 .../solrj/io/stream/StreamExpressionTest.java      |   55 +-
 .../io/stream/StreamExpressionToExpessionTest.java |   12 +-
 .../solr/client/solrj/io/stream/StreamingTest.java |   57 +-
 .../client/solrj/response/QueryResponseTest.java   |   27 +
 .../routing/NodePreferenceRulesComparatorTest.java |    8 +-
 .../solrj/routing/ReplicaListTransformerTest.java  |    3 +-
 ...RequestReplicaListTransformerGeneratorTest.java |    8 +-
 .../ShufflingReplicaListTransformerTest.java       |    2 +-
 .../apache/solr/BaseDistributedSearchTestCase.java |    6 +-
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |   19 +
 .../org/apache/solr/cloud/SolrCloudTestCase.java   |   24 +-
 .../org/apache/solr/util/SolrSecurityManager.java  |   14 +-
 .../src/java/org/apache/solr/util/TestHarness.java |    2 +-
 solr/webapp/web/css/angular/angular-csp.css        |   41 +
 solr/webapp/web/index.html                         |    3 +-
 solr/webapp/web/js/angular/app.js                  |    2 +-
 solr/webapp/web/js/angular/controllers/cloud.js    |    2 +-
 553 files changed, 14340 insertions(+), 4693 deletions(-)

diff --cc solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
index cb53d41,e514c5f..147b2616
--- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
@@@ -146,18 -149,22 +149,22 @@@ public abstract class RequestHandlerBas
  
    @Override
    public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
 -    this.solrMetricsContext = parentContext.getChildContext(this);
 -    numErrors = solrMetricsContext.meter("errors", getCategory().toString(), scope);
 -    numServerErrors = solrMetricsContext.meter("serverErrors", getCategory().toString(), scope);
 -    numClientErrors = solrMetricsContext.meter("clientErrors", getCategory().toString(), scope);
 -    numTimeouts = solrMetricsContext.meter("timeouts", getCategory().toString(), scope);
 -    requests = solrMetricsContext.counter("requests", getCategory().toString(), scope);
 +    this.solrMetricsContext = parentContext.getChildContext(this, scope);
 +    numErrors = solrMetricsContext.meter("errors", getCategory().toString());
 +    numServerErrors = solrMetricsContext.meter("serverErrors", getCategory().toString());
 +    numClientErrors = solrMetricsContext.meter("clientErrors", getCategory().toString());
 +    numTimeouts = solrMetricsContext.meter("timeouts", getCategory().toString());
 +    requests = solrMetricsContext.counter("requests", getCategory().toString());
      MetricsMap metricsMap = new MetricsMap((detail, map) ->
          shardPurposes.forEach((k, v) -> map.put(k, v.getCount())));
 -    solrMetricsContext.gauge(metricsMap, true, "shardRequests", getCategory().toString(), scope);
 -    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope);
 -    distribRequestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope, "distrib");
 -    localRequestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString(), scope, "local");
 -    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope);
 -    distribTotalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope, "distrib");
 -    localTotalTime = solrMetricsContext.counter("totalTime", getCategory().toString(), scope, "local");
 -    solrMetricsContext.gauge(() -> handlerStart, true, "handlerStart", getCategory().toString(), scope);
 +    solrMetricsContext.gauge(metricsMap, true, "shardRequests", getCategory().toString());
 +    requestTimes = solrMetricsContext.timer("requestTimes", getCategory().toString());
++    distribRequestTimes = solrMetricsContext.timer("distrib.requestTimes", getCategory().toString());
++    localRequestTimes = solrMetricsContext.timer("local.requestTimes", getCategory().toString());
 +    totalTime = solrMetricsContext.counter("totalTime", getCategory().toString());
++    distribTotalTime = solrMetricsContext.counter("distrib.totalTime", getCategory().toString());
++    localTotalTime = solrMetricsContext.counter("local.totalTime", getCategory().toString());
 +    solrMetricsContext.gauge(() -> handlerStart, true, "handlerStart", getCategory().toString());
    }
  
    public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) {


[lucene-solr] 23/36: First round of refactoring for better type safety.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit cd040a178a0495bf5478562624f61ba965dee94c
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Aug 1 13:37:59 2019 +0200

    First round of refactoring for better type safety.
---
 .../java/org/apache/solr/core/CoreContainer.java   |   3 +-
 .../solr/handler/admin/ResourceManagerHandler.java |  69 +++++++----
 .../managed/AbstractResourceManagerPlugin.java     |  23 ----
 .../solr/managed/DefaultResourceManager.java       |   2 +-
 .../DefaultResourceManagerPluginFactory.java       |  25 +++-
 .../solr/managed/DefaultResourceManagerPool.java   |  12 +-
 .../org/apache/solr/managed/ManagedComponent.java  |  53 --------
 .../apache/solr/managed/ManagedMetricProducer.java |  47 -------
 .../apache/solr/managed/NoOpResourceManager.java   |  61 +++++++--
 .../org/apache/solr/managed/ResourceManager.java   |  19 ++-
 .../apache/solr/managed/ResourceManagerPlugin.java |  28 +++--
 .../solr/managed/ResourceManagerPluginFactory.java |  18 ++-
 .../apache/solr/managed/ResourceManagerPool.java   |   2 +
 .../{plugins => types}/CacheManagerPlugin.java     |  54 ++++++--
 .../solr/managed/types/ManagedCacheComponent.java  |  22 ++++
 .../managed/{plugins => types}/package-info.java   |   2 +-
 .../java/org/apache/solr/search/FastLRUCache.java  | 138 ++++++++-------------
 .../src/java/org/apache/solr/search/LFUCache.java  | 125 ++++++-------------
 .../src/java/org/apache/solr/search/LRUCache.java  |  87 ++++++-------
 .../src/java/org/apache/solr/search/SolrCache.java |   5 +-
 .../org/apache/solr/search/SolrCacheHolder.java    |  58 +++++++--
 .../managed/TestDefaultResourceManagerPool.java    |   2 +-
 .../org/apache/solr/search/TestFastLRUCache.java   |   8 +-
 .../test/org/apache/solr/search/TestLFUCache.java  |   4 +-
 .../test/org/apache/solr/search/TestLRUCache.java  |   8 +-
 25 files changed, 425 insertions(+), 450 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 5da961b..daff00f 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -101,7 +101,6 @@ import org.apache.solr.logging.MDCLoggingContext;
 import org.apache.solr.managed.DefaultResourceManager;
 import org.apache.solr.managed.NoOpResourceManager;
 import org.apache.solr.managed.ResourceManager;
-import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.SolrCoreMetricManager;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricProducer;
@@ -676,7 +675,7 @@ public class CoreContainer {
     }
     try {
       resourceManager = ResourceManager.load(loader, TimeSource.NANO_TIME, DefaultResourceManager.class,
-          new PluginInfo("resourceManager", Collections.emptyMap()), poolConfigs);
+          new PluginInfo("resourceManager", Collections.emptyMap()), resManConfig);
     } catch (Exception e) {
       log.warn("Resource manager initialization error - disabling!", e);
       resourceManager = NoOpResourceManager.INSTANCE;
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index 76b3aa7..8c58dea 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -237,24 +237,32 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
     NamedList<Object> result = new SimpleOrderedMap<>();
     switch (op) {
       case LIST:
-        pool.getComponents().forEach((n, resource) -> {
+        pool.getComponents().forEach((n, component) -> {
           NamedList<Object> perRes = new SimpleOrderedMap<>();
           result.add(n, perRes);
-          perRes.add("class", resource.getClass().getName());
-          perRes.add("types", resource.getManagedResourceTypes());
-          perRes.add("resourceLimits", resource.getResourceLimits());
+          perRes.add("class", component.getClass().getName());
+          try {
+            perRes.add("resourceLimits", pool.getResourceManagerPlugin().getResourceLimits(component));
+          } catch (Exception e) {
+            log.warn("Error getting resourceLimits of " + component.getManagedComponentId(), e);
+            result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
+          }
         });
         break;
       case STATUS:
-        ManagedComponent managedComponent = pool.getComponents().get(resName);
-        if (managedComponent == null) {
-          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
+        ManagedComponent component = pool.getComponents().get(resName);
+        if (component == null) {
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Component '" + resName + " not found in pool '" + poolName + "'.");
+        }
+        result.add("class", component.getClass().getName());
+        try {
+          result.add("resourceLimits", pool.getResourceManagerPlugin().getResourceLimits(component));
+        } catch (Exception e) {
+          log.warn("Error getting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
+          result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
         }
-        result.add("class", managedComponent.getClass().getName());
-        result.add("types", managedComponent.getManagedResourceTypes());
-        result.add("resourceLimits", managedComponent.getResourceLimits());
         try {
-          result.add("monitoredValues", managedComponent.getMonitoredValues(Collections.emptySet()));
+          result.add("monitoredValues", pool.getResourceManagerPlugin().getMonitoredValues(component));
         } catch (Exception e) {
           log.warn("Error getting monitored values of " + resName + "/" + poolName + " : " + e.toString(), e);
           result.add("error", "Error getting monitored values of " + resName + ": " + e.toString());
@@ -263,26 +271,41 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
       case GETLIMITS:
         ManagedComponent managedComponent1 = pool.getComponents().get(resName);
         if (managedComponent1 == null) {
-          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
+          throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Component '" + resName + " not found in pool '" + poolName + "'.");
+        }
+        try {
+          result.add("resourceLimits", pool.getResourceManagerPlugin().getResourceLimits(managedComponent1));
+        } catch (Exception e) {
+          log.warn("Error getting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
+          result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
         }
-        result.add("resourceLimits", managedComponent1.getResourceLimits());
         break;
       case SETLIMITS:
         ManagedComponent managedComponent2 = pool.getComponents().get(resName);
         if (managedComponent2 == null) {
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
-        Map<String, Object> currentLimits = new HashMap<>(managedComponent2.getResourceLimits());
-        Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
-        newLimits.forEach((k, v) -> {
-          if (v == null) {
-            currentLimits.remove(k);
-          } else {
-            currentLimits.put(k, v);
+        try {
+          Map<String, Object> currentLimits = new HashMap<>(pool.getResourceManagerPlugin().getResourceLimits(managedComponent2));
+          Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
+          newLimits.forEach((k, v) -> {
+            if (v == null) {
+              currentLimits.remove(k);
+            } else {
+              currentLimits.put(k, v);
+            }
+          });
+          try {
+            pool.getResourceManagerPlugin().setResourceLimits(managedComponent2, newLimits);
+            result.add("success", newLimits);
+          } catch (Exception e) {
+            log.warn("Error setting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
+            result.add("error", "Error setting resource limits of " + resName + ": " + e.toString());
           }
-        });
-        managedComponent2.setResourceLimits(newLimits);
-        result.add("success", newLimits);
+        } catch (Exception e) {
+          log.warn("Error getting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
+          result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
+        }
         break;
       case DELETE:
         result.add("success", pool.unregisterComponent(resName) ? "removed" : "not found");
diff --git a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
deleted file mode 100644
index 1e630b1..0000000
--- a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.managed;
-
-/**
- *
- */
-public abstract class AbstractResourceManagerPlugin implements ResourceManagerPlugin {
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index 93dfb2d2..d485685 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -33,7 +33,7 @@ import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.managed.plugins.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.search.SolrCache;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.slf4j.Logger;
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
index ab6be81..0b00e74 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
@@ -20,17 +20,20 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.managed.plugins.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPlugin;
+import org.apache.solr.managed.types.ManagedCacheComponent;
 
 /**
  * Default implementation of {@link ResourceManagerPluginFactory}.
  */
 public class DefaultResourceManagerPluginFactory implements ResourceManagerPluginFactory {
 
-  private static final Map<String, String> typeToClass = new HashMap<>();
+  private static final Map<String, Class<? extends ResourceManagerPlugin>> typeToPluginClass = new HashMap<>();
+  private static final Map<String, Class<? extends ManagedComponent>> typeToComponentClass = new HashMap<>();
 
   static {
-    typeToClass.put(CacheManagerPlugin.TYPE, CacheManagerPlugin.class.getName());
+    typeToPluginClass.put(CacheManagerPlugin.TYPE, CacheManagerPlugin.class);
+    typeToComponentClass.put(CacheManagerPlugin.TYPE, ManagedCacheComponent.class);
   }
 
   private final SolrResourceLoader loader;
@@ -40,13 +43,23 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
   }
 
   @Override
-  public ResourceManagerPlugin create(String type, Map<String, Object> params) throws Exception {
-    String pluginClazz = typeToClass.get(type);
+  public <T extends ManagedComponent> ResourceManagerPlugin<T> create(String type, Map<String, Object> params) throws Exception {
+    Class<? extends ResourceManagerPlugin> pluginClazz = typeToPluginClass.get(type);
     if (pluginClazz == null) {
       throw new IllegalArgumentException("Unsupported plugin type '" + type + "'");
     }
-    ResourceManagerPlugin resourceManagerPlugin = loader.newInstance(pluginClazz, ResourceManagerPlugin.class);
+    ResourceManagerPlugin<T> resourceManagerPlugin = loader.newInstance(pluginClazz.getName(), ResourceManagerPlugin.class);
     resourceManagerPlugin.init(params);
     return resourceManagerPlugin;
   }
+
+  @Override
+  public Class<? extends ManagedComponent> getComponentClassByType(String type) {
+    return typeToComponentClass.get(type);
+  }
+
+  @Override
+  public Class<? extends ResourceManagerPlugin> getPluginClassByType(String type) {
+    return typeToPluginClass.get(type);
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 9f87f42..1729789 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -40,6 +40,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private final Map<String, ManagedComponent> resources = new ConcurrentHashMap<>();
   private Map<String, Object> poolLimits;
   private final String type;
+  private final Class<? extends ManagedComponent> componentClass;
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
@@ -62,6 +63,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
     this.name = name;
     this.type = type;
     this.resourceManagerPlugin = factory.create(type, args);
+    this.componentClass = factory.getComponentClassByType(type);
     this.poolLimits = new TreeMap<>(poolLimits);
     this.args = new HashMap<>(args);
   }
@@ -82,9 +84,13 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
+  public ResourceManagerPlugin getResourceManagerPlugin() {
+    return resourceManagerPlugin;
+  }
+
+  @Override
   public void registerComponent(ManagedComponent managedComponent) {
-    Collection<String> types = managedComponent.getManagedResourceTypes();
-    if (!types.contains(type)) {
+    if (!componentClass.isAssignableFrom(managedComponent.getClass())) {
       log.debug("Pool type '" + type + "' is not supported by the resource " + managedComponent.getManagedComponentId());
       return;
     }
@@ -112,7 +118,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
       Map<String, Map<String, Object>> currentValues = new HashMap<>();
       for (ManagedComponent managedComponent : resources.values()) {
         try {
-          currentValues.put(managedComponent.getManagedComponentId().toString(), managedComponent.getMonitoredValues(resourceManagerPlugin.getMonitoredParams()));
+          currentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
         } catch (Exception e) {
           log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
         }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index 2b9e6b8..cf75af3 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -16,19 +16,10 @@
  */
 package org.apache.solr.managed;
 
-import java.lang.invoke.MethodHandles;
-import java.util.Collection;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * A managed component.
  */
 public interface ManagedComponent {
-  Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
   /**
    * Unique name of this component. By convention id-s form a dot-separated hierarchy that
    * follows the naming of metric registries and metric names.
@@ -36,50 +27,6 @@ public interface ManagedComponent {
   ManagedComponentId getManagedComponentId();
 
   /**
-   * Returns types of management plugins supported by this component. This must always
-   * return a non-null collection with at least one entry.
-   */
-  Collection<String> getManagedResourceTypes();
-
-  /**
-   * Set values of managed resource limits.
-   * @param limits map of limit names and values
-   */
-  default void setResourceLimits(Map<String, Object> limits) {
-    if (limits == null) {
-      return;
-    }
-    limits.forEach((key, value) -> {
-      try {
-        setResourceLimit(key, value);
-      } catch (Exception e) {
-        log.warn("Exception setting resource limit on {}: key={}, value={}, exception={}",
-            getManagedComponentId(), key, value, e);
-      }
-    });
-  }
-
-  /**
-   * Set value of a managed resource limit.
-   * @param key limit name
-   * @param value limit value
-   */
-  void setResourceLimit(String key, Object value) throws Exception;
-
-  /**
-   * Returns current values of managed resource limits.
-   * @return map where keys are controlled parameters and values are current values of limits
-   */
-  Map<String, Object> getResourceLimits();
-
-  /**
-   * Returns monitored values that are used for calculating optimal settings of managed resource limits.
-   * @param params selected monitored parameters, empty collection to return all monitored values
-   * @return map of parameter names to current values.
-   */
-  Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception;
-
-  /**
    * Component context used for managing additional component state.
    * @return component's context
    */
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
deleted file mode 100644
index 1cb9a04..0000000
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.managed;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.solr.core.SolrInfoBean;
-
-/**
- * Convenience interface for {@link SolrInfoBean}-s that need to be managed.
- */
-public interface ManagedMetricProducer extends SolrInfoBean, ManagedComponent {
-
-  @Override
-  default Map<String, Object> getMonitoredValues(Collection<String> params) {
-    Map<String, Object> metrics = getMetricsSnapshot();
-    if (metrics == null) {
-      return Collections.emptyMap();
-    }
-    Map<String, Object> result = new HashMap<>();
-    params.forEach(tag -> {
-      Object value = metrics.get(tag);
-      if (value == null) {
-        return;
-      }
-      result.put(tag, value);
-    });
-    return result;
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index e2e12eb..282fd11 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -30,8 +30,42 @@ public class NoOpResourceManager extends ResourceManager {
 
   public static final NoOpResourceManager INSTANCE = new NoOpResourceManager();
 
+  private static final class NoOpResourceManagerPlugin implements ResourceManagerPlugin {
+    static final NoOpResourceManagerPlugin INSTANCE = new NoOpResourceManagerPlugin();
+
+    @Override
+    public String getType() {
+      return NOOP;
+    }
+
+    @Override
+    public Map<String, Object> getMonitoredValues(ManagedComponent component) throws Exception {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public void setResourceLimit(ManagedComponent component, String limitName, Object value) throws Exception {
+      // no-op
+    }
+
+    @Override
+    public Map<String, Object> getResourceLimits(ManagedComponent component) throws Exception {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public void manage(ResourceManagerPool pool) throws Exception {
+      // no-op
+    }
+
+    @Override
+    public void init(Map params) {
+      // no-op
+    }
+  }
+
   private static final class NoOpResourcePool implements ResourceManagerPool {
-    static NoOpResourcePool INSTANCE = new NoOpResourcePool();
+    static final NoOpResourcePool INSTANCE = new NoOpResourcePool();
 
     @Override
     public String getName() {
@@ -44,8 +78,13 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public void registerComponent(ManagedComponent managedComponent) {
+    public ResourceManagerPlugin getResourceManagerPlugin() {
+      return NoOpResourceManagerPlugin.INSTANCE;
+    }
 
+    @Override
+    public void registerComponent(ManagedComponent managedComponent) {
+      // no-op
     }
 
     @Override
@@ -80,7 +119,7 @@ public class NoOpResourceManager extends ResourceManager {
 
     @Override
     public void setPoolLimits(Map<String, Object> poolLimits) {
-
+      // no-op
     }
 
     @Override
@@ -90,23 +129,23 @@ public class NoOpResourceManager extends ResourceManager {
 
     @Override
     public void close() throws IOException {
-
+      // no-op
     }
 
     @Override
     public void run() {
-
+      // no-op
     }
   }
 
   @Override
   protected void doInit() throws Exception {
-
+    // no-op
   }
 
   @Override
   public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
-
+    // no-op
   }
 
   @Override
@@ -121,17 +160,17 @@ public class NoOpResourceManager extends ResourceManager {
 
   @Override
   public void setPoolLimits(String name, Map<String, Object> poolLimits) throws Exception {
-
+    // no-op
   }
 
   @Override
   public void removePool(String name) throws Exception {
-
+    // no-op
   }
 
   @Override
   public void registerComponent(String pool, ManagedComponent managedComponent) throws Exception {
-
+    // no-op
   }
 
   @Override
@@ -141,6 +180,6 @@ public class NoOpResourceManager extends ResourceManager {
 
   @Override
   public void close() throws IOException {
-
+    // no-op
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index 48c2273..d75cb37 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -36,9 +36,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Base class for a resource management. It uses a flat model where there are named
- * resource pools of a given type, each pool with its own defined resource limits. Resources can be added
- * to a pool for the management of a specific aspect of that resource using {@link ResourceManagerPlugin}.
+ * Base class for resource management. It uses a flat model where there are named
+ * resource pools of a given type, each pool with its own defined resource limits. Components can be added
+ * to a pool for the management of a specific aspect of that component using {@link ResourceManagerPlugin}.
  */
 public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -212,8 +212,7 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    * Add a managed component to a pool.
    * @param pool existing pool name.
    * @param managedComponent managed component. The component must support the management type
-   *                        (in its {@link ManagedComponent#getManagedResourceTypes()}) used
-   *                        in the selected pool. The component must not be already managed by
+   *                        used in the selected pool. The component must not be already managed by
    *                        another pool of the same type.
    */
   public abstract void registerComponent(String pool, ManagedComponent managedComponent) throws Exception;
@@ -224,6 +223,16 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    * @param componentId component id to remove
    * @return true if a component was actually registered and has been removed
    */
+  public boolean unregisterComponent(String pool, ManagedComponentId componentId) {
+    return unregisterComponent(pool, componentId.toString());
+  }
+
+  /**
+   * Remove a managed component from a pool.
+   * @param pool existing pool name.
+   * @param componentId component id to remove
+   * @return true if a component was actually registered and has been removed
+   */
   public abstract boolean unregisterComponent(String pool, String componentId);
 
   protected void ensureActive() {
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index 01f8363..61ec2e8 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -22,23 +22,27 @@ import java.util.Map;
 /**
  * A plugin that implements an algorithm for managing a pool of resources of a given type.
  */
-public interface ResourceManagerPlugin {
+public interface ResourceManagerPlugin<T extends ManagedComponent> {
 
-  /** Plugin type. */
+  /** Plugin symbolic type. */
   String getType();
 
   void init(Map<String, Object> params);
 
-  /**
-   * Name of monitored parameters that {@link ManagedComponent}-s managed by this plugin
-   * are expected to support.
-   */
-  Collection<String> getMonitoredParams();
-  /**
-   * Name of controlled parameters that {@link ManagedComponent}-s managed by this plugin
-   * are expected to support.
-   */
-  Collection<String> getControlledParams();
+  Map<String, Object> getMonitoredValues(T component) throws Exception;
+
+  default void setResourceLimits(T component, Map<String, Object> limits) throws Exception {
+    if (limits == null || limits.isEmpty()) {
+      return;
+    }
+    for (Map.Entry<String, Object> entry : limits.entrySet()) {
+      setResourceLimit(component, entry.getKey(), entry.getValue());
+    }
+  }
+
+  void setResourceLimit(T component, String limitName, Object value) throws Exception;
+
+  Map<String, Object> getResourceLimits(T component) throws Exception;
 
   /**
    * Manage resources in a pool. This method is called periodically by {@link ResourceManager},
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
index 6c8578a..508b5e9 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
@@ -24,9 +24,21 @@ import java.util.Map;
 public interface ResourceManagerPluginFactory {
 
   /**
-   * Create a plugin of a given type.
-   * @param type plugin type
+   * Create a plugin of a given symbolic type.
+   * @param type plugin symbolic type
    * @param params plugin parameters
    */
-  ResourceManagerPlugin create(String type, Map<String, Object> params) throws Exception;
+  <T extends ManagedComponent> ResourceManagerPlugin<T> create(String type, Map<String, Object> params) throws Exception;
+
+  /**
+   * Get the implementation class for a component of a given symbolic type.
+   * @param type symbolic type
+   */
+  Class<? extends ManagedComponent> getComponentClassByType(String type);
+
+  /**
+   * Get the implementation class for a plugin of a given symbolic type.
+   * @param type symbolic type
+   */
+  Class<? extends ResourceManagerPlugin> getPluginClassByType(String type);
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 783dc99..dc2ddac 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -14,6 +14,8 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   /** Pool type. */
   String getType();
 
+  ResourceManagerPlugin getResourceManagerPlugin();
+
   /** Add component to this pool. */
   void registerComponent(ManagedComponent managedComponent);
 
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
similarity index 70%
rename from solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
rename to solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
index ad1ef3e..0ee888b 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.managed.plugins;
+package org.apache.solr.managed.types;
 
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
@@ -22,7 +22,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.solr.managed.AbstractResourceManagerPlugin;
+import org.apache.solr.managed.ResourceManagerPlugin;
 import org.apache.solr.managed.ResourceManagerPool;
 import org.apache.solr.search.SolrCache;
 import org.slf4j.Logger;
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
  * which can be adjusted using configuration parameter {@link #DEAD_BAND}. If monitored values don't
  * exceed the limits +/- the dead band then no action is taken.</p>
  */
-public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
+public class CacheManagerPlugin implements ResourceManagerPlugin<ManagedCacheComponent> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static String TYPE = "cache";
@@ -66,13 +66,45 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   protected float deadBand = DEFAULT_DEAD_BAND;
 
   @Override
-  public Collection<String> getMonitoredParams() {
-    return MONITORED_PARAMS;
+  public void setResourceLimit(ManagedCacheComponent component, String limitName, Object val) {
+    if (!(val instanceof Number)) {
+      try {
+        val = Long.parseLong(String.valueOf(val));
+      } catch (Exception e) {
+        throw new IllegalArgumentException("Unsupported value type (not a number) for limit '" + limitName + "': " + val + " (" + val.getClass().getName() + ")");
+      }
+    }
+    Number value = (Number)val;
+    if (value.longValue() > Integer.MAX_VALUE) {
+      throw new IllegalArgumentException("Invalid new value for limit '" + limitName +"': " + value);
+    }
+    switch (limitName) {
+      case SolrCache.MAX_SIZE_PARAM:
+        component.setMaxSize(value.intValue());
+        break;
+      case SolrCache.MAX_RAM_MB_PARAM:
+        component.setMaxRamMB(value.intValue());
+        break;
+      default:
+        throw new IllegalArgumentException("Unsupported limit name '" + limitName + "'");
+    }
+  }
+
+  @Override
+  public Map<String, Object> getResourceLimits(ManagedCacheComponent component) {
+    Map<String, Object> limits = new HashMap<>();
+    limits.put(SolrCache.MAX_SIZE_PARAM, component.getMaxSize());
+    limits.put(SolrCache.MAX_RAM_MB_PARAM, component.getMaxRamMB());
+    return limits;
   }
 
   @Override
-  public Collection<String> getControlledParams() {
-    return CONTROLLED_PARAMS;
+  public Map<String, Object> getMonitoredValues(ManagedCacheComponent component) throws Exception {
+    Map<String, Object> values = new HashMap<>();
+    values.put(SolrCache.HIT_RATIO_PARAM, component.getHitRatio());
+    values.put(SolrCache.RAM_BYTES_USED_PARAM, component.ramBytesUsed());
+    values.put(SolrCache.SIZE_PARAM, component.getSize());
+    return values;
   }
 
   @Override
@@ -121,8 +153,8 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
 
       float changeRatio = poolLimitValue / totalValue.floatValue();
       // modify current limits by the changeRatio
-      pool.getComponents().forEach((name, resource) -> {
-        Map<String, Object> resourceLimits = resource.getResourceLimits();
+      pool.getComponents().forEach((name, component) -> {
+        Map<String, Object> resourceLimits = getResourceLimits((ManagedCacheComponent)component);
         Object limit = resourceLimits.get(poolLimitName);
         // XXX we could attempt here to control eg. ramBytesUsed by adjusting maxSize limit
         // XXX and vice versa if the current limit is undefined or unsupported
@@ -135,10 +167,10 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
         }
         float newLimit = currentResourceLimit * changeRatio;
         try {
-          resource.setResourceLimit(poolLimitName, newLimit);
+          setResourceLimit((ManagedCacheComponent)component, poolLimitName, newLimit);
         } catch (Exception e) {
           log.warn("Failed to set managed limit " + poolLimitName +
-              " from " + currentResourceLimit + " to " + newLimit + " on " + resource.getManagedComponentId(), e);
+              " from " + currentResourceLimit + " to " + newLimit + " on " + component.getManagedComponentId(), e);
         }
       });
     });
diff --git a/solr/core/src/java/org/apache/solr/managed/types/ManagedCacheComponent.java b/solr/core/src/java/org/apache/solr/managed/types/ManagedCacheComponent.java
new file mode 100644
index 0000000..d36a842
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/types/ManagedCacheComponent.java
@@ -0,0 +1,22 @@
+package org.apache.solr.managed.types;
+
+import org.apache.lucene.util.Accountable;
+import org.apache.solr.managed.ManagedComponent;
+
+/**
+ *
+ */
+public interface ManagedCacheComponent extends ManagedComponent, Accountable {
+  /** Set maximum cache size limit (number of items). */
+  void setMaxSize(int size);
+  /** Set maximum cache size limit (in MB of RAM). */
+  void setMaxRamMB(int maxRamMB);
+  /** Get the configured maximum size limit (number of items). */
+  int getMaxSize();
+  /** Get the configured maximym size limit (in MB of RAM). */
+  int getMaxRamMB();
+  /** Get the current number of items in cache. */
+  int getSize();
+  /** Get the ratio of hits to lookups. */
+  float getHitRatio();
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/package-info.java b/solr/core/src/java/org/apache/solr/managed/types/package-info.java
similarity index 95%
rename from solr/core/src/java/org/apache/solr/managed/plugins/package-info.java
rename to solr/core/src/java/org/apache/solr/managed/types/package-info.java
index 5b4ff61..5dd0a71 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/package-info.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/package-info.java
@@ -18,4 +18,4 @@
 /**
  * Implementations of {@link org.apache.solr.managed.ResourceManagerPlugin}.
  */
-package org.apache.solr.managed.plugins;
+package org.apache.solr.managed.types;
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 2fb9ada..ad5d82a 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -22,7 +22,7 @@ import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
-import org.apache.solr.managed.plugins.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.ConcurrentLRUCache;
@@ -53,7 +53,7 @@ import java.util.concurrent.TimeUnit;
  * @see org.apache.solr.search.SolrCache
  * @since solr 1.4
  */
-public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>, Accountable {
+public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(FastLRUCache.class);
@@ -339,23 +339,6 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   }
 
   @Override
-  public Map<String, Object> getResourceLimits() {
-    Map<String, Object> limits = new HashMap<>();
-    limits.put(MAX_SIZE_PARAM, maxSize);
-    limits.put(MIN_SIZE_PARAM, minSize);
-    limits.put(ACCEPTABLE_SIZE_PARAM, acceptableSize);
-    limits.put(CLEANUP_THREAD_PARAM, cleanupThread);
-    limits.put(SHOW_ITEMS_PARAM, showItems);
-    limits.put(MAX_RAM_MB_PARAM, maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
-    return limits;
-  }
-
-  @Override
-  public Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception {
-    return cacheMap.getValue();
-  }
-
-  @Override
   public ManagedContext getManagedContext() {
     return managedContext;
   }
@@ -365,75 +348,6 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
     return managedComponentId;
   }
 
-  @Override
-  public Collection<String> getManagedResourceTypes() {
-    return Collections.singleton(CacheManagerPlugin.TYPE);
-  }
-
-  @Override
-  public void setResourceLimit(String limitName, Object val) {
-    if (CLEANUP_THREAD_PARAM.equals(limitName)) {
-      Boolean value;
-      try {
-        value = Boolean.parseBoolean(val.toString());
-        cleanupThread = value;
-        cache.setRunCleanupThread(cleanupThread);
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Invalid new value for boolean limit '" + limitName + "': " + val);
-      }
-    }
-    Number value;
-    try {
-      value = Long.parseLong(String.valueOf(val));
-    } catch (Exception e) {
-      throw new IllegalArgumentException("Invalid new value for numeric limit '" + limitName +"': " + val);
-    }
-    if (!limitName.equals(MAX_RAM_MB_PARAM)) {
-      if (value.intValue() <= 1) {
-        throw new IllegalArgumentException("Invalid new value for numeric limit '" + limitName +"': " + value);
-      }
-    }
-    if (value.longValue() > Integer.MAX_VALUE) {
-      throw new IllegalArgumentException("Invalid new value for numeric limit '" + limitName +"': " + value);
-    }
-    switch (limitName) {
-      case MAX_SIZE_PARAM:
-        maxSize = value.intValue();
-        checkAndAdjustLimits();
-        cache.setUpperWaterMark(maxSize);
-        cache.setLowerWaterMark(minSize);
-        break;
-      case MIN_SIZE_PARAM:
-        minSize = value.intValue();
-        checkAndAdjustLimits();
-        cache.setUpperWaterMark(maxSize);
-        cache.setLowerWaterMark(minSize);
-        break;
-      case ACCEPTABLE_SIZE_PARAM:
-        acceptableSize = value.intValue();
-        acceptableSize = Math.max(minSize, acceptableSize);
-        cache.setAcceptableWaterMark(acceptableSize);
-        break;
-      case MAX_RAM_MB_PARAM:
-        long maxRamMB = value.intValue();
-        maxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * 1024L * 1024L;
-        if (maxRamMB < 0) {
-          ramLowerWatermark = Long.MIN_VALUE;
-        } else {
-          ramLowerWatermark = Math.round(maxRamBytes * 0.8);
-        }
-        cache.setRamUpperWatermark(maxRamBytes);
-        cache.setRamLowerWatermark(ramLowerWatermark);
-        break;
-      case SHOW_ITEMS_PARAM:
-        showItems = value.intValue();
-        break;
-      default:
-        throw new IllegalArgumentException("Unsupported limit '" + limitName + "'");
-    }
-    description = generateDescription();
-  }
-
   private void checkAndAdjustLimits() {
     if (minSize <= 0) minSize = 1;
     if (maxSize <= minSize) {
@@ -444,6 +358,54 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
       }
     }
   }
+
+  @Override
+  public void setMaxSize(int size) {
+    if (size < 1) {
+      throw new IllegalArgumentException("Invalid new value for maxSize: " + size);
+    }
+    maxSize = size;
+    checkAndAdjustLimits();
+    cache.setUpperWaterMark(maxSize);
+    cache.setLowerWaterMark(minSize);
+    generateDescription();
+  }
+
+  @Override
+  public void setMaxRamMB(int maxRamMB) {
+    maxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * MB;
+    if (maxRamMB < 0) {
+      ramLowerWatermark = Long.MIN_VALUE;
+    } else {
+      ramLowerWatermark = Math.round(maxRamBytes * 0.8);
+    }
+    cache.setRamUpperWatermark(maxRamBytes);
+    cache.setRamLowerWatermark(ramLowerWatermark);
+    generateDescription();
+  }
+
+  @Override
+  public int getMaxSize() {
+    return maxSize;
+  }
+
+  @Override
+  public int getMaxRamMB() {
+    return maxRamBytes == Long.MAX_VALUE ? -1 : (int)(maxRamBytes / MB);
+  }
+
+  @Override
+  public int getSize() {
+    return cache.size();
+  }
+
+  @Override
+  public float getHitRatio() {
+    ConcurrentLRUCache.Stats stats = cache.getStats();
+    long lookups = stats.getCumulativeLookups();
+    long hits = stats.getCumulativeHits();
+    return calcHitRatio(lookups, hits);
+  }
 }
 
 
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 28decac..7bff8de 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -28,12 +28,11 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
 
 import com.codahale.metrics.MetricRegistry;
-import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
-import org.apache.solr.managed.plugins.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.ConcurrentLFUCache;
@@ -56,7 +55,7 @@ import static org.apache.solr.common.params.CommonParams.NAME;
  * @see org.apache.solr.search.SolrCache
  * @since solr 3.6
  */
-public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
+public class LFUCache<K, V> implements SolrCache<K, V> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(LFUCache.class);
@@ -252,7 +251,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   // returns a ratio, not a percent.
-  private static String calcHitRatio(long lookups, long hits) {
+  private static String calcHitRatioStr(long lookups, long hits) {
     if (lookups == 0) return "0.00";
     if (lookups == hits) return "1.00";
     int hundredths = (int) (hits * 100 / lookups);   // rounded down
@@ -274,13 +273,14 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
 
         map.put("lookups", lookups);
         map.put("hits", hits);
-        map.put(HIT_RATIO_PARAM, calcHitRatio(lookups, hits));
+        map.put(HIT_RATIO_PARAM, calcHitRatioStr(lookups, hits));
         map.put("inserts", inserts);
         map.put("evictions", evictions);
         map.put(SIZE_PARAM, size);
         map.put(MAX_SIZE_PARAM, maxSize);
         map.put(MIN_SIZE_PARAM, minSize);
         map.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
+        map.put(MAX_RAM_MB_PARAM, getMaxRamMB());
 
         map.put("warmupTime", warmupTime);
         map.put("timeDecay", timeDecay);
@@ -300,7 +300,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
         }
         map.put("cumulative_lookups", clookups);
         map.put("cumulative_hits", chits);
-        map.put("cumulative_hitratio", calcHitRatio(clookups, chits));
+        map.put("cumulative_hitratio", calcHitRatioStr(clookups, chits));
         map.put("cumulative_inserts", cinserts);
         map.put("cumulative_evictions", cevictions);
 
@@ -364,98 +364,51 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
     return managedComponentId;
   }
 
+  private void checkAndAdjustLimits() {
+    if (minSize <= 0) minSize = 1;
+    if (maxSize <= minSize) {
+      if (maxSize > 1) {
+        minSize = maxSize - 1;
+      } else {
+        maxSize = minSize + 1;
+      }
+    }
+  }
+
   @Override
-  public Map<String, Object> getResourceLimits() {
-    Map<String, Object> limits = new HashMap<>();
-    limits.put(MAX_SIZE_PARAM, maxSize);
-    limits.put(MIN_SIZE_PARAM, minSize);
-    limits.put(ACCEPTABLE_SIZE_PARAM, acceptableSize);
-    limits.put(AUTOWARM_COUNT_PARAM, autowarmCount);
-    limits.put(CLEANUP_THREAD_PARAM, cleanupThread);
-    limits.put(SHOW_ITEMS_PARAM, showItems);
-    limits.put(TIME_DECAY_PARAM, timeDecay);
-    return limits;
+  public void setMaxSize(int size) {
+    maxSize = size;
+    checkAndAdjustLimits();
+    cache.setUpperWaterMark(maxSize);
+    cache.setLowerWaterMark(minSize);
+    generateDescription();
   }
 
   @Override
-  public Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception {
-    return cacheMap.getValue();
+  public void setMaxRamMB(int maxRamMB) {
+    // no-op
   }
 
   @Override
-  public Collection<String> getManagedResourceTypes() {
-    return Collections.singleton(CacheManagerPlugin.TYPE);
+  public int getMaxSize() {
+    return maxSize;
   }
 
   @Override
-  public synchronized void setResourceLimit(String limitName, Object val) {
-    if (TIME_DECAY_PARAM.equals(limitName) || CLEANUP_THREAD_PARAM.equals(limitName)) {
-      Boolean value;
-      try {
-        value = Boolean.parseBoolean(String.valueOf(val));
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Invalid value of boolean limit '" + limitName + "': " + val);
-      }
-      switch (limitName) {
-        case TIME_DECAY_PARAM:
-          timeDecay = value;
-          cache.setTimeDecay(timeDecay);
-          break;
-        case CLEANUP_THREAD_PARAM:
-          cleanupThread = value;
-          cache.setRunCleanupThread(cleanupThread);
-          break;
-      }
-    } else {
-      Number value;
-      try {
-        value = Long.parseLong(String.valueOf(val));
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Invalid new value for numeric limit '" + limitName +"': " + val);
-      }
-      if (value.intValue() <= 1 || value.longValue() > Integer.MAX_VALUE) {
-        throw new IllegalArgumentException("Out of range new value for numeric limit '" + limitName +"': " + value);
-      }
-      switch (limitName) {
-        case MAX_SIZE_PARAM:
-          maxSize = value.intValue();
-          checkAndAdjustLimits();
-          cache.setUpperWaterMark(maxSize);
-          cache.setLowerWaterMark(minSize);
-          break;
-        case MIN_SIZE_PARAM:
-          minSize = value.intValue();
-          checkAndAdjustLimits();
-          cache.setUpperWaterMark(maxSize);
-          cache.setLowerWaterMark(minSize);
-          break;
-        case ACCEPTABLE_SIZE_PARAM:
-          acceptableSize = value.intValue();
-          acceptableSize = Math.max(minSize, acceptableSize);
-          cache.setAcceptableWaterMark(acceptableSize);
-          break;
-        case AUTOWARM_COUNT_PARAM:
-          autowarmCount = value.intValue();
-          break;
-        case SHOW_ITEMS_PARAM:
-          showItems = value.intValue();
-          break;
-        default:
-          throw new IllegalArgumentException("Unsupported numeric limit '" + limitName + "'");
-      }
-    }
-    description = generateDescription();
+  public int getMaxRamMB() {
+    return -1;
   }
 
-  private void checkAndAdjustLimits() {
-    if (minSize <= 0) minSize = 1;
-    if (maxSize <= minSize) {
-      if (maxSize > 1) {
-        minSize = maxSize - 1;
-      } else {
-        maxSize = minSize + 1;
-      }
-    }
+  @Override
+  public int getSize() {
+    return cache.getStats().getCurrentSize();
   }
 
+  @Override
+  public float getHitRatio() {
+    ConcurrentLFUCache.Stats stats = cache.getStats();
+    long lookups = stats.getCumulativeLookups();
+    long hits = stats.getCumulativeHits();
+    return SolrCacheBase.calcHitRatio(lookups, hits);
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index b4669bc..e9f5768 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -35,7 +35,7 @@ import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
-import org.apache.solr.managed.plugins.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.slf4j.Logger;
@@ -47,7 +47,7 @@ import static org.apache.lucene.util.RamUsageEstimator.QUERY_DEFAULT_RAM_BYTES_U
 /**
  *
  */
-public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Accountable {
+public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(LRUCache.class);
@@ -163,6 +163,24 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
     return maxRamBytes;
   }
 
+  public int getMaxRamMB() {
+    if (maxRamBytes != Long.MAX_VALUE) {
+      return (int)(maxRamBytes / MB);
+    } else {
+      return -1;
+    }
+  }
+
+  @Override
+  public int getSize() {
+    return map.size();
+  }
+
+  @Override
+  public float getHitRatio() {
+    return calcHitRatio(lookups, hits);
+  }
+
   /**
    * 
    * @return Returns the description of this cache. 
@@ -172,9 +190,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
     if (isAutowarmingOn()) {
       description += ", " + getAutowarmDescription();
     }
-    if (getMaxRamBytes() != Long.MAX_VALUE)  {
-      description += ", maxRamMB=" + (getMaxRamBytes() / 1024L / 1024L);
-    }
+    description += ", maxRamMB=" + getMaxRamMB();
     description += ')';
     return description;
   }
@@ -327,7 +343,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
         res.put(SIZE_PARAM, map.size());
         res.put(MAX_SIZE_PARAM, maxSize);
         res.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
-        res.put(MAX_RAM_MB_PARAM, maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
+        res.put(MAX_RAM_MB_PARAM, getMaxRamMB());
         res.put("evictionsRamUsage", evictionsRamUsage);
       }
       res.put("warmupTime", warmupTime);
@@ -375,19 +391,6 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   }
 
   @Override
-  public Map<String, Object> getResourceLimits() {
-    Map<String, Object> limits = new HashMap<>();
-    limits.put(MAX_SIZE_PARAM, maxSize);
-    limits.put(MAX_RAM_MB_PARAM, maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
-    return limits;
-  }
-
-  @Override
-  public Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception {
-    return cacheMap.getValue();
-  }
-
-  @Override
   public ManagedContext getManagedContext() {
     return managedContext;
   }
@@ -398,41 +401,23 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   }
 
   @Override
-  public Collection<String> getManagedResourceTypes() {
-    return Collections.singleton(CacheManagerPlugin.TYPE);
+  public void setMaxSize(int newMaxSize) {
+    if (newMaxSize > 0) {
+      maxSize = newMaxSize;
+    } else {
+      maxSize = Integer.MAX_VALUE;
+    }
+    generateDescription();
   }
 
   @Override
-  public void setResourceLimit(String limitName, Object val) {
-    if (!(val instanceof Number)) {
-      try {
-        val = Long.parseLong(String.valueOf(val));
-      } catch (Exception e) {
-        throw new IllegalArgumentException("Unsupported value type (not a number) for limit '" + limitName + "': " + val + " (" + val.getClass().getName() + ")");
-      }
+  public void setMaxRamMB(int newMaxRamMB) {
+    if (newMaxRamMB > 0) {
+      maxRamBytes = newMaxRamMB * MB;
+    } else {
+      maxRamBytes = Long.MAX_VALUE;
     }
-    Number value = (Number)val;
-    if (value.longValue() > Integer.MAX_VALUE) {
-      throw new IllegalArgumentException("Invalid new value for limit '" + limitName +"': " + value);
-    }
-    switch (limitName) {
-      case MAX_SIZE_PARAM:
-        if (value.intValue() > 0) {
-          maxSize = value.intValue();
-        } else {
-          maxSize = Integer.MAX_VALUE;
-        }
-        break;
-      case MAX_RAM_MB_PARAM:
-        if (value.intValue() > 0) {
-          maxRamBytes = value.intValue() * 1024L * 1024L;
-        } else {
-          maxRamBytes = Long.MAX_VALUE;
-        }
-        break;
-      default:
-        throw new IllegalArgumentException("Unsupported limit name '" + limitName + "'");
-    }
-    description = generateDescription();
+    generateDescription();
   }
+
 }
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 7814384..b1d090d 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -18,6 +18,7 @@ package org.apache.solr.search;
 
 import org.apache.solr.core.SolrInfoBean;
 import org.apache.solr.managed.ManagedComponent;
+import org.apache.solr.managed.types.ManagedCacheComponent;
 import org.apache.solr.metrics.SolrMetricProducer;
 
 import java.util.Map;
@@ -26,7 +27,7 @@ import java.util.Map;
 /**
  * Primary API for dealing with Solr's internal caches.
  */
-public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedComponent {
+public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedCacheComponent {
 
   /** Current size of the cache. */
   String SIZE_PARAM = "size";
@@ -42,6 +43,8 @@ public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, Manage
   /** Cache hit ratio. */
   String HIT_RATIO_PARAM = "hitratio";
 
+  long MB = 1024L * 1024L;
+
   /**
    * The initialization routine. Instance specific arguments are passed in
    * the <code>args</code> map.
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index 29dab92..fb562a2 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -22,6 +22,8 @@ import java.util.Map;
 import java.util.Set;
 
 import com.codahale.metrics.MetricRegistry;
+import org.apache.solr.managed.ManagedComponentId;
+import org.apache.solr.managed.ManagedContext;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -80,18 +82,6 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
     delegate.close();
   }
 
-  @Override
-  public Map<String, Object> getResourceLimits() {
-    return delegate.getResourceLimits();
-  }
-
-  @Override
-  public void setResourceLimit(String limitName, Object value) throws Exception {
-    delegate.setResourceLimit(limitName, value);
-
-  }
-
-
   public void warm(SolrIndexSearcher searcher, SolrCacheHolder src) {
     delegate.warm(searcher, src.get());
   }
@@ -139,4 +129,48 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
 
   }
 
+  @Override
+  public void setMaxSize(int size) {
+    delegate.setMaxSize(size);
+  }
+
+  @Override
+  public void setMaxRamMB(int maxRamMB) {
+    delegate.setMaxRamMB(maxRamMB);
+  }
+
+  @Override
+  public int getMaxSize() {
+    return delegate.getMaxSize();
+  }
+
+  @Override
+  public int getMaxRamMB() {
+    return delegate.getMaxRamMB();
+  }
+
+  @Override
+  public int getSize() {
+    return delegate.getSize();
+  }
+
+  @Override
+  public float getHitRatio() {
+    return delegate.getHitRatio();
+  }
+
+  @Override
+  public long ramBytesUsed() {
+    return delegate.ramBytesUsed();
+  }
+
+  @Override
+  public ManagedComponentId getManagedComponentId() {
+    return delegate.getManagedComponentId();
+  }
+
+  @Override
+  public ManagedContext getManagedContext() {
+    return delegate.getManagedContext();
+  }
 }
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
index 3b83093..9f65ec2 100644
--- a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
@@ -30,7 +30,7 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
   }
 
   @Test
-  public void testBasic() throws Exception {
+  public void testBasicRegistration() throws Exception {
 
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java b/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
index 3159e3e..0fb1765 100644
--- a/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
@@ -346,7 +346,7 @@ public class TestFastLRUCache extends SolrTestCase {
     // no evictions yet
     assertEquals(6, cache.size());
     // this also sets minLimit = 4
-    cache.setResourceLimit(SolrCache.SIZE_PARAM, 5);
+    cache.setMaxSize(5);
     // should not happen yet - evictions are triggered by put
     assertEquals(6, cache.size());
     cache.put("6", new Accountable() {
@@ -359,7 +359,7 @@ public class TestFastLRUCache extends SolrTestCase {
     assertEquals(4, cache.size());
 
     // modify ram limit
-    cache.setResourceLimit(SolrCache.MAX_RAM_MB_PARAM, 3);
+    cache.setMaxRamMB(3);
     // should not happen yet - evictions are triggered by put
     assertEquals(4, cache.size());
     // this evicts down to 3MB * 0.8, ie. ramLowerWaterMark
@@ -376,7 +376,7 @@ public class TestFastLRUCache extends SolrTestCase {
 
     // scale up
 
-    cache.setResourceLimit(SolrCache.MAX_RAM_MB_PARAM, 4);
+    cache.setMaxRamMB(4);
     cache.put("8", new Accountable() {
       @Override
       public long ramBytesUsed() {
@@ -385,7 +385,7 @@ public class TestFastLRUCache extends SolrTestCase {
     });
     assertEquals(4, cache.size());
 
-    cache.setResourceLimit(SolrCache.SIZE_PARAM, 10);
+    cache.setMaxSize(10);
     for (int i = 0; i < 6; i++) {
       cache.put("new" + i, new Accountable() {
         @Override
diff --git a/solr/core/src/test/org/apache/solr/search/TestLFUCache.java b/solr/core/src/test/org/apache/solr/search/TestLFUCache.java
index 324d7f4..beac366 100644
--- a/solr/core/src/test/org/apache/solr/search/TestLFUCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestLFUCache.java
@@ -472,7 +472,7 @@ public class TestLFUCache extends SolrTestCaseJ4 {
     // no evictions yet
     assertEquals(6, cache.size());
     // this sets minSize = 4, evictions will target minSize
-    cache.setResourceLimit(SolrCache.SIZE_PARAM, 5);
+    cache.setMaxSize(5);
     // should not happen yet - evictions are triggered by put
     assertEquals(6, cache.size());
     cache.put("6", "foo 6");
@@ -487,7 +487,7 @@ public class TestLFUCache extends SolrTestCaseJ4 {
 
     // scale up
 
-    cache.setResourceLimit(SolrCache.SIZE_PARAM, 10);
+    cache.setMaxSize(10);
     for (int i = 0; i < 6; i++) {
       cache.put("new" + i, "bar " + i);
     }
diff --git a/solr/core/src/test/org/apache/solr/search/TestLRUCache.java b/solr/core/src/test/org/apache/solr/search/TestLRUCache.java
index 3c33e27..f9cd0db 100644
--- a/solr/core/src/test/org/apache/solr/search/TestLRUCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestLRUCache.java
@@ -206,7 +206,7 @@ public class TestLRUCache extends SolrTestCase {
     }
     // no evictions yet
     assertEquals(6, cache.size());
-    cache.setResourceLimit(SolrCache.SIZE_PARAM, 5);
+    cache.setMaxSize(5);
     // should not happen yet - evictions are triggered by put
     assertEquals(6, cache.size());
     cache.put("6", new Accountable() {
@@ -219,7 +219,7 @@ public class TestLRUCache extends SolrTestCase {
     assertEquals(5, cache.size());
 
     // modify ram limit
-    cache.setResourceLimit(SolrCache.MAX_RAM_MB_PARAM, 3);
+    cache.setMaxRamMB(3);
     // should not happen yet - evictions are triggered by put
     assertEquals(5, cache.size());
     cache.put("7", new Accountable() {
@@ -235,7 +235,7 @@ public class TestLRUCache extends SolrTestCase {
 
     // scale up
 
-    cache.setResourceLimit(SolrCache.MAX_RAM_MB_PARAM, 4);
+    cache.setMaxRamMB(4);
     cache.put("8", new Accountable() {
       @Override
       public long ramBytesUsed() {
@@ -244,7 +244,7 @@ public class TestLRUCache extends SolrTestCase {
     });
     assertEquals(4, cache.size());
 
-    cache.setResourceLimit(SolrCache.SIZE_PARAM, 10);
+    cache.setMaxSize(10);
     for (int i = 0; i < 6; i++) {
       cache.put("new" + i, new Accountable() {
         @Override


[lucene-solr] 09/36: Refactoring + updates.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 6f2ccb27589745c3702b2f96ebb8466a109c5f43
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 4 14:27:40 2019 +0200

    Refactoring + updates.
---
 .../managed/AbstractResourceManagerPlugin.java     | 16 +++++++
 .../solr/managed/DefaultResourceManager.java       | 18 +++++++
 .../DefaultResourceManagerPluginFactory.java       | 18 ++++++-
 .../apache/solr/managed/ManagedMetricProducer.java | 20 +++++++-
 .../org/apache/solr/managed/ManagedResource.java   | 37 +++++++++++----
 .../org/apache/solr/managed/ResourceManager.java   | 55 ++++++++++++++++++++--
 .../apache/solr/managed/ResourceManagerPlugin.java | 32 ++++++++++++-
 .../solr/managed/ResourceManagerPluginFactory.java | 23 ++++++++-
 .../apache/solr/managed/ResourceManagerPool.java   | 28 ++++++++---
 .../java/org/apache/solr/managed/package-info.java | 21 +++++++++
 .../solr/managed/plugins/CacheManagerPlugin.java   | 35 ++++++++++----
 .../apache/solr/managed/plugins/package-info.java  | 21 +++++++++
 12 files changed, 288 insertions(+), 36 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
index f75d104..1e630b1 100644
--- a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManagerPlugin.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 /**
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index 3f51897..e6005c8 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.io.IOException;
@@ -19,6 +35,8 @@ import org.slf4j.LoggerFactory;
 
 /**
  * Default implementation of {@link ResourceManager}.
+ * <p>Resource pools managed by this implementation are run periodically, each according to
+ * its schedule defined by {@link #SCHEDULE_DELAY_SECONDS_PARAM} parameter during the pool creation.</p>
  */
 public class DefaultResourceManager extends ResourceManager {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
index 3967c87..ab6be81 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.util.HashMap;
@@ -7,7 +23,7 @@ import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 
 /**
- *
+ * Default implementation of {@link ResourceManagerPluginFactory}.
  */
 public class DefaultResourceManagerPluginFactory implements ResourceManagerPluginFactory {
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
index 9f48702..7885d0f 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.util.Collection;
@@ -8,12 +24,12 @@ import java.util.Map;
 import org.apache.solr.core.SolrInfoBean;
 
 /**
- *
+ * Convenience interface for {@link SolrInfoBean}-s that need to be managed.
  */
 public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
 
   @Override
-  default Map<String, Float> getManagedValues(Collection<String> tags) {
+  default Map<String, Float> getMonitoredValues(Collection<String> tags) {
     Map<String, Object> metrics = getMetricsSnapshot();
     if (metrics == null) {
       return Collections.emptyMap();
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
index 1351a76..0f18028 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.lang.invoke.MethodHandles;
@@ -8,7 +24,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- *
+ * A managed resource.
  */
 public interface ManagedResource {
   Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -19,13 +35,13 @@ public interface ManagedResource {
   String getResourceName();
 
   /**
-   * Returns types of management schemes supported by this resource. This always
-   * returns a non-null collection with at least one entry.
+   * Returns types of management plugins supported by this resource. This must always
+   * return a non-null collection with at least one entry.
    */
   Collection<String> getManagedResourceTypes();
 
   /**
-   * Set current managed limits.
+   * Set values of managed limits.
    * @param limits map of limit names and values
    */
   default void setManagedLimits(Map<String, Float> limits) {
@@ -43,21 +59,22 @@ public interface ManagedResource {
   }
 
   /**
-   * Set a managed limit.
+   * Set value of a managed limit.
    * @param key limit name
    * @param value limit value
    */
   void setManagedLimit(String key, float value) throws Exception;
 
   /**
-   * Returns current managed limits.
+   * Returns current values of managed limits.
+   * @return map where keys are controlled tags and values are current limits
    */
   Map<String, Float> getManagedLimits();
 
   /**
-   * Returns monitored values that are used for calculating optimal setting of managed limits.
-   * @param tags value names
-   * @return map of names to current values.
+   * Returns monitored values that are used for calculating optimal settings of managed limits.
+   * @param tags monitored tags
+   * @return map of tags to current values.
    */
-  Map<String, Float> getManagedValues(Collection<String> tags) throws Exception;
+  Map<String, Float> getMonitoredValues(Collection<String> tags) throws Exception;
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index a49f5d7..867e3f9 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.lang.invoke.MethodHandles;
@@ -17,9 +33,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Base class for resource management. It represents a flat model where there are named
- * resource pools of a given type, each pool with its own defined limits. Resources can be added
- * to a pool for management of a specific aspect of that resource using {@link ResourceManagerPlugin}.
+ * Base class for a resource managemer. It uses a flat model where there are named
+ * resource pools of a given type, each pool with its own defined resource limits. Resources can be added
+ * to a pool for the management of a specific aspect of that resource using {@link ResourceManagerPlugin}.
  */
 public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -65,19 +81,48 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
 
   protected abstract void doInit() throws Exception;
 
+  /**
+   * Create a named resource management pool.
+   * @param name pool name
+   * @param type pool type (one of the supported {@link ResourceManagerPlugin} types)
+   * @param poolLimits pool limits
+   * @param params other parameters. These are also used for creating a {@link ResourceManagerPlugin}
+   */
   public abstract void createPool(String name, String type, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception;
 
+  /**
+   * Modify pool limits.
+   * @param name existing pool name
+   * @param poolLimits new pool limits
+   */
   public abstract void modifyPoolLimits(String name, Map<String, Float> poolLimits) throws Exception;
 
+  /**
+   * Remove pool. This also stops the management of resources registered with that pool.
+   * @param name existing pool name
+   */
   public abstract void removePool(String name) throws Exception;
 
-  public void addResources(String pool, Collection<ManagedResource> managedResource) throws Exception {
+  /**
+   * Add managed resources to a pool.
+   * @param pool existing pool name.
+   * @param managedResources resources to add
+   */
+  public void addResources(String pool, Collection<ManagedResource> managedResources) throws Exception {
     ensureNotClosed();
-    for (ManagedResource resource : managedResource) {
+    for (ManagedResource resource : managedResources) {
       addResource(pool, resource);
     }
   }
 
+  /**
+   * Add a managed resource to a pool.
+   * @param pool existing pool name.
+   * @param managedResource managed resource. The resource must support the management type
+   *                        (in its {@link ManagedResource#getManagedResourceTypes()}) used
+   *                        in the selected pool. The resource must not be already managed by
+   *                        another pool of the same type.
+   */
   public abstract void addResource(String pool, ManagedResource managedResource) throws Exception;
 
   protected void ensureNotClosed() {
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index 0b00198..feb35a1 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -1,20 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.util.Collection;
 import java.util.Map;
 
 /**
- *
+ * A plugin that implements an algorithm for managing a pool of resources of a given type.
  */
 public interface ResourceManagerPlugin {
 
+  /** Plugin type. */
   String getType();
 
   void init(Map<String, Object> params);
 
+  /**
+   * Name of monitored parameters that {@link ManagedResource}-s managed by this plugin
+   * are expected to support.
+   */
   Collection<String> getMonitoredTags();
+  /**
+   * Name of controlled parameters that {@link ManagedResource}-s managed by this plugin
+   * are expected to support.
+   */
   Collection<String> getControlledTags();
 
+  /**
+   * Manage resources in a pool. This method is called periodically by {@link ResourceManager},
+   * according to a schedule defined by the pool.
+   * @param pool pool instance.
+   */
   void manage(ResourceManagerPool pool) throws Exception;
 
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
index b4e1a54..6c8578a 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
@@ -1,11 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.util.Map;
 
 /**
- *
+ * Factory for creating instances of {@link ResourceManagerPlugin}-s.
  */
 public interface ResourceManagerPluginFactory {
 
+  /**
+   * Create a plugin of a given type.
+   * @param type plugin type
+   * @param params plugin parameters
+   */
   ResourceManagerPlugin create(String type, Map<String, Object> params) throws Exception;
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index a1c437a..bfb1b8c 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed;
 
 import java.io.Closeable;
@@ -16,8 +32,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * A pool of resources of the same type, which use the same {@link ResourceManagerPlugin} for managing their
- * resource use.
+ * This class manages a pool of resources of the same type, which use the same
+ * {@link ResourceManagerPlugin} for managing their resource limits.
  */
 public class ResourceManagerPool implements Runnable, Closeable {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -75,7 +91,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
   }
 
   /**
-   * Get the current values from all resources. Result is a map with resource names as keys,
+   * Get the current monitored values from all resources. Result is a map with resource names as keys,
    * and tag/value maps as values.
    */
   public Map<String, Map<String, Float>> getCurrentValues() throws InterruptedException {
@@ -85,7 +101,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
       Map<String, Map<String, Float>> currentValues = new HashMap<>();
       for (ManagedResource resource : resources.values()) {
         try {
-          currentValues.put(resource.getResourceName(), resource.getManagedValues(resourceManagerPlugin.getMonitoredTags()));
+          currentValues.put(resource.getResourceName(), resource.getMonitoredValues(resourceManagerPlugin.getMonitoredTags()));
         } catch (Exception e) {
           log.warn("Error getting managed values from " + resource.getResourceName(), e);
         }
@@ -108,8 +124,8 @@ public class ResourceManagerPool implements Runnable, Closeable {
   }
 
   /**
-   * This returns cumulative values of all resources. NOTE:
-   * you must call {@link #getCurrentValues()} first!
+   * This returns cumulative monitored values of all resources.
+   * <p>NOTE: you must call {@link #getCurrentValues()} first!</p>
    */
   public Map<String, Float> getTotalValues() throws InterruptedException {
     updateLock.lockInterruptibly();
diff --git a/solr/core/src/java/org/apache/solr/managed/package-info.java b/solr/core/src/java/org/apache/solr/managed/package-info.java
new file mode 100644
index 0000000..fd6bf00
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * API and implementation of a resource manager.
+ */
+package org.apache.solr.managed;
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index 345dae4..8783334 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -12,7 +12,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- *
+ * An implementation of {@link org.apache.solr.managed.ResourceManagerPlugin} specific to
+ * the management of {@link org.apache.solr.search.SolrCache} instances.
+ * <p>This plugin calculates the total size and maxRamMB of all registered cache instances
+ * and adjusts each cache's limits so that the aggregated values again fit within the pool limits.</p>
+ * <p>In order to avoid thrashing the plugin uses a dead zone (by default {@link #DEFAULT_DEAD_ZONE}),
+ * which can be adjusted using configuration parameter {@link #DEAD_ZONE}. If monitored values don't
+ * exceed the limits +/- the dead zone no action is taken.</p>
  */
 public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -24,6 +30,9 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   public static final String RAM_BYTES_USED_TAG = "ramBytesUsed";
   public static final String MAX_RAM_MB_TAG = "maxRamMB";
 
+  public static final String DEAD_ZONE = "deadZone";
+  public static final float DEFAULT_DEAD_ZONE = 0.1f;
+
   private static final Map<String, String> controlledToMonitored = new HashMap<>();
 
   static {
@@ -37,16 +46,18 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
       RAM_BYTES_USED_TAG
   );
 
-  @Override
-  public Collection<String> getMonitoredTags() {
-    return MONITORED_TAGS;
-  }
-
   private static final Collection<String> CONTROLLED_TAGS = Arrays.asList(
       MAX_RAM_MB_TAG,
       SIZE_TAG
   );
 
+  private float deadZone = DEFAULT_DEAD_ZONE;
+
+  @Override
+  public Collection<String> getMonitoredTags() {
+    return MONITORED_TAGS;
+  }
+
   @Override
   public Collection<String> getControlledTags() {
     return CONTROLLED_TAGS;
@@ -59,7 +70,12 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
 
   @Override
   public void init(Map<String, Object> params) {
-
+    String deadZoneStr = String.valueOf(params.getOrDefault(DEAD_ZONE, DEFAULT_DEAD_ZONE));
+    try {
+      deadZone = Float.parseFloat(deadZoneStr);
+    } catch (Exception e) {
+      log.warn("Invalid deadZone parameter value '" + deadZoneStr + "', using default " + DEFAULT_DEAD_ZONE);
+    }
   }
 
   @Override
@@ -81,9 +97,8 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
       }
       float totalDelta = poolLimitValue - totalValue;
 
-      // 10% hysteresis to avoid thrashing
-      // TODO: make the threshold configurable
-      if (Math.abs(totalDelta / poolLimitValue) < 0.1f) {
+      // dead zone to avoid thrashing
+      if (Math.abs(totalDelta / poolLimitValue) < deadZone) {
         return;
       }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/package-info.java b/solr/core/src/java/org/apache/solr/managed/plugins/package-info.java
new file mode 100644
index 0000000..5b4ff61
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementations of {@link org.apache.solr.managed.ResourceManagerPlugin}.
+ */
+package org.apache.solr.managed.plugins;


[lucene-solr] 18/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 0a14b236729c2d6d51b74becfef34a5357c382eb
Merge: 32e2cad 1ea8419
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Jul 24 22:10:45 2019 +0200

    Merge branch 'master' into jira/solr-13579

 lucene/CHANGES.txt                                 |   5 +
 .../apache/lucene/search/DisjunctionMaxScorer.java |  28 +++--
 .../DisjunctionScoreBlockBoundaryPropagator.java   | 112 +++++++++++++++++++
 ...estDisjunctionScoreBlockBoundaryPropagator.java | 121 +++++++++++++++++++++
 .../test-files/runtimecode/runtimelibs_v3.jar.bin  | Bin 6526 -> 7337 bytes
 solr/core/src/test-files/runtimecode/sig.txt       |  35 ++++--
 .../org/apache/solr/core/TestDynamicLoading.java   |   8 +-
 .../solr/handler/TestContainerReqHandler.java      |  18 ++-
 .../solr-ref-guide/src/command-line-utilities.adoc |   2 +-
 9 files changed, 294 insertions(+), 35 deletions(-)


[lucene-solr] 14/36: Small fixes and improvements.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 0876676ea869930b123d9e22caf86751e4443a40
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 18 18:49:22 2019 +0200

    Small fixes and improvements.
---
 solr/core/src/java/org/apache/solr/core/CoreContainer.java       | 8 ++++++++
 .../org/apache/solr/handler/admin/ResourceManagerHandler.java    | 8 ++++----
 .../java/org/apache/solr/managed/DefaultResourceManagerPool.java | 9 +++++++--
 solr/core/src/java/org/apache/solr/managed/ResourceManager.java  | 2 ++
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index b68e701..7f27ac9 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -100,6 +100,7 @@ import org.apache.solr.logging.LogWatcher;
 import org.apache.solr.logging.MDCLoggingContext;
 import org.apache.solr.managed.DefaultResourceManager;
 import org.apache.solr.managed.ResourceManager;
+import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.SolrCoreMetricManager;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricProducer;
@@ -616,6 +617,13 @@ public class CoreContainer {
     resourceManager = new DefaultResourceManager(loader, TimeSource.NANO_TIME);
     // TODO: get the config from solr.xml?
     resourceManager.init(new PluginInfo("resourceManager", Collections.emptyMap()));
+    // TODO: create default pools from solr.xml?
+    try {
+      resourceManager.createPool(ResourceManager.SEARCHER_CACHE_POOL, CacheManagerPlugin.TYPE,
+          Collections.singletonMap("maxRamMB", 500), Collections.emptyMap());
+    } catch (Exception e) {
+      log.warn("failed to create default searcherCache pool,, disabling", e);
+    }
 
     coreContainerWorkExecutor = MetricUtils.instrumentedExecutorService(
         coreContainerWorkExecutor, null,
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index bd65132..596672d 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -45,7 +45,6 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static final String POOL_PARAM = "pool";
-  public static final String RESOURCE_PARAM = "resource";
   public static final String LIMIT_PREFIX_PARAM = "limit.";
   public static final String ARG_PREFIX_PARAM = "arg.";
   public static final String POOL_ACTION_PARAM = "poolAction";
@@ -138,6 +137,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           perPool.add("size", pool.getResources().size());
           perPool.add("limits", pool.getPoolLimits());
           perPool.add("args", pool.getArgs());
+          perPool.add("resources", pool.getResources().keySet());
         });
         break;
       case STATUS:
@@ -151,7 +151,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         result.add("args", pool.getArgs());
         result.add("resources", pool.getResources().keySet());
         try {
-          result.add("currentValues", pool.getCurrentValues());
+          pool.getCurrentValues();
           result.add("totalValues", pool.getTotalValues());
         } catch (Exception e) {
           log.warn("Error getting current values from pool " + name, e);
@@ -230,9 +230,9 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
     if (pool == null) {
       throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Pool '" + poolName + "' not found.");
     }
-    String resName = params.get(RESOURCE_PARAM);
+    String resName = params.get(CommonParams.NAME);
     if ((resName == null || resName.isBlank()) && op != ResOp.LIST) {
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Missing '" + RESOURCE_PARAM + "' parameter.");
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Missing '" + CommonParams.NAME + "' parameter.");
     }
     NamedList<Object> result = new SimpleOrderedMap<>();
     switch (op) {
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index aada8c2..3295ef6 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -123,11 +123,16 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
         if (!(v instanceof Number)) {
           return;
         }
+        Float val = ((Number)v).floatValue();
+        // -1 and MAX_VALUE are our special guard values
+        if (val < 0 || val.longValue() == Long.MAX_VALUE || val.longValue() == Integer.MAX_VALUE) {
+          return;
+        }
         Float total = newTotalValues.get(k);
         if (total == null) {
-          newTotalValues.put(k, ((Number)v).floatValue());
+          newTotalValues.put(k, val);
         } else {
-          newTotalValues.put(k, total + ((Number)v).floatValue());
+          newTotalValues.put(k, total + val);
         }
       }));
       totalValues = newTotalValues;
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index aaeedbf..bd2e924 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -36,6 +36,8 @@ import org.slf4j.LoggerFactory;
 public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  public static final String SEARCHER_CACHE_POOL = "searcherCache";
+
   protected PluginInfo pluginInfo;
   protected boolean isClosed = false;
   protected boolean enabled = true;


[lucene-solr] 16/36: Initial integration with SolrIndexSearcher caches.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 1f742686feba3cf5a3db0fb94892a89d083d4a6b
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jul 23 20:42:07 2019 +0200

    Initial integration with SolrIndexSearcher caches.
---
 .../java/org/apache/solr/core/CoreContainer.java   |  27 ++--
 .../solr/handler/admin/ResourceManagerHandler.java |  18 +--
 .../solr/managed/DefaultResourceManager.java       |  35 ++++-
 .../solr/managed/DefaultResourceManagerPool.java   |  12 +-
 .../apache/solr/managed/ManagedMetricProducer.java |   5 -
 .../org/apache/solr/managed/ManagedResource.java   |  27 ++--
 .../apache/solr/managed/NoOpResourceManager.java   | 141 +++++++++++++++++++++
 .../java/org/apache/solr/managed/ResourceId.java   |  63 +++++++++
 .../org/apache/solr/managed/ResourceManager.java   | 103 ++++++++++++++-
 .../apache/solr/managed/ResourceManagerPlugin.java |   4 +-
 .../apache/solr/managed/ResourceManagerPool.java   |   2 +-
 .../solr/managed/plugins/CacheManagerPlugin.java   |  30 ++---
 .../java/org/apache/solr/search/FastLRUCache.java  |  21 +++
 .../src/java/org/apache/solr/search/LFUCache.java  |  21 +++
 .../src/java/org/apache/solr/search/LRUCache.java  |  20 +++
 .../src/java/org/apache/solr/search/SolrCache.java |  19 +--
 .../org/apache/solr/search/SolrIndexSearcher.java  |   9 ++
 17 files changed, 470 insertions(+), 87 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index d350e12..5da961b 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -99,6 +99,7 @@ import org.apache.solr.handler.component.ShardHandlerFactory;
 import org.apache.solr.logging.LogWatcher;
 import org.apache.solr.logging.MDCLoggingContext;
 import org.apache.solr.managed.DefaultResourceManager;
+import org.apache.solr.managed.NoOpResourceManager;
 import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.SolrCoreMetricManager;
@@ -616,17 +617,6 @@ public class CoreContainer {
 
     metricManager = new SolrMetricManager(loader, cfg.getMetricsConfig());
 
-    resourceManager = new DefaultResourceManager(loader, TimeSource.NANO_TIME);
-    // TODO: get the config from solr.xml?
-    resourceManager.init(new PluginInfo("resourceManager", Collections.emptyMap()));
-    // TODO: create default pools from solr.xml?
-    try {
-      resourceManager.createPool(ResourceManager.SEARCHER_CACHE_POOL, CacheManagerPlugin.TYPE,
-          Collections.singletonMap("maxRamMB", 500), Collections.emptyMap());
-    } catch (Exception e) {
-      log.warn("failed to create default searcherCache pool,, disabling", e);
-    }
-
     coreContainerWorkExecutor = MetricUtils.instrumentedExecutorService(
         coreContainerWorkExecutor, null,
         metricManager.registry(SolrMetricManager.getRegistryName(SolrInfoBean.Group.node)),
@@ -677,6 +667,21 @@ public class CoreContainer {
 
     createMetricsHistoryHandler();
 
+    Map<String, Object> resManConfig = new HashMap<>();
+    Map<String, Object> poolConfigs = new HashMap<>(DefaultResourceManager.DEFAULT_NODE_POOLS);
+    resManConfig.put(DefaultResourceManager.POOL_CONFIGS_PARAM, poolConfigs);
+    if (isZooKeeperAware()) {
+      Map<String, Object> clusterProps = getZkController().getZkStateReader().getClusterProperties();
+      poolConfigs.putAll((Map<String, Object>)clusterProps.getOrDefault(DefaultResourceManager.POOL_CONFIGS_PARAM, Collections.emptyMap()));
+    }
+    try {
+      resourceManager = ResourceManager.load(loader, TimeSource.NANO_TIME, DefaultResourceManager.class,
+          new PluginInfo("resourceManager", Collections.emptyMap()), poolConfigs);
+    } catch (Exception e) {
+      log.warn("Resource manager initialization error - disabling!", e);
+      resourceManager = NoOpResourceManager.INSTANCE;
+    }
+
     resourceManagerHandler = new ResourceManagerHandler(resourceManager);
     containerHandlers.put(RESOURCE_MANAGER_PATH, resourceManagerHandler);
     resourceManagerHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, RESOURCE_MANAGER_PATH);
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index 596672d..e76dbc7 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -135,8 +135,8 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           result.add(p, perPool);
           perPool.add("type", pool.getType());
           perPool.add("size", pool.getResources().size());
-          perPool.add("limits", pool.getPoolLimits());
-          perPool.add("args", pool.getArgs());
+          perPool.add("poolLimits", pool.getPoolLimits());
+          perPool.add("poolParams", pool.getParams());
           perPool.add("resources", pool.getResources().keySet());
         });
         break;
@@ -147,8 +147,8 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         }
         result.add("type", pool.getType());
         result.add("size", pool.getResources().size());
-        result.add("limits", pool.getPoolLimits());
-        result.add("args", pool.getArgs());
+        result.add("poolLimits", pool.getPoolLimits());
+        result.add("poolParams", pool.getParams());
         result.add("resources", pool.getResources().keySet());
         try {
           pool.getCurrentValues();
@@ -242,7 +242,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           result.add(n, perRes);
           perRes.add("class", resource.getClass().getName());
           perRes.add("types", resource.getManagedResourceTypes());
-          perRes.add("managedLimits", resource.getManagedLimits());
+          perRes.add("resourceLimits", resource.getResourceLimits());
         });
         break;
       case STATUS:
@@ -252,7 +252,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         }
         result.add("class", resource.getClass().getName());
         result.add("types", resource.getManagedResourceTypes());
-        result.add("managedLimits", resource.getManagedLimits());
+        result.add("resourceLimits", resource.getResourceLimits());
         try {
           result.add("monitoredValues", resource.getMonitoredValues(Collections.emptySet()));
         } catch (Exception e) {
@@ -265,14 +265,14 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         if (resource1 == null) {
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
-        result.add("managedLimits", resource1.getManagedLimits());
+        result.add("resourceLimits", resource1.getResourceLimits());
         break;
       case SETLIMITS:
         ManagedResource resource2 = pool.getResources().get(resName);
         if (resource2 == null) {
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
-        Map<String, Object> currentLimits = new HashMap<>(resource2.getManagedLimits());
+        Map<String, Object> currentLimits = new HashMap<>(resource2.getResourceLimits());
         Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
         newLimits.forEach((k, v) -> {
           if (v == null) {
@@ -281,7 +281,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
             currentLimits.put(k, v);
           }
         });
-        resource2.setManagedLimits(newLimits);
+        resource2.setResourceLimits(newLimits);
         result.add("success", newLimits);
         break;
       case DELETE:
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index e8c9c99..df211b3 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -20,17 +20,21 @@ import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.managed.plugins.CacheManagerPlugin;
+import org.apache.solr.search.SolrCache;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,12 +47,26 @@ import org.slf4j.LoggerFactory;
 public class DefaultResourceManager extends ResourceManager {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+
   public static final String SCHEDULE_DELAY_SECONDS_PARAM = "scheduleDelaySeconds";
   public static final String MAX_NUM_POOLS_PARAM = "maxNumPools";
 
   public static final int DEFAULT_MAX_POOLS = 100;
   public static final int DEFAULT_SCHEDULE_DELAY_SECONDS = 30;
 
+  public static final String NODE_SEARCHER_CACHE_POOL = "nodeSearcherCachePool";
+
+  public static final Map<String, Map<String, Object>> DEFAULT_NODE_POOLS = new HashMap<>();
+
+  static {
+    Map<String, Object> params = new HashMap<>();
+    params.put(CommonParams.TYPE, CacheManagerPlugin.TYPE);
+    // unlimited RAM
+    params.put(SolrCache.MAX_RAM_MB_PARAM, -1L);
+    DEFAULT_NODE_POOLS.put(NODE_SEARCHER_CACHE_POOL, params);
+  }
+
+
   protected int maxNumPools = DEFAULT_MAX_POOLS;
 
   protected Map<String, ResourceManagerPool> resourcePools = new ConcurrentHashMap<>();
@@ -67,6 +85,7 @@ public class DefaultResourceManager extends ResourceManager {
   protected ResourceManagerPluginFactory resourceManagerPluginFactory;
   protected SolrResourceLoader loader;
 
+
   public DefaultResourceManager(SolrResourceLoader loader, TimeSource timeSource) {
     this.loader = loader;
     this.timeSource = timeSource;
@@ -77,7 +96,7 @@ public class DefaultResourceManager extends ResourceManager {
         new DefaultSolrThreadFactory(getClass().getSimpleName()));
     scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
     scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-    // TODO: make configurable
+    // TODO: make configurable based on plugin info
     resourceManagerPluginFactory = new DefaultResourceManagerPluginFactory(loader);
     log.info("Resource manager initialized.");
   }
@@ -127,7 +146,7 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void modifyPoolLimits(String name, Map<String, Object> poolLimits) throws Exception {
+  public void setPoolLimits(String name, Map<String, Object> poolLimits) throws Exception {
     ensureActive();
     ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
@@ -162,7 +181,7 @@ public class DefaultResourceManager extends ResourceManager {
         return;
       }
       if (otherPool.getType().equals(type)) {
-        throw new IllegalArgumentException("Resource " + managedResource.getResourceName() +
+        throw new IllegalArgumentException("Resource " + managedResource.getResourceId() +
             " is already managed in another pool (" +
             otherPool.getName() + ") of the same type " + type);
       }
@@ -171,6 +190,16 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
+  public boolean removeResource(String poolName, String resourceId) {
+    ensureActive();
+    ResourceManagerPool pool = resourcePools.get(poolName);
+    if (pool == null) {
+      throw new IllegalArgumentException("Pool '" + poolName + "' doesn't exist.");
+    }
+    return pool.removeResource(resourceId);
+  }
+
+  @Override
   public void close() throws IOException {
     synchronized (this) {
       isClosed = true;
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 3295ef6..ace9da4 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -76,7 +76,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public Map<String, Object> getArgs() {
+  public Map<String, Object> getParams() {
     return args;
   }
 
@@ -84,12 +84,12 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   public void addResource(ManagedResource managedResource) {
     Collection<String> types = managedResource.getManagedResourceTypes();
     if (!types.contains(type)) {
-      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getResourceName());
+      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getResourceId());
       return;
     }
-    ManagedResource existing = resources.putIfAbsent(managedResource.getResourceName(), managedResource);
+    ManagedResource existing = resources.putIfAbsent(managedResource.getResourceId().toString(), managedResource);
     if (existing != null) {
-      throw new IllegalArgumentException("Resource '" + managedResource.getResourceName() + "' already exists in pool '" + name + "' !");
+      throw new IllegalArgumentException("Resource '" + managedResource.getResourceId() + "' already exists in pool '" + name + "' !");
     }
   }
 
@@ -111,9 +111,9 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
       Map<String, Map<String, Object>> currentValues = new HashMap<>();
       for (ManagedResource resource : resources.values()) {
         try {
-          currentValues.put(resource.getResourceName(), resource.getMonitoredValues(resourceManagerPlugin.getMonitoredTags()));
+          currentValues.put(resource.getResourceId().toString(), resource.getMonitoredValues(resourceManagerPlugin.getMonitoredParams()));
         } catch (Exception e) {
-          log.warn("Error getting managed values from " + resource.getResourceName(), e);
+          log.warn("Error getting managed values from " + resource.getResourceId(), e);
         }
       }
       // calculate totals
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
index 00167ab6..891c1d8 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
@@ -44,9 +44,4 @@ public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
     });
     return result;
   }
-
-  @Override
-  default String getResourceName() {
-    return getName();
-  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
index 7ace1e1..d943384 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -30,9 +30,10 @@ public interface ManagedResource {
   Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   /**
-   * Unique name of this resource.
+   * Unique name of this resource. By convention id-s form a dot-separated hierarchy that
+   * follows the naming of metric registries and metric names.
    */
-  String getResourceName();
+  ResourceId getResourceId();
 
   /**
    * Returns types of management plugins supported by this resource. This must always
@@ -41,38 +42,38 @@ public interface ManagedResource {
   Collection<String> getManagedResourceTypes();
 
   /**
-   * Set values of managed limits.
+   * Set values of managed resource limits.
    * @param limits map of limit names and values
    */
-  default void setManagedLimits(Map<String, Object> limits) {
+  default void setResourceLimits(Map<String, Object> limits) {
     if (limits == null) {
       return;
     }
     limits.forEach((key, value) -> {
       try {
-        setManagedLimit(key, value);
+        setResourceLimit(key, value);
       } catch (Exception e) {
-        log.warn("Exception setting managed limit on {}: key={}, value={}, exception={}",
-            getResourceName(), key, value, e);
+        log.warn("Exception setting resource limit on {}: key={}, value={}, exception={}",
+            getResourceId(), key, value, e);
       }
     });
   }
 
   /**
-   * Set value of a managed limit.
+   * Set value of a managed resource limit.
    * @param key limit name
    * @param value limit value
    */
-  void setManagedLimit(String key, Object value) throws Exception;
+  void setResourceLimit(String key, Object value) throws Exception;
 
   /**
-   * Returns current values of managed limits.
-   * @return map where keys are controlled tags and values are current limits
+   * Returns current values of managed resource limits.
+   * @return map where keys are controlled parameters and values are current values of limits
    */
-  Map<String, Object> getManagedLimits();
+  Map<String, Object> getResourceLimits();
 
   /**
-   * Returns monitored values that are used for calculating optimal settings of managed limits.
+   * Returns monitored values that are used for calculating optimal settings of managed resource limits.
    * @param tags selected monitored tags, empty collection to return all monitored values
    * @return map of tags to current values.
    */
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
new file mode 100644
index 0000000..08546aa
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.managed;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ *
+ */
+public class NoOpResourceManager extends ResourceManager {
+  public static final String NOOP = "--noop--";
+
+  public static final NoOpResourceManager INSTANCE = new NoOpResourceManager();
+
+  private static final class NoOpResourcePool implements ResourceManagerPool {
+    static NoOpResourcePool INSTANCE = new NoOpResourcePool();
+
+    @Override
+    public String getName() {
+      return NOOP;
+    }
+
+    @Override
+    public String getType() {
+      return NOOP;
+    }
+
+    @Override
+    public void addResource(ManagedResource managedResource) {
+
+    }
+
+    @Override
+    public boolean removeResource(String name) {
+      return false;
+    }
+
+    @Override
+    public Map<String, ManagedResource> getResources() {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<String, Float> getTotalValues() throws InterruptedException {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<String, Object> getPoolLimits() {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public Map<String, Object> getParams() {
+      return Collections.emptyMap();
+    }
+
+    @Override
+    public void setPoolLimits(Map<String, Object> poolLimits) {
+
+    }
+
+    @Override
+    public void close() throws IOException {
+
+    }
+
+    @Override
+    public void run() {
+
+    }
+  }
+
+  @Override
+  protected void doInit() throws Exception {
+
+  }
+
+  @Override
+  public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
+
+  }
+
+  @Override
+  public Collection<String> listPools() {
+    return Collections.singleton(NoOpResourcePool.INSTANCE.getName());
+  }
+
+  @Override
+  public ResourceManagerPool getPool(String name) {
+    return NoOpResourcePool.INSTANCE;
+  }
+
+  @Override
+  public void setPoolLimits(String name, Map<String, Object> poolLimits) throws Exception {
+
+  }
+
+  @Override
+  public void removePool(String name) throws Exception {
+
+  }
+
+  @Override
+  public void addResource(String pool, ManagedResource managedResource) throws Exception {
+
+  }
+
+  @Override
+  public boolean removeResource(String pool, String resourceId) {
+    return false;
+  }
+
+  @Override
+  public void close() throws IOException {
+
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceId.java b/solr/core/src/java/org/apache/solr/managed/ResourceId.java
new file mode 100644
index 0000000..81b7a80
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceId.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.managed;
+
+import java.util.Arrays;
+
+import org.apache.solr.metrics.SolrMetricManager;
+
+/**
+ * Hierarchical resource id.
+ */
+public class ResourceId {
+  private final String name;
+  private final String[] path;
+  private final String id;
+
+  public ResourceId(String name, String... path) {
+    this.name = name;
+    this.path = path;
+    this.id = SolrMetricManager.mkName(name, path);
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String[] getPath() {
+    return path;
+  }
+
+  public String toString() {
+    return id;
+  }
+
+  public ResourceId of(String fullName) {
+    if (fullName == null || fullName.isEmpty()) {
+      return null;
+    }
+    String[] parts = fullName.split("\\.");
+    if (parts.length > 1) {
+      String name = parts[parts.length - 1];
+      String[] path = Arrays.copyOfRange(parts, 0, parts.length - 1);
+      return new ResourceId(name, path);
+    } else {
+      return new ResourceId(parts[0]);
+    }
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index bd2e924..43054fe 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -14,35 +14,97 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.solr.managed;
 
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.solr.common.SolrCloseable;
+import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.util.IOUtils;
+import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
+import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.schema.FieldType;
 import org.apache.solr.util.SolrPluginUtils;
 import org.apache.solr.util.plugin.PluginInfoInitialized;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Base class for a resource managemer. It uses a flat model where there are named
+ * Base class for a resource management. It uses a flat model where there are named
  * resource pools of a given type, each pool with its own defined resource limits. Resources can be added
  * to a pool for the management of a specific aspect of that resource using {@link ResourceManagerPlugin}.
  */
 public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  public static final String SEARCHER_CACHE_POOL = "searcherCache";
+  public static final String RESOURCE_MANAGER_PARAM = "resourceManager";
+  public static final String POOL_CONFIGS_PARAM = "poolConfigs";
+  public static final String POOL_LIMITS_PARAM = "poolLimits";
+  public static final String POOL_PARAMS_PARAM = "poolParams";
 
   protected PluginInfo pluginInfo;
   protected boolean isClosed = false;
   protected boolean enabled = true;
   protected boolean initialized = false;
 
+  /**
+   * Create a resource manager and optionally create configured pools.
+   * @param loader SolrResourceLoader instance
+   * @param timeSource time source instance
+   * @param resourceManagerClass implementation class for the resource manager
+   * @param pluginInfo resource manager plugin info
+   * @param config resource manager and pool configurations
+   */
+  public static ResourceManager load(SolrResourceLoader loader, TimeSource timeSource,
+                           Class<? extends ResourceManager> resourceManagerClass, PluginInfo pluginInfo,
+                           Map<String, Object> config) throws Exception {
+    Map<String, Object> managerOverrides = (Map<String, Object>)config.getOrDefault(RESOURCE_MANAGER_PARAM, Collections.emptyMap());
+    if (!managerOverrides.isEmpty()) {
+      Map<String, Object> pluginMap = new HashMap<>();
+      pluginInfo.toMap(pluginMap);
+      pluginMap.putAll(managerOverrides);
+      if (pluginMap.containsKey(FieldType.CLASS_NAME)) {
+        resourceManagerClass = loader.findClass((String)pluginMap.get(FieldType.CLASS_NAME), ResourceManager.class);
+      }
+      pluginInfo = new PluginInfo(pluginInfo.type, pluginMap);
+    }
+
+    ResourceManager resourceManager = loader.newInstance(
+        resourceManagerClass.getName(),
+        resourceManagerClass,
+        null,
+        new Class[]{SolrResourceLoader.class, TimeSource.class},
+        new Object[]{loader, timeSource});
+    resourceManager.init(pluginInfo);
+    Map<String, Object> poolConfigs = (Map<String, Object>)config.get(POOL_CONFIGS_PARAM);
+    if (poolConfigs != null) {
+      for (String poolName : poolConfigs.keySet()) {
+        Map<String, Object> params = (Map<String, Object>)poolConfigs.get(poolName);
+        if (params == null || params.isEmpty()) {
+          throw new IllegalArgumentException("Pool '" + poolName + "' configuration missing: " + poolConfigs);
+        }
+        String type = (String)params.get(CommonParams.TYPE);
+        if (type == null || type.isBlank()) {
+          throw new IllegalArgumentException("Pool '" + poolName + "' type is missing: " + params);
+        }
+        Map<String, Object> poolLimits = (Map<String, Object>)params.getOrDefault(POOL_LIMITS_PARAM, Collections.emptyMap());
+        Map<String, Object> poolParams = (Map<String, Object>)params.getOrDefault(POOL_PARAMS_PARAM, Collections.emptyMap());
+        try {
+          resourceManager.createPool(poolName, type, poolLimits, poolParams);
+        } catch (Exception e) {
+          log.warn("Failed to create resource manager pool '" + poolName + "'", e);
+        }
+      }
+    }
+    return resourceManager;
+  }
+
   @Override
   public void init(PluginInfo info) {
     if (info != null) {
@@ -81,6 +143,28 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
 
   protected abstract void doInit() throws Exception;
 
+  public void updatePoolConfigs(Map<String, Object> newPoolConfigs) throws Exception {
+    if (newPoolConfigs == null || newPoolConfigs.isEmpty()) {
+      return;
+    }
+
+    for (Map.Entry<String, Object> entry : newPoolConfigs.entrySet()) {
+      String poolName = entry.getKey();
+      Map<String, Object> params = (Map<String, Object>)entry.getValue();
+      ResourceManagerPool pool = getPool(poolName);
+      if (pool == null) {
+        log.warn("Cannot update config - pool '" + poolName + "' not found.");
+        continue;
+      }
+      String type = (String)params.get(CommonParams.TYPE);
+      if (type == null || type.isBlank()) {
+        throw new IllegalArgumentException("Pool '" + poolName + "' type is missing: " + params);
+      }
+      Map<String, Object> poolLimits = (Map<String, Object>)params.getOrDefault(POOL_LIMITS_PARAM, Collections.emptyMap());
+      pool.setPoolLimits(poolLimits);
+    }
+  }
+
   /**
    * Create a named resource management pool.
    * @param name pool name
@@ -99,11 +183,12 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
   public abstract ResourceManagerPool getPool(String name);
 
   /**
-   * Modify pool limits.
+   * Modify pool limits of an existing pool.
    * @param name existing pool name
-   * @param poolLimits new pool limits
+   * @param poolLimits new pool limits. By convention only the values present in this map will be modified,
+   *                   all other limits will remain unchanged. In order to remove a limit use null value.
    */
-  public abstract void modifyPoolLimits(String name, Map<String, Object> poolLimits) throws Exception;
+  public abstract void setPoolLimits(String name, Map<String, Object> poolLimits) throws Exception;
 
   /**
    * Remove pool. This also stops the management of resources registered with that pool.
@@ -133,6 +218,14 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    */
   public abstract void addResource(String pool, ManagedResource managedResource) throws Exception;
 
+  /**
+   * Remove a managed resource from a pool.
+   * @param pool existing pool name.
+   * @param resourceId resource id to remove
+   * @return true if a resource was actually registered and has been removed
+   */
+  public abstract boolean removeResource(String pool, String resourceId);
+
   protected void ensureActive() {
     if (isClosed()) {
       throw new IllegalStateException("Already closed.");
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index feb35a1..f531c46 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -33,12 +33,12 @@ public interface ResourceManagerPlugin {
    * Name of monitored parameters that {@link ManagedResource}-s managed by this plugin
    * are expected to support.
    */
-  Collection<String> getMonitoredTags();
+  Collection<String> getMonitoredParams();
   /**
    * Name of controlled parameters that {@link ManagedResource}-s managed by this plugin
    * are expected to support.
    */
-  Collection<String> getControlledTags();
+  Collection<String> getControlledParams();
 
   /**
    * Manage resources in a pool. This method is called periodically by {@link ResourceManager},
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 453e293..cf32d40 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -40,7 +40,7 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   Map<String, Object> getPoolLimits();
 
   /** Get parameters specified during creation. */
-  Map<String, Object> getArgs();
+  Map<String, Object> getParams();
 
   /**
    * Pool limits are defined using controlled tags.
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index 5adf7ef..1524d89 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -16,8 +16,8 @@ import org.slf4j.LoggerFactory;
  * the management of {@link org.apache.solr.search.SolrCache} instances.
  * <p>This plugin calculates the total size and maxRamMB of all registered cache instances
  * and adjusts each cache's limits so that the aggregated values again fit within the pool limits.</p>
- * <p>In order to avoid thrashing the plugin uses a dead zone (by default {@link #DEFAULT_DEAD_ZONE}),
- * which can be adjusted using configuration parameter {@link #DEAD_ZONE}. If monitored values don't
+ * <p>In order to avoid thrashing the plugin uses a dead zone (by default {@link #DEFAULT_DEAD_BAND}),
+ * which can be adjusted using configuration parameter {@link #DEAD_BAND}. If monitored values don't
  * exceed the limits +/- the dead zone no action is taken.</p>
  */
 public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
@@ -30,8 +30,8 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   public static final String RAM_BYTES_USED_TAG = "ramBytesUsed";
   public static final String MAX_RAM_MB_TAG = "maxRamMB";
 
-  public static final String DEAD_ZONE = "deadZone";
-  public static final float DEFAULT_DEAD_ZONE = 0.1f;
+  public static final String DEAD_BAND = "deadBand";
+  public static final float DEFAULT_DEAD_BAND = 0.1f;
 
   private static final Map<String, String> controlledToMonitored = new HashMap<>();
 
@@ -51,15 +51,15 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
       SIZE_TAG
   );
 
-  private float deadZone = DEFAULT_DEAD_ZONE;
+  private float deadBand = DEFAULT_DEAD_BAND;
 
   @Override
-  public Collection<String> getMonitoredTags() {
+  public Collection<String> getMonitoredParams() {
     return MONITORED_TAGS;
   }
 
   @Override
-  public Collection<String> getControlledTags() {
+  public Collection<String> getControlledParams() {
     return CONTROLLED_TAGS;
   }
 
@@ -70,11 +70,11 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
 
   @Override
   public void init(Map<String, Object> params) {
-    String deadZoneStr = String.valueOf(params.getOrDefault(DEAD_ZONE, DEFAULT_DEAD_ZONE));
+    String deadBandStr = String.valueOf(params.getOrDefault(DEAD_BAND, DEFAULT_DEAD_BAND));
     try {
-      deadZone = Float.parseFloat(deadZoneStr);
+      deadBand = Float.parseFloat(deadBandStr);
     } catch (Exception e) {
-      log.warn("Invalid deadZone parameter value '" + deadZoneStr + "', using default " + DEFAULT_DEAD_ZONE);
+      log.warn("Invalid deadBand parameter value '" + deadBandStr + "', using default " + DEFAULT_DEAD_BAND);
     }
   }
 
@@ -102,15 +102,15 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
       }
       float totalDelta = poolLimitValue - totalValue;
 
-      // dead zone to avoid thrashing
-      if (Math.abs(totalDelta / poolLimitValue) < deadZone) {
+      // dead band to avoid thrashing
+      if (Math.abs(totalDelta / poolLimitValue) < deadBand) {
         return;
       }
 
       float changeRatio = poolLimitValue / totalValue;
       // modify current limits by the changeRatio
       pool.getResources().forEach((name, resource) -> {
-        Map<String, Object> resourceLimits = resource.getManagedLimits();
+        Map<String, Object> resourceLimits = resource.getResourceLimits();
         Object limit = resourceLimits.get(poolLimitName);
         if (limit == null || !(limit instanceof Number)) {
           return;
@@ -121,10 +121,10 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
         }
         float newLimit = currentResourceLimit * changeRatio;
         try {
-          resource.setManagedLimit(poolLimitName, newLimit);
+          resource.setResourceLimit(poolLimitName, newLimit);
         } catch (Exception e) {
           log.warn("Failed to set managed limit " + poolLimitName +
-              " from " + currentResourceLimit + " to " + newLimit + " on " + resource.getResourceName(), e);
+              " from " + currentResourceLimit + " to " + newLimit + " on " + resource.getResourceId(), e);
         }
       });
     });
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 8f19729..539cd05 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -20,6 +20,8 @@ import com.codahale.metrics.MetricRegistry;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.managed.ResourceId;
+import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.ConcurrentLRUCache;
@@ -27,6 +29,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.List;
@@ -79,6 +83,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
+  private ResourceId resourceId;
 
   @Override
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
@@ -305,6 +310,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
       }
     });
     manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+    resourceId = new ResourceId(tag, registryName, getCategory().toString(), scope);
   }
 
 
@@ -343,6 +349,21 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   }
 
   @Override
+  public Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception {
+    return cacheMap.getValue();
+  }
+
+  @Override
+  public ResourceId getResourceId() {
+    return resourceId;
+  }
+
+  @Override
+  public Collection<String> getManagedResourceTypes() {
+    return Collections.singleton(CacheManagerPlugin.TYPE);
+  }
+
+  @Override
   public void setResourceLimit(String limitName, Object val) {
     if (CLEANUP_THREAD_PARAM.equals(limitName)) {
       Boolean value;
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 37ef4c6..5750247 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -17,6 +17,8 @@
 package org.apache.solr.search;
 
 import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.List;
@@ -29,6 +31,8 @@ import com.codahale.metrics.MetricRegistry;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.managed.ResourceId;
+import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.ConcurrentLFUCache;
@@ -80,6 +84,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
+  private ResourceId resourceId;
 
   private int sizeLimit;
   private int minSizeLimit;
@@ -312,6 +317,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
       }
     });
     manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+    resourceId = new ResourceId(tag, registryName, getCategory().toString(), scope);
   }
 
   // for unit tests only
@@ -346,6 +352,11 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   @Override
+  public ResourceId getResourceId() {
+    return resourceId;
+  }
+
+  @Override
   public Map<String, Object> getResourceLimits() {
     Map<String, Object> limits = new HashMap<>();
     limits.put(SIZE_PARAM, cache.getStats().getCurrentSize());
@@ -359,6 +370,16 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   @Override
+  public Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception {
+    return cacheMap.getValue();
+  }
+
+  @Override
+  public Collection<String> getManagedResourceTypes() {
+    return Collections.singleton(CacheManagerPlugin.TYPE);
+  }
+
+  @Override
   public synchronized void setResourceLimit(String limitName, Object val) {
     if (TIME_DECAY_PARAM.equals(limitName) || CLEANUP_THREAD_PARAM.equals(limitName)) {
       Boolean value;
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index 3bd5f00..535c2f0 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -18,6 +18,7 @@ package org.apache.solr.search;
 
 import java.lang.invoke.MethodHandles;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.Iterator;
@@ -32,6 +33,8 @@ import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Accountables;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.managed.ResourceId;
+import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.slf4j.Logger;
@@ -78,6 +81,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   private MetricRegistry registry;
   private int sizeLimit;
   private int initialSize;
+  private ResourceId resourceId;
 
   private long maxRamBytes = Long.MAX_VALUE;
   // The synchronization used for the map will be used to update this,
@@ -335,6 +339,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
       res.put("cumulative_evictionsRamUsage", stats.evictionsRamUsage.longValue());
     });
     manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+    resourceId = new ResourceId(tag, registryName, getCategory().toString(), scope);
   }
 
   // for unit tests only
@@ -375,6 +380,21 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   }
 
   @Override
+  public Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception {
+    return cacheMap.getValue();
+  }
+
+  @Override
+  public ResourceId getResourceId() {
+    return resourceId;
+  }
+
+  @Override
+  public Collection<String> getManagedResourceTypes() {
+    return Collections.singleton(CacheManagerPlugin.TYPE);
+  }
+
+  @Override
   public void setResourceLimit(String limitName, Object val) {
     if (!(val instanceof Number)) {
       try {
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 2cf49da..14fbb82 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -17,6 +17,7 @@
 package org.apache.solr.search;
 
 import org.apache.solr.core.SolrInfoBean;
+import org.apache.solr.managed.ManagedResource;
 import org.apache.solr.metrics.SolrMetricProducer;
 
 import java.util.Map;
@@ -25,7 +26,7 @@ import java.util.Map;
 /**
  * Primary API for dealing with Solr's internal caches.
  */
-public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer {
+public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedResource {
 
   String SIZE_PARAM = "size";
   String MAX_RAM_MB_PARAM = "maxRamMB";
@@ -129,20 +130,4 @@ public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer {
   /** Frees any non-memory resources */
   public void close();
 
-  /** Report current resource limits. */
-  public Map<String, Object> getResourceLimits();
-
-  /** Set resource limits. */
-  default void setResourceLimits(Map<String, Object> limits) throws Exception {
-    if (limits == null || limits.isEmpty()) {
-      return;
-    }
-    for (Map.Entry<String, Object> entry : limits.entrySet()) {
-      setResourceLimit(entry.getKey(), entry.getValue());
-    }
-  }
-
-  /** Set a named resource limit. */
-  public void setResourceLimit(String limitName, Object value) throws Exception;
-
 }
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 8b121e0..561136e 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -67,6 +67,8 @@ import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrInfoBean;
 import org.apache.solr.index.SlowCompositeReaderWrapper;
+import org.apache.solr.managed.DefaultResourceManager;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricProducer;
 import org.apache.solr.request.LocalSolrQueryRequest;
@@ -424,9 +426,15 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
       infoRegistry.put(cache.name(), cache);
     }
     metricManager = core.getCoreContainer().getMetricManager();
+    ResourceManager resourceManager = core.getCoreContainer().getResourceManager();
     registryName = core.getCoreMetricManager().getRegistryName();
     for (SolrCache cache : cacheList) {
       cache.initializeMetrics(metricManager, registryName, core.getMetricTag(), SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
+      try {
+        resourceManager.addResource(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache);
+      } catch (Exception e) {
+        log.warn("Exception adding cache '" + cache.getResourceId() + "' to the resource manager pool", e);
+      }
     }
     initializeMetrics(metricManager, registryName, core.getMetricTag(), STATISTICS_KEY);
     registerTime = new Date();
@@ -471,6 +479,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
     }
 
     for (SolrCache cache : cacheList) {
+      core.getCoreContainer().getResourceManager().removeResource(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getResourceId().toString());
       cache.close();
     }
 


[lucene-solr] 21/36: Minor edits.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 4890c43040229b739e893101a3708033a24255d4
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jul 30 20:49:50 2019 +0200

    Minor edits.
---
 .../solr/managed/DefaultResourceManagerPool.java   |  4 +--
 .../solr/managed/plugins/CacheManagerPlugin.java   |  8 ++---
 .../managed/TestDefaultResourceManagerPool.java    | 36 ++++++++++++++++++++++
 3 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index efe892d..9f87f42 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -108,7 +108,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
     updateLock.lockInterruptibly();
     try {
-      // collect current values
+      // collect the current values
       Map<String, Map<String, Object>> currentValues = new HashMap<>();
       for (ManagedComponent managedComponent : resources.values()) {
         try {
@@ -117,7 +117,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
           log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
         }
       }
-      // calculate totals
+      // calculate the totals
       Map<String, Float> newTotalValues = new HashMap<>();
       currentValues.values().forEach(map -> map.forEach((k, v) -> {
         // only calculate totals for numbers
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index 67a5bf3..ad1ef3e 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -45,25 +45,25 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   public static final String DEAD_BAND = "deadBand";
   public static final float DEFAULT_DEAD_BAND = 0.1f;
 
-  private static final Map<String, String> controlledToMonitored = new HashMap<>();
+  protected static final Map<String, String> controlledToMonitored = new HashMap<>();
 
   static {
     controlledToMonitored.put(SolrCache.MAX_RAM_MB_PARAM, SolrCache.RAM_BYTES_USED_PARAM);
     controlledToMonitored.put(SolrCache.MAX_SIZE_PARAM, SolrCache.SIZE_PARAM);
   }
 
-  private static final Collection<String> MONITORED_PARAMS = Arrays.asList(
+  protected static final Collection<String> MONITORED_PARAMS = Arrays.asList(
       SolrCache.SIZE_PARAM,
       SolrCache.HIT_RATIO_PARAM,
       SolrCache.RAM_BYTES_USED_PARAM
   );
 
-  private static final Collection<String> CONTROLLED_PARAMS = Arrays.asList(
+  protected static final Collection<String> CONTROLLED_PARAMS = Arrays.asList(
       SolrCache.MAX_RAM_MB_PARAM,
       SolrCache.MAX_SIZE_PARAM
   );
 
-  private float deadBand = DEFAULT_DEAD_BAND;
+  protected float deadBand = DEFAULT_DEAD_BAND;
 
   @Override
   public Collection<String> getMonitoredParams() {
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
new file mode 100644
index 0000000..3b83093
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
@@ -0,0 +1,36 @@
+package org.apache.solr.managed;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.util.IOUtils;
+import org.apache.solr.common.util.TimeSource;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
+
+  private final int SPEED = 50;
+
+  private ResourceManager resourceManager;
+
+  @Before
+  public void initManager() {
+    resourceManager = new DefaultResourceManager(h.getCoreContainer().getResourceLoader(), TimeSource.get("simTime:" + SPEED));
+  }
+
+  @After
+  public void destroyManager() {
+    if (resourceManager != null) {
+      IOUtils.closeQuietly(resourceManager);
+      resourceManager = null;
+    }
+  }
+
+  @Test
+  public void testBasic() throws Exception {
+
+  }
+}


[lucene-solr] 04/36: Small refactorings.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 2f7bdfed57d643d3cedb8577c251c0614487398d
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Mon Jun 24 20:15:06 2019 +0200

    Small refactorings.
---
 .../solr/managed/DefaultResourceManager.java       | 54 ++++-------------
 .../org/apache/solr/managed/ResourceManager.java   | 70 +++++++++++++++++++---
 .../apache/solr/managed/ResourceManagerPool.java   | 30 +++++++---
 3 files changed, 93 insertions(+), 61 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index c509e2b..743b1d9 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -2,7 +2,6 @@ package org.apache.solr.managed;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
-import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
@@ -15,25 +14,26 @@ import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.util.DefaultSolrThreadFactory;
-import org.apache.solr.util.SolrPluginUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  *
  */
-public class DefaultResourceManager implements ResourceManager {
+public class DefaultResourceManager extends ResourceManager {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static final String SCHEDULE_DELAY_SECONDS_PARAM = "scheduleDelaySeconds";
   public static final String MAX_NUM_POOLS_PARAM = "maxNumPools";
 
-  public static final int DEFAULT_MAX_POOLS = 20;
+  public static final int DEFAULT_MAX_POOLS = 100;
+  public static final int DEFAULT_SCHEDULE_DELAY_SECONDS = 60;
+
+  protected int maxNumPools = DEFAULT_MAX_POOLS;
+
+  protected Map<String, ResourceManagerPool> resourcePools = new ConcurrentHashMap<>();
 
 
-  private Map<String, ResourceManagerPool> resourcePools = new ConcurrentHashMap<>();
-  private PluginInfo pluginInfo;
-  private int maxNumPools = DEFAULT_MAX_POOLS;
   private TimeSource timeSource;
 
   /**
@@ -52,18 +52,7 @@ public class DefaultResourceManager implements ResourceManager {
     this.timeSource = timeSource;
   }
 
-  @Override
-  public void init(PluginInfo info) {
-    if (info != null) {
-      this.pluginInfo = info.copy();
-      if (pluginInfo.initArgs != null) {
-        SolrPluginUtils.invokeSetters(this, this.pluginInfo.initArgs);
-      }
-    }
-    if (!enabled) {
-      log.debug("Resource manager " + getClass().getSimpleName() + " disabled.");
-      return;
-    }
+  protected void doInit() throws Exception {
     scheduledThreadPoolExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(maxNumPools,
         new DefaultSolrThreadFactory(getClass().getSimpleName()));
     scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
@@ -81,13 +70,6 @@ public class DefaultResourceManager implements ResourceManager {
   }
 
   @Override
-  public void setEnabled(Boolean enabled) {
-    if (enabled != null) {
-      this.enabled = enabled;
-    }
-  }
-
-  @Override
   public PluginInfo getPluginInfo() {
     return pluginInfo;
   }
@@ -101,8 +83,8 @@ public class DefaultResourceManager implements ResourceManager {
     if (resourcePools.size() >= maxNumPools) {
       throw new IllegalArgumentException("Maximum number of pools (" + maxNumPools + ") reached.");
     }
-    ResourceManagerPool newPool = new ResourceManagerPool(resourceManagerPluginFactory, type, limits, params);
-    newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(params.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, 10)));
+    ResourceManagerPool newPool = new ResourceManagerPool(name, type, resourceManagerPluginFactory, limits, params);
+    newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(params.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, DEFAULT_SCHEDULE_DELAY_SECONDS)));
     resourcePools.putIfAbsent(name, newPool);
     newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(newPool, 0,
         timeSource.convertDelay(TimeUnit.SECONDS, newPool.scheduleDelaySeconds, TimeUnit.MILLISECONDS),
@@ -126,17 +108,7 @@ public class DefaultResourceManager implements ResourceManager {
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
     }
-    if (pool.scheduledFuture != null) {
-      pool.scheduledFuture.cancel(true);
-    }
-  }
-
-  @Override
-  public void addResources(String name, Collection<ManagedResource> managedResource) {
-    ensureNotClosed();
-    for (ManagedResource resource : managedResource) {
-      addResource(name, resource);
-    }
+    IOUtils.closeQuietly(pool);
   }
 
   @Override
@@ -166,8 +138,4 @@ public class DefaultResourceManager implements ResourceManager {
     log.debug("Closed.");
   }
 
-  @Override
-  public boolean isClosed() {
-    return isClosed;
-  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index a2e3fe3..e808bdb 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -1,39 +1,91 @@
 package org.apache.solr.managed;
 
+import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 import org.apache.solr.common.SolrCloseable;
+import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.core.PluginInfo;
+import org.apache.solr.util.DefaultSolrThreadFactory;
+import org.apache.solr.util.SolrPluginUtils;
 import org.apache.solr.util.plugin.PluginInfoInitialized;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
  */
-public interface ResourceManager extends SolrCloseable, PluginInfoInitialized {
+public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  void setEnabled(Boolean enabled);
+  protected PluginInfo pluginInfo;
+  protected boolean isClosed = false;
+  protected boolean enabled = true;
 
-  PluginInfo getPluginInfo();
+  @Override
+  public void init(PluginInfo info) {
+    if (info != null) {
+      this.pluginInfo = info.copy();
+      if (pluginInfo.initArgs != null) {
+        SolrPluginUtils.invokeSetters(this, this.pluginInfo.initArgs);
+      }
+    }
+    if (!enabled) {
+      log.debug("Resource manager " + getClass().getSimpleName() + " disabled.");
+      return;
+    }
+    try {
+      doInit();
+    } catch (Exception e) {
+      log.warn("Exception initializing resource manager " + getClass().getSimpleName() + ", disabling!");
+      IOUtils.closeQuietly(this);
+    }
+  }
+
+  /**
+   * Enable resource management, defaults to true. {@link #init(PluginInfo)} checks
+   * this flag before calling {@link #doInit()}.
+   * @param enabled - whether or not resource management is to be enabled
+   */
+  public void setEnabled(Boolean enabled) {
+    if (enabled != null) {
+      this.enabled = enabled;
+    }
+  }
+
+  public PluginInfo getPluginInfo() {
+    return pluginInfo;
+  }
 
-  void createPool(String name, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception;
+  protected abstract void doInit() throws Exception;
 
-  void modifyPoolLimits(String name, Map<String, Float> limits) throws Exception;
+  public abstract void createPool(String name, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception;
 
-  void removePool(String name) throws Exception;
+  public abstract void modifyPoolLimits(String name, Map<String, Float> limits) throws Exception;
 
-  default void addResources(String pool, Collection<ManagedResource> managedResource) {
+  public abstract void removePool(String name) throws Exception;
+
+  public void addResources(String pool, Collection<ManagedResource> managedResource) {
     ensureNotClosed();
     for (ManagedResource resource : managedResource) {
       addResource(pool, resource);
     }
   }
 
-  void addResource(String pool, ManagedResource managedResource);
+  public abstract void addResource(String pool, ManagedResource managedResource);
 
-  default void ensureNotClosed() {
+  protected void ensureNotClosed() {
     if (isClosed()) {
       throw new IllegalStateException("Already closed.");
     }
   }
+
+  @Override
+  public synchronized boolean isClosed() {
+    return isClosed;
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 88b4c06..952dbb5 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -2,6 +2,7 @@ package org.apache.solr.managed;
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.lang.invoke.MethodHandles;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -9,36 +10,47 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledFuture;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  *
  */
 public class ResourceManagerPool implements Runnable, Closeable {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
   private Map<String, Float> limits;
   private final String type;
+  private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> params;
-  private Map<String, Map<String, Float>> currentValues = null;
   private Map<String, Float> totalValues = null;
   int scheduleDelaySeconds;
   ScheduledFuture<?> scheduledFuture;
 
-  public ResourceManagerPool(ResourceManagerPluginFactory factory, String type, Map<String, Float> limits, Map<String, Object> params) throws Exception {
+  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Float> limits, Map<String, Object> params) throws Exception {
+    this.name = name;
     this.type = type;
     this.resourceManagerPlugin = factory.create(type, params);
     this.limits = new HashMap<>(limits);
     this.params = new HashMap<>(params);
   }
 
-  public synchronized void addResource(ManagedResource managedResource) {
-    if (resources.containsKey(managedResource.getName())) {
-      throw new IllegalArgumentException("Pool already has resource '" + managedResource.getName() + "'.");
-    }
+  public String getName() {
+    return name;
+  }
+
+  public void addResource(ManagedResource managedResource) {
     Collection<String> types = managedResource.getManagedResourceTypes();
     if (!types.contains(type)) {
-      throw new IllegalArgumentException("Pool type '" + type + "' is not supported by the resource " + managedResource.getName());
+      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getName());
+      return;
+    }
+    ManagedResource existing = resources.putIfAbsent(managedResource.getName(), managedResource);
+    if (existing != null) {
+      throw new IllegalArgumentException("Resource '" + managedResource.getName() + "' already exists in pool '" + name + "' !");
     }
-    resources.put(managedResource.getName(), managedResource);
   }
 
   public Map<String, ManagedResource> getResources() {
@@ -47,7 +59,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
 
   public Map<String, Map<String, Float>> getCurrentValues() {
     // collect current values
-    currentValues = new HashMap<>();
+    Map<String, Map<String, Float>> currentValues = new HashMap<>();
     for (ManagedResource resource : resources.values()) {
       currentValues.put(resource.getName(), resource.getManagedValues(resourceManagerPlugin.getMonitoredTags()));
     }


[lucene-solr] 17/36: More refactoring.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 32e2cad6df07a4b8ea73d48a0bed05216abb8950
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Jul 24 22:10:08 2019 +0200

    More refactoring.
---
 .../solr/managed/DefaultResourceManager.java       |  2 +-
 .../solr/managed/DefaultResourceManagerPool.java   | 19 ++++++-
 .../apache/solr/managed/ManagedMetricProducer.java |  4 +-
 .../org/apache/solr/managed/ManagedResource.java   |  6 +-
 .../apache/solr/managed/NoOpResourceManager.java   | 12 +++-
 .../apache/solr/managed/ResourceManagerPool.java   | 22 +++++++-
 .../solr/managed/plugins/CacheManagerPlugin.java   | 44 +++++++--------
 .../java/org/apache/solr/search/FastLRUCache.java  | 64 +++++++++++-----------
 .../src/java/org/apache/solr/search/LFUCache.java  | 63 ++++++++++-----------
 .../src/java/org/apache/solr/search/LRUCache.java  | 37 +++++++------
 .../src/java/org/apache/solr/search/SolrCache.java | 11 ++++
 11 files changed, 169 insertions(+), 115 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index df211b3..d0d8233 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -52,7 +52,7 @@ public class DefaultResourceManager extends ResourceManager {
   public static final String MAX_NUM_POOLS_PARAM = "maxNumPools";
 
   public static final int DEFAULT_MAX_POOLS = 100;
-  public static final int DEFAULT_SCHEDULE_DELAY_SECONDS = 30;
+  public static final int DEFAULT_SCHEDULE_DELAY_SECONDS = 10;
 
   public static final String NODE_SEARCHER_CACHE_POOL = "nodeSearcherCachePool";
 
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index ace9da4..d46666f 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -38,11 +38,13 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
+  private final Map<String, Context> resourceContexts = new ConcurrentHashMap<>();
   private Map<String, Object> poolLimits;
   private final String type;
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
+  private final Context poolContext = new Context();
   private Map<String, Float> totalValues = null;
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
@@ -91,10 +93,12 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
     if (existing != null) {
       throw new IllegalArgumentException("Resource '" + managedResource.getResourceId() + "' already exists in pool '" + name + "' !");
     }
+    resourceContexts.putIfAbsent(managedResource.getResourceId().toString(), new Context());
   }
 
   @Override
   public boolean removeResource(String name) {
+    resourceContexts.remove(name);
     return resources.remove(name) != null;
   }
 
@@ -143,7 +147,7 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public Map<String, Float> getTotalValues() throws InterruptedException {
+  public Map<String, Number> getTotalValues() throws InterruptedException {
     updateLock.lockInterruptibly();
     try {
       return Collections.unmodifiableMap(totalValues);
@@ -163,6 +167,16 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
+  public Context getPoolContext() {
+    return poolContext;
+  }
+
+  @Override
+  public Context getResourceContext(String name) {
+    return resourceContexts.get(name);
+  }
+
+  @Override
   public void run() {
     try {
       resourceManagerPlugin.manage(this);
@@ -177,5 +191,8 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
       scheduledFuture.cancel(true);
       scheduledFuture = null;
     }
+    resources.clear();
+    resourceContexts.clear();
+    poolContext.clear();
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
index 891c1d8..82d431e 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
@@ -29,13 +29,13 @@ import org.apache.solr.core.SolrInfoBean;
 public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
 
   @Override
-  default Map<String, Object> getMonitoredValues(Collection<String> tags) {
+  default Map<String, Object> getMonitoredValues(Collection<String> params) {
     Map<String, Object> metrics = getMetricsSnapshot();
     if (metrics == null) {
       return Collections.emptyMap();
     }
     Map<String, Object> result = new HashMap<>();
-    tags.forEach(tag -> {
+    params.forEach(tag -> {
       Object value = metrics.get(tag);
       if (value == null) {
         return;
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
index d943384..d058c97 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -74,8 +74,8 @@ public interface ManagedResource {
 
   /**
    * Returns monitored values that are used for calculating optimal settings of managed resource limits.
-   * @param tags selected monitored tags, empty collection to return all monitored values
-   * @return map of tags to current values.
+   * @param params selected monitored parameters, empty collection to return all monitored values
+   * @return map of parameter names to current values.
    */
-  Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception;
+  Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception;
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index 08546aa..1eccff2 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -64,7 +64,7 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public Map<String, Float> getTotalValues() throws InterruptedException {
+    public Map<String, Number> getTotalValues() throws InterruptedException {
       return Collections.emptyMap();
     }
 
@@ -84,6 +84,16 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
+    public Context getPoolContext() {
+      return null;
+    }
+
+    @Override
+    public Context getResourceContext(String name) {
+      return null;
+    }
+
+    @Override
     public void close() throws IOException {
 
     }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index cf32d40..a8a7666 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -1,14 +1,18 @@
 package org.apache.solr.managed;
 
 import java.io.Closeable;
-import java.io.IOException;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  *
  */
 public interface ResourceManagerPool extends Runnable, Closeable {
 
+  public class Context extends ConcurrentHashMap<String, Object> {
+
+  }
+
   /** Unique pool name. */
   String getName();
 
@@ -26,7 +30,7 @@ public interface ResourceManagerPool extends Runnable, Closeable {
 
   /**
    * Get the current monitored values from all resources. Result is a map with resource names as keys,
-   * and tag/value maps as values.
+   * and param/value maps as values.
    */
   Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException;
 
@@ -34,7 +38,7 @@ public interface ResourceManagerPool extends Runnable, Closeable {
    * This returns cumulative monitored values of all resources.
    * <p>NOTE: you must call {@link #getCurrentValues()} first!</p>
    */
-  Map<String, Float> getTotalValues() throws InterruptedException;
+  Map<String, Number> getTotalValues() throws InterruptedException;
 
   /** Get current pool limits. */
   Map<String, Object> getPoolLimits();
@@ -46,4 +50,16 @@ public interface ResourceManagerPool extends Runnable, Closeable {
    * Pool limits are defined using controlled tags.
    */
   void setPoolLimits(Map<String, Object> poolLimits);
+
+  /**
+   * Pool context used for managing pool state.
+   */
+  Context getPoolContext();
+
+  /**
+   * Resource context used for managing resource state. This context is always present for
+   * a resource registered in this pool, and it is unique to this pool.
+   * @param name resource name
+   */
+  Context getResourceContext(String name);
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index 1524d89..f522ad3 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -8,6 +8,7 @@ import java.util.Map;
 
 import org.apache.solr.managed.AbstractResourceManagerPlugin;
 import org.apache.solr.managed.ResourceManagerPool;
+import org.apache.solr.search.SolrCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -16,51 +17,46 @@ import org.slf4j.LoggerFactory;
  * the management of {@link org.apache.solr.search.SolrCache} instances.
  * <p>This plugin calculates the total size and maxRamMB of all registered cache instances
  * and adjusts each cache's limits so that the aggregated values again fit within the pool limits.</p>
- * <p>In order to avoid thrashing the plugin uses a dead zone (by default {@link #DEFAULT_DEAD_BAND}),
+ * <p>In order to avoid thrashing the plugin uses a dead band (by default {@link #DEFAULT_DEAD_BAND}),
  * which can be adjusted using configuration parameter {@link #DEAD_BAND}. If monitored values don't
- * exceed the limits +/- the dead zone no action is taken.</p>
+ * exceed the limits +/- the dead band then no action is taken.</p>
  */
 public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static String TYPE = "cache";
 
-  public static final String SIZE_TAG = "size";
-  public static final String HIT_RATIO_TAG = "hitratio";
-  public static final String RAM_BYTES_USED_TAG = "ramBytesUsed";
-  public static final String MAX_RAM_MB_TAG = "maxRamMB";
-
   public static final String DEAD_BAND = "deadBand";
   public static final float DEFAULT_DEAD_BAND = 0.1f;
 
   private static final Map<String, String> controlledToMonitored = new HashMap<>();
 
   static {
-    controlledToMonitored.put(MAX_RAM_MB_TAG, RAM_BYTES_USED_TAG);
-    controlledToMonitored.put(SIZE_TAG, SIZE_TAG);
+    controlledToMonitored.put(SolrCache.MAX_RAM_MB_PARAM, SolrCache.RAM_BYTES_USED_PARAM);
+    controlledToMonitored.put(SolrCache.MAX_SIZE_PARAM, SolrCache.SIZE_PARAM);
   }
 
-  private static final Collection<String> MONITORED_TAGS = Arrays.asList(
-      SIZE_TAG,
-      HIT_RATIO_TAG,
-      RAM_BYTES_USED_TAG
+  private static final Collection<String> MONITORED_PARAMS = Arrays.asList(
+      SolrCache.SIZE_PARAM,
+      SolrCache.HIT_RATIO_PARAM,
+      SolrCache.RAM_BYTES_USED_PARAM
   );
 
-  private static final Collection<String> CONTROLLED_TAGS = Arrays.asList(
-      MAX_RAM_MB_TAG,
-      SIZE_TAG
+  private static final Collection<String> CONTROLLED_PARAMS = Arrays.asList(
+      SolrCache.MAX_RAM_MB_PARAM,
+      SolrCache.MAX_SIZE_PARAM
   );
 
   private float deadBand = DEFAULT_DEAD_BAND;
 
   @Override
   public Collection<String> getMonitoredParams() {
-    return MONITORED_TAGS;
+    return MONITORED_PARAMS;
   }
 
   @Override
   public Collection<String> getControlledParams() {
-    return CONTROLLED_TAGS;
+    return CONTROLLED_PARAMS;
   }
 
   @Override
@@ -81,7 +77,7 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
   @Override
   public void manage(ResourceManagerPool pool) throws Exception {
     Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-    Map<String, Float> totalValues = pool.getTotalValues();
+    Map<String, Number> totalValues = pool.getTotalValues();
     // pool limits are defined using controlled tags
     pool.getPoolLimits().forEach((poolLimitName, value) -> {
       // only numeric limits are supported
@@ -96,22 +92,24 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
       if (monitoredTag == null) {
         return;
       }
-      Float totalValue = totalValues.get(monitoredTag);
-      if (totalValue == null || totalValue <= 0.0f) {
+      Number totalValue = totalValues.get(monitoredTag);
+      if (totalValue == null || totalValue.floatValue() <= 0.0f) {
         return;
       }
-      float totalDelta = poolLimitValue - totalValue;
+      float totalDelta = poolLimitValue - totalValue.floatValue();
 
       // dead band to avoid thrashing
       if (Math.abs(totalDelta / poolLimitValue) < deadBand) {
         return;
       }
 
-      float changeRatio = poolLimitValue / totalValue;
+      float changeRatio = poolLimitValue / totalValue.floatValue();
       // modify current limits by the changeRatio
       pool.getResources().forEach((name, resource) -> {
         Map<String, Object> resourceLimits = resource.getResourceLimits();
         Object limit = resourceLimits.get(poolLimitName);
+        // XXX we could attempt here to control eg. ramBytesUsed by adjusting maxSize limit
+        // XXX and vice versa if the current limit is undefined or unsupported
         if (limit == null || !(limit instanceof Number)) {
           return;
         }
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 539cd05..0ad4a9b 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -57,7 +57,6 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
 
   private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(FastLRUCache.class);
 
-  public static final String MIN_SIZE_PARAM = "minSize";
   public static final String ACCEPTABLE_SIZE_PARAM = "acceptableSize";
   public static final String INITIAL_SIZE_PARAM = "initialSize";
   public static final String CLEANUP_THREAD_PARAM = "cleanupThread";
@@ -73,8 +72,8 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   private int showItems = 0;
 
   private long maxRamBytes;
-  private int sizeLimit;
-  private int minSizeLimit;
+  private int maxSize;
+  private int minSize;
   private int initialSize;
   private int acceptableSize;
   private boolean cleanupThread;
@@ -89,26 +88,26 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
     super.init(args, regenerator);
     String str = (String) args.get(SIZE_PARAM);
-    sizeLimit = str == null ? 1024 : Integer.parseInt(str);
+    maxSize = str == null ? 1024 : Integer.parseInt(str);
     str = (String) args.get(MIN_SIZE_PARAM);
     if (str == null) {
-      minSizeLimit = (int) (sizeLimit * 0.9);
+      minSize = (int) (maxSize * 0.9);
     } else {
-      minSizeLimit = Integer.parseInt(str);
+      minSize = Integer.parseInt(str);
     }
     checkAndAdjustLimits();
 
     str = (String) args.get(ACCEPTABLE_SIZE_PARAM);
     if (str == null) {
-      acceptableSize = (int) (sizeLimit * 0.95);
+      acceptableSize = (int) (maxSize * 0.95);
     } else {
       acceptableSize = Integer.parseInt(str);
     }
     // acceptable limit should be somewhere between minLimit and limit
-    acceptableSize = Math.max(minSizeLimit, acceptableSize);
+    acceptableSize = Math.max(minSize, acceptableSize);
 
     str = (String) args.get(INITIAL_SIZE_PARAM);
-    initialSize = str == null ? sizeLimit : Integer.parseInt(str);
+    initialSize = str == null ? maxSize : Integer.parseInt(str);
     str = (String) args.get(CLEANUP_THREAD_PARAM);
     cleanupThread = str == null ? false : Boolean.parseBoolean(str);
 
@@ -124,8 +123,8 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
       cache = new ConcurrentLRUCache<>(ramLowerWatermark, maxRamBytes, cleanupThread, null);
     } else  {
       ramLowerWatermark = -1L;
-      description = generateDescription(sizeLimit, initialSize, minSizeLimit, acceptableSize, cleanupThread);
-      cache = new ConcurrentLRUCache<>(sizeLimit, minSizeLimit, acceptableSize, initialSize, cleanupThread, false, null);
+      description = generateDescription(maxSize, initialSize, minSize, acceptableSize, cleanupThread);
+      cache = new ConcurrentLRUCache<>(maxSize, minSize, acceptableSize, initialSize, cleanupThread, false, null);
     }
 
     cache.setAlive(false);
@@ -148,7 +147,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
     if (maxRamBytes != Long.MAX_VALUE) {
       return generateDescription(maxRamBytes, ramLowerWatermark, cleanupThread);
     } else {
-      return generateDescription(sizeLimit, initialSize, minSizeLimit, acceptableSize, cleanupThread);
+      return generateDescription(maxSize, initialSize, minSize, acceptableSize, cleanupThread);
     }
   }
 
@@ -280,13 +279,14 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
 
         map.put("lookups", lookups);
         map.put("hits", hits);
-        map.put("hitratio", calcHitRatio(lookups, hits));
+        map.put(HIT_RATIO_PARAM, calcHitRatio(lookups, hits));
         map.put("inserts", inserts);
         map.put("evictions", evictions);
-        map.put("size", size);
+        map.put(SIZE_PARAM, size);
         map.put("cleanupThread", cleanupThread);
-        map.put("ramBytesUsed", ramBytesUsed());
-        map.put("maxRamMB", maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
+        map.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
+        map.put(MAX_SIZE_PARAM, maxSize);
+        map.put(MAX_RAM_MB_PARAM, maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
 
         map.put("warmupTime", warmupTime);
         map.put("cumulative_lookups", clookups);
@@ -339,8 +339,8 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   @Override
   public Map<String, Object> getResourceLimits() {
     Map<String, Object> limits = new HashMap<>();
-    limits.put(SIZE_PARAM, cache.getStats().getCurrentSize());
-    limits.put(MIN_SIZE_PARAM, minSizeLimit);
+    limits.put(MAX_SIZE_PARAM, maxSize);
+    limits.put(MIN_SIZE_PARAM, minSize);
     limits.put(ACCEPTABLE_SIZE_PARAM, acceptableSize);
     limits.put(CLEANUP_THREAD_PARAM, cleanupThread);
     limits.put(SHOW_ITEMS_PARAM, showItems);
@@ -349,7 +349,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   }
 
   @Override
-  public Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception {
+  public Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception {
     return cacheMap.getValue();
   }
 
@@ -390,21 +390,21 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
       throw new IllegalArgumentException("Invalid new value for numeric limit '" + limitName +"': " + value);
     }
     switch (limitName) {
-      case SIZE_PARAM:
-        sizeLimit = value.intValue();
+      case MAX_SIZE_PARAM:
+        maxSize = value.intValue();
         checkAndAdjustLimits();
-        cache.setUpperWaterMark(sizeLimit);
-        cache.setLowerWaterMark(minSizeLimit);
+        cache.setUpperWaterMark(maxSize);
+        cache.setLowerWaterMark(minSize);
         break;
       case MIN_SIZE_PARAM:
-        minSizeLimit = value.intValue();
+        minSize = value.intValue();
         checkAndAdjustLimits();
-        cache.setUpperWaterMark(sizeLimit);
-        cache.setLowerWaterMark(minSizeLimit);
+        cache.setUpperWaterMark(maxSize);
+        cache.setLowerWaterMark(minSize);
         break;
       case ACCEPTABLE_SIZE_PARAM:
         acceptableSize = value.intValue();
-        acceptableSize = Math.max(minSizeLimit, acceptableSize);
+        acceptableSize = Math.max(minSize, acceptableSize);
         cache.setAcceptableWaterMark(acceptableSize);
         break;
       case MAX_RAM_MB_PARAM:
@@ -428,12 +428,12 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   }
 
   private void checkAndAdjustLimits() {
-    if (minSizeLimit <= 0) minSizeLimit = 1;
-    if (sizeLimit <= minSizeLimit) {
-      if (sizeLimit > 1) {
-        minSizeLimit = sizeLimit - 1;
+    if (minSize <= 0) minSize = 1;
+    if (maxSize <= minSize) {
+      if (maxSize > 1) {
+        minSize = maxSize - 1;
       } else {
-        sizeLimit = minSizeLimit + 1;
+        maxSize = minSize + 1;
       }
     }
   }
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 5750247..5d82a2d 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -63,7 +63,6 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   public static final String TIME_DECAY_PARAM = "timeDecay";
   public static final String CLEANUP_THREAD_PARAM = "cleanupThread";
   public static final String INITIAL_SIZE_PARAM = "initialSize";
-  public static final String MIN_SIZE_PARAM = "minSize";
   public static final String ACCEPTABLE_SIZE_PARAM = "acceptableSize";
   public static final String AUTOWARM_COUNT_PARAM = "autowarmCount";
   public static final String SHOW_ITEMS_PARAM = "showItems";
@@ -86,8 +85,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   private MetricRegistry registry;
   private ResourceId resourceId;
 
-  private int sizeLimit;
-  private int minSizeLimit;
+  private int maxSize;
+  private int minSize;
   private int initialSize;
   private int acceptableSize;
   private boolean cleanupThread;
@@ -98,26 +97,26 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
     this.regenerator = regenerator;
     name = (String) args.get(NAME);
     String str = (String) args.get(SIZE_PARAM);
-    sizeLimit = str == null ? 1024 : Integer.parseInt(str);
+    maxSize = str == null ? 1024 : Integer.parseInt(str);
     str = (String) args.get(MIN_SIZE_PARAM);
     if (str == null) {
-      minSizeLimit = (int) (sizeLimit * 0.9);
+      minSize = (int) (maxSize * 0.9);
     } else {
-      minSizeLimit = Integer.parseInt(str);
+      minSize = Integer.parseInt(str);
     }
     checkAndAdjustLimits();
 
     str = (String) args.get(ACCEPTABLE_SIZE_PARAM);
     if (str == null) {
-      acceptableSize = (int) (sizeLimit * 0.95);
+      acceptableSize = (int) (maxSize * 0.95);
     } else {
       acceptableSize = Integer.parseInt(str);
     }
     // acceptable limit should be somewhere between minLimit and limit
-    acceptableSize = Math.max(minSizeLimit, acceptableSize);
+    acceptableSize = Math.max(minSize, acceptableSize);
 
     str = (String) args.get(INITIAL_SIZE_PARAM);
-    initialSize = str == null ? sizeLimit : Integer.parseInt(str);
+    initialSize = str == null ? maxSize : Integer.parseInt(str);
     str = (String) args.get(AUTOWARM_COUNT_PARAM);
     autowarmCount = str == null ? 0 : Integer.parseInt(str);
     str = (String) args.get(CLEANUP_THREAD_PARAM);
@@ -132,7 +131,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
 
     description = generateDescription();
 
-    cache = new ConcurrentLFUCache<>(sizeLimit, minSizeLimit, acceptableSize, initialSize, cleanupThread, false, null, timeDecay);
+    cache = new ConcurrentLFUCache<>(maxSize, minSize, acceptableSize, initialSize, cleanupThread, false, null, timeDecay);
     cache.setAlive(false);
 
     statsList = (List<ConcurrentLFUCache.Stats>) persistence;
@@ -150,8 +149,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   private String generateDescription() {
-    String descr = "Concurrent LFU Cache(maxSize=" + sizeLimit + ", initialSize=" + initialSize +
-        ", minSize=" + minSizeLimit + ", acceptableSize=" + acceptableSize + ", cleanupThread=" + cleanupThread +
+    String descr = "Concurrent LFU Cache(maxSize=" + maxSize + ", initialSize=" + initialSize +
+        ", minSize=" + minSize + ", acceptableSize=" + acceptableSize + ", cleanupThread=" + cleanupThread +
         ", timeDecay=" + Boolean.toString(timeDecay);
     if (autowarmCount > 0) {
       descr += ", autowarmCount=" + autowarmCount + ", regenerator=" + regenerator;
@@ -273,10 +272,13 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
 
         map.put("lookups", lookups);
         map.put("hits", hits);
-        map.put("hitratio", calcHitRatio(lookups, hits));
+        map.put(HIT_RATIO_PARAM, calcHitRatio(lookups, hits));
         map.put("inserts", inserts);
         map.put("evictions", evictions);
-        map.put("size", size);
+        map.put(SIZE_PARAM, size);
+        map.put(MAX_SIZE_PARAM, maxSize);
+        map.put(MIN_SIZE_PARAM, minSize);
+        map.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
 
         map.put("warmupTime", warmupTime);
         map.put("timeDecay", timeDecay);
@@ -299,7 +301,6 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
         map.put("cumulative_hitratio", calcHitRatio(clookups, chits));
         map.put("cumulative_inserts", cinserts);
         map.put("cumulative_evictions", cevictions);
-        map.put("ramBytesUsed", ramBytesUsed());
 
         if (detailed && showItems != 0) {
           Map items = cache.getMostUsedItems(showItems == -1 ? Integer.MAX_VALUE : showItems);
@@ -359,8 +360,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   @Override
   public Map<String, Object> getResourceLimits() {
     Map<String, Object> limits = new HashMap<>();
-    limits.put(SIZE_PARAM, cache.getStats().getCurrentSize());
-    limits.put(MIN_SIZE_PARAM, minSizeLimit);
+    limits.put(MAX_SIZE_PARAM, maxSize);
+    limits.put(MIN_SIZE_PARAM, minSize);
     limits.put(ACCEPTABLE_SIZE_PARAM, acceptableSize);
     limits.put(AUTOWARM_COUNT_PARAM, autowarmCount);
     limits.put(CLEANUP_THREAD_PARAM, cleanupThread);
@@ -370,7 +371,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   @Override
-  public Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception {
+  public Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception {
     return cacheMap.getValue();
   }
 
@@ -409,21 +410,21 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
         throw new IllegalArgumentException("Out of range new value for numeric limit '" + limitName +"': " + value);
       }
       switch (limitName) {
-        case SIZE_PARAM:
-          sizeLimit = value.intValue();
+        case MAX_SIZE_PARAM:
+          maxSize = value.intValue();
           checkAndAdjustLimits();
-          cache.setUpperWaterMark(sizeLimit);
-          cache.setLowerWaterMark(minSizeLimit);
+          cache.setUpperWaterMark(maxSize);
+          cache.setLowerWaterMark(minSize);
           break;
         case MIN_SIZE_PARAM:
-          minSizeLimit = value.intValue();
+          minSize = value.intValue();
           checkAndAdjustLimits();
-          cache.setUpperWaterMark(sizeLimit);
-          cache.setLowerWaterMark(minSizeLimit);
+          cache.setUpperWaterMark(maxSize);
+          cache.setLowerWaterMark(minSize);
           break;
         case ACCEPTABLE_SIZE_PARAM:
           acceptableSize = value.intValue();
-          acceptableSize = Math.max(minSizeLimit, acceptableSize);
+          acceptableSize = Math.max(minSize, acceptableSize);
           cache.setAcceptableWaterMark(acceptableSize);
           break;
         case AUTOWARM_COUNT_PARAM:
@@ -440,12 +441,12 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   private void checkAndAdjustLimits() {
-    if (minSizeLimit <= 0) minSizeLimit = 1;
-    if (sizeLimit <= minSizeLimit) {
-      if (sizeLimit > 1) {
-        minSizeLimit = sizeLimit - 1;
+    if (minSize <= 0) minSize = 1;
+    if (maxSize <= minSize) {
+      if (maxSize > 1) {
+        minSize = maxSize - 1;
       } else {
-        sizeLimit = minSizeLimit + 1;
+        maxSize = minSize + 1;
       }
     }
   }
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index 535c2f0..3ab0d60 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -79,7 +79,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
-  private int sizeLimit;
+  private int maxSize;
   private int initialSize;
   private ResourceId resourceId;
 
@@ -92,9 +92,9 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
     super.init(args, regenerator);
     String str = (String)args.get(SIZE_PARAM);
-    this.sizeLimit = str==null ? 1024 : Integer.parseInt(str);
+    this.maxSize = str==null ? 1024 : Integer.parseInt(str);
     str = (String)args.get("initialSize");
-    initialSize = Math.min(str==null ? 1024 : Integer.parseInt(str), sizeLimit);
+    initialSize = Math.min(str==null ? 1024 : Integer.parseInt(str), maxSize);
     str = (String) args.get(MAX_RAM_MB_PARAM);
     this.maxRamBytes = str == null ? Long.MAX_VALUE : (long) (Double.parseDouble(str) * 1024L * 1024L);
     description = generateDescription();
@@ -119,7 +119,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
             // must return false according to javadocs of removeEldestEntry if we're modifying
             // the map ourselves
             return false;
-          } else if (size() > getSizeLimit()) {
+          } else if (size() > getMaxSize()) {
             Iterator<Map.Entry<K, V>> iterator = entrySet().iterator();
             do {
               Map.Entry<K, V> entry = iterator.next();
@@ -133,7 +133,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
               iterator.remove();
               evictions++;
               stats.evictions.increment();
-            } while (iterator.hasNext() && size() > getSizeLimit());
+            } while (iterator.hasNext() && size() > getMaxSize());
             // must return false according to javadocs of removeEldestEntry if we're modifying
             // the map ourselves
             return false;
@@ -153,8 +153,8 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
     return persistence;
   }
 
-  public int getSizeLimit() {
-    return sizeLimit;
+  public int getMaxSize() {
+    return maxSize;
   }
 
   public long getMaxRamBytes() {
@@ -166,7 +166,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
    * @return Returns the description of this cache. 
    */
   private String generateDescription() {
-    String description = "LRU Cache(maxSize=" + getSizeLimit() + ", initialSize=" + initialSize;
+    String description = "LRU Cache(maxSize=" + getMaxSize() + ", initialSize=" + initialSize;
     if (isAutowarmingOn()) {
       description += ", " + getAutowarmDescription();
     }
@@ -186,7 +186,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
 
   @Override
   public V put(K key, V value) {
-    if (sizeLimit == Integer.MAX_VALUE && maxRamBytes == Long.MAX_VALUE) {
+    if (maxSize == Integer.MAX_VALUE && maxRamBytes == Long.MAX_VALUE) {
       throw new IllegalStateException("Cache: " + getName() + " has neither size nor RAM limit!");
     }
     synchronized (map) {
@@ -319,12 +319,13 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
       synchronized (map) {
         res.put("lookups", lookups);
         res.put("hits", hits);
-        res.put("hitratio", calcHitRatio(lookups,hits));
+        res.put(HIT_RATIO_PARAM, calcHitRatio(lookups,hits));
         res.put("inserts", inserts);
         res.put("evictions", evictions);
-        res.put("size", map.size());
-        res.put("ramBytesUsed", ramBytesUsed());
-        res.put("maxRamMB", maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
+        res.put(SIZE_PARAM, map.size());
+        res.put(MAX_SIZE_PARAM, maxSize);
+        res.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
+        res.put(MAX_RAM_MB_PARAM, maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
         res.put("evictionsRamUsage", evictionsRamUsage);
       }
       res.put("warmupTime", warmupTime);
@@ -374,13 +375,13 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   @Override
   public Map<String, Object> getResourceLimits() {
     Map<String, Object> limits = new HashMap<>();
-    limits.put(SIZE_PARAM, sizeLimit);
+    limits.put(MAX_SIZE_PARAM, maxSize);
     limits.put(MAX_RAM_MB_PARAM, maxRamBytes != Long.MAX_VALUE ? maxRamBytes / 1024L / 1024L : -1L);
     return limits;
   }
 
   @Override
-  public Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception {
+  public Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception {
     return cacheMap.getValue();
   }
 
@@ -408,11 +409,11 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
       throw new IllegalArgumentException("Invalid new value for limit '" + limitName +"': " + value);
     }
     switch (limitName) {
-      case SIZE_PARAM:
+      case MAX_SIZE_PARAM:
         if (value.intValue() > 0) {
-          sizeLimit = value.intValue();
+          maxSize = value.intValue();
         } else {
-          sizeLimit = Integer.MAX_VALUE;
+          maxSize = Integer.MAX_VALUE;
         }
         break;
       case MAX_RAM_MB_PARAM:
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 14fbb82..e2c6440 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -28,8 +28,19 @@ import java.util.Map;
  */
 public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedResource {
 
+  /** Current size of the cache. */
   String SIZE_PARAM = "size";
+  /** Maximum size of the cache. */
+  String MAX_SIZE_PARAM = "maxSize";
+  /** Minimum size of the cache. */
+  String MIN_SIZE_PARAM = "minSize";
+  /** Maximum RAM use in MB. */
   String MAX_RAM_MB_PARAM = "maxRamMB";
+  /** Ram usage estimate. */
+  String RAM_BYTES_USED_PARAM = "ramBytesUsed";
+  // not camelCase for back-compat
+  /** Cache hit ratio. */
+  String HIT_RATIO_PARAM = "hitratio";
 
   /**
    * The initialization routine. Instance specific arguments are passed in


[lucene-solr] 36/36: SOLR-13579: Soft optimization, unit tests.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 27ef7cc6ba2a7e39b3dd99c1f5b35c341fbbc0f1
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Dec 18 15:59:00 2019 +0100

    SOLR-13579: Soft optimization, unit tests.
---
 .../solr/handler/admin/ResourceManagerHandler.java |   3 +-
 .../org/apache/solr/managed/ChangeListener.java    |  23 ++-
 .../apache/solr/managed/ResourceManagerPool.java   |   8 +-
 .../solr/managed/types/CacheManagerPool.java       | 189 +++++++++++++++++++--
 .../java/org/apache/solr/search/CaffeineCache.java |   1 +
 .../src/java/org/apache/solr/search/SolrCache.java |   1 +
 .../managed/types/TestCacheManagerPluginCloud.java |   9 -
 .../solr/managed/types/TestCacheManagerPool.java   | 157 +++++++++++++++--
 8 files changed, 343 insertions(+), 48 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index dd587ca..7cd1733 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -27,6 +27,7 @@ import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.handler.RequestHandlerBase;
+import org.apache.solr.managed.ChangeListener;
 import org.apache.solr.managed.ManagedComponent;
 import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.ResourceManagerPool;
@@ -295,7 +296,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
             }
           });
           try {
-            pool.setResourceLimits(managedComponent2, newLimits);
+            pool.setResourceLimits(managedComponent2, newLimits, ChangeListener.Reason.USER);
             result.add("success", newLimits);
           } catch (Exception e) {
             log.warn("Error setting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
diff --git a/solr/core/src/java/org/apache/solr/managed/ChangeListener.java b/solr/core/src/java/org/apache/solr/managed/ChangeListener.java
index 49fbad6..42201d5 100644
--- a/solr/core/src/java/org/apache/solr/managed/ChangeListener.java
+++ b/solr/core/src/java/org/apache/solr/managed/ChangeListener.java
@@ -17,10 +17,28 @@
 package org.apache.solr.managed;
 
 /**
- *
+ * Listen to changes in resource limit settings caused by resource management framework
+ * (or by users via resource management API).
  */
 public interface ChangeListener {
 
+  enum Reason {
+    /** Administrative user action. */
+    USER,
+    /** Adjustment made to optimize the resource behavior. */
+    OPTIMIZATION,
+    /** Adjustment made due to total limit exceeded. */
+    ABOVE_TOTAL_LIMIT,
+    /** Adjustment made due to total limit underuse. */
+    BELOW_TOTAL_LIMIT,
+    /** Adjustment made due to individual resource limit exceeded. */
+    ABOVE_LIMIT,
+    /** Adjustment made due to individual resource limit underuse. */
+    BELOW_LIMIT,
+    /** Other unspecified reason. */
+    OTHER
+  }
+
   /**
    * Notify about changing a limit of a resource.
    * @param poolName pool name where resource is managed.
@@ -29,6 +47,7 @@ public interface ChangeListener {
    * @param newRequestedVal requested new value of the resource limit.
    * @param newActualVal actual value applied to the resource configuration. Note: this may differ from the
    *                     value requested due to internal logic of the component.
+   * @param reason reason of the change
    */
-  void changedLimit(String poolName, ManagedComponent component, String limitName, Object newRequestedVal, Object newActualVal);
+  void changedLimit(String poolName, ManagedComponent component, String limitName, Object newRequestedVal, Object newActualVal, Reason reason);
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index dfa822f..d9aa346 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -124,19 +124,19 @@ public abstract class ResourceManagerPool<T extends ManagedComponent> implements
 
   public abstract Map<String, Object> getMonitoredValues(T component) throws Exception;
 
-  public void setResourceLimits(T component, Map<String, Object> limits) throws Exception {
+  public void setResourceLimits(T component, Map<String, Object> limits, ChangeListener.Reason reason) throws Exception {
     if (limits == null || limits.isEmpty()) {
       return;
     }
     for (Map.Entry<String, Object> entry : limits.entrySet()) {
-      setResourceLimit(component, entry.getKey(), entry.getValue());
+      setResourceLimit(component, entry.getKey(), entry.getValue(), reason);
     }
   }
 
-  public Object setResourceLimit(T component, String limitName, Object value) throws Exception {
+  public Object setResourceLimit(T component, String limitName, Object value, ChangeListener.Reason reason) throws Exception {
     Object newActualLimit = doSetResourceLimit(component, limitName, value);
     for (ChangeListener listener : listeners) {
-      listener.changedLimit(getName(), component, limitName, value, newActualLimit);
+      listener.changedLimit(getName(), component, limitName, value, newActualLimit, reason);
     }
     return newActualLimit;
   }
diff --git a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java
index cee4fe7..483b1f4 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java
@@ -17,10 +17,14 @@
 package org.apache.solr.managed.types;
 
 import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
 
+import org.apache.solr.managed.ChangeListener;
 import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.ResourceManagerPool;
 import org.apache.solr.metrics.SolrMetricsContext;
@@ -34,16 +38,53 @@ import org.slf4j.LoggerFactory;
  * <p>This plugin calculates the total size and maxRamMB of all registered cache instances
  * and adjusts each cache's limits so that the aggregated values again fit within the pool limits.</p>
  * <p>In order to avoid thrashing the plugin uses a dead band (by default {@link #DEFAULT_DEAD_BAND}),
- * which can be adjusted using configuration parameter {@link #DEAD_BAND}. If monitored values don't
- * exceed the limits +/- the dead band then no action is taken.</p>
+ * which can be adjusted using configuration parameter {@link #DEAD_BAND_PARAM}. If monitored values don't
+ * exceed the limits +/- the dead band then no forcible adjustment takes place.</p>
+ * <p>The management strategy consists of two distinct phases: soft optimization phase and then hard limit phase.</p>
+ * <p><b>Soft optimization</b> tries to adjust the resource consumption based on the cache hit ratio.
+ * This phase is executed only if there's no total limit exceeded. Also, hit ratio is considered a valid monitored
+ * variable only when at least N lookups occurred since the last adjustment (default value is {@link #DEFAULT_LOOKUP_DELTA}).
+ * If the hit ratio is higher than a threshold (default value is {@link #DEFAULT_TARGET_HITRATIO}) then the size
+ * of the cache can be reduced so that the resource consumption is minimized while still keeping acceptable hit
+ * ratio - and vice versa.</p>
+ * <p>This optimization phase can only adjust the limits within a {@link #DEFAULT_MAX_ADJUST_RATIO}, i.e. increased
+ * or decreased values may not be larger / smaller than this multiple / fraction of the initially configured limit.</p>
+ * <p><b>Hard limit</b> phase follows the soft optimization phase and it forcibly reduces resource consumption of all components
+ * if the total usage is still above the pool limit after the first phase has completed. Each component's limit is reduced
+ * by the same factor, regardless of the actual population or hit ratio.</p>
  */
 public class CacheManagerPool extends ResourceManagerPool<SolrCache> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static String TYPE = "cache";
 
-  public static final String DEAD_BAND = "deadBand";
+  /** Controller dead-band - changes smaller than this ratio will be ignored. */
+  public static final String DEAD_BAND_PARAM = "deadBand";
+  /** Target hit ratio - high enough to be useful, low enough to avoid excessive cache size. */
+  public static final String TARGET_HIT_RATIO_PARAM = "targetHitRatio";
+  /**
+   * Maximum allowed adjustment ratio from the initial configuration value. Adjusted value may not be
+   * higher than multiple of this factor, and not lower than divided by this factor.
+   */
+  public static final String MAX_ADJUST_RATIO_PARAM = "maxAdjustRatio";
+  /**
+   * Minimum number of lookups since last adjustment to consider the reported hitRatio
+   *  to be statistically valid.
+   */
+  public static final String MIN_LOOKUP_DELTA_PARAM = "minLookupDelta";
+  /** Default value of dead band (10%). */
   public static final double DEFAULT_DEAD_BAND = 0.1;
+  /** Default target hit ratio - a compromise between usefulness and limited resource usage. */
+  public static final double DEFAULT_TARGET_HITRATIO = 0.8;
+  /**
+   * Default minimum number of lookups since the last adjustment. This can be treated as Bernoulli trials
+   * that give a 5% confidence about the statistical validity of hit ratio (<code>0.5 / sqrt(lookups)</code>).
+   */
+  public static final long DEFAULT_LOOKUP_DELTA = 100;
+  /**
+   * Default maximum adjustment ratio from the initially configured values.
+   */
+  public static final double DEFAULT_MAX_ADJUST_RATIO = 2.0;
 
   protected static final Map<String, Function<Map<String, Object>, Double>> controlledToMonitored = new HashMap<>();
 
@@ -53,22 +94,40 @@ public class CacheManagerPool extends ResourceManagerPool<SolrCache> {
       return ramBytes != null ? ramBytes.doubleValue() / SolrCache.MB : 0.0;
     });
     controlledToMonitored.put(SolrCache.MAX_SIZE_PARAM, values ->
-        ((Number)values.getOrDefault(SolrCache.MAX_SIZE_PARAM, -1.0)).doubleValue());
+        ((Number)values.getOrDefault(SolrCache.SIZE_PARAM, -1.0)).doubleValue());
   }
 
   protected double deadBand = DEFAULT_DEAD_BAND;
+  protected double targetHitRatio = DEFAULT_TARGET_HITRATIO;
+  protected long lookupDelta = DEFAULT_LOOKUP_DELTA;
+  protected double maxAdjustRatio = DEFAULT_MAX_ADJUST_RATIO;
+  protected Map<String, Long> lookups = new HashMap<>();
+  protected Map<String, Map<String, Object>> initialComponentLimits = new HashMap<>();
 
   public CacheManagerPool(String name, String type, ResourceManager resourceManager, Map<String, Object> poolLimits, Map<String, Object> poolParams) {
     super(name, type, resourceManager, poolLimits, poolParams);
-    String deadBandStr = String.valueOf(poolParams.getOrDefault(DEAD_BAND, DEFAULT_DEAD_BAND));
+    String str = String.valueOf(poolParams.getOrDefault(DEAD_BAND_PARAM, DEFAULT_DEAD_BAND));
     try {
-      deadBand = Double.parseDouble(deadBandStr);
+      deadBand = Double.parseDouble(str);
     } catch (Exception e) {
-      log.warn("Invalid deadBand parameter value '" + deadBandStr + "', using default " + DEFAULT_DEAD_BAND);
+      log.warn("Invalid deadBand parameter value '" + str + "', using default " + DEFAULT_DEAD_BAND);
     }
   }
 
   @Override
+  public void registerComponent(SolrCache component) {
+    super.registerComponent(component);
+    initialComponentLimits.put(component.getManagedComponentId().toString(), getResourceLimits(component));
+  }
+
+  @Override
+  public boolean unregisterComponent(String componentId) {
+    lookups.remove(componentId);
+    initialComponentLimits.remove(componentId);
+    return super.unregisterComponent(componentId);
+  }
+
+  @Override
   public Object doSetResourceLimit(SolrCache component, String limitName, Object val) {
     if (!(val instanceof Number)) {
       try {
@@ -110,8 +169,10 @@ public class CacheManagerPool extends ResourceManagerPool<SolrCache> {
     SolrMetricsContext metricsContext = component.getSolrMetricsContext();
     if (metricsContext != null) {
       Map<String, Object> metrics = metricsContext.getMetricsSnapshot();
-      String hitRatioKey = component.getCategory().toString() + "." + metricsContext.getScope() + "." + SolrCache.HIT_RATIO_PARAM;
-      values.put(SolrCache.HIT_RATIO_PARAM, metrics.get(hitRatioKey));
+      String key = component.getCategory().toString() + "." + metricsContext.getScope() + "." + SolrCache.HIT_RATIO_PARAM;
+      values.put(SolrCache.HIT_RATIO_PARAM, metrics.get(key));
+      key = component.getCategory().toString() + "." + metricsContext.getScope() + "." + SolrCache.LOOKUPS_PARAM;
+      values.put(SolrCache.LOOKUPS_PARAM, metrics.get(key));
     }
     return values;
   }
@@ -145,8 +206,7 @@ public class CacheManagerPool extends ResourceManagerPool<SolrCache> {
         return;
       }
 
-      double changeRatio = poolLimitValue / totalValue.doubleValue();
-      // modify evenly every component's current limits by the changeRatio
+      List<SolrCache> adjustableComponents = new ArrayList<>();
       components.forEach((name, component) -> {
         Map<String, Object> resourceLimits = getResourceLimits((SolrCache) component);
         Object limit = resourceLimits.get(poolLimitName);
@@ -159,14 +219,111 @@ public class CacheManagerPool extends ResourceManagerPool<SolrCache> {
         if (currentResourceLimit <= 0) { // undefined or unsupported
           return;
         }
-        double newLimit = currentResourceLimit * changeRatio;
+        adjustableComponents.add(component);
+      });
+      optimize(adjustableComponents, currentValues, poolLimitName, poolLimitValue, totalValue.doubleValue());
+    });
+  }
+
+  /**
+   * Manage all eligible components that support this pool limit.
+   */
+  private void optimize(List<SolrCache> components, Map<String, Map<String, Object>> currentValues, String limitName,
+                        double poolLimitValue, double totalValue) {
+    // changeRatio > 1.0 means there are available free resources
+    // changeRatio < 1.0 means there's shortage of resources
+    final AtomicReference<Double> changeRatio = new AtomicReference<>(poolLimitValue / totalValue);
+
+    // ========================== OPTIMIZATION ==============================
+    // if the situation is not critical (ie. total consumption is less than max)
+    // try to proactively optimize by reducing the size of caches with too high hitRatio
+    // (because a lower hit ratio is still acceptable if it means saving resources) and
+    // expand the size of caches with too low hitRatio
+    final AtomicReference<Double> newTotalValue = new AtomicReference<>(totalValue);
+    components.forEach(component -> {
+      long currentLookups = ((Number)currentValues.get(component.getManagedComponentId().toString()).get(SolrCache.LOOKUPS_PARAM)).longValue();
+      long lastLookups = lookups.computeIfAbsent(component.getManagedComponentId().toString(), k -> 0L);
+      if (currentLookups < lastLookups + lookupDelta) {
+        // too little data, skip the optimization
+        return;
+      }
+      Map<String, Object> resourceLimits = getResourceLimits(component);
+      double currentLimit = ((Number)resourceLimits.get(limitName)).doubleValue();
+      double currentHitRatio = ((Number)currentValues.get(component.getManagedComponentId().toString()).get(SolrCache.HIT_RATIO_PARAM)).doubleValue();
+      Number initialLimit = (Number)initialComponentLimits.get(component.getManagedComponentId().toString()).get(limitName);
+      if (initialLimit == null) {
+        // can't optimize because we don't know how far off we are from the initial setting
+        return;
+      }
+      if (currentHitRatio < targetHitRatio) {
+        if (changeRatio.get() < 1.0) {
+          // don't expand if we're already short on resources
+          return;
+        }
+        // expand to increase the hitRatio, but not more than maxAdjustRatio from the initialLimit
+        double newLimit = currentLimit * changeRatio.get();
+        if (newLimit > initialLimit.doubleValue() * maxAdjustRatio) {
+          // don't expand ad infinitum
+          newLimit = initialLimit.doubleValue() * maxAdjustRatio;
+        }
+        if (newLimit > poolLimitValue) {
+          // don't expand above the total pool limit
+          newLimit = poolLimitValue;
+        }
+        if (newLimit <= currentLimit) {
+          return;
+        }
+        lookups.put(component.getManagedComponentId().toString(), currentLookups);
         try {
-          setResourceLimit((SolrCache) component, poolLimitName, newLimit);
+          Number actualNewLimit = (Number)setResourceLimit(component, limitName, newLimit, ChangeListener.Reason.OPTIMIZATION);
+          newTotalValue.getAndUpdate(v -> v - currentLimit + actualNewLimit.doubleValue());
         } catch (Exception e) {
-          log.warn("Failed to set managed limit " + poolLimitName +
-              " from " + currentResourceLimit + " to " + newLimit + " on " + component.getManagedComponentId(), e);
+          log.warn("Failed to set managed limit " + limitName +
+              " from " + currentLimit + " to " + newLimit + " on " + component.getManagedComponentId(), e);
         }
-      });
+      } else {
+        // shrink to release some resources but not more than maxAdjustRatio from the initialLimit
+        double newLimit = targetHitRatio / currentHitRatio * currentLimit;
+        if (newLimit * maxAdjustRatio < initialLimit.doubleValue()) {
+          // don't shrink ad infinitum
+          return;
+        }
+        lookups.put(component.getManagedComponentId().toString(), currentLookups);
+        try {
+          Number actualNewLimit = (Number)setResourceLimit(component, limitName, newLimit, ChangeListener.Reason.OPTIMIZATION);
+          newTotalValue.getAndUpdate(v -> v - currentLimit + actualNewLimit.doubleValue());
+        } catch (Exception e) {
+          log.warn("Failed to set managed limit " + limitName +
+              " from " + currentLimit + " to " + newLimit + " on " + component.getManagedComponentId(), e);
+        }
+      }
+    });
+
+    // ======================== HARD LIMIT ================
+    // now re-calculate the new changeRatio based on possible
+    // optimizations made above
+    double totalDelta = poolLimitValue - newTotalValue.get();
+
+    // dead band to avoid thrashing
+    if (Math.abs(totalDelta / poolLimitValue) < deadBand) {
+      return;
+    }
+
+    changeRatio.set(poolLimitValue / newTotalValue.get());
+    if (changeRatio.get() >= 1.0) { // there's no resource shortage
+      return;
+    }
+    // forcibly trim each resource limit (evenly) to fit within the total pool limit
+    components.forEach(component -> {
+      Map<String, Object> resourceLimits = getResourceLimits(component);
+      double currentLimit = ((Number)resourceLimits.get(limitName)).doubleValue();
+      double newLimit = currentLimit * changeRatio.get();
+      try {
+        setResourceLimit(component, limitName, newLimit, ChangeListener.Reason.ABOVE_TOTAL_LIMIT);
+      } catch (Exception e) {
+        log.warn("Failed to set managed limit " + limitName +
+            " from " + currentLimit + " to " + newLimit + " on " + component.getManagedComponentId(), e);
+      }
     });
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index d40b319..451f72b 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -378,6 +378,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
         map.put("warmupTime", warmupTime);
         map.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
         map.put(MAX_RAM_MB_PARAM, getMaxRamMB());
+        map.put(MAX_SIZE_PARAM, getMaxSize());
 
         CacheStats cumulativeStats = priorStats.plus(stats);
         map.put("cumulative_lookups", cumulativeStats.requestCount());
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index ecc0308..ebe5079 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -55,6 +55,7 @@ public interface SolrCache<K,V> extends SolrInfoBean, ManagedComponent, Accounta
   /** Use a background thread for cache evictions and cleanup. */
   String CLEANUP_THREAD_PARAM = "cleanupThread";
 
+  long KB = 1024L;
   long MB = 1024L * 1024L;
 
   /**
diff --git a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPluginCloud.java b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPluginCloud.java
deleted file mode 100644
index 2abcca6..0000000
--- a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPluginCloud.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.apache.solr.managed.types;
-
-import org.apache.solr.cloud.SolrCloudTestCase;
-
-/**
- *
- */
-public class TestCacheManagerPluginCloud extends SolrCloudTestCase {
-}
diff --git a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java
index 9e22158..cba581c 100644
--- a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java
@@ -1,5 +1,6 @@
 package org.apache.solr.managed.types;
 
+import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -7,8 +8,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.math3.distribution.ZipfDistribution;
 import org.apache.lucene.util.Accountable;
 import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.managed.ChangeListener;
 import org.apache.solr.managed.DefaultResourceManager;
 import org.apache.solr.managed.ManagedComponent;
 import org.apache.solr.managed.ResourceManager;
@@ -21,11 +24,14 @@ import org.apache.solr.search.SolrCache;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
  */
 public class TestCacheManagerPool extends SolrTestCaseJ4 {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   ResourceManager resourceManager;
 
@@ -37,16 +43,14 @@ public class TestCacheManagerPool extends SolrTestCaseJ4 {
     resourceManager.init(null);
   }
 
-  private static final long KB = 1024;
-  private static final long MB = 1024 * KB;
-
-  private static class ChangeListener implements org.apache.solr.managed.ChangeListener {
+  private static class ChangeTestListener implements ChangeListener {
     Map<String, Map<String, Object>> changedValues = new ConcurrentHashMap<>();
 
     @Override
-    public void changedLimit(String poolName, ManagedComponent component, String limitName, Object newRequestedVal, Object newActualVal) {
+    public void changedLimit(String poolName, ManagedComponent component, String limitName, Object newRequestedVal, Object newActualVal, Reason reason) {
       Map<String, Object> perComponent = changedValues.computeIfAbsent(component.getManagedComponentId().toString(), id -> new ConcurrentHashMap<>());
       perComponent.put(limitName, newActualVal);
+      perComponent.put("reason", reason);
     }
 
     public void clear() {
@@ -56,7 +60,7 @@ public class TestCacheManagerPool extends SolrTestCaseJ4 {
 
   @Test
   public void testPoolLimits() throws Exception {
-    ResourceManagerPool pool = resourceManager.createPool("test", CacheManagerPool.TYPE, Collections.singletonMap("maxRamMB", 200), Collections.emptyMap());
+    ResourceManagerPool pool = resourceManager.createPool("testPoolLimits", CacheManagerPool.TYPE, Collections.singletonMap("maxRamMB", 200), Collections.emptyMap());
     SolrMetricManager metricManager = new SolrMetricManager();
     SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, "fooRegistry", "barScope", "bazTag");
     List<SolrCache> caches = new ArrayList<>();
@@ -66,10 +70,10 @@ public class TestCacheManagerPool extends SolrTestCaseJ4 {
       params.put("maxRamMB", "50");
       cache.init(params, null, new NoOpRegenerator());
       cache.initializeMetrics(solrMetricsContext, "child-" + i);
-      cache.initializeManagedComponent(resourceManager, "test");
+      cache.initializeManagedComponent(resourceManager, "testPoolLimits");
       caches.add(cache);
     }
-    ChangeListener listener = new ChangeListener();
+    ChangeTestListener listener = new ChangeTestListener();
     pool.addChangeListener(listener);
     // fill up all caches just below the global limit, evenly with small values
     for (int i = 0; i < 202; i++) {
@@ -77,11 +81,17 @@ public class TestCacheManagerPool extends SolrTestCaseJ4 {
         cache.put("id-" + i, new Accountable() {
           @Override
           public long ramBytesUsed() {
-            return 100 * KB;
+            return 100 * SolrCache.KB;
           }
         });
       }
     }
+    // generate lookups to trigger the optimization
+    for (SolrCache<String, Accountable> cache : caches) {
+      for (int i = 0; i < CacheManagerPool.DEFAULT_LOOKUP_DELTA * 2; i++) {
+        cache.get("id-" + i);
+      }
+    }
     pool.manage();
     Map<String, Object> totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
 
@@ -92,22 +102,137 @@ public class TestCacheManagerPool extends SolrTestCaseJ4 {
       caches.get(0).put("large-" + i, new Accountable() {
         @Override
         public long ramBytesUsed() {
-          return 2560 * KB;
+          return 2560 * SolrCache.KB;
         }
       });
     }
     pool.manage();
     totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
-
+    // OPTIMIZATION should have handled this, due to abnormally high hit ratios
     assertEquals("should adjust all: " + listener.changedValues.toString(), 10, listener.changedValues.size());
-    listener.clear();
+    listener.changedValues.values().forEach(map -> assertEquals(ChangeListener.Reason.OPTIMIZATION, map.get("reason")));
+    // add more large values
+    for (int i = 0; i < 10; i++) {
+      caches.get(i).put("large1-" + i, new Accountable() {
+        @Override
+        public long ramBytesUsed() {
+          return 2560 * SolrCache.KB;
+        }
+      });
+    }
+    // don't generate any new lookups - prevents OPTIMIZATION
+
+    //
+
+    // NOTE: this takes a few rounds to adjust because we modify the original maxRamMB which
+    // may have been very different for each cache.
+    int cnt = 0;
+    do {
+      cnt++;
+      listener.clear();
+      pool.manage();
+      if (listener.changedValues.isEmpty()) {
+        break;
+      }
+      totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
+      assertEquals("should adjust all again: " + listener.changedValues.toString(), 10, listener.changedValues.size());
+      listener.changedValues.values().forEach(map -> assertEquals(ChangeListener.Reason.ABOVE_TOTAL_LIMIT, map.get("reason")));
+      log.info(" - step " + cnt + ": " + listener.changedValues);
+    } while (cnt < 10);
+    if (cnt == 0) {
+      fail("failed to adjust to fit in 10 steps: " + listener.changedValues);
+    }
+  }
+
+  private static final Accountable LARGE_ITEM = new Accountable() {
+    @Override
+    public long ramBytesUsed() {
+      return SolrCache.MB;
+    }
+  };
+
+  private static final Accountable SMALL_ITEM = new Accountable() {
+    @Override
+    public long ramBytesUsed() {
+      return SolrCache.KB;
+    }
+  };
+
+  @Test
+  public void testHitRatioOptimization() throws Exception {
+    ResourceManagerPool pool = resourceManager.createPool("testHitRatio", CacheManagerPool.TYPE, Collections.singletonMap("maxSize", 200), Collections.emptyMap());
+    SolrMetricManager metricManager = new SolrMetricManager();
+    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, "fooRegistry", "barScope", "bazTag");
+    SolrCache<Integer, Accountable> cache = new CaffeineCache<>();
+    Map<String, String> params = new HashMap<>();
+    int initialSize = 100;
+    params.put("size", "" + initialSize);
+    cache.init(params, null, new NoOpRegenerator());
+    cache.initializeMetrics(solrMetricsContext, "testHitRatio");
+    cache.initializeManagedComponent(resourceManager, "testHitRatio");
+
+    ChangeTestListener listener = new ChangeTestListener();
+    pool.addChangeListener(listener);
+
+    // ===== test shrinking =====
+    // populate / lookup with a small set of items -> high hit ratio.
+    // Optimization should kick in and shrink the cache
+    ZipfDistribution zipf = new ZipfDistribution(100, 0.99);
+    int NUM_LOOKUPS = 3000;
+    for (int i = 0; i < NUM_LOOKUPS; i++) {
+      cache.computeIfAbsent(zipf.sample(), k -> SMALL_ITEM);
+    }
     pool.manage();
-    totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
-    assertEquals("should adjust all again: " + listener.changedValues.toString(), 10, listener.changedValues.size());
+    assertTrue(cache.getMaxSize() < initialSize);
+    assertEquals(listener.changedValues.toString(), 1, listener.changedValues.size());
+    listener.changedValues.values().forEach(map -> assertEquals(ChangeListener.Reason.OPTIMIZATION, map.get("reason")));
+    // iterate until it's small enough to affect the hit ratio
+    int cnt = 0;
+    do {
+      listener.clear();
+      cnt++;
+      for (int i = 0; i < NUM_LOOKUPS; i++) {
+        cache.computeIfAbsent(zipf.sample(), k -> SMALL_ITEM);
+      }
+      pool.manage();
+      if (listener.changedValues.isEmpty()) {
+        break;
+      }
+      log.info(" - step " + cnt + ": " + listener.changedValues);
+    } while (cnt < 10);
+    if (cnt == 10) {
+      fail("failed to reach the balance: " + listener.changedValues);
+    }
+    assertTrue("maxSize adjusted more than allowed: " + cache.getMaxSize(), cache.getMaxSize() >= initialSize / CacheManagerPool.DEFAULT_MAX_ADJUST_RATIO);
+
+    // ========= test expansion ===========
     listener.clear();
+    zipf = new ZipfDistribution(100000, 0.5);
+    for (int i = 0; i < NUM_LOOKUPS * 2; i++) {
+      cache.computeIfAbsent(zipf.sample(), k -> SMALL_ITEM);
+    }
     pool.manage();
-    totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
-    assertEquals("should not adjust (within deadband): " + listener.changedValues.toString(), 0, listener.changedValues.size());
+    assertEquals(listener.changedValues.toString(), 1, listener.changedValues.size());
+    listener.changedValues.values().forEach(map -> assertEquals(ChangeListener.Reason.OPTIMIZATION, map.get("reason")));
+    assertTrue(cache.getMaxSize() > initialSize);
+
+    cnt = 0;
+    do {
+      listener.clear();
+      cnt++;
+      for (int i = 0; i < NUM_LOOKUPS * 2; i++) {
+        cache.computeIfAbsent(zipf.sample(), k -> SMALL_ITEM);
+      }
+      pool.manage();
+      if (listener.changedValues.isEmpty()) {
+        break;
+      }
+      log.info(" - step " + cnt + ": " + listener.changedValues);
+    } while (cnt < 10);
+    if (cnt == 10) {
+      fail("failed to reach the balance: " + listener.changedValues);
+    }
+    assertTrue("maxSize adjusted more than allowed: " + cache.getMaxSize(), cache.getMaxSize() <= initialSize * CacheManagerPool.DEFAULT_MAX_ADJUST_RATIO);
   }
 
   @After


[lucene-solr] 35/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit cb7d8351e2a31091a7eea860abaa1ddb3e5620ac
Merge: f1ebfdc 56839f6
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Dec 18 15:51:36 2019 +0100

    Merge branch 'master' into jira/solr-13579

 lucene/CHANGES.txt                                 |   4 +-
 .../analysis/cn/smart/hhmm/BigramDictionary.java   |   3 +
 .../analysis/cn/smart/hhmm/WordDictionary.java     |   3 +
 .../src/java/org/apache/lucene/geo/EdgeTree.java   |  44 +-
 .../src/java/org/apache/lucene/geo/Polygon2D.java  |   8 +-
 .../facet/taxonomy/writercache/CharBlockArray.java |   4 +
 lucene/ivy-versions.properties                     |  51 +-
 lucene/licenses/asm-5.1.jar.sha1                   |   1 -
 lucene/licenses/asm-7.2.jar.sha1                   |   1 +
 lucene/licenses/asm-commons-5.1.jar.sha1           |   1 -
 lucene/licenses/asm-commons-7.2.jar.sha1           |   1 +
 lucene/licenses/commons-codec-1.11.jar.sha1        |   1 -
 lucene/licenses/commons-codec-1.13.jar.sha1        |   1 +
 lucene/licenses/commons-compress-1.18.jar.sha1     |   1 -
 lucene/licenses/commons-compress-1.19.jar.sha1     |   1 +
 lucene/licenses/httpclient-4.5.10.jar.sha1         |   1 +
 lucene/licenses/httpclient-4.5.6.jar.sha1          |   1 -
 lucene/licenses/httpcore-4.4.10.jar.sha1           |   1 -
 lucene/licenses/httpcore-4.4.12.jar.sha1           |   1 +
 lucene/licenses/xercesImpl-2.12.0.jar.sha1         |   1 +
 lucene/licenses/xercesImpl-2.9.1.jar.sha1          |   1 -
 .../lucene/replicator/http/HttpClientBase.java     |   2 +
 .../lucene/replicator/http/ReplicationService.java |   2 +
 .../src/java/org/apache/lucene/geo/Line2D.java     |   2 +-
 .../apache/lucene/document/TestLatLonShape.java    |  40 +
 lucene/tools/forbiddenApis/base.txt                |   4 +
 solr/CHANGES.txt                                   |  31 +-
 .../stream/AnalyticsShardResponseParser.java       |   2 +
 .../response/AnalyticsShardResponseWriter.java     |   2 +
 .../solr/handler/dataimport/ScriptTransformer.java |  33 +-
 .../handler/dataimport/TestScriptTransformer.java  |  22 +
 solr/contrib/extraction/ivy.xml                    |   1 +
 solr/core/ivy.xml                                  |   4 -
 .../java/org/apache/solr/handler/CatStream.java    |   2 +-
 .../solr/handler/admin/SystemInfoHandler.java      |  45 -
 .../java/org/apache/solr/search/QParserPlugin.java |   4 +
 .../search/join/BlockJoinDocSetFacetComponent.java | 195 -----
 .../solr/search/join/BlockJoinFacetAccsHolder.java |  83 --
 .../solr/search/join/BlockJoinFacetComponent.java  |  23 -
 .../join/BlockJoinFacetComponentSupport.java       | 158 ----
 .../solr/search/join/BlockJoinFacetFilter.java     |  96 ---
 .../join/BlockJoinFieldFacetAccumulator.java       | 235 -----
 .../solr/search/join/BlockJoinParentQParser.java   |   1 +
 .../search/join/ChildFieldValueSourceParser.java   |   7 +-
 .../{BitSetSlice.java => HashRangeQParser.java}    |  38 +-
 ...itSetSlice.java => HashRangeQParserPlugin.java} |  37 +-
 .../apache/solr/search/join/HashRangeQuery.java    | 144 ++++
 .../apache/solr/search/join/ScoreModeParser.java   |   1 +
 .../org/apache/solr/search/join/XCJFQParser.java   |  90 ++
 .../apache/solr/search/join/XCJFQParserPlugin.java |  66 ++
 .../org/apache/solr/search/join/XCJFQuery.java     | 380 +++++++++
 .../StatelessScriptUpdateProcessorFactory.java     |  33 +-
 .../src/test-files/solr/collection1/conf/evil.js   |  21 +
 .../conf/schema-blockjoinfacetcomponent.xml        |  40 -
 .../conf/solrconfig-blockjoinfacetcomponent.xml    |  58 --
 .../conf/solrconfig-script-updateprocessor.xml     |   6 +
 .../solr/configsets/xcjf/conf/schema.xml           |  32 +
 .../solr/configsets/xcjf/conf/solrconfig.xml       |  72 ++
 .../solr/cloud/FullSolrCloudDistribCmdsTest.java   | 946 ++++++++-------------
 .../solr/handler/admin/LoggingHandlerTest.java     |  54 +-
 .../org/apache/solr/rest/TestManagedResource.java  |   5 +
 .../solr/search/DelayingSearchComponent.java       |  31 +-
 .../org/apache/solr/search/QueryEqualityTest.java  | 244 +++---
 .../org/apache/solr/search/join/BJQParserTest.java |   6 +-
 .../search/join/BlockJoinFacetDistribTest.java     | 237 ------
 .../solr/search/join/BlockJoinFacetRandomTest.java | 637 --------------
 .../solr/search/join/BlockJoinFacetSimpleTest.java | 121 ---
 .../solr/search/join/TestScoreJoinQPNoScore.java   |   5 +-
 .../solr/search/join/TestScoreJoinQPScore.java     |   4 +-
 .../org/apache/solr/search/join/XCJFQueryTest.java | 280 ++++++
 .../join/another/BJQFilterAccessibleTest.java      |   3 +-
 .../processor/RoutedAliasUpdateProcessorTest.java  |   1 +
 .../StatelessScriptUpdateProcessorFactoryTest.java |  10 +
 solr/licenses/apache-mime4j-core-0.8.2.jar.sha1    |   1 -
 solr/licenses/apache-mime4j-core-0.8.3.jar.sha1    |   1 +
 solr/licenses/apache-mime4j-dom-0.8.2.jar.sha1     |   1 -
 solr/licenses/apache-mime4j-dom-0.8.3.jar.sha1     |   1 +
 solr/licenses/asm-5.1.jar.sha1                     |   1 -
 solr/licenses/asm-7.2.jar.sha1                     |   1 +
 solr/licenses/asm-LICENSE-BSD.txt                  |   2 +-
 solr/licenses/asm-LICENSE-BSD_LIKE.txt             |  26 -
 solr/licenses/asm-commons-5.1.jar.sha1             |   1 -
 solr/licenses/asm-commons-7.2.jar.sha1             |   1 +
 solr/licenses/bcmail-jdk15on-1.60.jar.sha1         |   1 -
 solr/licenses/bcmail-jdk15on-1.64.jar.sha1         |   1 +
 solr/licenses/bcpkix-jdk15on-1.60.jar.sha1         |   1 -
 solr/licenses/bcpkix-jdk15on-1.64.jar.sha1         |   1 +
 solr/licenses/bcprov-jdk15on-1.60.jar.sha1         |   1 -
 solr/licenses/bcprov-jdk15on-1.64.jar.sha1         |   1 +
 solr/licenses/commons-codec-1.11.jar.sha1          |   1 -
 solr/licenses/commons-codec-1.13.jar.sha1          |   1 +
 solr/licenses/commons-compress-1.18.jar.sha1       |   1 -
 solr/licenses/commons-compress-1.19.jar.sha1       |   1 +
 .../licenses/commons-configuration-LICENSE-ASL.txt | 403 ---------
 solr/licenses/commons-configuration-NOTICE.txt     |   9 -
 solr/licenses/commons-csv-1.7.jar.sha1             |   1 +
 ...LICENSE-ASL.txt => commons-csv-LICENSE-ASL.txt} |   0
 ...-digester-NOTICE.txt => commons-csv-NOTICE.txt} |   8 +-
 solr/licenses/commons-digester-LICENSE-ASL.txt     | 202 -----
 solr/licenses/commons-io-2.5.jar.sha1              |   1 -
 solr/licenses/commons-io-2.6.jar.sha1              |   1 +
 solr/licenses/commons-lang3-3.8.1.jar.sha1         |   1 -
 solr/licenses/commons-lang3-3.9.jar.sha1           |   1 +
 solr/licenses/curvesapi-1.04.jar.sha1              |   1 -
 solr/licenses/curvesapi-1.06.jar.sha1              |   1 +
 solr/licenses/fontbox-2.0.12.jar.sha1              |   1 -
 solr/licenses/fontbox-2.0.17.jar.sha1              |   1 +
 solr/licenses/hadoop-common-tests-LICENSE-ASL.txt  | 244 ------
 solr/licenses/hadoop-common-tests-NOTICE.txt       |   2 -
 solr/licenses/hadoop-hdfs-tests-LICENSE-ASL.txt    | 244 ------
 solr/licenses/hadoop-hdfs-tests-NOTICE.txt         |   2 -
 solr/licenses/hadoop-minicluster-3.2.0.jar.sha1    |   1 -
 solr/licenses/hadoop-minicluster-LICENSE-ASL.txt   | 244 ------
 solr/licenses/hadoop-minicluster-NOTICE.txt        |   2 -
 solr/licenses/httpclient-4.5.10.jar.sha1           |   1 +
 solr/licenses/httpclient-4.5.6.jar.sha1            |   1 -
 solr/licenses/httpcore-4.4.10.jar.sha1             |   1 -
 solr/licenses/httpcore-4.4.12.jar.sha1             |   1 +
 solr/licenses/httpmime-4.5.10.jar.sha1             |   1 +
 solr/licenses/httpmime-4.5.6.jar.sha1              |   1 -
 solr/licenses/jackcess-2.1.12.jar.sha1             |   1 -
 solr/licenses/jackcess-3.0.1.jar.sha1              |   1 +
 solr/licenses/jackcess-encrypt-2.1.4.jar.sha1      |   1 -
 solr/licenses/jackcess-encrypt-3.0.0.jar.sha1      |   1 +
 solr/licenses/jackson-annotations-2.10.0.jar.sha1  |   1 -
 solr/licenses/jackson-annotations-2.10.1.jar.sha1  |   1 +
 solr/licenses/jackson-core-2.10.0.jar.sha1         |   1 -
 solr/licenses/jackson-core-2.10.1.jar.sha1         |   1 +
 solr/licenses/jackson-core-asl-LICENSE-ASL.txt     | 202 -----
 solr/licenses/jackson-core-asl-NOTICE.txt          |   7 -
 solr/licenses/jackson-databind-2.10.0.jar.sha1     |   1 -
 solr/licenses/jackson-databind-2.10.1.jar.sha1     |   1 +
 .../jackson-dataformat-smile-2.10.0.jar.sha1       |   1 -
 .../jackson-dataformat-smile-2.10.1.jar.sha1       |   1 +
 solr/licenses/jackson-mapper-asl-LICENSE-ASL.txt   | 202 -----
 solr/licenses/jackson-mapper-asl-NOTICE.txt        |   7 -
 solr/licenses/jersey-core-1.19.jar.sha1            |   1 -
 solr/licenses/jersey-core-LICENSE-CDDL.txt         |  81 --
 solr/licenses/jersey-server-1.19.jar.sha1          |   1 -
 solr/licenses/jersey-server-LICENSE-CDDL.txt       |  85 --
 solr/licenses/jsoup-1.11.3.jar.sha1                |   1 -
 solr/licenses/jsoup-1.12.1.jar.sha1                |   1 +
 solr/licenses/metrics-json-LICENSE-ASL.txt         | 203 -----
 solr/licenses/metrics-json-NOTICE.txt              |  12 -
 solr/licenses/metrics-servlets-LICENSE-ASL.txt     | 203 -----
 solr/licenses/metrics-servlets-NOTICE.txt          |  12 -
 solr/licenses/mina-core-LICENSE-ASL.txt            | 341 --------
 solr/licenses/mina-core-NOTICE.txt                 |   7 -
 solr/licenses/netty-all-4.1.29.Final.jar.sha1      |   1 -
 solr/licenses/netty-all-LICENSE-ASL.txt            | 202 -----
 solr/licenses/netty-all-NOTICE.txt                 | 223 -----
 solr/licenses/parso-2.0.11.jar.sha1                |   1 +
 solr/licenses/parso-2.0.9.jar.sha1                 |   1 -
 solr/licenses/pdfbox-2.0.12.jar.sha1               |   1 -
 solr/licenses/pdfbox-2.0.17.jar.sha1               |   1 +
 solr/licenses/pdfbox-tools-2.0.12.jar.sha1         |   1 -
 solr/licenses/pdfbox-tools-2.0.17.jar.sha1         |   1 +
 solr/licenses/poi-4.0.0.jar.sha1                   |   1 -
 solr/licenses/poi-4.1.1.jar.sha1                   |   1 +
 solr/licenses/poi-ooxml-4.0.0.jar.sha1             |   1 -
 solr/licenses/poi-ooxml-4.1.1.jar.sha1             |   1 +
 solr/licenses/poi-ooxml-schemas-4.0.0.jar.sha1     |   1 -
 solr/licenses/poi-ooxml-schemas-4.1.1.jar.sha1     |   1 +
 solr/licenses/poi-scratchpad-4.0.0.jar.sha1        |   1 -
 solr/licenses/poi-scratchpad-4.1.1.jar.sha1        |   1 +
 solr/licenses/presto-parser-LICENSE-ASL.txt        | 202 -----
 solr/licenses/presto-parser-NOTICE.txt             |   0
 solr/licenses/protobuf-java-3.11.0.jar.sha1        |   1 +
 solr/licenses/protobuf-java-3.6.1.jar.sha1         |   1 -
 solr/licenses/rome-1.12.2.jar.sha1                 |   1 +
 solr/licenses/rome-1.5.1.jar.sha1                  |   1 -
 solr/licenses/rome-utils-1.12.2.jar.sha1           |   1 +
 solr/licenses/rome-utils-1.5.1.jar.sha1            |   1 -
 solr/licenses/servlet-api-LICENSE-CDDL.txt         | 126 ---
 solr/licenses/servlet-api-NOTICE.txt               |   2 -
 solr/licenses/slice-NOTICE.txt                     |   0
 solr/licenses/tika-core-1.19.1.jar.sha1            |   1 -
 solr/licenses/tika-core-1.23.jar.sha1              |   1 +
 solr/licenses/tika-java7-1.19.1.jar.sha1           |   1 -
 solr/licenses/tika-java7-1.23.jar.sha1             |   1 +
 solr/licenses/tika-parsers-1.19.1.jar.sha1         |   1 -
 solr/licenses/tika-parsers-1.23.jar.sha1           |   1 +
 solr/licenses/tika-xmp-1.19.1.jar.sha1             |   1 -
 solr/licenses/tika-xmp-1.23.jar.sha1               |   1 +
 solr/licenses/xercesImpl-2.12.0.jar.sha1           |   1 +
 solr/licenses/xercesImpl-2.9.1.jar.sha1            |   1 -
 solr/licenses/xmlbeans-3.0.1.jar.sha1              |   1 -
 solr/licenses/xmlbeans-3.1.0.jar.sha1              |   1 +
 solr/solr-ref-guide/src/aliases.adoc               |   2 +-
 .../authentication-and-authorization-plugins.adoc  |   2 +-
 solr/solr-ref-guide/src/blockjoin-faceting.adoc    | 115 ---
 .../src/cluster-node-management.adoc               |   6 +-
 solr/solr-ref-guide/src/collection-management.adoc |  32 +-
 .../solr-ref-guide/src/command-line-utilities.adoc |   2 +-
 .../src/common-query-parameters.adoc               |   4 +-
 solr/solr-ref-guide/src/config-sets.adoc           |   4 +-
 solr/solr-ref-guide/src/configsets-api.adoc        |   2 +-
 solr/solr-ref-guide/src/coreadmin-api.adoc         |   4 +-
 .../src/defining-core-properties.adoc              |   2 +-
 solr/solr-ref-guide/src/distributed-requests.adoc  |   4 +-
 solr/solr-ref-guide/src/enabling-ssl.adoc          |   2 +-
 solr/solr-ref-guide/src/faceting.adoc              |   1 -
 solr/solr-ref-guide/src/format-of-solr-xml.adoc    |   6 +-
 .../src/implicit-requesthandlers.adoc              |   2 +-
 .../src/json-faceting-domain-changes.adoc          |   2 +-
 solr/solr-ref-guide/src/json-query-dsl.adoc        |   2 +-
 .../src/jwt-authentication-plugin.adoc             |   2 +-
 .../src/major-changes-in-solr-7.adoc               |   4 +-
 .../src/major-changes-in-solr-8.adoc               |   2 +-
 solr/solr-ref-guide/src/other-parsers.adoc         | 104 +++
 .../src/package-manager-internals.adoc             |  43 +-
 solr/solr-ref-guide/src/package-manager.adoc       |  31 +-
 .../src/performance-statistics-reference.adoc      |   4 +-
 solr/solr-ref-guide/src/resource-loading.adoc      |   6 +-
 .../src/searching-nested-documents.adoc            |   2 +-
 solr/solr-ref-guide/src/securing-solr.adoc         |   4 +-
 .../src/solr-control-script-reference.adoc         |   4 +-
 .../src/solr-cores-and-solr-xml.adoc               |   2 +-
 solr/solr-ref-guide/src/solr-upgrade-notes.adoc    | 134 ++-
 .../solrcloud-autoscaling-policy-preferences.adoc  |  18 +-
 .../src/solrcloud-autoscaling-triggers.adoc        |   4 +-
 .../solrcloud-configuration-and-parameters.adoc    |   2 +-
 solr/solr-ref-guide/src/solrcloud.adoc             |   2 +-
 .../src/the-dismax-query-parser.adoc               |  12 +-
 .../src/updating-parts-of-documents.adoc           |   2 +-
 ...ng-zookeeper-to-manage-configuration-files.adoc |   2 +-
 .../org/apache/solr/client/solrj/SolrResponse.java |   3 +
 .../apache/solr/client/solrj/SolrQueryTest.java    |   3 +
 .../src/java/org/apache/solr/util/LogLevel.java    |  33 +-
 .../org/apache/solr/TestLogLevelAnnotations.java   | 113 ++-
 solr/webapp/web/js/angular/controllers/index.js    |   8 +-
 solr/webapp/web/partials/index.html                |   2 +-
 232 files changed, 2460 insertions(+), 6595 deletions(-)


[lucene-solr] 25/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit e8a45caea28e3f38c571e94de3590c13143b19c7
Merge: 2a0c575 ab470a6
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Aug 1 21:42:47 2019 +0200

    Merge branch 'master' into jira/solr-13579

 solr/CHANGES.txt                                   | 12 ++++
 .../TestSolrEntityProcessorEndToEnd.java           |  7 ++-
 .../test/org/apache/solr/TestSolrTestCaseJ4.java   | 36 ++++++++++++
 .../solr/core/SolrCoreCheckLockOnStartupTest.java  |  6 +-
 .../test/org/apache/solr/core/TestConfigSets.java  |  7 +--
 .../src/test/org/apache/solr/core/TestNRTOpen.java | 14 +----
 .../solr/handler/PingRequestHandlerTest.java       |  4 +-
 .../solr/handler/admin/CoreAdminHandlerTest.java   | 12 +---
 .../component/QueryElevationComponentTest.java     |  4 +-
 .../solr/metrics/SolrMetricsIntegrationTest.java   |  6 +-
 .../reporters/SolrGraphiteReporterTest.java        |  6 +-
 .../metrics/reporters/SolrSlf4jReporterTest.java   |  6 +-
 .../solr/schema/TestUseDocValuesAsStored.java      |  2 +
 .../test/org/apache/solr/search/TestRecovery.java  |  8 ---
 .../org/apache/solr/servlet/CacheHeaderTest.java   |  2 +-
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   | 65 +++++++++++++++++++---
 16 files changed, 138 insertions(+), 59 deletions(-)


[lucene-solr] 15/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit b576520dba6b80a6d0d49bbf76ee2dd3b3c48d5e
Merge: 0876676 d92159b
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jul 23 13:40:40 2019 +0200

    Merge branch 'master' into jira/solr-13579

 README.md                                          |   8 +-
 lucene/CHANGES.txt                                 |   3 +
 .../analysis/shingle/FixedShingleFilterTest.java   |  17 +
 lucene/analysis/nori/build.xml                     |  14 +-
 .../ko/util/TokenInfoDictionaryBuilder.java        |  12 +-
 .../util/graph/GraphTokenStreamFiniteStrings.java  |  84 ++-
 .../graph/TestGraphTokenStreamFiniteStrings.java   |   9 +-
 solr/CHANGES.txt                                   |  36 +-
 solr/core/src/java/org/apache/solr/api/ApiBag.java |  21 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |  50 +-
 .../java/org/apache/solr/core/BlobRepository.java  |   7 +-
 .../java/org/apache/solr/core/CoreContainer.java   |  12 +
 .../src/java/org/apache/solr/core/LibListener.java | 273 ++++++++++
 .../java/org/apache/solr/core/MemClassLoader.java  |  17 +-
 .../src/java/org/apache/solr/core/PluginBag.java   | 284 ++++-------
 .../src/java/org/apache/solr/core/PluginInfo.java  |  25 +-
 .../src/java/org/apache/solr/core/RuntimeLib.java  | 220 ++++++++
 .../src/java/org/apache/solr/core/SolrConfig.java  |   2 +-
 .../src/java/org/apache/solr/core/SolrCore.java    |  18 +-
 .../org/apache/solr/handler/SolrConfigHandler.java | 511 ++++++++++---------
 .../solr/handler/admin/CollectionHandlerApi.java   | 300 +++++++++--
 .../solr/handler/admin/CollectionsHandler.java     |  35 +-
 .../org/apache/solr/handler/admin/SplitOp.java     | 248 ++++++++-
 .../java/org/apache/solr/search/FastLRUCache.java  | 162 +++++-
 .../src/java/org/apache/solr/search/LFUCache.java  | 158 +++++-
 .../src/java/org/apache/solr/search/LRUCache.java  | 169 +++---
 .../src/java/org/apache/solr/search/SolrCache.java |  19 +
 .../SearchGroupsResultTransformer.java             |  64 ++-
 .../org/apache/solr/security/BasicAuthPlugin.java  |   2 +-
 .../solr/security/PermissionNameProvider.java      |   1 +
 .../solr/servlet/cache/HttpCacheHeaderUtil.java    |  15 +-
 .../processor/UpdateRequestProcessorChain.java     |  16 +-
 .../org/apache/solr/util/ConcurrentLFUCache.java   |  65 ++-
 .../org/apache/solr/util/ConcurrentLRUCache.java   |  67 ++-
 .../src/java/org/apache/solr/util/CryptoKeys.java  |  22 +-
 .../src/java/org/apache/solr/util/SolrCLI.java     |   6 +-
 .../src/test-files/cryptokeys/priv_key2048.pem     |  27 +
 .../core/src/test-files/cryptokeys/priv_key512.pem |   9 +
 .../core/src/test-files/cryptokeys/pub_key2048.der | Bin 0 -> 294 bytes
 solr/core/src/test-files/cryptokeys/pub_key512.der | Bin 0 -> 94 bytes
 .../test-files/runtimecode/runtimelibs_v3.jar.bin  | Bin 0 -> 6526 bytes
 solr/core/src/test-files/runtimecode/sig.txt       |  48 ++
 .../configsets/cloud-managed/conf/managed-schema   |  11 +
 .../apache/solr/cloud/ClusterStateMockUtil.java    |   9 +-
 ...OverriddenZkACLAndCredentialsProvidersTest.java |  12 +-
 .../apache/solr/cloud/TestClusterProperties.java   |   6 +-
 .../test/org/apache/solr/cloud/TestCryptoKeys.java |   2 +-
 .../VMParamsZkACLAndCredentialsProvidersTest.java  |   4 +-
 .../AbstractCloudBackupRestoreTestCase.java        |   2 +-
 .../cloud/api/collections/SplitByPrefixTest.java   | 259 ++++++++++
 .../collections/TestHdfsCloudBackupRestore.java    |   3 +
 .../collections/TestLocalFSCloudBackupRestore.java |  98 +++-
 .../cloud/autoscaling/HttpTriggerListenerTest.java |   3 +-
 .../solr/core/TestBackupRepositoryFactory.java     |  21 +-
 .../apache/solr/core/TestCorePropertiesReload.java |   4 +-
 .../org/apache/solr/core/TestDynamicLoading.java   |   2 +-
 .../solr/handler/TestContainerReqHandler.java      | 566 +++++++++++++++++++++
 .../solr/handler/admin/SplitHandlerTest.java       | 218 ++++++++
 .../reporters/SolrGraphiteReporterTest.java        |   4 +-
 .../org/apache/solr/response/TestPushWriter.java   |   6 +-
 .../org/apache/solr/search/TestFastLRUCache.java   |  71 +++
 .../test/org/apache/solr/search/TestLFUCache.java  |  40 ++
 .../test/org/apache/solr/search/TestLRUCache.java  |  84 ++-
 .../DimensionalRoutedAliasUpdateProcessorTest.java |   2 +-
 .../apache/solr/update/processor/RuntimeUrp.java   |   2 +-
 solr/site/index.xsl                                |  22 +-
 .../org/apache/solr/client/solrj/SolrResponse.java |   9 +-
 .../client/solrj/io/stream/JSONTupleStream.java    |   3 +-
 .../solr/client/solrj/io/stream/SolrStream.java    |   3 +-
 .../solrj/request/CollectionAdminRequest.java      |  14 +
 .../client/solrj/request/CollectionApiMapping.java |  17 +
 .../solr/common/cloud/ClusterProperties.java       |  14 +-
 .../solr/common/cloud/CompositeIdRouter.java       |  17 +
 .../org/apache/solr/common/cloud/DocRouter.java    |   8 +
 ...eSetCredentialsDigestZkCredentialsProvider.java |   9 +-
 .../apache/solr/common/cloud/ZkStateReader.java    |  90 ++--
 .../solr/common/params/CommonAdminParams.java      |   2 +
 .../apache/solr/common/params/CoreAdminParams.java |   2 +
 .../apache/solr/common/util/CommandOperation.java  |   9 +-
 .../java/org/apache/solr/common/util/Utils.java    | 337 ++++++------
 .../src/resources/apispec/cluster.Commands.json    |  37 ++
 .../cluster.Commands.runtimelib.properties.json    |  23 +
 ...nfig.Commands.addRequestHandler.properties.json |   2 +-
 .../apispec/core.config.Commands.generic.json      |   2 +-
 solr/solrj/src/resources/apispec/node.ext.json     |  13 +
 .../client/solrj/SolrSchemalessExampleTest.java    |  10 +-
 .../solrj/embedded/SolrExampleJettyTest.java       |   4 +-
 .../client/solrj/io/graph/GraphExpressionTest.java |   3 +-
 .../solrj/io/stream/StreamDecoratorTest.java       |  28 +-
 .../java/org/apache/solr/SolrJettyTestBase.java    |   4 +-
 .../solr/cloud/AbstractFullDistribZkTestBase.java  |   4 +-
 .../org/apache/solr/cloud/SolrCloudTestCase.java   |   4 +-
 .../java/org/apache/solr/cloud/ZkTestServer.java   |   5 +-
 .../src/java/org/apache/solr/util/TestHarness.java |   3 +-
 solr/webapp/web/js/angular/controllers/query.js    |   2 +
 solr/webapp/web/partials/query.html                |  18 +-
 96 files changed, 4099 insertions(+), 1104 deletions(-)

diff --cc solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 7f27ac9,d6098fb..d350e12
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@@ -225,10 -219,8 +225,12 @@@ public class CoreContainer 
  
    protected volatile AutoscalingHistoryHandler autoscalingHistoryHandler;
  
 +  protected volatile ResourceManager resourceManager;
 +
 +  protected volatile ResourceManagerHandler resourceManagerHandler;
 +
+   private final LibListener clusterPropertiesListener = new LibListener(this);
+ 
  
    // Bits for the state variable.
    public final static long LOAD_COMPLETE = 0x1L;


[lucene-solr] 26/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit fb32394f1dc9d435bbcdfdd69658e7fbf3a9c666
Merge: e8a45ca 2eb493d
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Aug 8 18:15:06 2019 +0200

    Merge branch 'master' into jira/solr-13579

 .github/PULL_REQUEST_TEMPLATE.md                   |   2 +-
 .gitignore                                         |   1 +
 dev-tools/scripts/addVersion.py                    |  14 +-
 lucene/CHANGES.txt                                 |  13 +
 lucene/MIGRATE.txt                                 |  15 +
 .../codecs/lucene50/Lucene50PostingsFormat.java    |  40 +-
 .../lucene/search/DisjunctionMatchesIterator.java  |  84 +++-
 .../src/java/org/apache/lucene/search/Matches.java |   7 +
 .../org/apache/lucene/search/MatchesUtils.java     |  24 +-
 .../org/apache/lucene/search/NamedMatches.java     | 158 +++++++
 .../apache/lucene/search/TestMatchesIterator.java  | 106 ++++-
 .../app/desktop/components/MenuBarProvider.java    |  19 +
 .../dialog/menubar/ExportTermsDialogFactory.java   | 275 +++++++++++
 .../lucene/luke/models/tools/IndexTools.java       |   9 +
 .../lucene/luke/models/tools/IndexToolsImpl.java   |  29 ++
 .../luke/app/desktop/messages/messages.properties  |  10 +
 .../org/apache/lucene/search/AssertingMatches.java |  14 +
 solr/CHANGES.txt                                   |  20 +-
 .../handler/dataimport/TestJdbcDataSource.java     |  37 +-
 .../dataimport/TestSimplePropertiesWriter.java     |  32 +-
 .../TestSolrEntityProcessorEndToEnd.java           |  34 +-
 .../extraction/ExtractingRequestHandlerTest.java   |  74 ++-
 .../apache/solr/ltr/feature/TestValueFeature.java  |  21 +-
 .../org/apache/solr/ltr/model/TestLinearModel.java | 135 +++---
 .../ltr/model/TestMultipleAdditiveTreesModel.java  | 129 +++---
 .../solr/ltr/model/TestNeuralNetworkModel.java     |  66 ++-
 .../apache/solr/ltr/model/TestWrapperModel.java    |  52 +--
 .../apache/solr/ltr/norm/TestMinMaxNormalizer.java |  20 +-
 .../solr/ltr/norm/TestStandardNormalizer.java      |  46 +-
 .../ltr/store/rest/TestManagedFeatureStore.java    |  17 +-
 .../solr/velocity/VelocityResponseWriterTest.java  |  15 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |  10 +-
 .../solr/cloud/autoscaling/ComputePlanAction.java  |   3 +
 .../solr/cloud/autoscaling/NodeAddedTrigger.java   |  17 +-
 .../handler/{FilesStream.java => CatStream.java}   |   6 +-
 .../solr/handler/SolrDefaultStreamFactory.java     |   2 +-
 .../org/apache/solr/handler/admin/SplitOp.java     | 166 ++++++-
 .../solr/handler/admin/ZookeeperStatusHandler.java |  71 ++-
 .../handler/component/QueryElevationComponent.java | 516 ++++++++++++++++++---
 .../transform/ExplainAugmenterFactory.java         |  17 +-
 .../org/apache/solr/store/hdfs/HdfsFileWriter.java |   3 +-
 .../test-files/solr/collection1/conf/elevate.xml   |  22 +
 .../solr/collection1/conf/solrconfig-elevate.xml   |   2 +-
 .../solr/collection1/conf/solrconfig.xml           |  10 +-
 .../org/apache/solr/TestDistributedGrouping.java   |   6 +-
 .../embedded/TestEmbeddedSolrServerSchemaAPI.java  |  14 +-
 .../org/apache/solr/cloud/CollectionPropsTest.java |  90 +++-
 .../cloud/api/collections/SplitByPrefixTest.java   |  21 +-
 .../cloud/autoscaling/ComputePlanActionTest.java   |  53 ++-
 .../test/org/apache/solr/cloud/rule/RulesTest.java |  27 +-
 .../test/org/apache/solr/core/PluginInfoTest.java  |   7 +-
 .../handler/FieldAnalysisRequestHandlerTest.java   |  12 +-
 .../org/apache/solr/handler/JsonLoaderTest.java    |  60 +--
 .../solr/handler/PingRequestHandlerTest.java       |   9 +-
 .../solr/handler/TestReplicationHandler.java       |   6 +-
 .../org/apache/solr/handler/TestRestoreCore.java   |   2 -
 .../solr/handler/TestSQLHandlerNonCloud.java       |   8 +-
 .../apache/solr/handler/V2ApiIntegrationTest.java  |  10 +-
 .../handler/admin/CoreAdminCreateDiscoverTest.java |  13 +-
 .../solr/handler/admin/CoreAdminHandlerTest.java   |  70 ++-
 .../solr/handler/admin/CoreAdminOperationTest.java | 440 +++++-------------
 .../admin/CoreMergeIndexesAdminHandlerTest.java    |  19 +-
 .../apache/solr/handler/admin/InfoHandlerTest.java |  20 +-
 .../handler/admin/ShowFileRequestHandlerTest.java  |  44 +-
 .../solr/handler/admin/SplitHandlerTest.java       |  70 +++
 .../solr/handler/admin/TestCollectionAPIs.java     |  19 +-
 .../handler/admin/ZookeeperStatusHandlerTest.java  |  74 +++
 .../component/DistributedDebugComponentTest.java   |  35 +-
 .../component/DistributedFacetExistsSmallTest.java |  20 +-
 .../component/QueryElevationComponentTest.java     | 166 ++++++-
 .../handler/component/SpellCheckComponentTest.java |  40 +-
 .../solr/handler/component/StatsComponentTest.java | 109 ++---
 .../SuggestComponentContextFilterQueryTest.java    |  23 +-
 .../component/TestHttpShardHandlerFactory.java     |  72 ++-
 .../org/apache/solr/highlight/HighlighterTest.java |  12 +-
 .../highlight/TestPostingsSolrHighlighter.java     |   9 +-
 .../solr/highlight/TestUnifiedSolrHighlighter.java |  17 +-
 .../solr/index/WrapperMergePolicyFactoryTest.java  |   8 +-
 .../apache/solr/internal/csv/CharBufferTest.java   |   9 +-
 .../apache/solr/metrics/SolrMetricManagerTest.java |   7 +-
 .../org/apache/solr/request/SimpleFacetsTest.java  |  26 +-
 .../apache/solr/request/TestIntervalFaceting.java  |  10 +-
 .../apache/solr/request/TestRemoteStreaming.java   |  28 +-
 .../org/apache/solr/request/TestStreamBody.java    |  10 +-
 .../transform/TestExplainDocTransformer.java       |  75 +++
 .../apache/solr/schema/ChangedSchemaMergeTest.java |  15 +-
 .../test/org/apache/solr/schema/CopyFieldTest.java |  69 ++-
 .../apache/solr/schema/CurrencyFieldTypeTest.java  |   8 +-
 .../apache/solr/schema/PreAnalyzedFieldTest.java   |  19 +-
 .../solr/schema/SpatialRPTFieldTypeTest.java       |  16 +-
 .../apache/solr/schema/TestCloudSchemaless.java    |  41 +-
 .../solr/security/BasicAuthIntegrationTest.java    |  77 +--
 .../solr/security/TestAuthorizationFramework.java  |   5 +-
 .../hadoop/TestDelegationWithHadoopAuth.java       |  20 +-
 .../hadoop/TestImpersonationWithHadoopAuth.java    |  51 +-
 .../solr/servlet/DirectSolrConnectionTest.java     |  11 +-
 .../apache/solr/servlet/SolrRequestParserTest.java |  68 ++-
 .../spelling/ConjunctionSolrSpellCheckerTest.java  |   7 +-
 .../apache/solr/store/hdfs/HdfsDirectoryTest.java  |   6 +-
 .../org/apache/solr/update/AddBlockUpdateTest.java |   8 +-
 .../solr/update/AnalysisErrorHandlingTest.java     |  13 +-
 .../apache/solr/update/DocumentBuilderTest.java    |  46 +-
 .../solr/update/TestAtomicUpdateErrorCases.java    |  52 +--
 .../test/org/apache/solr/update/TestUpdate.java    |  62 +--
 .../IgnoreLargeDocumentProcessorFactoryTest.java   |  14 +-
 .../StatelessScriptUpdateProcessorFactoryTest.java |  49 +-
 .../processor/TestDocBasedVersionConstraints.java  | 157 +++----
 .../processor/TolerantUpdateProcessorTest.java     | 129 ++----
 .../org/apache/solr/util/DateMathParserTest.java   |  11 +-
 .../org/apache/solr/util/TestTestInjection.java    |  26 +-
 .../BigEndianAscendingWordDeserializerTest.java    |  24 +-
 .../hll/BigEndianAscendingWordSerializerTest.java  |  42 +-
 .../src/solrcloud-autoscaling-triggers.adoc        |   7 +-
 .../src/stream-source-reference.adoc               |  14 +-
 .../src/the-query-elevation-component.adoc         |   8 +
 .../java/org/apache/solr/client/solrj/io/Lang.java |   4 +
 .../client/solrj/io/eval/FieldValueEvaluator.java  |   6 +-
 .../solr/client/solrj/io/eval/IsNullEvaluator.java |   4 +
 .../{IsNullEvaluator.java => LowerEvaluator.java}  |  36 +-
 .../client/solrj/io/eval/NotNullEvaluator.java     |   4 +
 .../{IsNullEvaluator.java => SplitEvaluator.java}  |  37 +-
 .../{IsNullEvaluator.java => TrimEvaluator.java}   |  36 +-
 .../{IsNullEvaluator.java => UpperEvaluator.java}  |  36 +-
 .../solr/client/solrj/io/stream/CsvStream.java     |  11 +-
 .../solr/client/solrj/io/stream/SelectStream.java  |   6 +-
 .../solr/common/cloud/CompositeIdRouter.java       |   5 +-
 .../solr/common/params/AutoScalingParams.java      |   1 +
 .../apache/solr/client/solrj/SolrExampleTests.java | 120 ++---
 .../client/solrj/cloud/autoscaling/TestPolicy.java |   9 +-
 .../solrj/embedded/SolrExampleJettyTest.java       |  18 +-
 .../client/solrj/embedded/TestSolrProperties.java  |  20 +-
 .../client/solrj/impl/BasicHttpSolrClientTest.java | 154 ++----
 .../client/solrj/impl/CloudSolrClientTest.java     |  33 +-
 .../solrj/impl/SolrPortAwareCookieSpecTest.java    |  66 +--
 .../solrj/impl/TestCloudSolrClientConnections.java |  17 +-
 .../org/apache/solr/client/solrj/io/TestLang.java  |   3 +-
 .../client/solrj/io/stream/MathExpressionTest.java | 122 +++--
 .../solrj/io/stream/StreamExpressionTest.java      |  33 +-
 .../io/stream/eval/AbsoluteValueEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/AddEvaluatorTest.java     |   6 +-
 .../io/stream/eval/ArcCosineEvaluatorTest.java     |   5 +-
 .../solrj/io/stream/eval/ArcSineEvaluatorTest.java |   4 +-
 .../io/stream/eval/ArcTangentEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/CeilingEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/CosineEvaluatorTest.java  |   4 +-
 .../io/stream/eval/CubedRootEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/DivideEvaluatorTest.java  |  10 +-
 .../solrj/io/stream/eval/FloorEvaluatorTest.java   |   6 +-
 .../stream/eval/HyperbolicCosineEvaluatorTest.java |   4 +-
 .../stream/eval/HyperbolicSineEvaluatorTest.java   |   4 +-
 .../eval/HyperbolicTangentEvaluatorTest.java       |   4 +-
 .../solrj/io/stream/eval/ModuloEvaluatorTest.java  |  10 +-
 .../io/stream/eval/MultiplyEvaluatorTest.java      |   6 +-
 .../io/stream/eval/NaturalLogEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/PowerEvaluatorTest.java   |   2 +-
 .../solrj/io/stream/eval/RoundEvaluatorTest.java   |   5 +-
 .../solrj/io/stream/eval/SineEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SquareRootEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SubtractEvaluatorTest.java      |   6 +-
 .../solrj/io/stream/eval/TangentEvaluatorTest.java |   4 +-
 .../solr/client/solrj/request/SchemaTest.java      |  15 +-
 .../solrj/request/TestConfigSetAdminRequest.java   |  11 +-
 .../solr/client/solrj/request/TestCoreAdmin.java   |  41 +-
 .../response/TestDelegationTokenResponse.java      |  28 +-
 .../solr/common/TestToleratedUpdateError.java      |  26 +-
 .../apache/solr/common/util/JsonValidatorTest.java |  27 +-
 .../org/apache/solr/common/util/NamedListTest.java |  11 +-
 .../solr/common/util/TestValidatingJsonMap.java    |   7 +-
 .../solr/cloud/MiniSolrCloudClusterTest.java       |  14 +-
 solr/webapp/web/js/angular/controllers/cloud.js    |  11 +-
 solr/webapp/web/partials/cloud.html                |   2 +-
 171 files changed, 3607 insertions(+), 2683 deletions(-)


[lucene-solr] 33/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 5932e53c65e65e4b920fadc22085dc5ee18a68ea
Merge: 5860e3d ded8efa
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Nov 26 15:11:35 2019 +0100

    Merge branch 'master' into jira/solr-13579

 dev-tools/scripts/jenkins.build.ref.guide.sh       |    2 +-
 dev-tools/scripts/reproduceJenkinsFailures.py      |   25 +-
 lucene/CHANGES.txt                                 |   14 +
 .../org/apache/lucene/codecs/lucene50/ForUtil.java |    0
 .../codecs/lucene50/Lucene50PostingsFormat.java    |   33 +-
 .../codecs/lucene50/Lucene50PostingsReader.java    |    0
 .../codecs/lucene50/Lucene50ScoreSkipReader.java   |    0
 .../lucene/codecs/lucene50/Lucene50SkipReader.java |    0
 .../codecs/{lucene70 => lucene50}/package.html     |    2 +-
 .../apache/lucene/codecs/lucene70/IndexedDISI.java |  315 -----
 .../codecs/lucene70/Lucene70DocValuesConsumer.java |  638 ---------
 .../codecs/lucene70/Lucene70DocValuesFormat.java   |  161 ---
 .../codecs/lucene70/Lucene70DocValuesProducer.java | 1426 --------------------
 .../codecs/lucene70/Lucene70NormsConsumer.java     |  159 ---
 .../codecs/lucene70/Lucene70NormsFormat.java       |   99 --
 .../codecs/lucene70/Lucene70NormsProducer.java     |  361 -----
 .../Lucene80Codec.java}                            |   29 +-
 .../codecs/{lucene70 => lucene80}/package.html     |    2 +-
 .../services/org.apache.lucene.codecs.Codec        |    2 +-
 .../org.apache.lucene.codecs.DocValuesFormat       |    1 -
 .../org.apache.lucene.codecs.PostingsFormat        |    1 +
 .../codecs/lucene50/Lucene50PostingsWriter.java    |    0
 .../codecs/lucene50/Lucene50RWPostingsFormat.java} |   45 +-
 .../lucene/codecs/lucene50/Lucene50SkipWriter.java |    7 +-
 .../codecs/lucene50/TestBlockPostingsFormat.java   |   16 +-
 .../codecs/lucene50/TestBlockPostingsFormat2.java  |    4 +-
 .../codecs/lucene50/TestBlockPostingsFormat3.java  |   34 +-
 .../apache/lucene/codecs/lucene50/TestForUtil.java |    0
 .../lucene/codecs/lucene70/TestIndexedDISI.java    |  249 ----
 .../lucene70/TestLucene70DocValuesFormat.java      |  685 ----------
 .../benchmark/byTask/tasks/CreateIndexTask.java    |    6 +-
 .../blocktreeords/BlockTreeOrdsPostingsFormat.java |   10 +-
 .../lucene/codecs/memory/DirectPostingsFormat.java |    8 +-
 .../lucene/codecs/memory/FSTOrdPostingsFormat.java |    8 +-
 .../lucene/codecs/memory/FSTPostingsFormat.java    |    8 +-
 .../uniformsplit/DeltaBaseTermStateSerializer.java |   16 +-
 .../uniformsplit/UniformSplitPostingsFormat.java   |    8 +-
 .../lucene/codecs/uniformsplit/package-info.java   |    2 +-
 .../MockTermStateFactory.java                      |   10 +-
 .../codecs/uniformsplit/TestBlockWriter.java       |    2 +-
 .../sharedterms/STBlockReaderTest.java             |    2 +-
 .../src/java/org/apache/lucene/codecs/Codec.java   |    2 +-
 .../codecs/CompetitiveImpactAccumulator.java       |   86 +-
 .../lucene/codecs/lucene80/package-info.java       |  394 +-----
 .../lucene/codecs/lucene84/ForDeltaUtil.java       |   93 ++
 .../org/apache/lucene/codecs/lucene84/ForUtil.java | 1128 ++++++++++++++++
 .../Lucene84Codec.java}                            |   24 +-
 .../Lucene84PostingsFormat.java}                   |   54 +-
 .../Lucene84PostingsReader.java}                   |  660 +++++----
 .../Lucene84PostingsWriter.java}                   |  111 +-
 .../Lucene84ScoreSkipReader.java}                  |   11 +-
 .../Lucene84SkipReader.java}                       |   27 +-
 .../Lucene84SkipWriter.java}                       |   13 +-
 .../apache/lucene/codecs/lucene84/PForUtil.java    |  130 ++
 .../apache/lucene/codecs/lucene84/gen_ForUtil.py   |  484 +++++++
 .../{lucene80 => lucene84}/package-info.java       |   26 +-
 .../lucene/index/ExitableDirectoryReader.java      |  215 ++-
 .../apache/lucene/index/FilterBinaryDocValues.java |    2 +
 .../lucene/index/FilterNumericDocValues.java       |    2 +
 ...ryDocValues.java => FilterSortedDocValues.java} |   66 +-
 ...lues.java => FilterSortedNumericDocValues.java} |   46 +-
 ...ocValues.java => FilterSortedSetDocValues.java} |   64 +-
 .../org/apache/lucene/search/IndexSearcher.java    |   10 +-
 .../org/apache/lucene/search/LRUQueryCache.java    |   76 +-
 .../java/org/apache/lucene/search/PhraseQuery.java |   10 +-
 .../java/org/apache/lucene/search/QueryCache.java  |    5 +-
 .../org/apache/lucene/store/ByteBufferGuard.java   |    8 +-
 .../apache/lucene/store/ByteBufferIndexInput.java  |   58 +-
 .../apache/lucene/store/ByteBuffersDataOutput.java |   13 +-
 .../java/org/apache/lucene/store/DataInput.java    |   21 +
 .../services/org.apache.lucene.codecs.Codec        |    2 +-
 .../org.apache.lucene.codecs.PostingsFormat        |    2 +-
 .../codecs/TestCompetitiveFreqNormAccumulator.java |   34 +-
 ...tLucene50StoredFieldsFormatHighCompression.java |    8 +-
 .../codecs/lucene80/TestLucene80NormsFormat.java   |    3 +-
 .../TestForDeltaUtil.java}                         |   71 +-
 .../codecs/{lucene50 => lucene84}/TestForUtil.java |   69 +-
 .../TestLucene84PostingsFormat.java}               |   21 +-
 .../TestPForUtil.java}                             |   73 +-
 .../test/org/apache/lucene/index/Test2BPoints.java |    2 +-
 .../lucene/index/TestExitableDirectoryReader.java  |  101 ++
 .../org/apache/lucene/index/TestPointValues.java   |    8 +-
 .../org/apache/lucene/search/TestBoolean2.java     |    8 +-
 .../apache/lucene/search/TestIndexSearcher.java    |    7 +-
 .../apache/lucene/search/TestLRUQueryCache.java    |  607 ++++++++-
 .../org/apache/lucene/search/TestPointQueries.java |    4 +-
 .../org/apache/lucene/store/TestMultiMMap.java     |   20 +
 .../TestUnifiedHighlighterTermIntervals.java       |  998 ++++++++++++++
 .../queries/intervals/CachingMatchesIterator.java  |   10 +-
 .../lucene/queries/intervals/IntervalMatches.java  |    2 +-
 .../intervals/MultiTermIntervalsSource.java        |    4 +-
 .../queries/intervals/OffsetIntervalsSource.java   |    3 +-
 .../queries/intervals/TermIntervalsSource.java     |   18 +-
 .../lucene/queries/intervals/TestIntervals.java    |   88 +-
 .../document/TestFloatPointNearestNeighbor.java    |    2 +-
 .../test/org/apache/lucene/search/TestNearest.java |    2 +-
 .../apache/lucene/spatial3d/TestGeo3DPoint.java    |    4 +-
 .../document/Completion50PostingsFormat.java       |    7 +-
 ...Format.java => Completion84PostingsFormat.java} |   16 +-
 .../suggest/document/CompletionFieldsConsumer.java |    9 +-
 .../suggest/document/CompletionFieldsProducer.java |    7 +-
 .../suggest/document/CompletionPostingsFormat.java |   13 +-
 .../org.apache.lucene.codecs.PostingsFormat        |    1 +
 .../search/suggest/document/TestSuggestField.java  |   15 +-
 .../lucene/codecs/blockterms/LuceneFixedGap.java   |   12 +-
 .../blockterms/LuceneVarGapDocFreqInterval.java    |   12 +-
 .../blockterms/LuceneVarGapFixedInterval.java      |   12 +-
 .../mockrandom/MockRandomPostingsFormat.java       |    8 +-
 .../UniformSplitRot13PostingsFormat.java           |    8 +-
 .../apache/lucene/geo/BaseGeoPointTestCase.java    |    2 +-
 .../apache/lucene/store/BaseDirectoryTestCase.java |   53 +
 .../org/apache/lucene/util/RamUsageTester.java     |    2 +
 .../util/TestRuleSetupAndRestoreClassEnv.java      |    6 +-
 .../src/java/org/apache/lucene/util/TestUtil.java  |   34 +-
 .../org/apache/lucene/mockfile/TestLeakFS.java     |   24 +-
 .../org/apache/lucene/mockfile/TestVerboseFS.java  |   67 +-
 solr/CHANGES.txt                                   |   27 +
 .../client/solrj/embedded/JettySolrRunner.java     |   32 +-
 .../java/org/apache/solr/core/CoreContainer.java   |    2 +-
 .../src/java/org/apache/solr/core/PluginBag.java   |    5 +-
 .../org/apache/solr/core/SchemaCodecFactory.java   |    6 +-
 .../java/org/apache/solr/core/XmlConfigFile.java   |   12 +-
 .../apache/solr/filestore/DistribPackageStore.java |    2 +-
 .../org/apache/solr/handler/StreamHandler.java     |   24 +-
 .../src/java/org/apache/solr/pkg/PackageAPI.java   |   14 +-
 .../org/apache/solr/search/ValueSourceParser.java  |   10 +-
 .../org/apache/solr/search/facet/CountValsAgg.java |  151 +++
 .../org/apache/solr/search/facet/DocValuesAcc.java |  218 +++
 .../java/org/apache/solr/search/facet/HLLAgg.java  |   29 +-
 .../solr/search/facet/UnInvertedFieldAcc.java      |   32 +-
 .../org/apache/solr/search/facet/UniqueAgg.java    |   20 +-
 .../java/org/apache/solr/security/AuditEvent.java  |   48 +-
 .../java/org/apache/solr/servlet/HttpSolrCall.java |    6 +-
 .../java/org/apache/solr/servlet/ServletUtils.java |   20 +-
 .../apache/solr/servlet/SolrDispatchFilter.java    |   19 +-
 .../processor/AtomicUpdateDocumentMerger.java      |    2 +-
 .../processor/UpdateRequestProcessorChain.java     |    8 +-
 .../test-files/runtimecode/TestVersionedURP.java   |   19 +-
 solr/core/src/test-files/runtimecode/sig.txt       |   15 +
 .../src/test-files/runtimecode/testurp_v1.jar.bin  |  Bin 0 -> 689 bytes
 .../src/test-files/runtimecode/testurp_v2.jar.bin  |  Bin 0 -> 689 bytes
 .../solr/collection1/conf/schema_codec.xml         |    2 +-
 .../configsets/exitable-directory/conf/schema.xml  |    4 +
 .../cloud/CloudExitableDirectoryReaderTest.java    |   30 +-
 .../org/apache/solr/cloud/MoveReplicaHDFSTest.java |    2 +
 .../cloud/TestDynamicFieldNamesIndexCorrectly.java |  818 +++++++++++
 .../apache/solr/cloud/hdfs/HdfsNNFailoverTest.java |    2 -
 .../apache/solr/cloud/hdfs/HdfsRecoveryZkTest.java |    2 -
 .../solr/handler/admin/CoreAdminHandlerTest.java   |    2 +-
 .../src/test/org/apache/solr/pkg/TestPackages.java |   50 +-
 .../org/apache/solr/search/QueryEqualityTest.java  |    3 +
 ...stributedFacetSimpleRefinementLongTailTest.java |   11 +-
 .../apache/solr/search/facet/TestJsonFacets.java   |   67 +-
 .../solr/security/AuditLoggerIntegrationTest.java  |   14 +
 .../solr/security/AuditLoggerPluginTest.java       |   22 +-
 .../solr/spelling/SpellCheckCollatorTest.java      |   28 +-
 .../update/processor/NestedAtomicUpdateTest.java   |   67 +
 .../TimeRoutedAliasUpdateProcessorTest.java        |    1 +
 solr/solr-ref-guide/README.adoc                    |   13 +-
 solr/solr-ref-guide/build.xml                      |   78 +-
 solr/solr-ref-guide/ivy.xml                        |    1 -
 solr/solr-ref-guide/src/_config.yml.template       |    5 +-
 solr/solr-ref-guide/src/_includes/topnav.html      |    1 -
 solr/solr-ref-guide/src/errata.adoc                |    4 +-
 solr/solr-ref-guide/src/how-to-contribute.adoc     |   13 +-
 solr/solr-ref-guide/src/js/customscripts.js        |    2 +-
 solr/solr-ref-guide/src/json-facet-api.adoc        |    5 +-
 .../src/meta-docs/asciidoc-syntax.adoc             |   17 +-
 solr/solr-ref-guide/src/meta-docs/jekyll.adoc      |    5 +-
 solr/solr-ref-guide/src/meta-docs/pdf.adoc         |  145 --
 solr/solr-ref-guide/src/meta-docs/publish.adoc     |  224 +--
 .../src/package-manager-internals.adoc             |   12 +-
 solr/solr-ref-guide/src/pdf/SolrRefGuide-all.adoc  |   36 -
 .../src/pdf/themes/refguide-theme.yml              |  260 ----
 solr/solr-ref-guide/src/streaming-expressions.adoc |   10 +
 ...ldNavAndPDFBody.java => BuildNavDataFiles.java} |   50 +-
 .../solr-ref-guide/tools/CheckLinksAndAnchors.java |   62 +-
 solr/solr-ref-guide/tools/ReducePDFSize.java       |   90 --
 .../apache/solr/common/cloud/ZkStateReader.java    |    2 +-
 .../org/apache/solr/common/util/JavaBinCodec.java  |   14 +-
 solr/webapp/web/css/angular/cloud.css              |   11 +-
 181 files changed, 7038 insertions(+), 6576 deletions(-)



[lucene-solr] 32/36: SOLR-13579: Simplify the API, add more tests.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 5860e3dc96fee08b453fc1db76edc836d1a41631
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Nov 26 15:10:45 2019 +0100

    SOLR-13579: Simplify the API, add more tests.
---
 .../solr/handler/admin/ResourceManagerHandler.java |  16 +-
 .../{ManagedComponent.java => ChangeListener.java} |  26 ++-
 .../solr/managed/DefaultResourceManager.java       |  32 ++--
 .../solr/managed/DefaultResourceManagerPool.java   | 168 ------------------
 ...java => DefaultResourceManagerPoolFactory.java} |  53 +++---
 .../org/apache/solr/managed/ManagedComponent.java  |   6 +-
 .../apache/solr/managed/ManagedComponentId.java    |  25 +--
 .../apache/solr/managed/NoOpResourceManager.java   | 113 +++---------
 .../org/apache/solr/managed/ResourceManager.java   |  16 +-
 .../apache/solr/managed/ResourceManagerPlugin.java |  93 ----------
 .../apache/solr/managed/ResourceManagerPool.java   | 190 +++++++++++++++++++--
 ...actory.java => ResourceManagerPoolFactory.java} |  15 +-
 .../{PoolContext.java => ResourcePoolContext.java} |   2 +-
 ...anagedContext.java => SolrResourceContext.java} |   4 +-
 ...cheManagerPlugin.java => CacheManagerPool.java} | 112 ++++++------
 .../apache/solr/managed/types/package-info.java    |   2 +-
 .../java/org/apache/solr/search/CaffeineCache.java |  21 ++-
 .../src/java/org/apache/solr/search/SolrCache.java |   2 +
 .../org/apache/solr/search/SolrCacheHolder.java    |   6 +-
 ...nagerPool.java => TestResourceManagerPool.java} |  83 +++------
 ...lugin.java => TestCacheManagerPluginCloud.java} |   2 +-
 .../solr/managed/types/TestCacheManagerPool.java   | 117 +++++++++++++
 22 files changed, 507 insertions(+), 597 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index 854da43..dd587ca 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -151,7 +151,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         result.add("resources", pool.getComponents().keySet());
         try {
           Map<String, Map<String, Object>> values = pool.getCurrentValues();
-          result.add("totalValues", pool.getResourceManagerPlugin().aggregateTotalValues(values));
+          result.add("totalValues", pool.aggregateTotalValues(values));
         } catch (Exception e) {
           log.warn("Error getting current values from pool " + name, e);
           result.add("error", "Error getting current values: " + e.toString());
@@ -225,7 +225,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
     if (poolName == null || poolName.isBlank()) {
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Resource operation requires '" + POOL_PARAM + "' parameter.");
     }
-    ResourceManagerPool pool = resourceManager.getPool(poolName);
+    ResourceManagerPool<ManagedComponent> pool = resourceManager.getPool(poolName);
     if (pool == null) {
       throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Pool '" + poolName + "' not found.");
     }
@@ -241,7 +241,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           result.add(n, perRes);
           perRes.add("class", component.getClass().getName());
           try {
-            perRes.add("resourceLimits", pool.getResourceManagerPlugin().getResourceLimits(component));
+            perRes.add("resourceLimits", pool.getResourceLimits(component));
           } catch (Exception e) {
             log.warn("Error getting resourceLimits of " + component.getManagedComponentId(), e);
             result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
@@ -255,13 +255,13 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         }
         result.add("class", component.getClass().getName());
         try {
-          result.add("resourceLimits", pool.getResourceManagerPlugin().getResourceLimits(component));
+          result.add("resourceLimits", pool.getResourceLimits(component));
         } catch (Exception e) {
           log.warn("Error getting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
           result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
         }
         try {
-          result.add("monitoredValues", pool.getResourceManagerPlugin().getMonitoredValues(component));
+          result.add("monitoredValues", pool.getMonitoredValues(component));
         } catch (Exception e) {
           log.warn("Error getting monitored values of " + resName + "/" + poolName + " : " + e.toString(), e);
           result.add("error", "Error getting monitored values of " + resName + ": " + e.toString());
@@ -273,7 +273,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Component '" + resName + " not found in pool '" + poolName + "'.");
         }
         try {
-          result.add("resourceLimits", pool.getResourceManagerPlugin().getResourceLimits(managedComponent1));
+          result.add("resourceLimits", pool.getResourceLimits(managedComponent1));
         } catch (Exception e) {
           log.warn("Error getting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
           result.add("error", "Error getting resource limits of " + resName + ": " + e.toString());
@@ -285,7 +285,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
         try {
-          Map<String, Object> currentLimits = new HashMap<>(pool.getResourceManagerPlugin().getResourceLimits(managedComponent2));
+          Map<String, Object> currentLimits = new HashMap<>(pool.getResourceLimits(managedComponent2));
           Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
           newLimits.forEach((k, v) -> {
             if (v == null) {
@@ -295,7 +295,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
             }
           });
           try {
-            pool.getResourceManagerPlugin().setResourceLimits(managedComponent2, newLimits);
+            pool.setResourceLimits(managedComponent2, newLimits);
             result.add("success", newLimits);
           } catch (Exception e) {
             log.warn("Error setting resource limits of " + resName + "/" + poolName + " : " + e.toString(), e);
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ChangeListener.java
similarity index 58%
copy from solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
copy to solr/core/src/java/org/apache/solr/managed/ChangeListener.java
index 4ea5922..49fbad6 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ChangeListener.java
@@ -17,24 +17,18 @@
 package org.apache.solr.managed;
 
 /**
- * A managed component.
+ *
  */
-public interface ManagedComponent extends AutoCloseable {
-  /**
-   * Unique name of this component. By convention id-s form a colon-separated hierarchy.
-   */
-  ManagedComponentId getManagedComponentId();
-
-  void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools);
+public interface ChangeListener {
 
   /**
-   * Component context used for managing additional component state for the purpose of resource management.
+   * Notify about changing a limit of a resource.
+   * @param poolName pool name where resource is managed.
+   * @param component managed component
+   * @param limitName limit name
+   * @param newRequestedVal requested new value of the resource limit.
+   * @param newActualVal actual value applied to the resource configuration. Note: this may differ from the
+   *                     value requested due to internal logic of the component.
    */
-  ManagedContext getManagedContext();
-
-  default void close() throws Exception {
-    if (getManagedContext() != null) {
-      getManagedContext().close();
-    }
-  }
+  void changedLimit(String poolName, ManagedComponent component, String limitName, Object newRequestedVal, Object newActualVal);
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index 069628d..6042717 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -33,7 +33,7 @@ import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.managed.types.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPool;
 import org.apache.solr.search.SolrCache;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.slf4j.Logger;
@@ -60,7 +60,7 @@ public class DefaultResourceManager extends ResourceManager {
 
   static {
     Map<String, Object> params = new HashMap<>();
-    params.put(CommonParams.TYPE, CacheManagerPlugin.TYPE);
+    params.put(CommonParams.TYPE, CacheManagerPool.TYPE);
     // unlimited RAM
     params.put(SolrCache.MAX_RAM_MB_PARAM, -1L);
     DEFAULT_NODE_POOLS.put(NODE_SEARCHER_CACHE_POOL, params);
@@ -82,7 +82,7 @@ public class DefaultResourceManager extends ResourceManager {
   protected boolean isClosed = false;
   protected boolean enabled = true;
 
-  protected ResourceManagerPluginFactory resourceManagerPluginFactory;
+  protected ResourceManagerPoolFactory resourceManagerPoolFactory;
   protected SolrResourceLoader loader;
 
 
@@ -97,7 +97,7 @@ public class DefaultResourceManager extends ResourceManager {
     scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
     scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
     // TODO: make configurable based on plugin info
-    resourceManagerPluginFactory = new DefaultResourceManagerPluginFactory(loader,
+    resourceManagerPoolFactory = new DefaultResourceManagerPoolFactory(loader,
         pluginInfo != null ?
             (Map<String, Object>)pluginInfo.initArgs.toMap(new HashMap<>()).getOrDefault("plugins", Collections.emptyMap()) :
             Collections.emptyMap());
@@ -118,7 +118,12 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
+  public ResourceManagerPoolFactory getResourceManagerPoolFactory() {
+    return resourceManagerPoolFactory;
+  }
+
+  @Override
+  public ResourceManagerPool createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
     ensureActive();
     if (resourcePools.containsKey(name)) {
       throw new IllegalArgumentException("Pool '" + name + "' already exists.");
@@ -126,16 +131,19 @@ public class DefaultResourceManager extends ResourceManager {
     if (resourcePools.size() >= maxNumPools) {
       throw new IllegalArgumentException("Maximum number of pools (" + maxNumPools + ") reached.");
     }
-    DefaultResourceManagerPool newPool = new DefaultResourceManagerPool(name, type, resourceManagerPluginFactory, poolLimits, args);
+    ResourceManagerPool newPool = resourceManagerPoolFactory.create(name, type, this, poolLimits, args);
     newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(args.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, DEFAULT_SCHEDULE_DELAY_SECONDS)));
     resourcePools.putIfAbsent(name, newPool);
-    newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
-          log.info("- running pool " + newPool.getName() + " / " + newPool.getType());
-          newPool.run();
-        }, 0,
-        timeSource.convertDelay(TimeUnit.SECONDS, newPool.scheduleDelaySeconds, TimeUnit.MILLISECONDS),
-        TimeUnit.MILLISECONDS);
+    if (timeSource != null) {
+      newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
+            log.info("- running pool " + newPool.getName() + " / " + newPool.getType());
+            newPool.manage();
+          }, 0,
+          timeSource.convertDelay(TimeUnit.SECONDS, newPool.scheduleDelaySeconds, TimeUnit.MILLISECONDS),
+          TimeUnit.MILLISECONDS);
+    }
     log.info("- created pool " + newPool.getName() + " / " + newPool.getType());
+    return newPool;
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
deleted file mode 100644
index f00866c..0000000
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.managed;
-
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class manages a pool of resources of the same type, which use the same
- * {@link ResourceManagerPlugin} implementation for managing their resource limits.
- */
-public class DefaultResourceManagerPool implements ResourceManagerPool {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private final Map<String, ManagedComponent> components = new ConcurrentHashMap<>();
-  private Map<String, Object> poolLimits;
-  private final String type;
-  private final Class<? extends ManagedComponent> componentClass;
-  private final String name;
-  private final ResourceManagerPlugin resourceManagerPlugin;
-  private final Map<String, Object> args;
-  private final PoolContext poolContext = new PoolContext();
-  private final ReentrantLock updateLock = new ReentrantLock();
-  int scheduleDelaySeconds;
-  ScheduledFuture<?> scheduledFuture;
-
-  /**
-   * Create a pool of resources to manage.
-   * @param name unique name of the pool
-   * @param type one of the supported pool types (see {@link ResourceManagerPluginFactory})
-   * @param factory factory of {@link ResourceManagerPlugin}-s of the specified type
-   * @param poolLimits pool limits (keys are controlled tags)
-   * @param args parameters for the {@link ResourceManagerPlugin}
-   * @throws Exception when initialization of the management plugin fails.
-   */
-  public DefaultResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
-    this.name = name;
-    this.type = type;
-    this.resourceManagerPlugin = factory.create(type, args);
-    this.componentClass = factory.getComponentClassByType(type);
-    this.poolLimits = new TreeMap<>(poolLimits);
-    this.args = new HashMap<>(args);
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public String getType() {
-    return type;
-  }
-
-  @Override
-  public Map<String, Object> getParams() {
-    return args;
-  }
-
-  @Override
-  public ResourceManagerPlugin getResourceManagerPlugin() {
-    return resourceManagerPlugin;
-  }
-
-  @Override
-  public void registerComponent(ManagedComponent managedComponent) {
-    if (!componentClass.isAssignableFrom(managedComponent.getClass())) {
-      log.debug("Pool type '" + type + "' is not supported by the component " + managedComponent.getManagedComponentId());
-      return;
-    }
-    ManagedComponent existing = components.putIfAbsent(managedComponent.getManagedComponentId().toString(), managedComponent);
-    if (existing != null) {
-      throw new IllegalArgumentException("Component '" + managedComponent.getManagedComponentId() + "' already exists in pool '" + name + "' !");
-    }
-  }
-
-  @Override
-  public boolean unregisterComponent(String name) {
-    return components.remove(name) != null;
-  }
-
-  @Override
-  public boolean isRegistered(String componentId) {
-    return components.containsKey(componentId);
-  }
-
-  @Override
-  public Map<String, ManagedComponent> getComponents() {
-    return Collections.unmodifiableMap(components);
-  }
-
-  @Override
-  public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
-    updateLock.lockInterruptibly();
-    try {
-      // collect the current values
-      Map<String, Map<String, Object>> currentValues = new HashMap<>();
-      for (ManagedComponent managedComponent : components.values()) {
-        try {
-          currentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
-        } catch (Exception e) {
-          log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
-        }
-      }
-      return Collections.unmodifiableMap(currentValues);
-    } finally {
-      updateLock.unlock();
-    }
-  }
-
-  @Override
-  public Map<String, Object> getPoolLimits() {
-    return poolLimits;
-  }
-
-  @Override
-  public void setPoolLimits(Map<String, Object> poolLimits) {
-    this.poolLimits = new HashMap(poolLimits);
-  }
-
-  @Override
-  public PoolContext getPoolContext() {
-    return poolContext;
-  }
-
-  @Override
-  public void run() {
-    try {
-      resourceManagerPlugin.manage(this);
-    } catch (Exception e) {
-      log.warn("Error running management plugin " + getName(), e);
-    }
-  }
-
-  @Override
-  public void close() throws IOException {
-    if (scheduledFuture != null) {
-      scheduledFuture.cancel(true);
-      scheduledFuture = null;
-    }
-    components.clear();
-    poolContext.clear();
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPoolFactory.java
similarity index 55%
rename from solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
rename to solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPoolFactory.java
index 0f5cf79..3db59c7 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPoolFactory.java
@@ -22,39 +22,41 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.managed.types.CacheManagerPlugin;
+import org.apache.solr.managed.types.CacheManagerPool;
 import org.apache.solr.search.SolrCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Default implementation of {@link ResourceManagerPluginFactory}.
+ * Default implementation of {@link ResourceManagerPoolFactory}.
  */
-public class DefaultResourceManagerPluginFactory implements ResourceManagerPluginFactory {
+public class DefaultResourceManagerPoolFactory implements ResourceManagerPoolFactory {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private static final Map<String, Class<? extends ResourceManagerPlugin>> typeToPluginClass = new HashMap<>();
+  private static final Map<String, Class<? extends ResourceManagerPool>> typeToPoolClass = new HashMap<>();
   private static final Map<String, Class<? extends ManagedComponent>> typeToComponentClass = new HashMap<>();
 
-  public static final String TYPE_TO_PLUGIN = "typeToPlugin";
+  public static final String TYPE_TO_POOL = "typeToPool";
   public static final String TYPE_TO_COMPONENT = "typeToComponent";
 
   static {
-    typeToPluginClass.put(CacheManagerPlugin.TYPE, CacheManagerPlugin.class);
-    typeToComponentClass.put(CacheManagerPlugin.TYPE, SolrCache.class);
+    typeToPoolClass.put(CacheManagerPool.TYPE, CacheManagerPool.class);
+    typeToPoolClass.put(NoOpResourceManager.NOOP, NoOpResourceManager.NoOpResourcePool.class);
+    typeToComponentClass.put(CacheManagerPool.TYPE, SolrCache.class);
+    typeToComponentClass.put(NoOpResourceManager.NOOP, NoOpResourceManager.NoOpManagedComponent.class);
   }
 
   private final SolrResourceLoader loader;
 
-  public DefaultResourceManagerPluginFactory(SolrResourceLoader loader, Map<String, Object> config) {
+  public DefaultResourceManagerPoolFactory(SolrResourceLoader loader, Map<String, Object> config) {
     this.loader = loader;
-    Map<String, String> typeToPluginMap = (Map<String, String>)config.getOrDefault(TYPE_TO_PLUGIN, Collections.emptyMap());
+    Map<String, String> typeToPoolMap = (Map<String, String>)config.getOrDefault(TYPE_TO_POOL, Collections.emptyMap());
     Map<String, String> typeToComponentMap = (Map<String, String>)config.getOrDefault(TYPE_TO_COMPONENT, Collections.emptyMap());
-    Map<String, Class<? extends ResourceManagerPlugin>> newPlugins = new HashMap<>();
+    Map<String, Class<? extends ResourceManagerPool>> newPlugins = new HashMap<>();
     Map<String, Class<? extends ManagedComponent>> newComponents = new HashMap<>();
-    typeToPluginMap.forEach((type, className) -> {
+    typeToPoolMap.forEach((type, className) -> {
       try {
-        Class<? extends ResourceManagerPlugin> pluginClazz = loader.findClass(className, ResourceManagerPlugin.class);
+        Class<? extends ResourceManagerPool> pluginClazz = loader.findClass(className, ResourceManagerPool.class);
         newPlugins.put(type, pluginClazz);
       } catch (Exception e) {
         log.warn("Error finding plugin class", e);
@@ -63,7 +65,7 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
     typeToComponentMap.forEach((type, className) -> {
       try {
         Class<? extends ManagedComponent> componentClazz = loader.findClass(className, ManagedComponent.class);
-        if (typeToPluginClass.containsKey(type) || newPlugins.containsKey(type)) {
+        if (typeToPoolClass.containsKey(type) || newPlugins.containsKey(type)) {
           newComponents.put(type, componentClazz);
         }
       } catch (Exception e) {
@@ -75,7 +77,7 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
       if (!newComponents.containsKey(type) && !typeToComponentClass.containsKey(type)) {
         return;
       }
-      typeToPluginClass.put(type, pluginClass);
+      typeToPoolClass.put(type, pluginClass);
       if (newComponents.containsKey(type)) {
         typeToComponentClass.put(type, newComponents.get(type));
       }
@@ -83,14 +85,23 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
   }
 
   @Override
-  public <T extends ManagedComponent> ResourceManagerPlugin<T> create(String type, Map<String, Object> params) throws Exception {
-    Class<? extends ResourceManagerPlugin> pluginClazz = typeToPluginClass.get(type);
+  public <T extends ManagedComponent> ResourceManagerPool<T> create(String name, String type, ResourceManager resourceManager,
+                                                                    Map<String, Object> poolLimits, Map<String, Object> poolParams) throws Exception {
+    Class<? extends ResourceManagerPool> pluginClazz = typeToPoolClass.get(type);
     if (pluginClazz == null) {
       throw new IllegalArgumentException("Unsupported plugin type '" + type + "'");
     }
-    ResourceManagerPlugin<T> resourceManagerPlugin = loader.newInstance(pluginClazz.getName(), ResourceManagerPlugin.class);
-    resourceManagerPlugin.init(params);
-    return resourceManagerPlugin;
+    Class<? extends ManagedComponent> componentClass = typeToComponentClass.get(type);
+    if (componentClass == null) {
+      throw new IllegalArgumentException("Unsupported component type '" + type + "'");
+    }
+    ResourceManagerPool<T> resourceManagerPool = loader.newInstance(
+        pluginClazz.getName(),
+        ResourceManagerPool.class,
+        null,
+        new Class[]{String.class, String.class, ResourceManager.class, Map.class, Map.class},
+        new Object[]{name, type, resourceManager, poolLimits, poolParams});
+    return resourceManagerPool;
   }
 
   @Override
@@ -99,7 +110,7 @@ public class DefaultResourceManagerPluginFactory implements ResourceManagerPlugi
   }
 
   @Override
-  public Class<? extends ResourceManagerPlugin> getPluginClassByType(String type) {
-    return typeToPluginClass.get(type);
+  public Class<? extends ResourceManagerPool> getPoolClassByType(String type) {
+    return typeToPoolClass.get(type);
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index 4ea5922..df5c6c0 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -30,11 +30,11 @@ public interface ManagedComponent extends AutoCloseable {
   /**
    * Component context used for managing additional component state for the purpose of resource management.
    */
-  ManagedContext getManagedContext();
+  SolrResourceContext getSolrResourceContext();
 
   default void close() throws Exception {
-    if (getManagedContext() != null) {
-      getManagedContext().close();
+    if (getSolrResourceContext() != null) {
+      getSolrResourceContext().close();
     }
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index 9b80e2d..9f47d4a 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -29,21 +29,18 @@ public class ManagedComponentId {
 
   public static final String SEPARATOR = ":";
 
-  private final String type;
   private final String name;
   private final String[] path;
   private final String id;
 
-  public ManagedComponentId(String type, Object component, String... path) {
-    this(type, SolrMetricProducer.getUniqueMetricTag(component, null), path);
+  public ManagedComponentId(Object component, String... path) {
+    this(SolrMetricProducer.getUniqueMetricTag(component, null), path);
   }
 
-  ManagedComponentId(String type, String name, String... path) {
-    this.type = type;
+  ManagedComponentId(String name, String... path) {
     this.name = name;
     this.path = path;
     StringBuilder sb = new StringBuilder();
-    sb.append(type);
     if (path != null) {
       for (String pathEl : path) {
         if (sb.length() > 0) {
@@ -59,10 +56,6 @@ public class ManagedComponentId {
     id = sb.toString();
   }
 
-  public String getType() {
-    return type;
-  }
-
   public String getName() {
     return name;
   }
@@ -80,16 +73,12 @@ public class ManagedComponentId {
       return null;
     }
     String[] parts = fullName.split(SEPARATOR);
-    if (parts.length < 2) {
-      throw new RuntimeException("at least 2 parts (type and name) must be present: " + fullName);
-    }
-    if (parts.length > 2) {
-      String type = parts[0];
+    if (parts.length > 1) {
       String name = parts[parts.length - 1];
-      String[] path = Arrays.copyOfRange(parts, 1, parts.length - 1);
-      return new ManagedComponentId(type, name, path);
+      String[] path = Arrays.copyOfRange(parts, 0, parts.length - 1);
+      return new ManagedComponentId(name, path);
     } else {
-      return new ManagedComponentId(parts[0], parts[1]);
+      return new ManagedComponentId(parts[0]);
     }
   }
 }
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index 9dc0fc3..f6ce453 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -30,121 +30,49 @@ public class NoOpResourceManager extends ResourceManager {
 
   public static final NoOpResourceManager INSTANCE = new NoOpResourceManager();
 
-  private static final class NoOpResourceManagerPlugin implements ResourceManagerPlugin {
-    static final NoOpResourceManagerPlugin INSTANCE = new NoOpResourceManagerPlugin();
-
-    @Override
-    public String getType() {
-      return NOOP;
-    }
-
-    @Override
-    public Collection<String> getMonitoredParams() {
-      return Collections.emptySet();
-    }
-
-    @Override
-    public Collection<String> getControlledParams() {
-      return Collections.emptySet();
-    }
-
-    @Override
-    public Map<String, Object> getMonitoredValues(ManagedComponent component) throws Exception {
-      return Collections.emptyMap();
-    }
-
+  public static class NoOpManagedComponent implements ManagedComponent {
     @Override
-    public void setResourceLimit(ManagedComponent component, String limitName, Object value) throws Exception {
-      // no-op
+    public ManagedComponentId getManagedComponentId() {
+      return ManagedComponentId.of(NOOP);
     }
 
     @Override
-    public Map<String, Object> getResourceLimits(ManagedComponent component) throws Exception {
-      return Collections.emptyMap();
-    }
+    public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
 
-    @Override
-    public void manage(ResourceManagerPool pool) throws Exception {
-      // no-op
     }
 
     @Override
-    public void init(Map params) {
-      // no-op
+    public SolrResourceContext getSolrResourceContext() {
+      return null;
     }
   }
 
-  private static final class NoOpResourcePool implements ResourceManagerPool {
-    static final NoOpResourcePool INSTANCE = new NoOpResourcePool();
-
-    @Override
-    public String getName() {
-      return NOOP;
-    }
-
-    @Override
-    public String getType() {
-      return NOOP;
-    }
+  public static final class NoOpResourcePool<NoOpManagedComponent> extends ResourceManagerPool {
+    static final NoOpResourcePool<NoOpResourceManager.NoOpManagedComponent> INSTANCE =
+        new NoOpResourcePool<>(NoOpResourceManager.INSTANCE, Collections.emptyMap(), Collections.emptyMap());
 
-    @Override
-    public ResourceManagerPlugin getResourceManagerPlugin() {
-      return NoOpResourceManagerPlugin.INSTANCE;
+    public NoOpResourcePool(ResourceManager resourceManager, Map poolLimits, Map poolParams) {
+      super(NOOP, NOOP, resourceManager, poolLimits, poolParams);
     }
 
     @Override
-    public void registerComponent(ManagedComponent managedComponent) {
-      // no-op
-    }
-
-    @Override
-    public boolean unregisterComponent(String name) {
-      return false;
-    }
-
-    @Override
-    public boolean isRegistered(String componentId) {
-      return false;
-    }
-
-    @Override
-    public Map<String, ManagedComponent> getComponents() {
+    public Map<String, Object> getMonitoredValues(ManagedComponent component) {
       return Collections.emptyMap();
     }
 
     @Override
-    public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
-      return Collections.emptyMap();
+    protected Object doSetResourceLimit(ManagedComponent component, String limitName, Object value) throws Exception {
+      return value;
     }
 
     @Override
-    public Map<String, Object> getPoolLimits() {
+    public Map<String, Object> getResourceLimits(ManagedComponent component) throws Exception {
       return Collections.emptyMap();
     }
 
     @Override
-    public Map<String, Object> getParams() {
-      return Collections.emptyMap();
-    }
+    protected void doManage() throws Exception {
 
-    @Override
-    public void setPoolLimits(Map<String, Object> poolLimits) {
-      // no-op
-    }
-
-    @Override
-    public PoolContext getPoolContext() {
-      return null;
-    }
-
-    @Override
-    public void close() throws IOException {
-      // no-op
-    }
-
-    @Override
-    public void run() {
-      // no-op
     }
   }
 
@@ -154,8 +82,13 @@ public class NoOpResourceManager extends ResourceManager {
   }
 
   @Override
-  public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
-    // no-op
+  public ResourceManagerPoolFactory getResourceManagerPoolFactory() {
+    return null;
+  }
+
+  @Override
+  public ResourceManagerPool createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception {
+    return NoOpResourcePool.INSTANCE;
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index 364a99d..44b9c86 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -30,7 +30,6 @@ import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.schema.FieldType;
-import org.apache.solr.util.SolrPluginUtils;
 import org.apache.solr.util.plugin.PluginInfoInitialized;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,7 +37,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Base class for resource management. It uses a flat model where there are named
  * resource pools of a given type, each pool with its own defined resource limits. Components can be added
- * to a pool for the management of a specific aspect of that component using {@link ResourceManagerPlugin}.
+ * to a pool for the management of a specific aspect of that component.
  */
 public abstract class ResourceManager implements SolrCloseable, PluginInfoInitialized {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -162,14 +161,17 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
     }
   }
 
+  public abstract ResourceManagerPoolFactory getResourceManagerPoolFactory();
+
   /**
    * Create a named resource management pool.
-   * @param name pool name
-   * @param type pool type (one of the supported {@link ResourceManagerPlugin} types)
-   * @param poolLimits pool limits
-   * @param args other parameters. These are also used for creating a {@link ResourceManagerPlugin}
+   * @param name pool name (must not be empty)
+   * @param type pool type (one of the supported {@link ResourceManagerPool} types)
+   * @param poolLimits pool limits (must not be null)
+   * @param args other parameters (must not be null).
+   * @return newly created and scheduled resource pool
    */
-  public abstract void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception;
+  public abstract ResourceManagerPool createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> args) throws Exception;
 
   /**
    * List all currently existing pool names.
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
deleted file mode 100644
index dc6a5b6..0000000
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.managed;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A plugin that implements an algorithm for managing a pool of resources of a given type.
- */
-public interface ResourceManagerPlugin<T extends ManagedComponent> {
-
-  /** Plugin symbolic type. */
-  String getType();
-
-  void init(Map<String, Object> params);
-
-  /**
-   * Name of monitored parameters that {@link ManagedComponent}-s managed by this plugin
-   * are expected to support.
-   */
-  Collection<String> getMonitoredParams();
-  /**
-   * Name of controlled parameters that {@link ManagedComponent}-s managed by this plugin
-   * are expected to support.
-   */
-  Collection<String> getControlledParams();
-
-  /**
-   * Return current values of monitored parameters. Note: the resulting map may contain also
-   * other implementation-specific parameter values.
-   * @param component monitored component
-   */
-  Map<String, Object> getMonitoredValues(T component) throws Exception;
-
-  default void setResourceLimits(T component, Map<String, Object> limits) throws Exception {
-    if (limits == null || limits.isEmpty()) {
-      return;
-    }
-    for (Map.Entry<String, Object> entry : limits.entrySet()) {
-      setResourceLimit(component, entry.getKey(), entry.getValue());
-    }
-  }
-
-  void setResourceLimit(T component, String limitName, Object value) throws Exception;
-
-  Map<String, Object> getResourceLimits(T component) throws Exception;
-
-  /**
-   * Manage resources in a pool. This method is called periodically by {@link ResourceManager},
-   * according to a schedule defined by the pool.
-   * @param pool pool instance.
-   */
-  void manage(ResourceManagerPool pool) throws Exception;
-
-  /**
-   * Return aggregated current monitored values.
-   * <p>Default implementation of this method simply sums up all non-negative numeric values across
-   * components and ignores any non-numeric values.</p>
-   */
-  default Map<String, Object> aggregateTotalValues(Map<String, Map<String, Object>> perComponentValues) {
-    // calculate the totals
-    Map<String, Object> newTotalValues = new HashMap<>();
-    perComponentValues.values().forEach(map -> map.forEach((k, v) -> {
-      // only calculate totals for numbers
-      if (!(v instanceof Number)) {
-        return;
-      }
-      Double val = ((Number)v).doubleValue();
-      // -1 and MAX_VALUE are our special guard values
-      if (val < 0 || val.longValue() == Long.MAX_VALUE || val.longValue() == Integer.MAX_VALUE) {
-        return;
-      }
-      newTotalValues.merge(k, val, (v1, v2) -> ((Number)v1).doubleValue() + ((Number)v2).doubleValue());
-    }));
-    return newTotalValues;
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 4f1a786..dfa822f 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -1,56 +1,216 @@
 package org.apache.solr.managed;
 
 import java.io.Closeable;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
  */
-public interface ResourceManagerPool extends Runnable, Closeable {
+public abstract class ResourceManagerPool<T extends ManagedComponent> implements Closeable {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  protected final String name;
+  protected final String type;
+  protected Map<String, Object> poolLimits;
+  protected final Map<String, T> components = new ConcurrentHashMap<>();
+  protected final ResourceManager resourceManager;
+  protected final Class<? extends ManagedComponent> componentClass;
+  private final Map<String, Object> poolParams;
+  protected final ResourcePoolContext poolContext = new ResourcePoolContext();
+  protected final List<ChangeListener> listeners = new ArrayList<>();
+  protected final ReentrantLock updateLock = new ReentrantLock();
+  protected int scheduleDelaySeconds;
+  protected ScheduledFuture<?> scheduledFuture;
+
+  public ResourceManagerPool(String name, String type, ResourceManager resourceManager,
+                                Map<String, Object> poolLimits, Map<String, Object> poolParams) {
+    this.name = name;
+    this.type = type;
+    this.resourceManager = resourceManager;
+    this.componentClass = resourceManager.getResourceManagerPoolFactory().getComponentClassByType(type);
+    this.poolLimits = new HashMap<>(poolLimits);
+    this.poolParams = new HashMap<>(poolParams);
+  }
 
   /** Unique pool name. */
-  String getName();
+  public String getName() {
+    return name;
+  }
 
   /** Pool type. */
-  String getType();
+  public String getType() {
+    return type;
+  }
 
-  ResourceManagerPlugin getResourceManagerPlugin();
+  public ResourceManager getResourceManager() {
+    return resourceManager;
+  }
 
   /** Add component to this pool. */
-  void registerComponent(ManagedComponent managedComponent);
+  public void registerComponent(T managedComponent) {
+    if (!componentClass.isAssignableFrom(managedComponent.getClass())) {
+      log.debug("Pool type '" + type + "' is not supported by the component " + managedComponent.getManagedComponentId());
+      return;
+    }
+    ManagedComponent existing = components.putIfAbsent(managedComponent.getManagedComponentId().toString(), managedComponent);
+    if (existing != null) {
+      throw new IllegalArgumentException("Component '" + managedComponent.getManagedComponentId() + "' already exists in pool '" + name + "' !");
+    }
+  }
 
   /** Remove named component from this pool. */
-  boolean unregisterComponent(String componentId);
+  public boolean unregisterComponent(String componentId) {
+    return components.remove(name) != null;
+  }
 
   /**
    * Check whether a named component is registered in this pool.
    * @param componentId component id
    * @return true if the component with this name is registered, false otherwise.
    */
-  boolean isRegistered(String componentId);
+  public boolean isRegistered(String componentId) {
+    return components.containsKey(componentId);
+  }
 
   /** Get components managed by this pool. */
-  Map<String, ManagedComponent> getComponents();
+  public Map<String, T> getComponents() {
+    return Collections.unmodifiableMap(components);
+  }
+
+  public void addChangeListener(ChangeListener listener) {
+    if (!listeners.contains(listener)) {
+      listeners.add(listener);
+    }
+  }
+
+  public void removeChangeListener(ChangeListener listener) {
+    listeners.remove(listener);
+  }
+
 
   /**
    * Get the current monitored values from all resources. Result is a map with resource names as keys,
    * and param/value maps as values.
    */
-  Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException;
+  public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
+    updateLock.lockInterruptibly();
+    try {
+      // collect the current values
+      Map<String, Map<String, Object>> currentValues = new HashMap<>();
+      for (T managedComponent : components.values()) {
+        try {
+          currentValues.put(managedComponent.getManagedComponentId().toString(), getMonitoredValues(managedComponent));
+        } catch (Exception e) {
+          log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
+        }
+      }
+      return Collections.unmodifiableMap(currentValues);
+    } finally {
+      updateLock.unlock();
+    }
+  }
 
-  /** Get current pool limits. */
-  Map<String, Object> getPoolLimits();
+  public abstract Map<String, Object> getMonitoredValues(T component) throws Exception;
 
-  /** Get parameters specified during creation. */
-  Map<String, Object> getParams();
+  public void setResourceLimits(T component, Map<String, Object> limits) throws Exception {
+    if (limits == null || limits.isEmpty()) {
+      return;
+    }
+    for (Map.Entry<String, Object> entry : limits.entrySet()) {
+      setResourceLimit(component, entry.getKey(), entry.getValue());
+    }
+  }
+
+  public Object setResourceLimit(T component, String limitName, Object value) throws Exception {
+    Object newActualLimit = doSetResourceLimit(component, limitName, value);
+    for (ChangeListener listener : listeners) {
+      listener.changedLimit(getName(), component, limitName, value, newActualLimit);
+    }
+    return newActualLimit;
+  }
+
+  protected abstract Object doSetResourceLimit(T component, String limitName, Object value) throws Exception;
+
+  public abstract Map<String, Object> getResourceLimits(T component) throws Exception;
+
+  /**
+   * Calculate aggregated monitored values.
+   * <p>Default implementation of this method simply sums up all non-negative numeric values across
+   * components and ignores any non-numeric values.</p>
+   */
+  public Map<String, Object> aggregateTotalValues(Map<String, Map<String, Object>> perComponentValues) {
+    // calculate the totals
+    Map<String, Object> newTotalValues = new HashMap<>();
+    perComponentValues.values().forEach(map -> map.forEach((k, v) -> {
+      // only calculate totals for numbers
+      if (!(v instanceof Number)) {
+        return;
+      }
+      Double val = ((Number)v).doubleValue();
+      // -1 and MAX_VALUE are our special guard values
+      if (val < 0 || val.longValue() == Long.MAX_VALUE || val.longValue() == Integer.MAX_VALUE) {
+        return;
+      }
+      newTotalValues.merge(k, val, (v1, v2) -> ((Number)v1).doubleValue() + ((Number)v2).doubleValue());
+    }));
+    return newTotalValues;
+  }
+
+  /** Get current pool limits. */
+  public Map<String, Object> getPoolLimits() {
+    return Collections.unmodifiableMap(poolLimits);
+  }
 
   /**
    * Pool limits are defined using controlled tags.
    */
-  void setPoolLimits(Map<String, Object> poolLimits);
+  public void setPoolLimits(Map<String, Object> poolLimits) {
+    this.poolLimits = new HashMap(poolLimits);
+  }
+
+  /** Get parameters specified during creation. */
+  public Map<String, Object> getParams() {
+    return Collections.unmodifiableMap(poolParams);
+  }
 
   /**
    * Pool context used for managing additional pool state.
    */
-  PoolContext getPoolContext();
+  public ResourcePoolContext getResourcePoolContext() {
+    return poolContext;
+  }
+
+  public void manage() {
+    updateLock.lock();
+    try {
+      doManage();
+    } catch (Exception e) {
+      log.warn("Exception caught managing pool " + getName(), e);
+    } finally {
+      updateLock.unlock();
+    }
+  }
+
+  protected abstract void doManage() throws Exception;
+
+  public void close() throws IOException {
+    if (scheduledFuture != null) {
+      scheduledFuture.cancel(true);
+      scheduledFuture = null;
+    }
+    components.clear();
+    poolContext.clear();
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPoolFactory.java
similarity index 67%
rename from solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
rename to solr/core/src/java/org/apache/solr/managed/ResourceManagerPoolFactory.java
index 508b5e9..8110481 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPluginFactory.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPoolFactory.java
@@ -19,16 +19,17 @@ package org.apache.solr.managed;
 import java.util.Map;
 
 /**
- * Factory for creating instances of {@link ResourceManagerPlugin}-s.
+ * Factory for creating instances of {@link ResourceManagerPool}-s.
  */
-public interface ResourceManagerPluginFactory {
+public interface ResourceManagerPoolFactory {
 
   /**
-   * Create a plugin of a given symbolic type.
-   * @param type plugin symbolic type
-   * @param params plugin parameters
+   * Create a pool of a given symbolic type.
+   * @param type pool symbolic type
+   * @param poolParams pool parameters
    */
-  <T extends ManagedComponent> ResourceManagerPlugin<T> create(String type, Map<String, Object> params) throws Exception;
+  <T extends ManagedComponent> ResourceManagerPool<T> create(String name, String type, ResourceManager resourceManager,
+                                                             Map<String, Object> poolLimits, Map<String, Object> poolParams) throws Exception;
 
   /**
    * Get the implementation class for a component of a given symbolic type.
@@ -40,5 +41,5 @@ public interface ResourceManagerPluginFactory {
    * Get the implementation class for a plugin of a given symbolic type.
    * @param type symbolic type
    */
-  Class<? extends ResourceManagerPlugin> getPluginClassByType(String type);
+  Class<? extends ResourceManagerPool> getPoolClassByType(String type);
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/PoolContext.java b/solr/core/src/java/org/apache/solr/managed/ResourcePoolContext.java
similarity index 55%
rename from solr/core/src/java/org/apache/solr/managed/PoolContext.java
rename to solr/core/src/java/org/apache/solr/managed/ResourcePoolContext.java
index 221e1d0..dd1889c 100644
--- a/solr/core/src/java/org/apache/solr/managed/PoolContext.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourcePoolContext.java
@@ -5,5 +5,5 @@ import java.util.concurrent.ConcurrentHashMap;
 /**
  *
  */
-public class PoolContext extends ConcurrentHashMap<String, Object> {
+public class ResourcePoolContext extends ConcurrentHashMap<String, Object> {
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java b/solr/core/src/java/org/apache/solr/managed/SolrResourceContext.java
similarity index 90%
rename from solr/core/src/java/org/apache/solr/managed/ManagedContext.java
rename to solr/core/src/java/org/apache/solr/managed/SolrResourceContext.java
index f426d7c..09d86dce 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
+++ b/solr/core/src/java/org/apache/solr/managed/SolrResourceContext.java
@@ -24,12 +24,12 @@ import java.util.Set;
 /**
  *
  */
-public class ManagedContext implements Closeable {
+public class SolrResourceContext implements Closeable {
   private final ResourceManager resourceManager;
   private final String[] poolNames;
   private final ManagedComponent component;
 
-  public ManagedContext(ResourceManager resourceManager, ManagedComponent component, String poolName, String... otherPools) {
+  public SolrResourceContext(ResourceManager resourceManager, ManagedComponent component, String poolName, String... otherPools) {
     this.resourceManager = resourceManager;
     Set<String> pools = new LinkedHashSet<>();
     pools.add(poolName);
diff --git a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java
similarity index 61%
rename from solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
rename to solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java
index 695b046..cee4fe7 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/CacheManagerPool.java
@@ -17,19 +17,19 @@
 package org.apache.solr.managed.types;
 
 import java.lang.invoke.MethodHandles;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Function;
 
-import org.apache.solr.managed.ResourceManagerPlugin;
+import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.ResourceManagerPool;
+import org.apache.solr.metrics.SolrMetricsContext;
 import org.apache.solr.search.SolrCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * An implementation of {@link org.apache.solr.managed.ResourceManagerPlugin} specific to
+ * An implementation of {@link org.apache.solr.managed.ResourceManagerPool} specific to
  * the management of {@link org.apache.solr.search.SolrCache} instances.
  * <p>This plugin calculates the total size and maxRamMB of all registered cache instances
  * and adjusts each cache's limits so that the aggregated values again fit within the pool limits.</p>
@@ -37,46 +37,39 @@ import org.slf4j.LoggerFactory;
  * which can be adjusted using configuration parameter {@link #DEAD_BAND}. If monitored values don't
  * exceed the limits +/- the dead band then no action is taken.</p>
  */
-public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
+public class CacheManagerPool extends ResourceManagerPool<SolrCache> {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static String TYPE = "cache";
 
   public static final String DEAD_BAND = "deadBand";
-  public static final float DEFAULT_DEAD_BAND = 0.1f;
+  public static final double DEFAULT_DEAD_BAND = 0.1;
 
-  protected static final Map<String, String> controlledToMonitored = new HashMap<>();
+  protected static final Map<String, Function<Map<String, Object>, Double>> controlledToMonitored = new HashMap<>();
 
   static {
-    controlledToMonitored.put(SolrCache.MAX_RAM_MB_PARAM, SolrCache.RAM_BYTES_USED_PARAM);
-    controlledToMonitored.put(SolrCache.MAX_SIZE_PARAM, SolrCache.SIZE_PARAM);
+    controlledToMonitored.put(SolrCache.MAX_RAM_MB_PARAM, values -> {
+      Number ramBytes = (Number) values.get(SolrCache.RAM_BYTES_USED_PARAM);
+      return ramBytes != null ? ramBytes.doubleValue() / SolrCache.MB : 0.0;
+    });
+    controlledToMonitored.put(SolrCache.MAX_SIZE_PARAM, values ->
+        ((Number)values.getOrDefault(SolrCache.MAX_SIZE_PARAM, -1.0)).doubleValue());
   }
 
-  protected static final Collection<String> MONITORED_PARAMS = Arrays.asList(
-      SolrCache.SIZE_PARAM,
-      SolrCache.HIT_RATIO_PARAM,
-      SolrCache.RAM_BYTES_USED_PARAM
-  );
-
-  protected static final Collection<String> CONTROLLED_PARAMS = Arrays.asList(
-      SolrCache.MAX_RAM_MB_PARAM,
-      SolrCache.MAX_SIZE_PARAM
-  );
-
-  protected float deadBand = DEFAULT_DEAD_BAND;
-
-  @Override
-  public Collection<String> getMonitoredParams() {
-    return MONITORED_PARAMS;
-  }
+  protected double deadBand = DEFAULT_DEAD_BAND;
 
-  @Override
-  public Collection<String> getControlledParams() {
-    return CONTROLLED_PARAMS;
+  public CacheManagerPool(String name, String type, ResourceManager resourceManager, Map<String, Object> poolLimits, Map<String, Object> poolParams) {
+    super(name, type, resourceManager, poolLimits, poolParams);
+    String deadBandStr = String.valueOf(poolParams.getOrDefault(DEAD_BAND, DEFAULT_DEAD_BAND));
+    try {
+      deadBand = Double.parseDouble(deadBandStr);
+    } catch (Exception e) {
+      log.warn("Invalid deadBand parameter value '" + deadBandStr + "', using default " + DEFAULT_DEAD_BAND);
+    }
   }
 
   @Override
-  public void setResourceLimit(SolrCache component, String limitName, Object val) {
+  public Object doSetResourceLimit(SolrCache component, String limitName, Object val) {
     if (!(val instanceof Number)) {
       try {
         val = Long.parseLong(String.valueOf(val));
@@ -98,6 +91,7 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
       default:
         throw new IllegalArgumentException("Unsupported limit name '" + limitName + "'");
     }
+    return value.intValue();
   }
 
   @Override
@@ -110,60 +104,50 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
 
   @Override
   public Map<String, Object> getMonitoredValues(SolrCache component) throws Exception {
-    return component.getSolrMetricsContext().getMetricsSnapshot();
-  }
-
-  @Override
-  public String getType() {
-    return TYPE;
-  }
-
-  @Override
-  public void init(Map<String, Object> params) {
-    String deadBandStr = String.valueOf(params.getOrDefault(DEAD_BAND, DEFAULT_DEAD_BAND));
-    try {
-      deadBand = Float.parseFloat(deadBandStr);
-    } catch (Exception e) {
-      log.warn("Invalid deadBand parameter value '" + deadBandStr + "', using default " + DEFAULT_DEAD_BAND);
+    Map<String, Object> values = new HashMap<>();
+    values.put(SolrCache.SIZE_PARAM, component.size());
+    values.put(SolrCache.RAM_BYTES_USED_PARAM, component.ramBytesUsed());
+    SolrMetricsContext metricsContext = component.getSolrMetricsContext();
+    if (metricsContext != null) {
+      Map<String, Object> metrics = metricsContext.getMetricsSnapshot();
+      String hitRatioKey = component.getCategory().toString() + "." + metricsContext.getScope() + "." + SolrCache.HIT_RATIO_PARAM;
+      values.put(SolrCache.HIT_RATIO_PARAM, metrics.get(hitRatioKey));
     }
+    return values;
   }
 
   @Override
-  public void manage(ResourceManagerPool pool) throws Exception {
-    Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-    Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
+  protected void doManage() throws Exception {
+    Map<String, Map<String, Object>> currentValues = getCurrentValues();
+    Map<String, Object> totalValues = aggregateTotalValues(currentValues);
     // pool limits are defined using controlled tags
-    pool.getPoolLimits().forEach((poolLimitName, value) -> {
+    poolLimits.forEach((poolLimitName, value) -> {
       // only numeric limits are supported
       if (value == null || !(value instanceof Number)) {
         return;
       }
-      float poolLimitValue = ((Number)value).floatValue();
+      double poolLimitValue = ((Number)value).doubleValue();
       if (poolLimitValue <= 0) {
         return;
       }
-      String monitoredTag = controlledToMonitored.get(poolLimitName);
-      if (monitoredTag == null) {
-        return;
-      }
-      Object tv = totalValues.get(monitoredTag);
-      if (tv == null || !(tv instanceof Number)) {
+      Function<Map<String, Object>, Double> func = controlledToMonitored.get(poolLimitName);
+      if (func == null) {
         return;
       }
-      Number totalValue = (Number) tv;
-      if (totalValue.floatValue() <= 0.0f) {
+      Double totalValue = func.apply(totalValues);
+      if (totalValue.doubleValue() <= 0.0) {
         return;
       }
-      float totalDelta = poolLimitValue - totalValue.floatValue();
+      double totalDelta = poolLimitValue - totalValue.doubleValue();
 
       // dead band to avoid thrashing
       if (Math.abs(totalDelta / poolLimitValue) < deadBand) {
         return;
       }
 
-      float changeRatio = poolLimitValue / totalValue.floatValue();
-      // modify current limits by the changeRatio
-      pool.getComponents().forEach((name, component) -> {
+      double changeRatio = poolLimitValue / totalValue.doubleValue();
+      // modify evenly every component's current limits by the changeRatio
+      components.forEach((name, component) -> {
         Map<String, Object> resourceLimits = getResourceLimits((SolrCache) component);
         Object limit = resourceLimits.get(poolLimitName);
         // XXX we could attempt here to control eg. ramBytesUsed by adjusting maxSize limit
@@ -171,11 +155,11 @@ public class CacheManagerPlugin implements ResourceManagerPlugin<SolrCache> {
         if (limit == null || !(limit instanceof Number)) {
           return;
         }
-        float currentResourceLimit = ((Number)limit).floatValue();
+        double currentResourceLimit = ((Number)limit).doubleValue();
         if (currentResourceLimit <= 0) { // undefined or unsupported
           return;
         }
-        float newLimit = currentResourceLimit * changeRatio;
+        double newLimit = currentResourceLimit * changeRatio;
         try {
           setResourceLimit((SolrCache) component, poolLimitName, newLimit);
         } catch (Exception e) {
diff --git a/solr/core/src/java/org/apache/solr/managed/types/package-info.java b/solr/core/src/java/org/apache/solr/managed/types/package-info.java
index a7dde4d..5b8e137 100644
--- a/solr/core/src/java/org/apache/solr/managed/types/package-info.java
+++ b/solr/core/src/java/org/apache/solr/managed/types/package-info.java
@@ -16,7 +16,7 @@
  */
 
 /**
- * Implementations of {@link org.apache.solr.managed.ResourceManagerPlugin} specialized for
+ * Implementations of {@link org.apache.solr.managed.ResourceManagerPool} specialized for
  * particular types of objects.
  */
 package org.apache.solr.managed.types;
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index 2002d4b..d40b319 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -36,9 +36,8 @@ import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
-import org.apache.solr.managed.ManagedContext;
+import org.apache.solr.managed.SolrResourceContext;
 import org.apache.solr.managed.ResourceManager;
-import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.slf4j.Logger;
@@ -91,7 +90,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
   private MetricsMap cacheMap;
   private SolrMetricsContext solrMetricsContext;
 
-  private ManagedContext managedContext;
+  private SolrResourceContext solrResourceContext;
   private ManagedComponentId managedComponentId;
 
   private long initialRamBytes = 0;
@@ -117,7 +116,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
     }
     str = (String) args.get(MAX_RAM_MB_PARAM);
     int maxRamMB = str == null ? -1 : Double.valueOf(str).intValue();
-    maxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * 1024L * 1024L;
+    maxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * MB;
     str = (String) args.get(CLEANUP_THREAD_PARAM);
     cleanupThread = str != null && Boolean.parseBoolean(str);
     if (cleanupThread) {
@@ -265,12 +264,12 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
 
   @Override
   public int getMaxRamMB() {
-    return maxRamBytes != Long.MAX_VALUE ? (int) (maxRamBytes / 1024L / 1024L) : -1;
+    return maxRamBytes != Long.MAX_VALUE ? (int) (maxRamBytes / MB) : -1;
   }
 
   @Override
   public void setMaxRamMB(int maxRamMB) {
-    long newMaxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * 1024L * 1024L;
+    long newMaxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * MB;
     if (newMaxRamBytes != maxRamBytes) {
       maxRamBytes = newMaxRamBytes;
       Optional<Eviction<K, V>> evictionOpt = cache.policy().eviction();
@@ -388,13 +387,13 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
         map.put("cumulative_evictions", cumulativeStats.evictionCount());
       }
     });
-    solrMetricsContext.gauge(cacheMap, true, scope, getCategory().toString());
+    solrMetricsContext.gauge(cacheMap, true, null, getCategory().toString());
   }
 
   @Override
   public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
-    managedComponentId = new ManagedComponentId(CacheManagerPlugin.TYPE, this, solrMetricsContext.getRegistryName(), getCategory().toString(), solrMetricsContext.getScope());
-    managedContext = new ManagedContext(resourceManager, this, poolName, otherPools);
+    managedComponentId = new ManagedComponentId(this, solrMetricsContext.getRegistryName(), getCategory().toString(), solrMetricsContext.getScope());
+    solrResourceContext = new SolrResourceContext(resourceManager, this, poolName, otherPools);
   }
 
   @Override
@@ -403,7 +402,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
   }
 
   @Override
-  public ManagedContext getManagedContext() {
-    return managedContext;
+  public SolrResourceContext getSolrResourceContext() {
+    return solrResourceContext;
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index a8ead8c..ecc0308 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -55,6 +55,8 @@ public interface SolrCache<K,V> extends SolrInfoBean, ManagedComponent, Accounta
   /** Use a background thread for cache evictions and cleanup. */
   String CLEANUP_THREAD_PARAM = "cleanupThread";
 
+  long MB = 1024L * 1024L;
+
   /**
    * The initialization routine. Instance specific arguments are passed in
    * the <code>args</code> map.
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index 5f1dbf8..8f4b3d6 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -22,7 +22,7 @@ import java.util.Map;
 import java.util.function.Function;
 
 import org.apache.solr.managed.ManagedComponentId;
-import org.apache.solr.managed.ManagedContext;
+import org.apache.solr.managed.SolrResourceContext;
 import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.slf4j.Logger;
@@ -166,7 +166,7 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
   }
 
   @Override
-  public ManagedContext getManagedContext() {
-    return delegate.getManagedContext();
+  public SolrResourceContext getSolrResourceContext() {
+    return delegate.getSolrResourceContext();
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java b/solr/core/src/test/org/apache/solr/managed/TestResourceManagerPool.java
similarity index 69%
rename from solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
rename to solr/core/src/test/org/apache/solr/managed/TestResourceManagerPool.java
index ebb9129..9294d23 100644
--- a/solr/core/src/test/org/apache/solr/managed/TestDefaultResourceManagerPool.java
+++ b/solr/core/src/test/org/apache/solr/managed/TestResourceManagerPool.java
@@ -1,8 +1,6 @@
 package org.apache.solr.managed;
 
 import java.lang.invoke.MethodHandles;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -23,7 +21,7 @@ import org.slf4j.LoggerFactory;
 /**
  *
  */
-public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
+public class TestResourceManagerPool extends SolrTestCaseJ4 {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private static final int SPEED = 50;
@@ -33,15 +31,8 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
   private ResourceManager resourceManager;
   private SolrResourceLoader loader;
 
-  public interface MockManagedComponent extends ManagedComponent {
-    int getFoo();
-    int getBar();
-    int getBaz();
-    void setFoo(int foo);
-  }
-
-  public static class TestComponent implements MockManagedComponent {
-    ManagedContext context;
+  public static class TestComponent implements ManagedComponent {
+    SolrResourceContext context;
     ManagedComponentId id;
     int foo, bar, baz;
 
@@ -49,22 +40,18 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
       this.id = ManagedComponentId.of(id);
     }
 
-    @Override
     public int getFoo() {
       return foo;
     }
 
-    @Override
     public int getBar() {
       return bar;
     }
 
-    @Override
     public int getBaz() {
       return baz;
     }
 
-    @Override
     public void setFoo(int foo) {
       this.foo = foo;
       this.bar = foo + 1;
@@ -78,19 +65,18 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
 
     @Override
     public void initializeManagedComponent(ResourceManager resourceManager, String poolName, String... otherPools) {
-      context = new ManagedContext(resourceManager, this, poolName, otherPools);
+      context = new SolrResourceContext(resourceManager, this, poolName, otherPools);
     }
 
     @Override
-    public ManagedContext getManagedContext() {
+    public SolrResourceContext getSolrResourceContext() {
       return context;
     }
   }
 
-  public static class MockManagerPlugin implements ResourceManagerPlugin<MockManagedComponent> {
-
-    public MockManagerPlugin() {
-
+  public static class MockManagerPool extends ResourceManagerPool<TestComponent> {
+    public MockManagerPool(String name, String type, ResourceManager resourceManager, Map<String, Object> poolLimits, Map<String, Object> poolParams) {
+      super(name, type, resourceManager, poolLimits, poolParams);
     }
 
     @Override
@@ -99,22 +85,7 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     }
 
     @Override
-    public void init(Map<String, Object> params) {
-
-    }
-
-    @Override
-    public Collection<String> getMonitoredParams() {
-      return Arrays.asList("foo", "bar", "baz");
-    }
-
-    @Override
-    public Collection<String> getControlledParams() {
-      return Collections.singleton("foo");
-    }
-
-    @Override
-    public Map<String, Object> getMonitoredValues(MockManagedComponent component) throws Exception {
+    public Map<String, Object> getMonitoredValues(TestComponent component) throws Exception {
       Map<String, Object> result = new HashMap<>();
       result.put("bar", component.getBar());
       result.put("baz", component.getBaz());
@@ -123,36 +94,36 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     }
 
     @Override
-    public void setResourceLimit(MockManagedComponent component, String limitName, Object value) throws Exception {
+    public Object doSetResourceLimit(TestComponent component, String limitName, Object value) throws Exception {
       if (limitName.equals("foo") && value instanceof Number) {
         component.setFoo(((Number)value).intValue());
+        return ((Number)value).intValue();
       } else {
         throw new Exception("invalid limit name or value");
       }
     }
 
     @Override
-    public Map<String, Object> getResourceLimits(MockManagedComponent component) throws Exception {
+    public Map<String, Object> getResourceLimits(TestComponent component) throws Exception {
       return Collections.singletonMap("foo", component.getFoo());
     }
 
     @Override
-    public void manage(ResourceManagerPool pool) throws Exception {
+    public void doManage() throws Exception {
       if (manageStartLatch.getCount() == 0) { // already fired
         return;
       }
       manageStartLatch.countDown();
       log.info("-- managing");
-      Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-      Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
-      Map<String, Object> poolLimits = pool.getPoolLimits();
+      Map<String, Map<String, Object>> currentValues = getCurrentValues();
+      Map<String, Object> totalValues = aggregateTotalValues(currentValues);
       if (poolLimits.containsKey("foo")) {
         // manage
         if (totalValues.containsKey("bar")) {
           int totalValue = ((Number)totalValues.get("bar")).intValue();
           int poolLimit = ((Number)poolLimits.get("foo")).intValue();
           if (totalValue > poolLimit) {
-            for (ManagedComponent cmp : pool.getComponents().values()) {
+            for (Object cmp : getComponents().values()) {
               TestComponent component = (TestComponent)cmp;
               int foo = component.getFoo();
               if (foo > 0) {
@@ -175,10 +146,10 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     initArgs.put("plugins", config);
     Map<String, String> plugins = new HashMap<>();
     Map<String, String> components = new HashMap<>();
-    config.put(DefaultResourceManagerPluginFactory.TYPE_TO_PLUGIN, plugins);
-    config.put(DefaultResourceManagerPluginFactory.TYPE_TO_COMPONENT, components);
-    plugins.put("mock", MockManagerPlugin.class.getName());
-    components.put("mock", MockManagedComponent.class.getName());
+    config.put(DefaultResourceManagerPoolFactory.TYPE_TO_POOL, plugins);
+    config.put(DefaultResourceManagerPoolFactory.TYPE_TO_COMPONENT, components);
+    plugins.put("mock", MockManagerPool.class.getName());
+    components.put("mock", TestComponent.class.getName());
     resourceManager.init(new PluginInfo("resourceManager", initArgs));
   }
 
@@ -198,21 +169,21 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     resourceManager.createPool("test", "mock", Collections.singletonMap("foo", 10), Collections.emptyMap());
     assertNotNull(resourceManager.getPool("test"));
     for (int i = 0; i < 10; i++) {
-      TestComponent component = new TestComponent("test:component:" + i);
+      TestComponent component = new TestComponent("component:" + i);
       component.setFoo(i);
       resourceManager.registerComponent("test", component);
     }
     ResourceManagerPool pool = resourceManager.getPool("test");
     assertEquals(10, pool.getComponents().size());
     Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
-    Map<String, Object> totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
+    Map<String, Object> totalValues = pool.aggregateTotalValues(currentValues);
     assertNotNull(totalValues.get("bar"));
     assertEquals(55, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
     assertEquals(65, ((Number)totalValues.get("baz")).intValue());
-    for (ManagedComponent cmp : pool.getComponents().values()) {
+    for (Object cmp : pool.getComponents().values()) {
       TestComponent component = (TestComponent)cmp;
-      Map<String, Object> limits = pool.getResourceManagerPlugin().getResourceLimits(component);
+      Map<String, Object> limits = pool.getResourceLimits(component);
       assertEquals(1, limits.size());
       assertNotNull(limits.get("foo"));
       String name = component.getManagedComponentId().getName();
@@ -228,15 +199,15 @@ public class TestDefaultResourceManagerPool extends SolrTestCaseJ4 {
     boolean await = manageFinishLatch.await(30000 / SPEED, TimeUnit.MILLISECONDS);
     assertTrue("did not finish in time", await);
     currentValues = pool.getCurrentValues();
-    totalValues = pool.getResourceManagerPlugin().aggregateTotalValues(currentValues);
+    totalValues = pool.aggregateTotalValues(currentValues);
     assertNotNull(totalValues.get("bar"));
     assertEquals(46, ((Number)totalValues.get("bar")).intValue());
     assertNotNull(totalValues.get("baz"));
     assertEquals(56, ((Number)totalValues.get("baz")).intValue());
     int changed = 0;
-    for (ManagedComponent cmp : pool.getComponents().values()) {
+    for (Object cmp : pool.getComponents().values()) {
       TestComponent component = (TestComponent)cmp;
-      Map<String, Object> limits = pool.getResourceManagerPlugin().getResourceLimits(component);
+      Map<String, Object> limits = pool.getResourceLimits(component);
       assertEquals(1, limits.size());
       assertNotNull(limits.get("foo"));
       String name = component.getManagedComponentId().getName();
diff --git a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPlugin.java b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPluginCloud.java
similarity index 59%
rename from solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPlugin.java
rename to solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPluginCloud.java
index dab094f..2abcca6 100644
--- a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPlugin.java
+++ b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPluginCloud.java
@@ -5,5 +5,5 @@ import org.apache.solr.cloud.SolrCloudTestCase;
 /**
  *
  */
-public class TestCacheManagerPlugin extends SolrCloudTestCase {
+public class TestCacheManagerPluginCloud extends SolrCloudTestCase {
 }
diff --git a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java
new file mode 100644
index 0000000..9e22158
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPool.java
@@ -0,0 +1,117 @@
+package org.apache.solr.managed.types;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.lucene.util.Accountable;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.managed.DefaultResourceManager;
+import org.apache.solr.managed.ManagedComponent;
+import org.apache.solr.managed.ResourceManager;
+import org.apache.solr.managed.ResourceManagerPool;
+import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
+import org.apache.solr.search.CaffeineCache;
+import org.apache.solr.search.NoOpRegenerator;
+import org.apache.solr.search.SolrCache;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class TestCacheManagerPool extends SolrTestCaseJ4 {
+
+  ResourceManager resourceManager;
+
+  @Before
+  public void setupTest() throws Exception {
+    initCore("solrconfig.xml", "schema.xml");
+    // disable automatic scheduling of pool runs
+    resourceManager = new DefaultResourceManager(h.getCore().getResourceLoader(), null);
+    resourceManager.init(null);
+  }
+
+  private static final long KB = 1024;
+  private static final long MB = 1024 * KB;
+
+  private static class ChangeListener implements org.apache.solr.managed.ChangeListener {
+    Map<String, Map<String, Object>> changedValues = new ConcurrentHashMap<>();
+
+    @Override
+    public void changedLimit(String poolName, ManagedComponent component, String limitName, Object newRequestedVal, Object newActualVal) {
+      Map<String, Object> perComponent = changedValues.computeIfAbsent(component.getManagedComponentId().toString(), id -> new ConcurrentHashMap<>());
+      perComponent.put(limitName, newActualVal);
+    }
+
+    public void clear() {
+      changedValues.clear();
+    }
+  }
+
+  @Test
+  public void testPoolLimits() throws Exception {
+    ResourceManagerPool pool = resourceManager.createPool("test", CacheManagerPool.TYPE, Collections.singletonMap("maxRamMB", 200), Collections.emptyMap());
+    SolrMetricManager metricManager = new SolrMetricManager();
+    SolrMetricsContext solrMetricsContext = new SolrMetricsContext(metricManager, "fooRegistry", "barScope", "bazTag");
+    List<SolrCache> caches = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      SolrCache<String, Accountable> cache = new CaffeineCache<>();
+      Map<String, String> params = new HashMap<>();
+      params.put("maxRamMB", "50");
+      cache.init(params, null, new NoOpRegenerator());
+      cache.initializeMetrics(solrMetricsContext, "child-" + i);
+      cache.initializeManagedComponent(resourceManager, "test");
+      caches.add(cache);
+    }
+    ChangeListener listener = new ChangeListener();
+    pool.addChangeListener(listener);
+    // fill up all caches just below the global limit, evenly with small values
+    for (int i = 0; i < 202; i++) {
+      for (SolrCache<String, Accountable> cache : caches) {
+        cache.put("id-" + i, new Accountable() {
+          @Override
+          public long ramBytesUsed() {
+            return 100 * KB;
+          }
+        });
+      }
+    }
+    pool.manage();
+    Map<String, Object> totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
+
+    assertEquals("should not adjust (within deadband): " + listener.changedValues.toString(), 0, listener.changedValues.size());
+    // add a few large values to exceed the total limit
+    // but without exceeding local (cache) limit
+    for (int i = 0; i < 10; i++) {
+      caches.get(0).put("large-" + i, new Accountable() {
+        @Override
+        public long ramBytesUsed() {
+          return 2560 * KB;
+        }
+      });
+    }
+    pool.manage();
+    totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
+
+    assertEquals("should adjust all: " + listener.changedValues.toString(), 10, listener.changedValues.size());
+    listener.clear();
+    pool.manage();
+    totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
+    assertEquals("should adjust all again: " + listener.changedValues.toString(), 10, listener.changedValues.size());
+    listener.clear();
+    pool.manage();
+    totalValues = pool.aggregateTotalValues(pool.getCurrentValues());
+    assertEquals("should not adjust (within deadband): " + listener.changedValues.toString(), 0, listener.changedValues.size());
+  }
+
+  @After
+  public void teardownTest() throws Exception {
+    resourceManager.close();
+  }
+}


[lucene-solr] 19/36: Renaming and refactoring.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 55c0060eaed0db72247a93a11d0bca6eaf6bda81
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Thu Jul 25 17:12:13 2019 +0200

    Renaming and refactoring.
---
 .../solr/handler/admin/ResourceManagerHandler.java | 40 +++++++++++-----------
 .../solr/managed/DefaultResourceManager.java       | 10 +++---
 .../solr/managed/DefaultResourceManagerPool.java   | 35 +++++++------------
 ...{ManagedResource.java => ManagedComponent.java} | 18 ++++++----
 .../{ResourceId.java => ManagedComponentId.java}   | 12 +++----
 .../apache/solr/managed/ManagedMetricProducer.java |  2 +-
 .../apache/solr/managed/NoOpResourceManager.java   | 17 ++++-----
 ...gedMetricProducer.java => ResourceContext.java} | 27 ++-------------
 .../org/apache/solr/managed/ResourceManager.java   | 28 +++++++--------
 .../apache/solr/managed/ResourceManagerPlugin.java |  4 +--
 .../apache/solr/managed/ResourceManagerPool.java   | 30 +++++-----------
 .../solr/managed/plugins/CacheManagerPlugin.java   | 20 +++++++++--
 .../java/org/apache/solr/search/FastLRUCache.java  | 10 +++---
 .../src/java/org/apache/solr/search/LFUCache.java  | 10 +++---
 .../src/java/org/apache/solr/search/LRUCache.java  | 10 +++---
 .../src/java/org/apache/solr/search/SolrCache.java |  4 +--
 .../org/apache/solr/search/SolrIndexSearcher.java  |  6 ++--
 17 files changed, 129 insertions(+), 154 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
index e76dbc7..76b3aa7 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ResourceManagerHandler.java
@@ -28,7 +28,7 @@ import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.handler.RequestHandlerBase;
-import org.apache.solr.managed.ManagedResource;
+import org.apache.solr.managed.ManagedComponent;
 import org.apache.solr.managed.ResourceManager;
 import org.apache.solr.managed.ResourceManagerPool;
 import org.apache.solr.request.SolrQueryRequest;
@@ -134,10 +134,10 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           NamedList<Object> perPool = new SimpleOrderedMap<>();
           result.add(p, perPool);
           perPool.add("type", pool.getType());
-          perPool.add("size", pool.getResources().size());
+          perPool.add("size", pool.getComponents().size());
           perPool.add("poolLimits", pool.getPoolLimits());
           perPool.add("poolParams", pool.getParams());
-          perPool.add("resources", pool.getResources().keySet());
+          perPool.add("resources", pool.getComponents().keySet());
         });
         break;
       case STATUS:
@@ -146,10 +146,10 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Pool '" + name + "' not found.");
         }
         result.add("type", pool.getType());
-        result.add("size", pool.getResources().size());
+        result.add("size", pool.getComponents().size());
         result.add("poolLimits", pool.getPoolLimits());
         result.add("poolParams", pool.getParams());
-        result.add("resources", pool.getResources().keySet());
+        result.add("resources", pool.getComponents().keySet());
         try {
           pool.getCurrentValues();
           result.add("totalValues", pool.getTotalValues());
@@ -237,7 +237,7 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
     NamedList<Object> result = new SimpleOrderedMap<>();
     switch (op) {
       case LIST:
-        pool.getResources().forEach((n, resource) -> {
+        pool.getComponents().forEach((n, resource) -> {
           NamedList<Object> perRes = new SimpleOrderedMap<>();
           result.add(n, perRes);
           perRes.add("class", resource.getClass().getName());
@@ -246,33 +246,33 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
         });
         break;
       case STATUS:
-        ManagedResource resource = pool.getResources().get(resName);
-        if (resource == null) {
+        ManagedComponent managedComponent = pool.getComponents().get(resName);
+        if (managedComponent == null) {
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
-        result.add("class", resource.getClass().getName());
-        result.add("types", resource.getManagedResourceTypes());
-        result.add("resourceLimits", resource.getResourceLimits());
+        result.add("class", managedComponent.getClass().getName());
+        result.add("types", managedComponent.getManagedResourceTypes());
+        result.add("resourceLimits", managedComponent.getResourceLimits());
         try {
-          result.add("monitoredValues", resource.getMonitoredValues(Collections.emptySet()));
+          result.add("monitoredValues", managedComponent.getMonitoredValues(Collections.emptySet()));
         } catch (Exception e) {
           log.warn("Error getting monitored values of " + resName + "/" + poolName + " : " + e.toString(), e);
           result.add("error", "Error getting monitored values of " + resName + ": " + e.toString());
         }
         break;
       case GETLIMITS:
-        ManagedResource resource1 = pool.getResources().get(resName);
-        if (resource1 == null) {
+        ManagedComponent managedComponent1 = pool.getComponents().get(resName);
+        if (managedComponent1 == null) {
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
-        result.add("resourceLimits", resource1.getResourceLimits());
+        result.add("resourceLimits", managedComponent1.getResourceLimits());
         break;
       case SETLIMITS:
-        ManagedResource resource2 = pool.getResources().get(resName);
-        if (resource2 == null) {
+        ManagedComponent managedComponent2 = pool.getComponents().get(resName);
+        if (managedComponent2 == null) {
           throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "Resource '" + resName + " not found in pool '" + poolName + "'.");
         }
-        Map<String, Object> currentLimits = new HashMap<>(resource2.getResourceLimits());
+        Map<String, Object> currentLimits = new HashMap<>(managedComponent2.getResourceLimits());
         Map<String, Object> newLimits = getMap(params, LIMIT_PREFIX_PARAM);
         newLimits.forEach((k, v) -> {
           if (v == null) {
@@ -281,11 +281,11 @@ public class ResourceManagerHandler extends RequestHandlerBase implements Permis
             currentLimits.put(k, v);
           }
         });
-        resource2.setResourceLimits(newLimits);
+        managedComponent2.setResourceLimits(newLimits);
         result.add("success", newLimits);
         break;
       case DELETE:
-        result.add("success", pool.removeResource(resName) ? "removed" : "not found");
+        result.add("success", pool.unregisterComponent(resName) ? "removed" : "not found");
     }
     rsp.getValues().add("result", result);
   }
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index d0d8233..93dfb2d2 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -169,7 +169,7 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void addResource(String name, ManagedResource managedResource) {
+  public void registerComponent(String name, ManagedComponent managedComponent) {
     ensureActive();
     ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
@@ -181,22 +181,22 @@ public class DefaultResourceManager extends ResourceManager {
         return;
       }
       if (otherPool.getType().equals(type)) {
-        throw new IllegalArgumentException("Resource " + managedResource.getResourceId() +
+        throw new IllegalArgumentException("Resource " + managedComponent.getManagedComponentId() +
             " is already managed in another pool (" +
             otherPool.getName() + ") of the same type " + type);
       }
     });
-    pool.addResource(managedResource);
+    pool.registerComponent(managedComponent);
   }
 
   @Override
-  public boolean removeResource(String poolName, String resourceId) {
+  public boolean unregisterComponent(String poolName, String resourceId) {
     ensureActive();
     ResourceManagerPool pool = resourcePools.get(poolName);
     if (pool == null) {
       throw new IllegalArgumentException("Pool '" + poolName + "' doesn't exist.");
     }
-    return pool.removeResource(resourceId);
+    return pool.unregisterComponent(resourceId);
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index d46666f..b966336 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -37,14 +37,13 @@ import org.slf4j.LoggerFactory;
 public class DefaultResourceManagerPool implements ResourceManagerPool {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
-  private final Map<String, Context> resourceContexts = new ConcurrentHashMap<>();
+  private final Map<String, ManagedComponent> resources = new ConcurrentHashMap<>();
   private Map<String, Object> poolLimits;
   private final String type;
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
-  private final Context poolContext = new Context();
+  private final ResourceContext poolContext = new ResourceContext();
   private Map<String, Float> totalValues = null;
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
@@ -83,27 +82,25 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public void addResource(ManagedResource managedResource) {
-    Collection<String> types = managedResource.getManagedResourceTypes();
+  public void registerComponent(ManagedComponent managedComponent) {
+    Collection<String> types = managedComponent.getManagedResourceTypes();
     if (!types.contains(type)) {
-      log.debug("Pool type '" + type + "' is not supported by the resource " + managedResource.getResourceId());
+      log.debug("Pool type '" + type + "' is not supported by the resource " + managedComponent.getManagedComponentId());
       return;
     }
-    ManagedResource existing = resources.putIfAbsent(managedResource.getResourceId().toString(), managedResource);
+    ManagedComponent existing = resources.putIfAbsent(managedComponent.getManagedComponentId().toString(), managedComponent);
     if (existing != null) {
-      throw new IllegalArgumentException("Resource '" + managedResource.getResourceId() + "' already exists in pool '" + name + "' !");
+      throw new IllegalArgumentException("Resource '" + managedComponent.getManagedComponentId() + "' already exists in pool '" + name + "' !");
     }
-    resourceContexts.putIfAbsent(managedResource.getResourceId().toString(), new Context());
   }
 
   @Override
-  public boolean removeResource(String name) {
-    resourceContexts.remove(name);
+  public boolean unregisterComponent(String name) {
     return resources.remove(name) != null;
   }
 
   @Override
-  public Map<String, ManagedResource> getResources() {
+  public Map<String, ManagedComponent> getComponents() {
     return Collections.unmodifiableMap(resources);
   }
 
@@ -113,11 +110,11 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
     try {
       // collect current values
       Map<String, Map<String, Object>> currentValues = new HashMap<>();
-      for (ManagedResource resource : resources.values()) {
+      for (ManagedComponent managedComponent : resources.values()) {
         try {
-          currentValues.put(resource.getResourceId().toString(), resource.getMonitoredValues(resourceManagerPlugin.getMonitoredParams()));
+          currentValues.put(managedComponent.getManagedComponentId().toString(), managedComponent.getMonitoredValues(resourceManagerPlugin.getMonitoredParams()));
         } catch (Exception e) {
-          log.warn("Error getting managed values from " + resource.getResourceId(), e);
+          log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
         }
       }
       // calculate totals
@@ -167,16 +164,11 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public Context getPoolContext() {
+  public ResourceContext getPoolContext() {
     return poolContext;
   }
 
   @Override
-  public Context getResourceContext(String name) {
-    return resourceContexts.get(name);
-  }
-
-  @Override
   public void run() {
     try {
       resourceManagerPlugin.manage(this);
@@ -192,7 +184,6 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
       scheduledFuture = null;
     }
     resources.clear();
-    resourceContexts.clear();
     poolContext.clear();
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
similarity index 83%
rename from solr/core/src/java/org/apache/solr/managed/ManagedResource.java
rename to solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index d058c97..c8d3dba 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -24,19 +24,19 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * A managed resource.
+ * A managed component.
  */
-public interface ManagedResource {
+public interface ManagedComponent {
   Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   /**
-   * Unique name of this resource. By convention id-s form a dot-separated hierarchy that
+   * Unique name of this component. By convention id-s form a dot-separated hierarchy that
    * follows the naming of metric registries and metric names.
    */
-  ResourceId getResourceId();
+  ManagedComponentId getManagedComponentId();
 
   /**
-   * Returns types of management plugins supported by this resource. This must always
+   * Returns types of management plugins supported by this component. This must always
    * return a non-null collection with at least one entry.
    */
   Collection<String> getManagedResourceTypes();
@@ -54,7 +54,7 @@ public interface ManagedResource {
         setResourceLimit(key, value);
       } catch (Exception e) {
         log.warn("Exception setting resource limit on {}: key={}, value={}, exception={}",
-            getResourceId(), key, value, e);
+            getManagedComponentId(), key, value, e);
       }
     });
   }
@@ -78,4 +78,10 @@ public interface ManagedResource {
    * @return map of parameter names to current values.
    */
   Map<String, Object> getMonitoredValues(Collection<String> params) throws Exception;
+
+  /**
+   * Component context used for managing additional component state.
+   * @return component's context
+   */
+  ResourceContext getManagedContext();
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
similarity index 85%
rename from solr/core/src/java/org/apache/solr/managed/ResourceId.java
rename to solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index 81b7a80..064cbe5 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -22,14 +22,14 @@ import java.util.Arrays;
 import org.apache.solr.metrics.SolrMetricManager;
 
 /**
- * Hierarchical resource id.
+ * Hierarchical component id.
  */
-public class ResourceId {
+public class ManagedComponentId {
   private final String name;
   private final String[] path;
   private final String id;
 
-  public ResourceId(String name, String... path) {
+  public ManagedComponentId(String name, String... path) {
     this.name = name;
     this.path = path;
     this.id = SolrMetricManager.mkName(name, path);
@@ -47,7 +47,7 @@ public class ResourceId {
     return id;
   }
 
-  public ResourceId of(String fullName) {
+  public ManagedComponentId of(String fullName) {
     if (fullName == null || fullName.isEmpty()) {
       return null;
     }
@@ -55,9 +55,9 @@ public class ResourceId {
     if (parts.length > 1) {
       String name = parts[parts.length - 1];
       String[] path = Arrays.copyOfRange(parts, 0, parts.length - 1);
-      return new ResourceId(name, path);
+      return new ManagedComponentId(name, path);
     } else {
-      return new ResourceId(parts[0]);
+      return new ManagedComponentId(parts[0]);
     }
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
index 82d431e..1cb9a04 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
@@ -26,7 +26,7 @@ import org.apache.solr.core.SolrInfoBean;
 /**
  * Convenience interface for {@link SolrInfoBean}-s that need to be managed.
  */
-public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
+public interface ManagedMetricProducer extends SolrInfoBean, ManagedComponent {
 
   @Override
   default Map<String, Object> getMonitoredValues(Collection<String> params) {
diff --git a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
index 1eccff2..cd94afe 100644
--- a/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/NoOpResourceManager.java
@@ -44,17 +44,17 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public void addResource(ManagedResource managedResource) {
+    public void registerComponent(ManagedComponent managedComponent) {
 
     }
 
     @Override
-    public boolean removeResource(String name) {
+    public boolean unregisterComponent(String name) {
       return false;
     }
 
     @Override
-    public Map<String, ManagedResource> getResources() {
+    public Map<String, ManagedComponent> getComponents() {
       return Collections.emptyMap();
     }
 
@@ -84,12 +84,7 @@ public class NoOpResourceManager extends ResourceManager {
     }
 
     @Override
-    public Context getPoolContext() {
-      return null;
-    }
-
-    @Override
-    public Context getResourceContext(String name) {
+    public ResourceContext getPoolContext() {
       return null;
     }
 
@@ -135,12 +130,12 @@ public class NoOpResourceManager extends ResourceManager {
   }
 
   @Override
-  public void addResource(String pool, ManagedResource managedResource) throws Exception {
+  public void registerComponent(String pool, ManagedComponent managedComponent) throws Exception {
 
   }
 
   @Override
-  public boolean removeResource(String pool, String resourceId) {
+  public boolean unregisterComponent(String pool, String componentId) {
     return false;
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ResourceContext.java
similarity index 53%
copy from solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
copy to solr/core/src/java/org/apache/solr/managed/ResourceContext.java
index 82d431e..0c8e5a3 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceContext.java
@@ -16,32 +16,11 @@
  */
 package org.apache.solr.managed;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.solr.core.SolrInfoBean;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * Convenience interface for {@link SolrInfoBean}-s that need to be managed.
+ *
  */
-public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
+public class ResourceContext extends ConcurrentHashMap<String, Object> {
 
-  @Override
-  default Map<String, Object> getMonitoredValues(Collection<String> params) {
-    Map<String, Object> metrics = getMetricsSnapshot();
-    if (metrics == null) {
-      return Collections.emptyMap();
-    }
-    Map<String, Object> result = new HashMap<>();
-    params.forEach(tag -> {
-      Object value = metrics.get(tag);
-      if (value == null) {
-        return;
-      }
-      result.put(tag, value);
-    });
-    return result;
-  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index 43054fe..48c2273 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -197,34 +197,34 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
   public abstract void removePool(String name) throws Exception;
 
   /**
-   * Add managed resources to a pool.
+   * Add managed components to a pool.
    * @param pool existing pool name.
-   * @param managedResources resources to add
+   * @param managedComponents components to add
    */
-  public void addResources(String pool, Collection<ManagedResource> managedResources) throws Exception {
+  public void registerComponents(String pool, Collection<ManagedComponent> managedComponents) throws Exception {
     ensureActive();
-    for (ManagedResource resource : managedResources) {
-      addResource(pool, resource);
+    for (ManagedComponent managedComponent : managedComponents) {
+      registerComponent(pool, managedComponent);
     }
   }
 
   /**
-   * Add a managed resource to a pool.
+   * Add a managed component to a pool.
    * @param pool existing pool name.
-   * @param managedResource managed resource. The resource must support the management type
-   *                        (in its {@link ManagedResource#getManagedResourceTypes()}) used
-   *                        in the selected pool. The resource must not be already managed by
+   * @param managedComponent managed component. The component must support the management type
+   *                        (in its {@link ManagedComponent#getManagedResourceTypes()}) used
+   *                        in the selected pool. The component must not be already managed by
    *                        another pool of the same type.
    */
-  public abstract void addResource(String pool, ManagedResource managedResource) throws Exception;
+  public abstract void registerComponent(String pool, ManagedComponent managedComponent) throws Exception;
 
   /**
-   * Remove a managed resource from a pool.
+   * Remove a managed component from a pool.
    * @param pool existing pool name.
-   * @param resourceId resource id to remove
-   * @return true if a resource was actually registered and has been removed
+   * @param componentId component id to remove
+   * @return true if a component was actually registered and has been removed
    */
-  public abstract boolean removeResource(String pool, String resourceId);
+  public abstract boolean unregisterComponent(String pool, String componentId);
 
   protected void ensureActive() {
     if (isClosed()) {
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index f531c46..01f8363 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -30,12 +30,12 @@ public interface ResourceManagerPlugin {
   void init(Map<String, Object> params);
 
   /**
-   * Name of monitored parameters that {@link ManagedResource}-s managed by this plugin
+   * Name of monitored parameters that {@link ManagedComponent}-s managed by this plugin
    * are expected to support.
    */
   Collection<String> getMonitoredParams();
   /**
-   * Name of controlled parameters that {@link ManagedResource}-s managed by this plugin
+   * Name of controlled parameters that {@link ManagedComponent}-s managed by this plugin
    * are expected to support.
    */
   Collection<String> getControlledParams();
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index a8a7666..3a3bd78 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -2,31 +2,26 @@ package org.apache.solr.managed;
 
 import java.io.Closeable;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  *
  */
 public interface ResourceManagerPool extends Runnable, Closeable {
 
-  public class Context extends ConcurrentHashMap<String, Object> {
-
-  }
-
   /** Unique pool name. */
   String getName();
 
   /** Pool type. */
   String getType();
 
-  /** Add resource to this pool. */
-  void addResource(ManagedResource managedResource);
+  /** Add component to this pool. */
+  void registerComponent(ManagedComponent managedComponent);
 
-  /** Remove named resource from this pool. */
-  boolean removeResource(String name);
+  /** Remove named component from this pool. */
+  boolean unregisterComponent(String componentId);
 
-  /** Get resources managed by this pool. */
-  Map<String, ManagedResource> getResources();
+  /** Get components managed by this pool. */
+  Map<String, ManagedComponent> getComponents();
 
   /**
    * Get the current monitored values from all resources. Result is a map with resource names as keys,
@@ -35,7 +30,7 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException;
 
   /**
-   * This returns cumulative monitored values of all resources.
+   * This returns cumulative monitored values of all components.
    * <p>NOTE: you must call {@link #getCurrentValues()} first!</p>
    */
   Map<String, Number> getTotalValues() throws InterruptedException;
@@ -52,14 +47,7 @@ public interface ResourceManagerPool extends Runnable, Closeable {
   void setPoolLimits(Map<String, Object> poolLimits);
 
   /**
-   * Pool context used for managing pool state.
-   */
-  Context getPoolContext();
-
-  /**
-   * Resource context used for managing resource state. This context is always present for
-   * a resource registered in this pool, and it is unique to this pool.
-   * @param name resource name
+   * Pool context used for managing additional pool state.
    */
-  Context getResourceContext(String name);
+  ResourceContext getPoolContext();
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index f522ad3..67a5bf3 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.solr.managed.plugins;
 
 import java.lang.invoke.MethodHandles;
@@ -105,7 +121,7 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
 
       float changeRatio = poolLimitValue / totalValue.floatValue();
       // modify current limits by the changeRatio
-      pool.getResources().forEach((name, resource) -> {
+      pool.getComponents().forEach((name, resource) -> {
         Map<String, Object> resourceLimits = resource.getResourceLimits();
         Object limit = resourceLimits.get(poolLimitName);
         // XXX we could attempt here to control eg. ramBytesUsed by adjusting maxSize limit
@@ -122,7 +138,7 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
           resource.setResourceLimit(poolLimitName, newLimit);
         } catch (Exception e) {
           log.warn("Failed to set managed limit " + poolLimitName +
-              " from " + currentResourceLimit + " to " + newLimit + " on " + resource.getResourceId(), e);
+              " from " + currentResourceLimit + " to " + newLimit + " on " + resource.getManagedComponentId(), e);
         }
       });
     });
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 0ad4a9b..3f40135 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -20,7 +20,7 @@ import com.codahale.metrics.MetricRegistry;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
-import org.apache.solr.managed.ResourceId;
+import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -82,7 +82,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
-  private ResourceId resourceId;
+  private ManagedComponentId managedComponentId;
 
   @Override
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
@@ -310,7 +310,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
       }
     });
     manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
-    resourceId = new ResourceId(tag, registryName, getCategory().toString(), scope);
+    managedComponentId = new ManagedComponentId(tag, registryName, getCategory().toString(), scope);
   }
 
 
@@ -354,8 +354,8 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
   }
 
   @Override
-  public ResourceId getResourceId() {
-    return resourceId;
+  public ManagedComponentId getManagedComponentId() {
+    return managedComponentId;
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 5d82a2d..a4dd8ff 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -31,7 +31,7 @@ import com.codahale.metrics.MetricRegistry;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
-import org.apache.solr.managed.ResourceId;
+import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -83,7 +83,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricRegistry registry;
-  private ResourceId resourceId;
+  private ManagedComponentId managedComponentId;
 
   private int maxSize;
   private int minSize;
@@ -318,7 +318,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
       }
     });
     manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
-    resourceId = new ResourceId(tag, registryName, getCategory().toString(), scope);
+    managedComponentId = new ManagedComponentId(tag, registryName, getCategory().toString(), scope);
   }
 
   // for unit tests only
@@ -353,8 +353,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   }
 
   @Override
-  public ResourceId getResourceId() {
-    return resourceId;
+  public ManagedComponentId getManagedComponentId() {
+    return managedComponentId;
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index 3ab0d60..c62d4fd 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -33,7 +33,7 @@ import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Accountables;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
-import org.apache.solr.managed.ResourceId;
+import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.plugins.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -81,7 +81,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   private MetricRegistry registry;
   private int maxSize;
   private int initialSize;
-  private ResourceId resourceId;
+  private ManagedComponentId managedComponentId;
 
   private long maxRamBytes = Long.MAX_VALUE;
   // The synchronization used for the map will be used to update this,
@@ -340,7 +340,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
       res.put("cumulative_evictionsRamUsage", stats.evictionsRamUsage.longValue());
     });
     manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
-    resourceId = new ResourceId(tag, registryName, getCategory().toString(), scope);
+    managedComponentId = new ManagedComponentId(tag, registryName, getCategory().toString(), scope);
   }
 
   // for unit tests only
@@ -386,8 +386,8 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   }
 
   @Override
-  public ResourceId getResourceId() {
-    return resourceId;
+  public ManagedComponentId getManagedComponentId() {
+    return managedComponentId;
   }
 
   @Override
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index e2c6440..7814384 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -17,7 +17,7 @@
 package org.apache.solr.search;
 
 import org.apache.solr.core.SolrInfoBean;
-import org.apache.solr.managed.ManagedResource;
+import org.apache.solr.managed.ManagedComponent;
 import org.apache.solr.metrics.SolrMetricProducer;
 
 import java.util.Map;
@@ -26,7 +26,7 @@ import java.util.Map;
 /**
  * Primary API for dealing with Solr's internal caches.
  */
-public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedResource {
+public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer, ManagedComponent {
 
   /** Current size of the cache. */
   String SIZE_PARAM = "size";
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 561136e..b1c4b12 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -431,9 +431,9 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
     for (SolrCache cache : cacheList) {
       cache.initializeMetrics(metricManager, registryName, core.getMetricTag(), SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
       try {
-        resourceManager.addResource(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache);
+        resourceManager.registerComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache);
       } catch (Exception e) {
-        log.warn("Exception adding cache '" + cache.getResourceId() + "' to the resource manager pool", e);
+        log.warn("Exception adding cache '" + cache.getManagedComponentId() + "' to the resource manager pool", e);
       }
     }
     initializeMetrics(metricManager, registryName, core.getMetricTag(), STATISTICS_KEY);
@@ -479,7 +479,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
     }
 
     for (SolrCache cache : cacheList) {
-      core.getCoreContainer().getResourceManager().removeResource(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getResourceId().toString());
+      core.getCoreContainer().getResourceManager().unregisterComponent(DefaultResourceManager.NODE_SEARCHER_CACHE_POOL, cache.getManagedComponentId().toString());
       cache.close();
     }
 


[lucene-solr] 01/36: Initial patch.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit d589383e5e3a95ef1cd3b78a51277f38ad18afd1
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jun 18 22:14:29 2019 +0200

    Initial patch.
---
 .../solr/managed/AbstractResourceManager.java      | 263 +++++++++++++++++++++
 .../src/java/org/apache/solr/managed/Limit.java    |  35 +++
 .../src/java/org/apache/solr/managed/Limits.java   |  75 ++++++
 .../solr/managed/ProportionalResourceManager.java  |  48 ++++
 .../org/apache/solr/managed/ResourceManaged.java   |  23 ++
 .../org/apache/solr/managed/ResourceManager.java   |  39 +++
 6 files changed, 483 insertions(+)

diff --git a/solr/core/src/java/org/apache/solr/managed/AbstractResourceManager.java b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManager.java
new file mode 100644
index 0000000..41cb185
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/AbstractResourceManager.java
@@ -0,0 +1,263 @@
+package org.apache.solr.managed;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.solr.common.util.ExecutorUtil;
+import org.apache.solr.common.util.IOUtils;
+import org.apache.solr.common.util.TimeSource;
+import org.apache.solr.core.PluginInfo;
+import org.apache.solr.util.DefaultSolrThreadFactory;
+import org.apache.solr.util.SolrPluginUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public abstract class AbstractResourceManager implements ResourceManager {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public static final String SCHEDULE_DELAY_SECONDS_PARAM = "scheduleDelaySeconds";
+  public static final String MAX_NUM_POOLS_PARAM = "maxNumPools";
+
+  public static final int DEFAULT_MAX_POOLS = 20;
+
+  public static class Pool implements Runnable, Closeable {
+    private final AbstractResourceManager resourceManager;
+    private final Map<String, ResourceManaged> resources = new ConcurrentHashMap<>();
+    private Limits limits;
+    private final Map<String, Object> params;
+    private final Map<String, Float> totalCosts = new ConcurrentHashMap<>();
+    private Map<String, Map<String, Float>> currentValues = null;
+    private Map<String, Float> totalValues = null;
+    int scheduleDelaySeconds;
+    ScheduledFuture<?> scheduledFuture;
+
+    public Pool(AbstractResourceManager resourceManager, Limits limits, Map<String, Object> params) {
+      this.resourceManager = resourceManager;
+      this.limits = limits.copy();
+      this.params = new HashMap<>(params);
+    }
+
+    public synchronized void addResource(ResourceManaged resourceManaged) {
+      if (resources.containsKey(resourceManaged.getName())) {
+        throw new IllegalArgumentException("Pool already has resource '" + resourceManaged.getName() + "'.");
+      }
+      resources.put(resourceManaged.getName(), resourceManaged);
+      Limits managedLimits = resourceManaged.getManagedLimits();
+      managedLimits.forEach(entry -> {
+        Float total = totalCosts.get(entry.getKey());
+        if (total == null) {
+          totalCosts.put(entry.getKey(), entry.getValue().cost);
+        } else {
+          totalCosts.put(entry.getKey(), entry.getValue().cost + total);
+        }
+      });
+    }
+
+    public Map<String, ResourceManaged> getResources() {
+      return Collections.unmodifiableMap(resources);
+    }
+
+    public Map<String, Map<String, Float>> getCurrentValues() {
+      // collect current values
+      currentValues = new HashMap<>();
+      for (ResourceManaged resource : resources.values()) {
+        currentValues.put(resource.getName(), resource.getManagedValues());
+      }
+      // calculate totals
+      totalValues = new HashMap<>();
+      currentValues.values().forEach(map -> map.forEach((k, v) -> {
+        Float total = totalValues.get(k);
+        if (total == null) {
+          totalValues.put(k, v);
+        } else {
+          totalValues.put(k, total + v);
+        }
+      }));
+      return Collections.unmodifiableMap(currentValues);
+    }
+
+    /**
+     * This returns cumulative values of all resources. NOTE:
+     * you must call {@link #getCurrentValues()} first!
+     * @return
+     */
+    public Map<String, Float> getTotalValues() {
+      return Collections.unmodifiableMap(totalValues);
+    }
+
+    public Map<String, Float> getTotalCosts() {
+      return Collections.unmodifiableMap(totalCosts);
+    }
+
+    public Limits getLimits() {
+      return limits;
+    }
+
+    public void setLimits(Limits limits) {
+      this.limits = limits.copy();
+    }
+
+    @Override
+    public void run() {
+      resourceManager.managePool(this);
+    }
+
+    @Override
+    public void close() throws IOException {
+      if (scheduledFuture != null) {
+        scheduledFuture.cancel(true);
+        scheduledFuture = null;
+      }
+    }
+  }
+
+
+  private Map<String, Pool> resourcePools = new ConcurrentHashMap<>();
+  private PluginInfo pluginInfo;
+  private int maxNumPools = DEFAULT_MAX_POOLS;
+  private TimeSource timeSource;
+
+  /**
+   * Thread pool for scheduling the pool runs.
+   */
+  private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
+
+  protected boolean isClosed = false;
+  protected boolean enabled = true;
+
+  public AbstractResourceManager(TimeSource timeSource) {
+    this.timeSource = timeSource;
+  }
+
+  @Override
+  public void init(PluginInfo info) {
+    if (info != null) {
+      this.pluginInfo = info.copy();
+      if (pluginInfo.initArgs != null) {
+        SolrPluginUtils.invokeSetters(this, this.pluginInfo.initArgs);
+      }
+    }
+    if (!enabled) {
+      log.debug("Resource manager " + getClass().getSimpleName() + " disabled.");
+      return;
+    }
+    scheduledThreadPoolExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(maxNumPools,
+        new DefaultSolrThreadFactory(getClass().getSimpleName()));
+    scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
+    scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+  }
+
+  public void setMaxNumPools(Integer maxNumPools) {
+    if (maxNumPools != null) {
+      this.maxNumPools = maxNumPools;
+    } else {
+      this.maxNumPools = DEFAULT_MAX_POOLS;
+    }
+  }
+
+  @Override
+  public void setEnabled(Boolean enabled) {
+    if (enabled != null) {
+      this.enabled = enabled;
+    }
+  }
+
+  @Override
+  public PluginInfo getPluginInfo() {
+    return pluginInfo;
+  }
+
+  protected abstract void managePool(Pool pool);
+
+  @Override
+  public void createPool(String name, Limits limits, Map<String, Object> params) throws Exception {
+    ensureNotClosed();
+    if (resourcePools.containsKey(name)) {
+      throw new IllegalArgumentException("Pool '" + name + "' already exists.");
+    }
+    if (resourcePools.size() >= maxNumPools) {
+      throw new IllegalArgumentException("Maximum number of pools (" + maxNumPools + ") reached.");
+    }
+    Pool newPool = new Pool(this, limits, params);
+    newPool.scheduleDelaySeconds = Integer.parseInt(String.valueOf(params.getOrDefault(SCHEDULE_DELAY_SECONDS_PARAM, 10)));
+    resourcePools.putIfAbsent(name, newPool);
+    newPool.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(newPool, 0,
+        timeSource.convertDelay(TimeUnit.SECONDS, newPool.scheduleDelaySeconds, TimeUnit.MILLISECONDS),
+        TimeUnit.MILLISECONDS);
+  }
+
+  @Override
+  public void modifyPoolLimits(String name, Limits limits) throws Exception {
+    ensureNotClosed();
+    Pool pool = resourcePools.get(name);
+    if (pool == null) {
+      throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
+    }
+    pool.setLimits(limits);
+  }
+
+  @Override
+  public void removePool(String name) throws Exception {
+    ensureNotClosed();
+    Pool pool = resourcePools.remove(name);
+    if (pool == null) {
+      throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
+    }
+    if (pool.scheduledFuture != null) {
+      pool.scheduledFuture.cancel(true);
+    }
+  }
+
+  @Override
+  public void addResources(String name, Collection<ResourceManaged> resourceManaged) {
+    ensureNotClosed();
+    for (ResourceManaged resource : resourceManaged) {
+      addResource(name, resource);
+    }
+  }
+
+  @Override
+  public void addResource(String name, ResourceManaged resourceManaged) {
+    ensureNotClosed();
+    Pool pool = resourcePools.get(name);
+    if (pool == null) {
+      throw new IllegalArgumentException("Pool '" + name + "' doesn't exist.");
+    }
+    pool.addResource(resourceManaged);
+  }
+
+  @Override
+  public void close() throws IOException {
+    synchronized (this) {
+      isClosed = true;
+      log.debug("Closing all pools.");
+      for (Pool pool : resourcePools.values()) {
+        IOUtils.closeQuietly(pool);
+      }
+      resourcePools.clear();
+    }
+    log.debug("Shutting down scheduled thread pool executor now");
+    scheduledThreadPoolExecutor.shutdownNow();
+    log.debug("Awaiting termination of scheduled thread pool executor");
+    ExecutorUtil.awaitTermination(scheduledThreadPoolExecutor);
+    log.debug("Closed.");
+  }
+
+  @Override
+  public boolean isClosed() {
+    return isClosed;
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/Limit.java b/solr/core/src/java/org/apache/solr/managed/Limit.java
new file mode 100644
index 0000000..0eee67d
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/Limit.java
@@ -0,0 +1,35 @@
+package org.apache.solr.managed;
+
+/**
+ *
+ */
+public class Limit {
+  public final float min, max, cost;
+
+  public Limit() {
+    this(Float.MIN_VALUE, Float.MAX_VALUE, 1.0f);
+  }
+
+  public Limit(float min, float max) {
+    this(min, max, 1.0f);
+  }
+
+  public Limit(float min, float max, float cost) {
+    if (cost <= 0.0f) {
+      throw new IllegalArgumentException("cost must be > 0.0f");
+    }
+    this.min = min;
+    this.max = max;
+    this.cost = cost;
+  }
+
+  public float deltaOutsideLimit(float currentValue) {
+    if (currentValue < min) {
+      return currentValue - min;
+    } else if (currentValue > max) {
+      return currentValue - max;
+    } else {
+      return 0;
+    }
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/Limits.java b/solr/core/src/java/org/apache/solr/managed/Limits.java
new file mode 100644
index 0000000..d817be9
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/Limits.java
@@ -0,0 +1,75 @@
+package org.apache.solr.managed;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public class Limits implements Iterable<Map.Entry<String, Limit>> {
+
+  public static final Limit UNLIMITED = new Limit(Float.MIN_VALUE, Float.MAX_VALUE);
+
+  private Map<String, Limit> values = new HashMap<>();
+
+  public void setLimit(String key, Limit value) {
+    if (value != null) {
+      values.put(key, value);
+    } else {
+      values.remove(key);
+    }
+  }
+
+  public void setLimitMax(String key, float max) {
+    Limit limit = values.computeIfAbsent(key, k -> new Limit(Float.MIN_VALUE, max));
+    if (limit.max == max) {
+      return;
+    } else {
+      values.put(key, new Limit(limit.min, max));
+    }
+  }
+
+  public void setLimitMin(String key, float min) {
+    Limit limit = values.computeIfAbsent(key, k -> new Limit(min, Float.MAX_VALUE));
+    if (limit.min == min) {
+      return;
+    } else {
+      values.put(key, new Limit(min, limit.max));
+    }
+  }
+
+  public Limit getLimit(String key) {
+    return getLimit(key, UNLIMITED);
+  }
+
+  public Limit getLimit(String key, Limit defValue) {
+    Limit value = values.get(key);
+    if (value != null) {
+      return value;
+    } else {
+      return defValue;
+    }
+  }
+
+  public Set<String> getKeys() {
+    return Collections.unmodifiableSet(values.keySet());
+  }
+
+  public void removeLimit(String key) {
+    values.remove(key);
+  }
+
+  public Limits copy() {
+    Limits cloned = new Limits();
+    cloned.values.putAll(values);
+    return cloned;
+  }
+
+  @Override
+  public Iterator<Map.Entry<String, Limit>> iterator() {
+    return Collections.unmodifiableMap(values).entrySet().iterator();
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ProportionalResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ProportionalResourceManager.java
new file mode 100644
index 0000000..f2edf65
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ProportionalResourceManager.java
@@ -0,0 +1,48 @@
+package org.apache.solr.managed;
+
+import java.util.Map;
+
+import org.apache.solr.common.util.TimeSource;
+
+/**
+ *
+ */
+public class ProportionalResourceManager extends AbstractResourceManager {
+  public ProportionalResourceManager(TimeSource timeSource) {
+    super(timeSource);
+  }
+
+  @Override
+  protected void managePool(Pool pool) {
+    Map<String, Map<String, Float>> currentValues = pool.getCurrentValues();
+    Map<String, Float> totalValues = pool.getTotalValues();
+    Map<String, Float> totalCosts = pool.getTotalCosts();
+    pool.getLimits().forEach(entry -> {
+      Limit poolLimit = entry.getValue();
+      Float totalValue = totalValues.get(entry.getKey());
+      if (totalValue == null) {
+        return;
+      }
+      float delta = poolLimit.deltaOutsideLimit(totalValue);
+      Float totalCost = totalCosts.get(entry.getKey());
+      if (totalCost == null || totalCost == 0) {
+        return;
+      }
+      // re-adjust the limits based on relative costs
+      pool.getResources().forEach((name, resource) -> {
+        Map<String, Float> current = currentValues.get(name);
+        if (current == null) {
+          return;
+        }
+        Limits limits = resource.getManagedLimits();
+        Limit limit = limits.getLimit(entry.getKey());
+        if (limit == null) {
+          return;
+        }
+        float newMax = limit.max - delta * limit.cost / totalCost;
+        resource.setManagedLimitMax(entry.getKey(), newMax);
+      });
+    });
+  }
+
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManaged.java b/solr/core/src/java/org/apache/solr/managed/ResourceManaged.java
new file mode 100644
index 0000000..889bc85
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManaged.java
@@ -0,0 +1,23 @@
+package org.apache.solr.managed;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface ResourceManaged {
+
+  String getName();
+
+  void setManagedLimits(Limits limits);
+
+  void setManagedLimit(String key, Limit limit);
+
+  void setManagedLimitMax(String key, float max);
+
+  void setManagedLimitMin(String key, float min);
+
+  Limits getManagedLimits();
+
+  Map<String, Float> getManagedValues();
+}
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
new file mode 100644
index 0000000..cd9e87d
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -0,0 +1,39 @@
+package org.apache.solr.managed;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.solr.common.SolrCloseable;
+import org.apache.solr.core.PluginInfo;
+import org.apache.solr.util.plugin.PluginInfoInitialized;
+
+/**
+ *
+ */
+public interface ResourceManager extends SolrCloseable, PluginInfoInitialized {
+
+  void setEnabled(Boolean enabled);
+
+  PluginInfo getPluginInfo();
+
+  void createPool(String name, Limits limits, Map<String, Object> params) throws Exception;
+
+  void modifyPoolLimits(String name, Limits limits) throws Exception;
+
+  void removePool(String name) throws Exception;
+
+  default void addResources(String pool, Collection<ResourceManaged> resourceManaged) {
+    ensureNotClosed();
+    for (ResourceManaged resource : resourceManaged) {
+      addResource(pool, resource);
+    }
+  }
+
+  void addResource(String pool, ResourceManaged resourceManaged);
+
+  default void ensureNotClosed() {
+    if (isClosed()) {
+      throw new IllegalStateException("Already closed.");
+    }
+  }
+}


[lucene-solr] 11/36: Support generic limits (eg. boolean, enum, etc).

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 56309ce5a5aad0144faa56e9cb7d84abefdaae3d
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jul 16 12:05:59 2019 +0200

    Support generic limits (eg. boolean, enum, etc).
---
 .../apache/solr/managed/DefaultResourceManager.java |  4 ++--
 .../apache/solr/managed/ManagedMetricProducer.java  |  8 ++++----
 .../org/apache/solr/managed/ManagedResource.java    |  8 ++++----
 .../org/apache/solr/managed/ResourceManager.java    |  4 ++--
 .../apache/solr/managed/ResourceManagerPool.java    | 20 ++++++++++++--------
 .../solr/managed/plugins/CacheManagerPlugin.java    | 21 +++++++++++++++------
 6 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
index e6005c8..5e708b7 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManager.java
@@ -93,7 +93,7 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void createPool(String name, String type, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception {
+  public void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception {
     ensureNotClosed();
     if (resourcePools.containsKey(name)) {
       throw new IllegalArgumentException("Pool '" + name + "' already exists.");
@@ -110,7 +110,7 @@ public class DefaultResourceManager extends ResourceManager {
   }
 
   @Override
-  public void modifyPoolLimits(String name, Map<String, Float> poolLimits) throws Exception {
+  public void modifyPoolLimits(String name, Map<String, Object> poolLimits) throws Exception {
     ensureNotClosed();
     ResourceManagerPool pool = resourcePools.get(name);
     if (pool == null) {
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
index 7885d0f..00167ab6 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedMetricProducer.java
@@ -29,18 +29,18 @@ import org.apache.solr.core.SolrInfoBean;
 public interface ManagedMetricProducer extends SolrInfoBean, ManagedResource {
 
   @Override
-  default Map<String, Float> getMonitoredValues(Collection<String> tags) {
+  default Map<String, Object> getMonitoredValues(Collection<String> tags) {
     Map<String, Object> metrics = getMetricsSnapshot();
     if (metrics == null) {
       return Collections.emptyMap();
     }
-    Map<String, Float> result = new HashMap<>();
+    Map<String, Object> result = new HashMap<>();
     tags.forEach(tag -> {
       Object value = metrics.get(tag);
-      if (value == null || !(value instanceof Number)) {
+      if (value == null) {
         return;
       }
-      result.put(tag, ((Number)value).floatValue());
+      result.put(tag, value);
     });
     return result;
   }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
index 0f18028..261d857 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedResource.java
@@ -44,7 +44,7 @@ public interface ManagedResource {
    * Set values of managed limits.
    * @param limits map of limit names and values
    */
-  default void setManagedLimits(Map<String, Float> limits) {
+  default void setManagedLimits(Map<String, Object> limits) {
     if (limits == null) {
       return;
     }
@@ -63,18 +63,18 @@ public interface ManagedResource {
    * @param key limit name
    * @param value limit value
    */
-  void setManagedLimit(String key, float value) throws Exception;
+  void setManagedLimit(String key, Object value) throws Exception;
 
   /**
    * Returns current values of managed limits.
    * @return map where keys are controlled tags and values are current limits
    */
-  Map<String, Float> getManagedLimits();
+  Map<String, Object> getManagedLimits();
 
   /**
    * Returns monitored values that are used for calculating optimal settings of managed limits.
    * @param tags monitored tags
    * @return map of tags to current values.
    */
-  Map<String, Float> getMonitoredValues(Collection<String> tags) throws Exception;
+  Map<String, Object> getMonitoredValues(Collection<String> tags) throws Exception;
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index 867e3f9..41dd690 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -88,14 +88,14 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    * @param poolLimits pool limits
    * @param params other parameters. These are also used for creating a {@link ResourceManagerPlugin}
    */
-  public abstract void createPool(String name, String type, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception;
+  public abstract void createPool(String name, String type, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception;
 
   /**
    * Modify pool limits.
    * @param name existing pool name
    * @param poolLimits new pool limits
    */
-  public abstract void modifyPoolLimits(String name, Map<String, Float> poolLimits) throws Exception;
+  public abstract void modifyPoolLimits(String name, Map<String, Object> poolLimits) throws Exception;
 
   /**
    * Remove pool. This also stops the management of resources registered with that pool.
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index bfb1b8c..79ecbb0 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -39,7 +39,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final Map<String, ManagedResource> resources = new ConcurrentHashMap<>();
-  private Map<String, Float> poolLimits;
+  private Map<String, Object> poolLimits;
   private final String type;
   private final String name;
   private final ResourceManagerPlugin resourceManagerPlugin;
@@ -58,7 +58,7 @@ public class ResourceManagerPool implements Runnable, Closeable {
    * @param params parameters for the {@link ResourceManagerPlugin}
    * @throws Exception
    */
-  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Float> poolLimits, Map<String, Object> params) throws Exception {
+  public ResourceManagerPool(String name, String type, ResourceManagerPluginFactory factory, Map<String, Object> poolLimits, Map<String, Object> params) throws Exception {
     this.name = name;
     this.type = type;
     this.resourceManagerPlugin = factory.create(type, params);
@@ -94,11 +94,11 @@ public class ResourceManagerPool implements Runnable, Closeable {
    * Get the current monitored values from all resources. Result is a map with resource names as keys,
    * and tag/value maps as values.
    */
-  public Map<String, Map<String, Float>> getCurrentValues() throws InterruptedException {
+  public Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException {
     updateLock.lockInterruptibly();
     try {
       // collect current values
-      Map<String, Map<String, Float>> currentValues = new HashMap<>();
+      Map<String, Map<String, Object>> currentValues = new HashMap<>();
       for (ManagedResource resource : resources.values()) {
         try {
           currentValues.put(resource.getResourceName(), resource.getMonitoredValues(resourceManagerPlugin.getMonitoredTags()));
@@ -109,11 +109,15 @@ public class ResourceManagerPool implements Runnable, Closeable {
       // calculate totals
       Map<String, Float> newTotalValues = new HashMap<>();
       currentValues.values().forEach(map -> map.forEach((k, v) -> {
+        // only calculate totals for numbers
+        if (!(v instanceof Number)) {
+          return;
+        }
         Float total = newTotalValues.get(k);
         if (total == null) {
-          newTotalValues.put(k, v);
+          newTotalValues.put(k, ((Number)v).floatValue());
         } else {
-          newTotalValues.put(k, total + v);
+          newTotalValues.put(k, total + ((Number)v).floatValue());
         }
       }));
       totalValues = newTotalValues;
@@ -136,14 +140,14 @@ public class ResourceManagerPool implements Runnable, Closeable {
     }
   }
 
-  public Map<String, Float> getPoolLimits() {
+  public Map<String, Object> getPoolLimits() {
     return poolLimits;
   }
 
   /**
    * Pool limits are defined using controlled tags.
    */
-  public void setPoolLimits(Map<String, Float> poolLimits) {
+  public void setPoolLimits(Map<String, Object> poolLimits) {
     this.poolLimits = new HashMap(poolLimits);
   }
 
diff --git a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
index 8783334..5adf7ef 100644
--- a/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/plugins/CacheManagerPlugin.java
@@ -80,11 +80,16 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
 
   @Override
   public void manage(ResourceManagerPool pool) throws Exception {
-    Map<String, Map<String, Float>> currentValues = pool.getCurrentValues();
+    Map<String, Map<String, Object>> currentValues = pool.getCurrentValues();
     Map<String, Float> totalValues = pool.getTotalValues();
     // pool limits are defined using controlled tags
-    pool.getPoolLimits().forEach((poolLimitName, poolLimitValue) -> {
-      if (poolLimitValue == null || poolLimitValue <= 0) {
+    pool.getPoolLimits().forEach((poolLimitName, value) -> {
+      // only numeric limits are supported
+      if (value == null || !(value instanceof Number)) {
+        return;
+      }
+      float poolLimitValue = ((Number)value).floatValue();
+      if (poolLimitValue <= 0) {
         return;
       }
       String monitoredTag = controlledToMonitored.get(poolLimitName);
@@ -105,9 +110,13 @@ public class CacheManagerPlugin extends AbstractResourceManagerPlugin {
       float changeRatio = poolLimitValue / totalValue;
       // modify current limits by the changeRatio
       pool.getResources().forEach((name, resource) -> {
-        Map<String, Float> resourceLimits = resource.getManagedLimits();
-        Float currentResourceLimit = resourceLimits.get(poolLimitName);
-        if (currentResourceLimit == null || currentResourceLimit <= 0) {
+        Map<String, Object> resourceLimits = resource.getManagedLimits();
+        Object limit = resourceLimits.get(poolLimitName);
+        if (limit == null || !(limit instanceof Number)) {
+          return;
+        }
+        float currentResourceLimit = ((Number)limit).floatValue();
+        if (currentResourceLimit <= 0) {
           return;
         }
         float newLimit = currentResourceLimit * changeRatio;


[lucene-solr] 30/36: Broken, interim check-in.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 9bd5ebb67a52b3bb84735719e2b54ccfcdf1f6c6
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Nov 19 12:09:10 2019 +0100

    Broken, interim check-in.
---
 .../solr/managed/DefaultResourceManagerPool.java   | 11 ++--------
 .../org/apache/solr/managed/ManagedComponent.java  | 14 +++++++-----
 .../apache/solr/managed/ManagedComponentId.java    | 24 +++++++++++++++------
 .../org/apache/solr/managed/ManagedContext.java    | 25 +++++++++++++++++++---
 .../org/apache/solr/managed/ResourceManager.java   |  4 ++--
 .../apache/solr/managed/ResourceManagerPlugin.java |  2 +-
 .../apache/solr/managed/ResourceManagerPool.java   |  6 ------
 .../java/org/apache/solr/search/CaffeineCache.java | 14 +++++++-----
 .../solr/managed/types/TestCacheManagerPlugin.java |  9 ++++++++
 9 files changed, 71 insertions(+), 38 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
index 07eb5bf..98771b8 100644
--- a/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/DefaultResourceManagerPool.java
@@ -44,7 +44,6 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   private final ResourceManagerPlugin resourceManagerPlugin;
   private final Map<String, Object> args;
   private final ManagedContext poolContext = new ManagedContext();
-  private Map<String, Map<String, Object>> currentValues = null;
   private final ReentrantLock updateLock = new ReentrantLock();
   int scheduleDelaySeconds;
   ScheduledFuture<?> scheduledFuture;
@@ -119,15 +118,14 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
     updateLock.lockInterruptibly();
     try {
       // collect the current values
-      Map<String, Map<String, Object>> newCurrentValues = new HashMap<>();
+      Map<String, Map<String, Object>> currentValues = new HashMap<>();
       for (ManagedComponent managedComponent : components.values()) {
         try {
-          newCurrentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
+          currentValues.put(managedComponent.getManagedComponentId().toString(), resourceManagerPlugin.getMonitoredValues(managedComponent));
         } catch (Exception e) {
           log.warn("Error getting managed values from " + managedComponent.getManagedComponentId(), e);
         }
       }
-      this.currentValues = newCurrentValues;
       return Collections.unmodifiableMap(currentValues);
     } finally {
       updateLock.unlock();
@@ -135,11 +133,6 @@ public class DefaultResourceManagerPool implements ResourceManagerPool {
   }
 
   @Override
-  public Map<String, Object> getTotalValues() throws InterruptedException {
-    return Collections.unmodifiableMap(resourceManagerPlugin.aggregateTotalValues(currentValues));
-  }
-
-  @Override
   public Map<String, Object> getPoolLimits() {
     return poolLimits;
   }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
index cf75af3..d8e6692 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponent.java
@@ -16,19 +16,23 @@
  */
 package org.apache.solr.managed;
 
+import org.apache.solr.core.SolrInfoBean;
+
 /**
  * A managed component.
  */
-public interface ManagedComponent {
+public interface ManagedComponent extends SolrInfoBean {
   /**
-   * Unique name of this component. By convention id-s form a dot-separated hierarchy that
-   * follows the naming of metric registries and metric names.
+   * Unique name of this component. By convention id-s form a colon-separated hierarchy.
    */
   ManagedComponentId getManagedComponentId();
 
   /**
-   * Component context used for managing additional component state.
-   * @return component's context
+   * Component context used for managing additional component state for the purpose of resource management.
    */
   ManagedContext getManagedContext();
+
+  default void close() throws Exception {
+    SolrInfoBean.super.close();
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
index bd09080..7b5d908 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedComponentId.java
@@ -23,11 +23,13 @@ import java.util.Arrays;
  * Hierarchical component id.
  */
 public class ManagedComponentId {
+  private final String type;
   private final String name;
   private final String[] path;
   private final String id;
 
-  public ManagedComponentId(String name, String... path) {
+  public ManagedComponentId(String type, String name, String... path) {
+    this.type = type;
     this.name = name;
     this.path = path;
     StringBuilder sb = new StringBuilder();
@@ -46,6 +48,10 @@ public class ManagedComponentId {
     id = sb.toString();
   }
 
+  public String getType() {
+    return type;
+  }
+
   public String getName() {
     return name;
   }
@@ -63,12 +69,16 @@ public class ManagedComponentId {
       return null;
     }
     String[] parts = fullName.split(":");
-    if (parts.length > 1) {
-      String name = parts[parts.length - 1];
-      String[] path = Arrays.copyOfRange(parts, 0, parts.length - 1);
-      return new ManagedComponentId(name, path);
+    if (parts.length < 2) {
+      throw new RuntimeException("at least 2 parts (type and name) must be present: " + fullName);
+    }
+    if (parts.length > 2) {
+      String type = parts[parts.length - 1];
+      String name = parts[parts.length - 2];
+      String[] path = Arrays.copyOfRange(parts, 0, parts.length - 2);
+      return new ManagedComponentId(type, name, path);
     } else {
-      return new ManagedComponentId(parts[0]);
+      return new ManagedComponentId(parts[0], parts[1]);
     }
   }
-}
+}
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
index 74919ee..3cf6839 100644
--- a/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
+++ b/solr/core/src/java/org/apache/solr/managed/ManagedContext.java
@@ -16,11 +16,30 @@
  */
 package org.apache.solr.managed;
 
-import java.util.concurrent.ConcurrentHashMap;
-
 /**
  *
  */
-public class ManagedContext extends ConcurrentHashMap<String, Object> {
+public class ManagedContext {
+  private final ResourceManager resourceManager;
+  private final String poolName;
+  private final ManagedComponent component;
+
+  public ManagedContext(ResourceManager resourceManager, String poolName, ManagedComponent component) {
+    this.resourceManager = resourceManager;
+    this.poolName = poolName;
+    this.component = component;
+    this.resourceManager.registerComponent(poolName, component);
+  }
+
+  public ResourceManager getResourceManager() {
+    return resourceManager;
+  }
+
+  public String getPoolName() {
+    return poolName;
+  }
 
+  public void unregister() {
+    resourceManager.unregisterComponent(poolName, component.getManagedComponentId());
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
index 24a6e44..364a99d 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManager.java
@@ -198,7 +198,7 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    * @param pool existing pool name.
    * @param managedComponents components to add
    */
-  public void registerComponents(String pool, Collection<ManagedComponent> managedComponents) throws Exception {
+  public void registerComponents(String pool, Collection<ManagedComponent> managedComponents) {
     ensureActive();
     for (ManagedComponent managedComponent : managedComponents) {
       registerComponent(pool, managedComponent);
@@ -212,7 +212,7 @@ public abstract class ResourceManager implements SolrCloseable, PluginInfoInitia
    *                        used in the selected pool. The component must not be already managed by
    *                        another pool of the same type.
    */
-  public abstract void registerComponent(String pool, ManagedComponent managedComponent) throws Exception;
+  public abstract void registerComponent(String pool, ManagedComponent managedComponent);
 
   /**
    * Remove a managed component from a pool.
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
index 1fbeaf0..dc6a5b6 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPlugin.java
@@ -69,7 +69,7 @@ public interface ResourceManagerPlugin<T extends ManagedComponent> {
   void manage(ResourceManagerPool pool) throws Exception;
 
   /**
-   * Aggregated current monitored values.
+   * Return aggregated current monitored values.
    * <p>Default implementation of this method simply sums up all non-negative numeric values across
    * components and ignores any non-numeric values.</p>
    */
diff --git a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
index 2bf4db7..9f2b4ff 100644
--- a/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
+++ b/solr/core/src/java/org/apache/solr/managed/ResourceManagerPool.java
@@ -38,12 +38,6 @@ public interface ResourceManagerPool extends Runnable, Closeable {
    */
   Map<String, Map<String, Object>> getCurrentValues() throws InterruptedException;
 
-  /**
-   * This returns cumulative monitored values of all components.
-   * <p>NOTE: you MUST call {@link #getCurrentValues()} first!</p>
-   */
-  Map<String, Object> getTotalValues() throws InterruptedException;
-
   /** Get current pool limits. */
   Map<String, Object> getPoolLimits();
 
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index 32837f6..ea1db54 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -23,8 +23,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ForkJoinPool;
@@ -39,6 +37,8 @@ import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.managed.ManagedComponentId;
 import org.apache.solr.managed.ManagedContext;
+import org.apache.solr.managed.ResourceManagerPluginFactory;
+import org.apache.solr.managed.types.CacheManagerPlugin;
 import org.apache.solr.metrics.MetricsMap;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.slf4j.Logger;
@@ -88,10 +88,12 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
   private int maxIdleTimeSec;
   private boolean cleanupThread;
 
-  private Set<String> metricNames = ConcurrentHashMap.newKeySet();
   private MetricsMap cacheMap;
   private SolrMetricsContext solrMetricsContext;
 
+  private ManagedContext managedContext;
+  private ManagedComponentId managedComponentId;
+
   private long initialRamBytes = 0;
   private final LongAdder ramBytes = new LongAdder();
 
@@ -387,15 +389,17 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
       }
     });
     solrMetricsContext.gauge(cacheMap, true, scope, getCategory().toString());
+    managedComponentId = new ManagedComponentId(CacheManagerPlugin.TYPE, solrMetricsContext.getTag(), solrMetricsContext.getRegistryName(), getCategory().toString(), scope);
+    managedContext = new ManagedContext()
   }
 
   @Override
   public ManagedComponentId getManagedComponentId() {
-    return null;
+    return managedComponentId;
   }
 
   @Override
   public ManagedContext getManagedContext() {
-    return null;
+    return managedContext;
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPlugin.java b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPlugin.java
new file mode 100644
index 0000000..dab094f
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/managed/types/TestCacheManagerPlugin.java
@@ -0,0 +1,9 @@
+package org.apache.solr.managed.types;
+
+import org.apache.solr.cloud.SolrCloudTestCase;
+
+/**
+ *
+ */
+public class TestCacheManagerPlugin extends SolrCloudTestCase {
+}


[lucene-solr] 22/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 56b250945c0ce4ffd4c90a8d41af23d0c655a2d2
Merge: 4890c43 15c2fd6
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Jul 31 12:21:23 2019 +0200

    Merge branch 'master' into jira/solr-13579

 dev-tools/doap/lucene.rdf                          |   7 +
 dev-tools/doap/solr.rdf                            |   7 +
 lucene/CHANGES.txt                                 |  10 +
 .../analysis/charfilter/MappingCharFilter.java     |   8 +-
 .../analysis/charfilter/NormalizeCharMap.java      |   6 +-
 .../analysis/es/SpanishMinimalStemFilter.java      |  58 +++
 .../es/SpanishMinimalStemFilterFactory.java        |  52 +++
 .../lucene/analysis/es/SpanishMinimalStemmer.java  |  80 ++++
 .../lucene/analysis/fr/FrenchMinimalStemmer.java   |   2 +-
 .../lucene/analysis/hunspell/Dictionary.java       |  12 +-
 .../apache/lucene/analysis/hunspell/Stemmer.java   |  12 +-
 .../miscellaneous/StemmerOverrideFilter.java       |   4 +-
 .../lucene/analysis/synonym/SynonymFilter.java     |   8 +-
 .../analysis/synonym/SynonymGraphFilter.java       |   8 +-
 ....apache.lucene.analysis.util.TokenFilterFactory |   1 +
 .../TestSpanishMinimalStemFilter.java}             |  66 +---
 .../es/TestSpanishMinimalStemFilterFactory.java    |  47 +++
 .../analysis/fr/TestFrenchMinimalStemFilter.java   |  19 +-
 .../analysis/synonym/TestSynonymGraphFilter.java   |  25 +-
 .../lucene/analysis/ja/JapaneseTokenizer.java      |   8 +-
 .../lucene/analysis/ja/dict/UserDictionary.java    |   4 +-
 lucene/analysis/nori/build.xml                     |  51 +--
 .../apache/lucene/analysis/ko/KoreanTokenizer.java |   8 +-
 .../analysis/ko/dict/TokenInfoDictionary.java      |  14 +-
 .../lucene/analysis/ko/dict/UserDictionary.java    |   4 +-
 .../analysis/ko/util/BinaryDictionaryWriter.java   |  66 ++--
 .../ko/util/CharacterDefinitionWriter.java         |  25 +-
 .../analysis/ko/util/ConnectionCostsBuilder.java   |  61 +++
 .../analysis/ko/util/ConnectionCostsWriter.java    |  30 +-
 .../lucene/analysis/ko/util/DictionaryBuilder.java |  54 +++
 .../ko/util/TokenInfoDictionaryBuilder.java        | 101 ++---
 .../ko/util/TokenInfoDictionaryWriter.java         |  18 +-
 .../analysis/ko/util/UnknownDictionaryBuilder.java | 118 ++++++
 .../analysis/ko/util/UnknownDictionaryWriter.java  |   5 +-
 .../analysis/ko/dict/TokenInfoDictionary$fst.dat   | Bin 5640903 -> 5641400 bytes
 ...ictionary.java => TokenInfoDictionaryTest.java} |  69 +++-
 .../analysis/ko/util}/UnknownDictionaryTest.java   |   5 +-
 .../analysis/ko/util/ConnectionCostsBuilder.java   |  67 ----
 .../lucene/analysis/ko/util/DictionaryBuilder.java |  67 ----
 .../analysis/ko/util/UnknownDictionaryBuilder.java | 134 -------
 .../analysis/ko/dict/TokenInfoDictionaryTest.java  |  80 ----
 .../lucene/index/TestBackwardsCompatibility.java   |   7 +-
 .../org/apache/lucene/index/index.8.2.0-cfs.zip    | Bin 0 -> 15617 bytes
 .../org/apache/lucene/index/index.8.2.0-nocfs.zip  | Bin 0 -> 15630 bytes
 .../test/org/apache/lucene/index/sorted.8.2.0.zip  | Bin 0 -> 131154 bytes
 .../benchmark/byTask/feeds/DemoHTMLParser.java     |  21 +-
 .../blocktreeords/OrdsIntersectTermsEnum.java      |   6 +-
 .../codecs/blocktreeords/OrdsSegmentTermsEnum.java |  78 ++--
 .../lucene/codecs/memory/FSTOrdTermsReader.java    |  35 +-
 .../lucene/codecs/memory/FSTTermsReader.java       |  45 +--
 .../codecs/blocktree/IntersectTermsEnum.java       |   6 +-
 .../lucene/codecs/blocktree/SegmentTermsEnum.java  |  48 +--
 .../java/org/apache/lucene/index/FieldInfos.java   |   2 +-
 .../lucene/search/Boolean2ScorerSupplier.java      |  13 +
 .../java/org/apache/lucene/store/FSDirectory.java  |   2 +-
 .../java/org/apache/lucene/store/RateLimiter.java  |  12 +-
 .../src/java/org/apache/lucene/util/Version.java   |   7 +
 .../apache/lucene/util/fst/BytesRefFSTEnum.java    |   2 +-
 .../src/java/org/apache/lucene/util/fst/FST.java   | 391 ++++++++++++--------
 .../java/org/apache/lucene/util/fst/FSTEnum.java   | 209 ++++-------
 .../org/apache/lucene/util/fst/IntsRefFSTEnum.java |   2 +-
 .../java/org/apache/lucene/util/fst/NodeHash.java  |  21 +-
 .../src/java/org/apache/lucene/util/fst/Util.java  | 223 ++++++-----
 .../apache/lucene/analysis/TestCharArrayMap.java   | 134 +++----
 .../apache/lucene/analysis/TestCharArraySet.java   | 110 ++----
 .../lucene/index/TestAllFilesCheckIndexHeader.java |  20 +-
 .../lucene/index/TestAllFilesDetectTruncation.java |  21 +-
 .../apache/lucene/index/TestDirectoryReader.java   |  19 +-
 .../apache/lucene/index/TestIndexableField.java    |   7 +-
 .../apache/lucene/index/TestSwappedIndexFiles.java |  21 +-
 .../apache/lucene/search/TestBooleanScorer.java    |  84 +++++
 .../TestTopFieldCollectorEarlyTermination.java     |  12 +-
 .../org/apache/lucene/store/TestRateLimiter.java   |   7 +-
 .../test/org/apache/lucene/util/fst/TestFSTs.java  |  20 +-
 .../org/apache/lucene/util/fst/TestFstDirect.java  |  54 +--
 .../test/org/apache/lucene/util/fst/TestUtil.java  | 115 ++++++
 .../lucene/search/join/TestCheckJoinIndex.java     |  15 +-
 .../queryparser/classic/TestQueryParser.java       |  14 +-
 .../queryparser/util/QueryParserTestBase.java      |  55 +--
 .../apache/lucene/replicator/nrt/PrimaryNode.java  |   2 +-
 .../lucene/replicator/LocalReplicatorTest.java     |   8 +-
 .../lucene/replicator/http/HttpReplicatorTest.java |  11 +-
 .../idversion/IDVersionSegmentTermsEnum.java       |  48 +--
 .../lucene/search/TestTermAutomatonQuery.java      |   7 +-
 .../suggest/analyzing/AnalyzingSuggester.java      |   2 +-
 .../lucene/search/suggest/analyzing/FSTUtil.java   |  18 +-
 .../suggest/analyzing/FreeTextSuggester.java       |   4 +-
 .../search/suggest/document/NRTSuggester.java      |   2 +-
 .../lucene/search/suggest/fst/FSTCompletion.java   |  10 +-
 .../search/suggest/fst/WFSTCompletionLookup.java   |   6 +-
 .../suggest/analyzing/AnalyzingSuggesterTest.java  |  11 +-
 .../org/apache/lucene/util/LuceneTestCase.java     |   7 +-
 .../java/org/apache/lucene/util/fst/FSTTester.java |   8 +-
 .../TestCompressingTermVectorsFormat.java          |  17 +-
 .../apache/lucene/mockfile/TestHandleLimitFS.java  |   9 +-
 .../lucene/mockfile/TestHandleTrackingFS.java      |  56 +--
 .../org/apache/lucene/mockfile/TestLeakFS.java     |  43 +--
 .../org/apache/lucene/mockfile/TestVerboseFS.java  |  76 +---
 .../org/apache/lucene/mockfile/TestWindowsFS.java  |  28 +-
 .../lucene/store/TestMockDirectoryWrapper.java     |  24 +-
 .../util/TestRunWithRestrictedPermissions.java     |  22 +-
 solr/.gitignore                                    |   1 +
 solr/CHANGES.txt                                   |  15 +
 .../org/apache/solr/analytics/AnalyticsDriver.java |  10 +-
 .../apache/solr/analytics/AnalyticsExpression.java |  14 +-
 .../solr/analytics/AnalyticsGroupingManager.java   |  48 +--
 .../solr/analytics/AnalyticsRequestManager.java    |  82 ++---
 .../solr/analytics/AnalyticsRequestParser.java     | 106 +++---
 .../apache/solr/analytics/ExpressionFactory.java   | 116 +++---
 .../analytics/facet/AbstractSolrQueryFacet.java    |  20 +-
 .../solr/analytics/facet/AnalyticsFacet.java       |  40 +-
 .../apache/solr/analytics/facet/PivotFacet.java    |  18 +-
 .../org/apache/solr/analytics/facet/PivotNode.java |  32 +-
 .../apache/solr/analytics/facet/QueryFacet.java    |   4 +-
 .../apache/solr/analytics/facet/RangeFacet.java    |  10 +-
 .../apache/solr/analytics/facet/SortableFacet.java |  36 +-
 .../apache/solr/analytics/facet/ValueFacet.java    |   6 +-
 .../facet/compare/DelegatingComparator.java        |   6 +-
 .../facet/compare/ExpressionComparator.java        |   6 +-
 .../facet/compare/FacetResultsComparator.java      |  10 +-
 .../facet/compare/FacetValueComparator.java        |   4 +-
 .../solr/analytics/facet/compare/package-info.java |   4 +-
 .../apache/solr/analytics/facet/package-info.java  |   4 +-
 .../analytics/function/ExpressionCalculator.java   |   8 +-
 .../MergingReductionCollectionManager.java         |   8 +-
 .../function/ReductionCollectionManager.java       |  90 ++---
 .../solr/analytics/function/ReductionFunction.java |   2 +-
 .../analytics/function/field/AnalyticsField.java   |  22 +-
 .../analytics/function/field/BooleanField.java     |   4 +-
 .../function/field/BooleanMultiField.java          |   8 +-
 .../solr/analytics/function/field/DateField.java   |   4 +-
 .../function/field/DateMultiPointField.java        |   2 +-
 .../function/field/DateMultiTrieField.java         |   2 +-
 .../solr/analytics/function/field/DoubleField.java |   4 +-
 .../function/field/DoubleMultiPointField.java      |   6 +-
 .../function/field/DoubleMultiTrieField.java       |   6 +-
 .../solr/analytics/function/field/FloatField.java  |   4 +-
 .../function/field/FloatMultiPointField.java       |   8 +-
 .../function/field/FloatMultiTrieField.java        |   8 +-
 .../solr/analytics/function/field/IntField.java    |   6 +-
 .../function/field/IntMultiPointField.java         |   8 +-
 .../function/field/IntMultiTrieField.java          |   8 +-
 .../function/field/LongMultiPointField.java        |   8 +-
 .../function/field/LongMultiTrieField.java         |   6 +-
 .../analytics/function/field/StringMultiField.java |   4 +-
 .../analytics/function/field/package-info.java     |   4 +-
 .../analytics/function/mapping/AddFunction.java    |   6 +-
 .../analytics/function/mapping/BottomFunction.java |   2 +-
 .../function/mapping/ComparisonFunction.java       |  18 +-
 .../analytics/function/mapping/ConcatFunction.java |   8 +-
 .../function/mapping/DateMathFunction.java         |   6 +-
 .../function/mapping/DateParseFunction.java        |  10 +-
 .../mapping/DecimalNumericConversionFunction.java  |  22 +-
 .../analytics/function/mapping/DivideFunction.java |   4 +-
 .../analytics/function/mapping/EqualFunction.java  |  14 +-
 .../analytics/function/mapping/ExistsFunction.java |  10 +-
 .../function/mapping/FillMissingFunction.java      |  78 ++--
 .../analytics/function/mapping/FilterFunction.java |  82 ++---
 .../analytics/function/mapping/IfFunction.java     |  42 +--
 .../analytics/function/mapping/LambdaFunction.java | 408 ++++++++++-----------
 .../analytics/function/mapping/LogFunction.java    |   4 +-
 .../analytics/function/mapping/LogicFunction.java  |  10 +-
 .../analytics/function/mapping/MultFunction.java   |   6 +-
 .../analytics/function/mapping/PowerFunction.java  |   4 +-
 .../analytics/function/mapping/RemoveFunction.java |  94 ++---
 .../function/mapping/ReplaceFunction.java          |  84 ++---
 .../function/mapping/SubtractFunction.java         |   2 +-
 .../analytics/function/mapping/TopFunction.java    |   2 +-
 .../analytics/function/mapping/package-info.java   |   4 +-
 .../solr/analytics/function/package-info.java      |   4 +-
 .../function/reduction/CountFunction.java          |   4 +-
 .../function/reduction/DocCountFunction.java       |   4 +-
 .../analytics/function/reduction/MaxFunction.java  |  14 +-
 .../analytics/function/reduction/MeanFunction.java |   4 +-
 .../function/reduction/MedianFunction.java         |   6 +-
 .../analytics/function/reduction/MinFunction.java  |  14 +-
 .../function/reduction/MissingFunction.java        |   2 +-
 .../function/reduction/OrdinalFunction.java        |  16 +-
 .../function/reduction/PercentileFunction.java     |  16 +-
 .../analytics/function/reduction/SumFunction.java  |   4 +-
 .../function/reduction/UniqueFunction.java         |   2 +-
 .../function/reduction/data/CountCollector.java    |  28 +-
 .../function/reduction/data/MaxCollector.java      |  62 ++--
 .../function/reduction/data/MinCollector.java      |  62 ++--
 .../reduction/data/ReductionDataCollector.java     |  70 ++--
 .../reduction/data/SortedListCollector.java        |  76 ++--
 .../function/reduction/data/SumCollector.java      |  16 +-
 .../function/reduction/data/UniqueCollector.java   |  42 +--
 .../function/reduction/data/package-info.java      |   4 +-
 .../analytics/function/reduction/package-info.java |   4 +-
 .../org/apache/solr/analytics/package-info.java    |   6 +-
 .../apache/solr/analytics/plugin/package-info.java |   6 +-
 .../stream/AnalyticsShardRequestManager.java       |  28 +-
 .../stream/AnalyticsShardResponseParser.java       |   6 +-
 .../apache/solr/analytics/stream/package-info.java |   4 +-
 .../reservation/BooleanArrayReservation.java       |   2 +-
 .../reservation/BooleanCheckedReservation.java     |   2 +-
 .../stream/reservation/BooleanReservation.java     |   2 +-
 .../stream/reservation/DoubleArrayReservation.java |   2 +-
 .../reservation/DoubleCheckedReservation.java      |   2 +-
 .../stream/reservation/DoubleReservation.java      |   2 +-
 .../stream/reservation/FloatArrayReservation.java  |   2 +-
 .../reservation/FloatCheckedReservation.java       |   2 +-
 .../stream/reservation/FloatReservation.java       |   2 +-
 .../stream/reservation/IntArrayReservation.java    |   2 +-
 .../stream/reservation/IntCheckedReservation.java  |   2 +-
 .../stream/reservation/IntReservation.java         |   2 +-
 .../stream/reservation/LongArrayReservation.java   |   2 +-
 .../stream/reservation/LongCheckedReservation.java |   2 +-
 .../stream/reservation/LongReservation.java        |   2 +-
 .../ReductionCheckedDataReservation.java           |   2 +-
 .../reservation/ReductionDataArrayReservation.java |   2 +-
 .../reservation/ReductionDataReservation.java      |  10 +-
 .../stream/reservation/StringArrayReservation.java |   2 +-
 .../reservation/StringCheckedReservation.java      |   2 +-
 .../stream/reservation/StringReservation.java      |   2 +-
 .../analytics/stream/reservation/package-info.java |   4 +-
 .../reservation/read/BooleanCheckedDataReader.java |   2 +-
 .../reservation/read/BooleanDataArrayReader.java   |   2 +-
 .../stream/reservation/read/BooleanDataReader.java |   2 +-
 .../reservation/read/DoubleCheckedDataReader.java  |   2 +-
 .../reservation/read/DoubleDataArrayReader.java    |   2 +-
 .../stream/reservation/read/DoubleDataReader.java  |   2 +-
 .../reservation/read/FloatCheckedDataReader.java   |   2 +-
 .../reservation/read/FloatDataArrayReader.java     |   2 +-
 .../stream/reservation/read/FloatDataReader.java   |   2 +-
 .../reservation/read/IntCheckedDataReader.java     |   2 +-
 .../reservation/read/IntDataArrayReader.java       |   2 +-
 .../stream/reservation/read/IntDataReader.java     |   2 +-
 .../reservation/read/LongCheckedDataReader.java    |   2 +-
 .../reservation/read/LongDataArrayReader.java      |   2 +-
 .../stream/reservation/read/LongDataReader.java    |   2 +-
 .../read/ReductionCheckedDataReader.java           |  10 +-
 .../reservation/read/ReductionDataArrayReader.java |  12 +-
 .../reservation/read/ReductionDataReader.java      |   6 +-
 .../reservation/read/StringCheckedDataReader.java  |   2 +-
 .../reservation/read/StringDataArrayReader.java    |   2 +-
 .../stream/reservation/read/StringDataReader.java  |   2 +-
 .../stream/reservation/read/package-info.java      |   4 +-
 .../write/BooleanCheckedDataWriter.java            |   2 +-
 .../reservation/write/BooleanDataArrayWriter.java  |   2 +-
 .../reservation/write/BooleanDataWriter.java       |   2 +-
 .../reservation/write/DoubleCheckedDataWriter.java |   2 +-
 .../reservation/write/DoubleDataArrayWriter.java   |   2 +-
 .../stream/reservation/write/DoubleDataWriter.java |   2 +-
 .../reservation/write/FloatCheckedDataWriter.java  |   2 +-
 .../reservation/write/FloatDataArrayWriter.java    |   2 +-
 .../stream/reservation/write/FloatDataWriter.java  |   2 +-
 .../reservation/write/IntCheckedDataWriter.java    |   2 +-
 .../reservation/write/IntDataArrayWriter.java      |   2 +-
 .../stream/reservation/write/IntDataWriter.java    |   2 +-
 .../reservation/write/LongCheckedDataWriter.java   |   2 +-
 .../reservation/write/LongDataArrayWriter.java     |   2 +-
 .../stream/reservation/write/LongDataWriter.java   |   2 +-
 .../write/ReductionCheckedDataWriter.java          |  12 +-
 .../write/ReductionDataArrayWriter.java            |  12 +-
 .../reservation/write/ReductionDataWriter.java     |   4 +-
 .../reservation/write/StringCheckedDataWriter.java |   2 +-
 .../reservation/write/StringDataArrayWriter.java   |   2 +-
 .../stream/reservation/write/StringDataWriter.java |   2 +-
 .../stream/reservation/write/package-info.java     |   4 +-
 .../analytics/util/AnalyticsResponseHeadings.java  |   2 +-
 .../solr/analytics/util/FacetRangeGenerator.java   |  94 ++---
 .../solr/analytics/util/OldAnalyticsParams.java    |  24 +-
 .../util/OldAnalyticsRequestConverter.java         |  36 +-
 .../solr/analytics/util/OrdinalCalculator.java     |   2 +-
 .../solr/analytics/util/function/package-info.java |   4 +-
 .../apache/solr/analytics/util/package-info.java   |   4 +-
 .../solr/analytics/value/AnalyticsValue.java       |   8 +-
 .../solr/analytics/value/AnalyticsValueStream.java |  36 +-
 .../apache/solr/analytics/value/BooleanValue.java  |   8 +-
 .../solr/analytics/value/BooleanValueStream.java   |   8 +-
 .../solr/analytics/value/ComparableValue.java      |   2 +-
 .../org/apache/solr/analytics/value/DateValue.java |   6 +-
 .../solr/analytics/value/DateValueStream.java      |   6 +-
 .../apache/solr/analytics/value/DoubleValue.java   |   6 +-
 .../solr/analytics/value/DoubleValueStream.java    |   4 +-
 .../apache/solr/analytics/value/FloatValue.java    |   4 +-
 .../solr/analytics/value/FloatValueStream.java     |   4 +-
 .../org/apache/solr/analytics/value/IntValue.java  |   4 +-
 .../solr/analytics/value/IntValueStream.java       |   6 +-
 .../org/apache/solr/analytics/value/LongValue.java |   4 +-
 .../solr/analytics/value/LongValueStream.java      |   6 +-
 .../apache/solr/analytics/value/StringValue.java   |   4 +-
 .../solr/analytics/value/StringValueStream.java    |   4 +-
 .../analytics/value/constant/ConstantValue.java    |  18 +-
 .../analytics/value/constant/package-info.java     |   4 +-
 .../apache/solr/analytics/value/package-info.java  |   4 +-
 .../org/apache/solr/handler/AnalyticsHandler.java  |  12 +-
 .../solr/handler/component/AnalyticsComponent.java |  87 +++--
 .../response/AnalyticsShardResponseWriter.java     |  10 +-
 .../solr/analytics/ExpressionFactoryTest.java      |  58 +--
 .../org/apache/solr/analytics/NoFacetTest.java     |  62 ++--
 .../solr/analytics/OverallAnalyticsTest.java       |  24 +-
 .../solr/analytics/SolrAnalyticsTestCase.java      |  62 ++--
 .../solr/analytics/facet/PivotFacetTest.java       |  22 +-
 .../solr/analytics/facet/QueryFacetTest.java       |  24 +-
 .../solr/analytics/facet/RangeFacetTest.java       |  92 ++---
 .../facet/SolrAnalyticsFacetTestCase.java          |  14 +-
 .../solr/analytics/facet/ValueFacetTest.java       |  90 ++---
 .../function/field/AbstractAnalyticsFieldTest.java | 100 ++---
 .../function/field/BooleanFieldsTest.java          |  10 +-
 .../analytics/function/field/DateFieldsTest.java   |  18 +-
 .../analytics/function/field/DoubleFieldsTest.java |  18 +-
 .../analytics/function/field/FloatFieldsTest.java  |  18 +-
 .../analytics/function/field/IntFieldsTest.java    |  18 +-
 .../analytics/function/field/LongFieldsTest.java   |  18 +-
 .../analytics/function/field/StringFieldsTest.java |  10 +-
 .../mapping/AbsoluteValueFunctionTest.java         |  24 +-
 .../function/mapping/AddFunctionTest.java          |  28 +-
 .../function/mapping/AndFunctionTest.java          |  32 +-
 .../function/mapping/BottomFunctionTest.java       |  86 ++---
 .../function/mapping/CeilingFunctionTest.java      |  18 +-
 .../function/mapping/ConcatFunctionTest.java       |  48 +--
 .../function/mapping/DateMathFunctionTest.java     |  14 +-
 .../function/mapping/DateParseFunctionTest.java    |  28 +-
 .../function/mapping/DivideFunctionTest.java       |  20 +-
 .../function/mapping/EqualFunctionTest.java        |  56 +--
 .../function/mapping/FillMissingFunctionTest.java  |  56 +--
 .../function/mapping/FilterFunctionTest.java       | 132 +++----
 .../function/mapping/FloorFunctionTest.java        |  18 +-
 .../function/mapping/GTEFunctionTest.java          |  30 +-
 .../analytics/function/mapping/GTFunctionTest.java |  30 +-
 .../analytics/function/mapping/IfFunctionTest.java | 112 +++---
 .../function/mapping/LTEFunctionTest.java          |  30 +-
 .../analytics/function/mapping/LTFunctionTest.java |  30 +-
 .../function/mapping/LogFunctionTest.java          |  28 +-
 .../function/mapping/MultFunctionTest.java         |  26 +-
 .../function/mapping/NegateFunctionTest.java       |  30 +-
 .../analytics/function/mapping/OrFunctionTest.java |  32 +-
 .../function/mapping/PowerFunctionTest.java        |  20 +-
 .../function/mapping/RemoveFunctionTest.java       |  68 ++--
 .../function/mapping/ReplaceFunctionTest.java      | 130 +++----
 .../function/mapping/RoundFunctionTest.java        |  18 +-
 .../function/mapping/StringCastFunctionTest.java   |   6 +-
 .../function/mapping/SubtractFunctionTest.java     |  20 +-
 .../function/mapping/TopFunctionTest.java          |  86 ++---
 .../legacy/LegacyAbstractAnalyticsCloudTest.java   |   8 +-
 .../legacy/LegacyAbstractAnalyticsTest.java        |  12 +-
 .../analytics/legacy/LegacyNoFacetCloudTest.java   | 128 +++----
 .../solr/analytics/legacy/LegacyNoFacetTest.java   | 118 +++---
 .../legacy/expression/LegacyFunctionTest.java      |  80 ++--
 .../LegacyAbstractAnalyticsFacetCloudTest.java     |  14 +-
 .../facet/LegacyAbstractAnalyticsFacetTest.java    |  24 +-
 .../legacy/facet/LegacyFacetSortingTest.java       |   6 +-
 .../legacy/facet/LegacyFieldFacetCloudTest.java    | 216 +++++------
 .../facet/LegacyFieldFacetExtrasCloudTest.java     |  52 +--
 .../legacy/facet/LegacyFieldFacetExtrasTest.java   |  46 +--
 .../legacy/facet/LegacyFieldFacetTest.java         | 190 +++++-----
 .../legacy/facet/LegacyQueryFacetCloudTest.java    |  24 +-
 .../legacy/facet/LegacyQueryFacetTest.java         |  18 +-
 .../legacy/facet/LegacyRangeFacetCloudTest.java    |  62 ++--
 .../legacy/facet/LegacyRangeFacetTest.java         |  62 ++--
 .../analytics/value/CastingAnalyticsValueTest.java |   6 +-
 .../value/CastingBooleanValueStreamTest.java       |  10 +-
 .../analytics/value/CastingBooleanValueTest.java   |  18 +-
 .../value/CastingDateValueStreamTest.java          |  14 +-
 .../solr/analytics/value/CastingDateValueTest.java |  22 +-
 .../value/CastingDoubleValueStreamTest.java        |  10 +-
 .../analytics/value/CastingDoubleValueTest.java    |  18 +-
 .../value/CastingFloatValueStreamTest.java         |  14 +-
 .../analytics/value/CastingFloatValueTest.java     |  24 +-
 .../analytics/value/CastingIntValueStreamTest.java |  22 +-
 .../solr/analytics/value/CastingIntValueTest.java  |  36 +-
 .../value/CastingLongValueStreamTest.java          |  14 +-
 .../solr/analytics/value/CastingLongValueTest.java |  24 +-
 .../value/CastingStringValueStreamTest.java        |   6 +-
 .../analytics/value/CastingStringValueTest.java    |  12 +-
 .../solr/analytics/value/ConstantValueTest.java    |  40 +-
 .../solr/analytics/value/FillableTestValue.java    |  94 ++---
 .../handler/dataimport/TestXPathRecordReader.java  |  26 +-
 solr/core/src/java/org/apache/solr/api/ApiBag.java |   5 +-
 .../src/java/org/apache/solr/core/SolrConfig.java  |   9 +-
 .../org/apache/solr/core/SolrResourceLoader.java   |  26 ++
 .../java/org/apache/solr/handler/FilesStream.java  | 262 +++++++++++++
 .../solr/handler/SolrDefaultStreamFactory.java     |   1 +
 .../solr/handler/component/ResponseBuilder.java    |  42 ++-
 .../java/org/apache/solr/search/CacheConfig.java   | 168 ++++-----
 .../org/apache/solr/search/SolrCacheHolder.java    | 142 +++++++
 .../apache/solr/search/SolrDocumentFetcher.java    |   3 +-
 .../org/apache/solr/search/SolrIndexSearcher.java  |  28 +-
 .../apache/solr/servlet/SolrDispatchFilter.java    |   6 +-
 .../solr/collection1/conf/bad-mpf-solrconfig.xml   |   2 +-
 .../solr/configsets/_default/conf/solrconfig.xml   |  16 +-
 .../cloud/api/collections/SplitByPrefixTest.java   |   2 +
 .../test/org/apache/solr/cloud/rule/RulesTest.java | 172 +++++++--
 .../apache/solr/core/TestSolrConfigHandler.java    |   6 +-
 .../solr/handler/TestContainerReqHandler.java      |   3 +-
 .../handler/component/ResponseBuilderTest.java     |  31 +-
 .../test/org/apache/solr/search/TestLFUCache.java  |   6 +-
 .../solr/security/BasicAuthIntegrationTest.java    |   4 +-
 .../org/apache/solr/update/DummyMergePolicy.java   |  33 --
 .../apache/solr/update/SolrIndexConfigTest.java    |  21 +-
 .../solr/configsets/_default/conf/solrconfig.xml   |  16 +-
 .../conf/solrconfig.xml                            |   2 +
 solr/solr-ref-guide/src/analytics.adoc             |   4 +-
 .../src/stream-source-reference.adoc               |  27 ++
 .../java/org/apache/solr/client/solrj/io/Lang.java |   9 +-
 .../solr/client/solrj/io/eval/ConcatEvaluator.java |  63 ++++
 .../solr/client/solrj/io/eval/DateEvaluator.java   |  73 ++++
 ...owLabelsEvaluator.java => DoubleEvaluator.java} |  35 +-
 ...tRowLabelsEvaluator.java => LongEvaluator.java} |  35 +-
 .../client/solrj/io/eval/RecursiveEvaluator.java   |  21 ++
 .../solrj/io/eval/RecursiveNumericEvaluator.java   |  11 +-
 .../io/eval/RecursiveNumericListEvaluator.java     |   2 +
 .../solrj/io/eval/SetColumnLabelsEvaluator.java    |  12 +-
 .../solrj/io/eval/SetRowLabelsEvaluator.java       |  14 +-
 .../solr/client/solrj/io/eval/UuidEvaluator.java   |   2 +-
 .../solr/client/solrj/io/stream/CsvStream.java     | 172 +++++++++
 .../solr/client/solrj/io/stream/SolrStream.java    |  12 +
 .../solr/client/solrj/io/stream/TsvStream.java     |  81 ++++
 .../org/apache/solr/client/solrj/io/TestLang.java  |   2 +-
 .../client/solrj/io/stream/MathExpressionTest.java | 117 ++++++
 .../solrj/io/stream/StreamDecoratorTest.java       |  67 ++++
 .../solrj/io/stream/StreamExpressionTest.java      | 176 ++++++++-
 .../io/stream/eval/AbsoluteValueEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/AddEvaluatorTest.java     |   7 +-
 .../io/stream/eval/ArcCosineEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/ArcSineEvaluatorTest.java |   4 +-
 .../io/stream/eval/ArcTangentEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/CeilingEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/CosineEvaluatorTest.java  |   4 +-
 .../io/stream/eval/CubedRootEvaluatorTest.java     |   4 +-
 .../solrj/io/stream/eval/DivideEvaluatorTest.java  |  10 +-
 .../solrj/io/stream/eval/FloorEvaluatorTest.java   |   4 +-
 .../stream/eval/HyperbolicCosineEvaluatorTest.java |   4 +-
 .../stream/eval/HyperbolicSineEvaluatorTest.java   |   4 +-
 .../eval/HyperbolicTangentEvaluatorTest.java       |   4 +-
 .../solrj/io/stream/eval/ModuloEvaluatorTest.java  |  10 +-
 .../io/stream/eval/MultiplyEvaluatorTest.java      |   7 +-
 .../io/stream/eval/NaturalLogEvaluatorTest.java    |   4 +-
 .../solrj/io/stream/eval/PowerEvaluatorTest.java   |   2 +-
 .../solrj/io/stream/eval/RoundEvaluatorTest.java   |   4 +-
 .../solrj/io/stream/eval/SineEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SquareRootEvaluatorTest.java    |   4 +-
 .../io/stream/eval/SubtractEvaluatorTest.java      |   6 +-
 .../solrj/io/stream/eval/TangentEvaluatorTest.java |   4 +-
 .../solrj/io/stream/eval/UuidEvaluatorTest.java    |  13 +-
 .../solr/cloud/AbstractFullDistribZkTestBase.java  |  51 ++-
 439 files changed, 6748 insertions(+), 5282 deletions(-)



[lucene-solr] 10/36: Merge branch 'master' into jira/solr-13579

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13579
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit d38973f09a89f2d22c7c18221729c108e0db0d0d
Merge: 6f2ccb2 26ede63
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jul 16 11:56:02 2019 +0200

    Merge branch 'master' into jira/solr-13579

 dev-tools/scripts/releaseWizard.yaml               |  10 +-
 lucene/CHANGES.txt                                 |  26 +-
 lucene/analysis/nori/build.xml                     |   4 +-
 .../lucene/analysis/ko/dict/BinaryDictionary.java  |  60 +-
 .../analysis/ko/dict/TokenInfoDictionary.java      |  15 +-
 .../analysis/ko/util/BinaryDictionaryWriter.java   |  31 +-
 .../ko/util/TokenInfoDictionaryBuilder.java        |   3 +-
 .../analysis/ko/dict/TokenInfoDictionaryTest.java  |  80 +++
 .../analysis/ko/dict/UnknownDictionaryTest.java    |  26 +-
 .../codecs/simpletext/SimpleTextBKDWriter.java     |  31 +-
 .../codecs/lucene50/Lucene50PostingsReader.java    | 528 ++++++++---------
 .../org/apache/lucene/document/FeatureField.java   |   2 +-
 .../apache/lucene/document/FeatureSortField.java   |   8 +-
 .../src/java/org/apache/lucene/geo/EdgeTree.java   |   2 +
 .../src/java/org/apache/lucene/geo/Polygon2D.java  |  12 +-
 .../java/org/apache/lucene/index/MultiSorter.java  | 161 +-----
 .../apache/lucene/search/ExactPhraseMatcher.java   | 209 ++++++-
 .../org/apache/lucene/search/MultiPhraseQuery.java |  10 +-
 .../org/apache/lucene/search/PhraseMatcher.java    |  15 +-
 .../java/org/apache/lucene/search/PhraseQuery.java |  28 +-
 .../org/apache/lucene/search/PhraseScorer.java     |  18 +-
 .../org/apache/lucene/search/PhraseWeight.java     |  12 +-
 .../apache/lucene/search/SloppyPhraseMatcher.java  |  60 +-
 .../apache/lucene/util/bkd/BKDRadixSelector.java   | 140 +++--
 .../java/org/apache/lucene/util/bkd/BKDWriter.java |  33 +-
 .../apache/lucene/util/bkd/HeapPointReader.java    |  39 +-
 .../apache/lucene/util/bkd/HeapPointWriter.java    |  50 +-
 .../lucene/util/bkd/MutablePointsReaderUtils.java  |  53 +-
 .../apache/lucene/util/bkd/OfflinePointReader.java |  22 +-
 .../apache/lucene/util/bkd/OfflinePointWriter.java |   9 +-
 .../org/apache/lucene/util/bkd/PointValue.java     |   7 +-
 .../src/java/org/apache/lucene/util/fst/Util.java  |   1 +
 .../apache/lucene/document/TestFeatureSort.java    |  66 ++-
 .../org/apache/lucene/index/TestCustomNorms.java   |   2 +-
 .../org/apache/lucene/search/TestPhraseQuery.java  | 312 +++++++++-
 .../test/org/apache/lucene/util/bkd/TestBKD.java   |  74 +++
 .../lucene/util/bkd/TestBKDRadixSelector.java      |  68 ++-
 .../apache/lucene/util/bkd/TestBKDRadixSort.java   |   7 +-
 .../util/bkd/TestMutablePointsReaderUtils.java     | 112 ++--
 .../org/apache/lucene/monitor/package-info.java    |   4 +-
 .../queries/intervals/TermIntervalsSource.java     |   4 +-
 .../org/apache/lucene/document/LatLonShape.java    | 311 +---------
 .../document/LatLonShapeBoundingBoxQuery.java      |  13 +-
 .../lucene/document/LatLonShapeLineQuery.java      |  10 +-
 .../lucene/document/LatLonShapePolygonQuery.java   |  13 +-
 .../org/apache/lucene/document/ShapeField.java     | 307 ++++++++++
 .../{LatLonShapeQuery.java => ShapeQuery.java}     |  61 +-
 .../java/org/apache/lucene/document/XYShape.java   | 103 ++++
 ...gBoxQuery.java => XYShapeBoundingBoxQuery.java} |  38 +-
 ...onShapeLineQuery.java => XYShapeLineQuery.java} |  56 +-
 ...ePolygonQuery.java => XYShapePolygonQuery.java} |  51 +-
 .../src/java/org/apache/lucene/geo/Line.java       |   4 +-
 .../src/java/org/apache/lucene/geo/Line2D.java     |  15 +-
 .../java/org/apache/lucene/geo/Rectangle2D.java    |  72 ++-
 .../java/org/apache/lucene/geo/Tessellator.java    | 168 ++++--
 .../org/apache/lucene/geo/XYEncodingUtils.java     |  74 +++
 .../src/java/org/apache/lucene/geo/XYLine.java     | 146 +++++
 .../src/java/org/apache/lucene/geo/XYPolygon.java  | 201 +++++++
 .../java/org/apache/lucene/geo/XYPolygon2D.java    |  44 ++
 .../java/org/apache/lucene/geo/XYRectangle.java    |  84 +++
 .../java/org/apache/lucene/geo/XYRectangle2D.java  |  57 ++
 .../search/LargeNumHitsTopDocsCollector.java       | 157 +++++
 .../lucene/document/BaseLatLonShapeTestCase.java   | 634 ++++-----------------
 .../lucene/document/BaseShapeEncodingTestCase.java | 573 +++++++++++++++++++
 ...onShapeTestCase.java => BaseShapeTestCase.java} | 424 +++++---------
 .../lucene/document/BaseXYShapeTestCase.java       | 232 ++++++++
 .../document/TestLatLonLineShapeQueries.java       |  23 +-
 .../document/TestLatLonMultiLineShapeQueries.java  |  29 +-
 .../document/TestLatLonMultiPointShapeQueries.java |  32 +-
 .../TestLatLonMultiPolygonShapeQueries.java        |  29 +-
 .../document/TestLatLonPointShapeQueries.java      |  27 +-
 .../document/TestLatLonPolygonShapeQueries.java    |  23 +-
 .../apache/lucene/document/TestLatLonShape.java    |  10 +-
 .../lucene/document/TestLatLonShapeEncoding.java   | 545 +-----------------
 ...apeQueries.java => TestXYLineShapeQueries.java} |  69 ++-
 ...eries.java => TestXYMultiLineShapeQueries.java} |  80 +--
 ...ries.java => TestXYMultiPointShapeQueries.java} |  37 +-
 ...es.java => TestXYMultiPolygonShapeQueries.java} |  58 +-
 ...peQueries.java => TestXYPointShapeQueries.java} |  55 +-
 ...Queries.java => TestXYPolygonShapeQueries.java} |  52 +-
 .../org/apache/lucene/document/TestXYShape.java    | 111 ++++
 .../lucene/document/TestXYShapeEncoding.java       |  65 +++
 .../test/org/apache/lucene/geo/ShapeTestUtil.java  | 208 +++++++
 .../src/test/org/apache/lucene/geo/TestLine2D.java |   2 +-
 .../org/apache/lucene/geo/TestTessellator.java     |   4 +-
 .../search/TestLargeNumHitsTopDocsCollector.java   | 158 +++++
 solr/CHANGES.txt                                   |  63 +-
 .../org/apache/solr/cloud/RecoveryStrategy.java    |  32 +-
 .../java/org/apache/solr/cloud/ZkController.java   |   3 +-
 .../cloud/api/collections/DeleteCollectionCmd.java |   5 +-
 .../org/apache/solr/request/SolrRequestInfo.java   |  22 +-
 .../org/apache/solr/schema/AbstractEnumField.java  |  11 +-
 .../java/org/apache/solr/schema/TrieDateField.java |   2 +-
 .../org/apache/solr/security/KerberosFilter.java   |  58 +-
 .../org/apache/solr/security/KerberosPlugin.java   |  23 +-
 .../security/RuleBasedAuthorizationPlugin.java     |  18 +
 .../java/org/apache/solr/servlet/HttpSolrCall.java |  81 +--
 .../apache/solr/cloud/AliasIntegrationTest.java    |  31 +-
 .../org/apache/solr/cloud/DeleteReplicaTest.java   |  67 ++-
 .../solr/cloud/autoscaling/TestPolicyCloud.java    | 243 +++++---
 .../solr/handler/component/StatsComponentTest.java |   2 +-
 .../test/org/apache/solr/schema/DateFieldTest.java |   9 +
 .../solr/search/function/TestFunctionQuery.java    |   4 +
 .../src/major-changes-in-solr-8.adoc               |   2 +-
 .../src/solr-system-requirements.adoc              |   2 +-
 .../src/taking-solr-to-production.adoc             |   4 +-
 .../java/org/apache/solr/common/cloud/Aliases.java |  25 +-
 107 files changed, 5563 insertions(+), 2963 deletions(-)