Fix 'invalid metric name' error

MetricMaker only allows certain characters to be used when registering a
new metric name, raising an 'IllegalArgumentException' when the provided
metric contains invalid characters.

This in turns prevents the chronicle-map cache from being created.

Sanitize the name of the cache before registering the new metric, so
that invalid characters are replaced by '_'.

Bug: Issue 14098
Change-Id: Id62a0755245179c8d27f67a4a4c99b5f32bbeb72
diff --git a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java
index e85e553..311445b 100644
--- a/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java
+++ b/src/main/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheImpl.java
@@ -118,10 +118,13 @@
 
     <K, V> void registerCallBackMetrics(
         String name, ChronicleMap<K, TimedValue<V>> store, InMemoryLRU<K> hotEntries) {
-      String PERCENTAGE_FREE_SPACE_METRIC = "cache/chroniclemap/percentage_free_space_" + name;
-      String REMAINING_AUTORESIZES_METRIC = "cache/chroniclemap/remaining_autoresizes_" + name;
-      String HOT_KEYS_CAPACITY_METRIC = "cache/chroniclemap/hot_keys_capacity_" + name;
-      String HOT_KEYS_SIZE_METRIC = "cache/chroniclemap/hot_keys_size_" + name;
+      String sanitizedName = metricMaker.sanitizeMetricName(name);
+      String PERCENTAGE_FREE_SPACE_METRIC =
+          "cache/chroniclemap/percentage_free_space_" + sanitizedName;
+      String REMAINING_AUTORESIZES_METRIC =
+          "cache/chroniclemap/remaining_autoresizes_" + sanitizedName;
+      String HOT_KEYS_CAPACITY_METRIC = "cache/chroniclemap/hot_keys_capacity_" + sanitizedName;
+      String HOT_KEYS_SIZE_METRIC = "cache/chroniclemap/hot_keys_size_" + sanitizedName;
 
       metricMaker.newCallbackMetric(
           PERCENTAGE_FREE_SPACE_METRIC,
diff --git a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java
index f8ef939..e8c1f4a 100644
--- a/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java
+++ b/src/test/java/com/googlesource/gerrit/modules/cache/chroniclemap/ChronicleMapCacheTest.java
@@ -469,6 +469,23 @@
         () -> (int) getMetric(hotKeysSizeMetricName).getValue() == 0, METRIC_TRIGGER_TIMEOUT);
   }
 
+  @Test
+  public void shouldSanitizeUnwantedCharsInMetricNames() throws Exception {
+    String cacheName = "very+confusing.cache#name";
+    String sanitized = "very_confusing_cache_name";
+    String hotKeySizeMetricName = "cache/chroniclemap/hot_keys_size_" + sanitized;
+    String percentageFreeMetricName = "cache/chroniclemap/percentage_free_space_" + sanitized;
+    String autoResizeMetricName = "cache/chroniclemap/remaining_autoresizes_" + sanitized;
+    String hotKeyCapacityMetricName = "cache/chroniclemap/hot_keys_capacity_" + sanitized;
+
+    newCacheWithMetrics(cacheName);
+
+    getMetric(hotKeySizeMetricName);
+    getMetric(percentageFreeMetricName);
+    getMetric(autoResizeMetricName);
+    getMetric(hotKeyCapacityMetricName);
+  }
+
   private int valueSize(String value) {
     final TimedValueMarshaller<String> marshaller =
         new TimedValueMarshaller<>(StringCacheSerializer.INSTANCE);