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

adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new eb031df2ed HDDS-7648. Add a servername tag in UGI metrics. (#4094)
eb031df2ed is described below

commit eb031df2edfceaf4ecc60751b5a67c5f2049dfdb
Author: Mladjan Gadzic <[email protected]>
AuthorDate: Tue Jan 3 12:19:02 2023 +0100

    HDDS-7648. Add a servername tag in UGI metrics. (#4094)
---
 .../TestVolumeIOStatsWithPrometheusSink.java       |   2 +-
 .../framework/dev-support/findbugsExcludeFile.xml  |   4 -
 .../hadoop/hdds/server/http/BaseHttpServer.java    |   2 +-
 .../hdds/server/http/PrometheusMetricsSink.java    |  82 +++-----
 .../hadoop/hdds/utils/DecayRpcSchedulerUtil.java   |  57 +++--
 .../hdds/utils/PrometheusMetricsSinkUtil.java      | 116 +++++++++++
 .../apache/hadoop/hdds/utils/UgiMetricsUtil.java   |  68 ++++++
 .../http/TestPrometheusMetricsIntegration.java     |   2 +-
 .../server/http/TestPrometheusMetricsSink.java     |  83 --------
 .../hdds/utils/TestDecayRpcSchedulerUtil.java      |  37 +++-
 .../hdds/utils/TestPrometheusMetricsSinkUtil.java  | 229 +++++++++++++++++++++
 .../hadoop/hdds/utils/TestUgiMetricsUtil.java      |  63 ++++++
 12 files changed, 568 insertions(+), 177 deletions(-)

diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeIOStatsWithPrometheusSink.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeIOStatsWithPrometheusSink.java
index 8600de5424..875f8ce636 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeIOStatsWithPrometheusSink.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/volume/TestVolumeIOStatsWithPrometheusSink.java
@@ -42,7 +42,7 @@ public class TestVolumeIOStatsWithPrometheusSink {
   public void init() {
     metrics = DefaultMetricsSystem.instance();
     metrics.init("test");
-    sink = new PrometheusMetricsSink();
+    sink = new PrometheusMetricsSink("random");
     metrics.register("Prometheus", "Prometheus", sink);
   }
 
diff --git a/hadoop-hdds/framework/dev-support/findbugsExcludeFile.xml 
b/hadoop-hdds/framework/dev-support/findbugsExcludeFile.xml
index 6251188ecc..a111802321 100644
--- a/hadoop-hdds/framework/dev-support/findbugsExcludeFile.xml
+++ b/hadoop-hdds/framework/dev-support/findbugsExcludeFile.xml
@@ -21,10 +21,6 @@
   </Match>
 
   <!-- Test -->
-  <Match>
-    <Class 
name="org.apache.hadoop.hdds.server.http.TestPrometheusMetricsSink"></Class>
-    <Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" />
-  </Match>
   <Match>
     <Class 
name="org.apache.hadoop.hdds.server.http.TestRatisDropwizardExports"></Class>
     <Bug pattern="DLS_DEAD_LOCAL_STORE" />
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
index 4315dcdd54..144cec8620 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java
@@ -148,7 +148,7 @@ public abstract class BaseHttpServer {
           conf.getBoolean(HddsConfigKeys.HDDS_PROFILER_ENABLED, false);
 
       if (prometheusSupport) {
-        prometheusMetricsSink = new PrometheusMetricsSink();
+        prometheusMetricsSink = new PrometheusMetricsSink(name);
         httpServer.getWebAppContext().getServletContext()
             .setAttribute(PROMETHEUS_SINK, prometheusMetricsSink);
         HddsPrometheusConfig prometheusConfig =
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/PrometheusMetricsSink.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/PrometheusMetricsSink.java
index 320f92efc7..a0bec87ea9 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/PrometheusMetricsSink.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/PrometheusMetricsSink.java
@@ -17,18 +17,14 @@
  */
 package org.apache.hadoop.hdds.server.http;
 
-import static 
org.apache.hadoop.hdds.utils.RocksDBStoreMBean.ROCKSDB_CONTEXT_PREFIX;
-
 import java.io.IOException;
 import java.io.Writer;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
-import java.util.List;
-import java.util.regex.Pattern;
 import org.apache.commons.configuration2.SubsetConfiguration;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.hadoop.hdds.utils.DecayRpcSchedulerUtil;
+import org.apache.hadoop.hdds.utils.PrometheusMetricsSinkUtil;
 import org.apache.hadoop.metrics2.AbstractMetric;
 import org.apache.hadoop.metrics2.MetricType;
 import org.apache.hadoop.metrics2.MetricsRecord;
@@ -49,14 +45,10 @@ public class PrometheusMetricsSink implements MetricsSink {
       Collections.synchronizedSortedMap(new TreeMap<>());
   private Map<String, Map<String, String>> nextMetricLines =
       Collections.synchronizedSortedMap(new TreeMap<>());
+  private final String servername;
 
-  private static final Pattern SPLIT_PATTERN =
-      Pattern.compile("(?<!(^|[A-Z_]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
-
-  private static final Pattern REPLACE_PATTERN =
-      Pattern.compile("[^a-zA-Z0-9]+");
-
-  public PrometheusMetricsSink() {
+  public PrometheusMetricsSink(String servername) {
+    this.servername = servername;
   }
 
   @Override
@@ -65,13 +57,16 @@ public class PrometheusMetricsSink implements MetricsSink {
       if (metric.type() == MetricType.COUNTER
           || metric.type() == MetricType.GAUGE) {
 
-        String metricName = DecayRpcSchedulerUtil
-            .splitMetricNameIfNeeded(metricsRecord.name(), metric.name());
+        String metricName =
+            PrometheusMetricsSinkUtil.getMetricName(metricsRecord.name(),
+                metric.name());
+
         // If there is no username this should be null
-        String username = DecayRpcSchedulerUtil
-            .checkMetricNameForUsername(metricsRecord.name(), metric.name());
+        String username =
+            PrometheusMetricsSinkUtil.getUsername(metricsRecord.name(),
+                metric.name());
 
-        String key = prometheusName(
+        String key = PrometheusMetricsSinkUtil.prometheusName(
             metricsRecord.name(), metricName);
 
         String prometheusMetricKeyAsString =
@@ -98,56 +93,31 @@ public class PrometheusMetricsSink implements MetricsSink {
         .append("{");
     String sep = "";
 
-    // tagListWithUsernameIfNeeded() checks if username is null.
-    // If it's not then it returns a list with the existing
-    // metric tags and a username tag.
-    List<MetricsTag> metricTagList = DecayRpcSchedulerUtil
-        .tagListWithUsernameIfNeeded(metricsRecord, username);
+    List<MetricsTag> metricsTags =
+        PrometheusMetricsSinkUtil.addTags(key, username, servername,
+            metricsRecord.tags());
 
     //add tags
-    for (MetricsTag tag : metricTagList) {
+    for (MetricsTag tag : metricsTags) {
       String tagName = tag.name().toLowerCase();
 
       //ignore specific tag which includes sub-hierarchy
-      if (!tagName.equals("numopenconnectionsperuser")) {
-        prometheusMetricKey.append(sep)
-            .append(tagName)
-            .append("=\"")
-            .append(tag.value())
-            .append("\"");
-        sep = ",";
+      if (tagName.equals("numopenconnectionsperuser")) {
+        continue;
       }
+
+      prometheusMetricKey.append(sep)
+          .append(tagName)
+          .append("=\"")
+          .append(tag.value())
+          .append("\"");
+      sep = ",";
     }
     prometheusMetricKey.append("}");
 
     return prometheusMetricKey.toString();
   }
 
-  /**
-   * Convert CamelCase based names to lower-case names where the separator
-   * is the underscore, to follow prometheus naming conventions.
-   */
-  public String prometheusName(String recordName,
-      String metricName) {
-
-    // RocksDB metric names already have underscores as delimiters,
-    // but record name is from DB file name and '.' (as in 'om.db') is invalid
-    if (StringUtils.isNotEmpty(recordName) &&
-        recordName.startsWith(ROCKSDB_CONTEXT_PREFIX)) {
-      return normalizeName(recordName) + "_" + metricName.toLowerCase();
-    }
-
-    String baseName = StringUtils.capitalize(recordName)
-        + StringUtils.capitalize(metricName);
-    return normalizeName(baseName);
-  }
-
-  public static String normalizeName(String baseName) {
-    String[] parts = SPLIT_PATTERN.split(baseName);
-    String result = String.join("_", parts).toLowerCase();
-    return REPLACE_PATTERN.matcher(result).replaceAll("_");
-  }
-
   @Override
   public void flush() {
     synchronized (this) {
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DecayRpcSchedulerUtil.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DecayRpcSchedulerUtil.java
index e0fe8be8a8..cfdf704016 100644
--- 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DecayRpcSchedulerUtil.java
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DecayRpcSchedulerUtil.java
@@ -18,13 +18,10 @@
 package org.apache.hadoop.hdds.utils;
 
 import com.google.common.base.Strings;
+import java.util.Optional;
 import org.apache.hadoop.metrics2.MetricsInfo;
-import org.apache.hadoop.metrics2.MetricsRecord;
 import org.apache.hadoop.metrics2.MetricsTag;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Helper functions for DecayRpcScheduler
  * metrics for Prometheus.
@@ -34,25 +31,13 @@ public final class DecayRpcSchedulerUtil {
   private DecayRpcSchedulerUtil() {
   }
 
-  private static final MetricsInfo USERNAME_INFO = new MetricsInfo() {
-    @Override
-    public String name() {
-      return "username";
-    }
-
-    @Override
-    public String description() {
-      return "caller username";
-    }
-  };
-
   /**
    * For Decay_Rpc_Scheduler, the metric name is in format
    * "Caller(<callers_username>).Volume"
    * or
    * "Caller(<callers_username>).Priority"
    * Split it and return the metric.
-   *
+   * <p>
    * If the recordName doesn't belong to Decay_Rpc_Scheduler,
    * then return the metricName as it is without making
    * any changes to it.
@@ -78,6 +63,7 @@ public final class DecayRpcSchedulerUtil {
    * For Decay_Rpc_Scheduler, split the metric name
    * and then get the part that is in the format "Caller(<callers_username>)"
    * and split it to return the username.
+   *
    * @param recordName
    * @param metricName
    * @return caller username or null if not present
@@ -102,20 +88,33 @@ public final class DecayRpcSchedulerUtil {
     return null;
   }
 
+
   /**
-   * MetricRecord.tags() is an unmodifiable collection of tags.
-   * Store it in a list, to modify it and add a username tag.
-   * @param metricsRecord
-   * @return the new list with the metric tags and the username tag
+   * Create a <tt>username</tt> metrics tag.
+   * @param username caller username
+   * @return empty optional if no metrics tag was created, otherwise
+   * optional of metrics tag.
    */
-  public static List<MetricsTag> tagListWithUsernameIfNeeded(
-      MetricsRecord metricsRecord, String username) {
-    List<MetricsTag> list = new ArrayList<>(metricsRecord.tags());
-
-    if (!Strings.isNullOrEmpty(username)) {
-      MetricsTag tag = new MetricsTag(USERNAME_INFO, username);
-      list.add(tag);
+  public static Optional<MetricsTag> createUsernameTag(String username) {
+    if (Strings.isNullOrEmpty(username)) {
+      return Optional.empty();
     }
-    return list;
+
+    final String name = "username";
+    final String description = "caller username";
+    final MetricsInfo metricsInfo = new MetricsInfo() {
+      @Override
+      public String name() {
+        return name;
+      }
+
+      @Override
+      public String description() {
+        return description;
+      }
+    };
+    MetricsTag metricsTag = new MetricsTag(metricsInfo, username);
+    return Optional.of(metricsTag);
   }
+
 }
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/PrometheusMetricsSinkUtil.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/PrometheusMetricsSinkUtil.java
new file mode 100644
index 0000000000..44ccb5397b
--- /dev/null
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/PrometheusMetricsSinkUtil.java
@@ -0,0 +1,116 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.hdds.utils;
+
+import static 
org.apache.hadoop.hdds.utils.RocksDBStoreMBean.ROCKSDB_CONTEXT_PREFIX;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.metrics2.MetricsTag;
+
+/**
+ * Util class for
+ * {@link org.apache.hadoop.hdds.server.http.PrometheusMetricsSink}.
+ */
+public final class PrometheusMetricsSinkUtil {
+  private static final Pattern SPLIT_PATTERN =
+      Pattern.compile("(?<!(^|[A-Z_]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
+  private static final Pattern REPLACE_PATTERN =
+      Pattern.compile("[^a-zA-Z0-9]+");
+
+  /**
+   * Never constructed.
+   */
+  private PrometheusMetricsSinkUtil() {
+  }
+
+  /**
+   * Adds necessary tags.
+   *
+   * @param key              metrics entry key
+   * @param username         caller username
+   * @param servername       servername
+   * @param unmodifiableTags list of metrics tags
+   * @return modifiable list of metrics tags
+   */
+  public static List<MetricsTag> addTags(String key, String username,
+      String servername, Collection<MetricsTag> unmodifiableTags) {
+    List<MetricsTag> metricTags = new ArrayList<>(unmodifiableTags);
+
+    Stream.of(DecayRpcSchedulerUtil.createUsernameTag(username),
+            UgiMetricsUtil.createServernameTag(key, servername))
+        .forEach(
+            metricsTag -> metricsTag.ifPresent(mt -> addTag(mt, metricTags)));
+
+    return metricTags;
+  }
+
+  /**
+   * Adds metric tag to a metrics tags.
+   * @param metricsTag metrics tag to be added
+   * @param metricsTags metrics tags where metrics tag needs to be added
+   */
+  private static void addTag(MetricsTag metricsTag,
+      List<MetricsTag> metricsTags) {
+    metricsTags.add(metricsTag);
+  }
+
+  /**
+   * Convert CamelCase based names to lower-case names where the separator
+   * is the underscore, to follow prometheus naming conventions.
+   */
+  public static String prometheusName(String recordName,
+      String metricName) {
+
+    // RocksDB metric names already have underscores as delimiters,
+    // but record name is from DB file name and '.' (as in 'om.db') is invalid
+    if (StringUtils.isNotEmpty(recordName) &&
+        recordName.startsWith(ROCKSDB_CONTEXT_PREFIX)) {
+      return normalizeName(recordName) + "_" + metricName.toLowerCase();
+    }
+
+    String baseName = StringUtils.capitalize(recordName)
+        + StringUtils.capitalize(metricName);
+    return normalizeName(baseName);
+  }
+
+  /**
+   * Normalizes metrics tag key name.
+   * @param baseName
+   * @return normalized name.
+   */
+  private static String normalizeName(String baseName) {
+    String[] parts = SPLIT_PATTERN.split(baseName);
+    String result = String.join("_", parts).toLowerCase();
+    return REPLACE_PATTERN.matcher(result).replaceAll("_");
+  }
+
+  public static String getMetricName(String recordName, String metricName) {
+    return DecayRpcSchedulerUtil.splitMetricNameIfNeeded(recordName,
+        metricName);
+  }
+
+  public static String getUsername(String recordName, String metricName) {
+    return DecayRpcSchedulerUtil.checkMetricNameForUsername(recordName,
+        metricName);
+  }
+}
diff --git 
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/UgiMetricsUtil.java
 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/UgiMetricsUtil.java
new file mode 100644
index 0000000000..60edf3c982
--- /dev/null
+++ 
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/UgiMetricsUtil.java
@@ -0,0 +1,68 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.hdds.utils;
+
+import java.util.Optional;
+import org.apache.hadoop.metrics2.MetricsInfo;
+import org.apache.hadoop.metrics2.MetricsTag;
+
+/**
+ * Util class for UGI metrics.
+ */
+public final class UgiMetricsUtil {
+
+  private static final String UGI_METRICS = "ugi_metrics";
+
+  /**
+   * Never constructed.
+   */
+  private UgiMetricsUtil() {
+  }
+
+  /**
+   * Creates servername metrics tag.
+   *
+   * @param key        metrics entry key
+   * @param servername server name
+   * @return empty optional if no metrics tag was created, otherwise
+   * optional of metrics tag.
+   */
+  public static Optional<MetricsTag> createServernameTag(String key,
+      String servername) {
+    if (!key.contains(UGI_METRICS)) {
+      return Optional.empty();
+    }
+
+    final String name = "servername";
+    final String description = "name of the server";
+    final MetricsInfo metricsInfo = new MetricsInfo() {
+      @Override
+      public String name() {
+        return name;
+      }
+
+      @Override
+      public String description() {
+        return description;
+      }
+    };
+    MetricsTag metricsTag = new MetricsTag(metricsInfo, servername);
+    return Optional.of(metricsTag);
+  }
+
+}
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsIntegration.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsIntegration.java
index bc2ccef57d..5243dfda51 100644
--- 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsIntegration.java
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsIntegration.java
@@ -79,7 +79,7 @@ public class TestPrometheusMetricsIntegration {
     metrics = DefaultMetricsSystem.instance();
 
     metrics.init("test");
-    sink = new PrometheusMetricsSink();
+    sink = new PrometheusMetricsSink("random");
     metrics.register("Prometheus", "Prometheus", sink);
   }
 
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsSink.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsSink.java
deleted file mode 100644
index dc15d805d6..0000000000
--- 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/server/http/TestPrometheusMetricsSink.java
+++ /dev/null
@@ -1,83 +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.hadoop.hdds.server.http;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-/**
- * Test prometheus Sink.
- */
-public class TestPrometheusMetricsSink {
-
-  private static PrometheusMetricsSink sink;
-
-  @BeforeAll
-  public static void setUp() {
-    sink = new PrometheusMetricsSink();
-  }
-
-  @Test
-  public void testNamingCamelCase() {
-    //THEN
-    Assertions.assertEquals("rpc_time_some_metrics",
-        sink.prometheusName("RpcTime", "SomeMetrics"));
-
-    Assertions.assertEquals("om_rpc_time_om_info_keys",
-        sink.prometheusName("OMRpcTime", "OMInfoKeys"));
-
-    Assertions.assertEquals("rpc_time_small",
-        sink.prometheusName("RpcTime", "small"));
-  }
-
-  @Test
-  public void testNamingRocksDB() {
-    //RocksDB metrics are handled differently.
-    // THEN
-    Assertions.assertEquals("rocksdb_om_db_num_open_connections",
-        sink.prometheusName("Rocksdb_om.db", "num_open_connections"));
-  }
-
-  @Test
-  public void testNamingPipeline() {
-    // GIVEN
-    String recordName = "SCMPipelineMetrics";
-    String metricName = "NumBlocksAllocated-"
-        + "RATIS-THREE-47659e3d-40c9-43b3-9792-4982fc279aba";
-
-    // THEN
-    Assertions.assertEquals(
-        "scm_pipeline_metrics_"
-            + "num_blocks_allocated_"
-            + "ratis_three_47659e3d_40c9_43b3_9792_4982fc279aba",
-        sink.prometheusName(recordName, metricName));
-  }
-
-  @Test
-  public void testNamingSpaces() {
-    //GIVEN
-    String recordName = "JvmMetrics";
-    String metricName = "GcTimeMillisG1 Young Generation";
-
-    // THEN
-    Assertions.assertEquals(
-        "jvm_metrics_gc_time_millis_g1_young_generation",
-        sink.prometheusName(recordName, metricName));
-  }
-}
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestDecayRpcSchedulerUtil.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestDecayRpcSchedulerUtil.java
index b3ccbafca6..f84e6ce068 100644
--- 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestDecayRpcSchedulerUtil.java
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestDecayRpcSchedulerUtil.java
@@ -19,6 +19,9 @@
 
 package org.apache.hadoop.hdds.utils;
 
+import java.util.Optional;
+import org.apache.hadoop.metrics2.MetricsTag;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -41,7 +44,7 @@ public class TestDecayRpcSchedulerUtil {
   private static final String RANDOM_METRIC_NAME = "ThreadsNew";
 
   @Test
-  public void testSplitMetricNameIfNeeded() {
+  void testSplitMetricNameIfNeeded() {
     // Split the metric name and return only the
     // name of the metric type.
     String splitName = DecayRpcSchedulerUtil
@@ -57,7 +60,7 @@ public class TestDecayRpcSchedulerUtil {
   }
 
   @Test
-  public void testCheckMetricNameForUsername() {
+  void testCheckMetricNameForUsername() {
     // Get the username from the metric name.
     String decayRpcSchedulerUsername = DecayRpcSchedulerUtil
         .checkMetricNameForUsername(RECORD_NAME, METRIC_NAME);
@@ -72,4 +75,34 @@ public class TestDecayRpcSchedulerUtil {
 
     assertNull(nullUsername);
   }
+
+  @Test
+  void testCreateUsernameTagWithNullUsername() {
+    // GIVEN
+    final String username = null;
+
+    // WHEN
+    Optional<MetricsTag> optionalMetricsTag =
+        DecayRpcSchedulerUtil.createUsernameTag(username);
+
+    // THEN
+    Assertions.assertFalse(optionalMetricsTag.isPresent());
+  }
+
+  @Test
+  void testCreateUsernameTagWithNotNullUsername() {
+    // GIVEN
+    final String username = "username";
+
+    // WHEN
+    Optional<MetricsTag> optionalMetricsTag =
+        DecayRpcSchedulerUtil.createUsernameTag(username);
+
+    // THEN
+    Assertions.assertTrue(optionalMetricsTag.isPresent());
+    Assertions.assertEquals(username, optionalMetricsTag.get().value());
+    Assertions.assertEquals(username, optionalMetricsTag.get().name());
+    Assertions.assertEquals("caller username",
+        optionalMetricsTag.get().description());
+  }
 }
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestPrometheusMetricsSinkUtil.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestPrometheusMetricsSinkUtil.java
new file mode 100644
index 0000000000..ef64bbb6e8
--- /dev/null
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestPrometheusMetricsSinkUtil.java
@@ -0,0 +1,229 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.hdds.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.hadoop.metrics2.MetricsTag;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Class for unit tests for {@link PrometheusMetricsSinkUtil}.
+ */
+class TestPrometheusMetricsSinkUtil {
+
+  private static final String USERNAME_TAG_NAME = "username";
+  private static final String USERNAME_TAG_DESCRIPTION = "caller username";
+  private static final String SERVERNAME_TAG_NAME = "servername";
+  private static final String SERVERNAME_TAG_DESCRIPTION = "name of the 
server";
+
+  @Test
+  void testAddTagsAddUsernameTagWithNullUsername() {
+    // GIVEN
+    final String key = "key";
+    final String username = null;
+    final String servername = null;
+    Collection<MetricsTag> unmodifiableMetricTags =
+        Collections.unmodifiableList(new ArrayList<>());
+
+    // WHEN
+    List<MetricsTag> metricsTags = PrometheusMetricsSinkUtil.addTags(key,
+        username, servername, unmodifiableMetricTags);
+
+    // THEN
+    Assertions.assertFalse(metricsTags.stream()
+        .anyMatch(metricsTag -> metricsTag.name().equals(USERNAME_TAG_NAME) ||
+            metricsTag.description().equals(USERNAME_TAG_DESCRIPTION)));
+  }
+
+  @Test
+  void testAddTagsAddUsernameTagWithEmptyUsername() {
+    // GIVEN
+    final String key = "key";
+    final String username = "";
+    final String servername = null;
+    Collection<MetricsTag> unmodifiableMetricTags =
+        Collections.unmodifiableList(new ArrayList<>());
+
+    // WHEN
+    List<MetricsTag> metricsTags = PrometheusMetricsSinkUtil.addTags(key,
+        username, servername, unmodifiableMetricTags);
+
+    // THEN
+    Assertions.assertFalse(metricsTags.stream()
+        .anyMatch(metricsTag -> metricsTag.name().equals(USERNAME_TAG_NAME) ||
+            metricsTag.description().equals(USERNAME_TAG_DESCRIPTION)));
+  }
+
+  @Test
+  void testAddTagsAddUsernameTagWithUsername() {
+    // GIVEN
+    final String key = "key";
+    final String username = "username";
+    final String servername = null;
+    Collection<MetricsTag> unmodifiableMetricTags =
+        Collections.unmodifiableList(new ArrayList<>());
+
+    // WHEN
+    List<MetricsTag> metricsTags = PrometheusMetricsSinkUtil.addTags(key,
+        username, servername, unmodifiableMetricTags);
+
+    // THEN
+    Assertions.assertTrue(metricsTags.stream()
+        .anyMatch(metricsTag -> metricsTag.name().equals(USERNAME_TAG_NAME) &&
+            metricsTag.description().equals(USERNAME_TAG_DESCRIPTION)));
+  }
+
+  @Test
+  void testAddTagsAddServernameTagWithNoUgiMetricsKey() {
+    // GIVEN
+    final String key = "key";
+    final String username = null;
+    final String servername = "SERVERNAME";
+    Collection<MetricsTag> unmodifiableMetricTags =
+        Collections.unmodifiableList(new ArrayList<>());
+
+    // WHEN
+    List<MetricsTag> metricsTags = PrometheusMetricsSinkUtil.addTags(key,
+        username, servername, unmodifiableMetricTags);
+
+    // THEN
+    Assertions.assertFalse(metricsTags.stream()
+        .anyMatch(metricsTag -> metricsTag.name().equals(SERVERNAME_TAG_NAME) 
||
+            metricsTag.description().equals(SERVERNAME_TAG_DESCRIPTION)));
+  }
+
+  @Test
+  void testAddTagsAddServernameTagWithUgiMetricsKey() {
+    // GIVEN
+    final String key = "ugi_metrics";
+    final String username = null;
+    final String servername = "SERVERNAME";
+    Collection<MetricsTag> unmodifiableMetricTags =
+        Collections.unmodifiableList(new ArrayList<>());
+
+    // WHEN
+    List<MetricsTag> metricsTags = PrometheusMetricsSinkUtil.addTags(key,
+        username, servername, unmodifiableMetricTags);
+
+    // THEN
+    Assertions.assertTrue(metricsTags.stream()
+        .anyMatch(metricsTag -> metricsTag.name().equals(SERVERNAME_TAG_NAME) 
&&
+            metricsTag.description().equals(SERVERNAME_TAG_DESCRIPTION)));
+  }
+
+  @Test
+  void testAddTags() {
+    // GIVEN
+    final String key = "ugi_metrics";
+    final String username = "username";
+    final String servername = "SERVERNAME";
+    Collection<MetricsTag> unmodifiableMetricTags =
+        Collections.unmodifiableList(new ArrayList<>());
+
+    // WHEN
+    List<MetricsTag> metricsTags = PrometheusMetricsSinkUtil.addTags(key,
+        username, servername, unmodifiableMetricTags);
+
+    // THEN
+    Assertions.assertTrue(metricsTags.stream()
+        .anyMatch(metricsTag -> metricsTag.name().equals(USERNAME_TAG_NAME)));
+    Assertions.assertTrue(metricsTags.stream()
+        .anyMatch(metricsTag -> 
metricsTag.name().equals(SERVERNAME_TAG_NAME)));
+  }
+
+  @Test
+  void testNamingCamelCase() {
+    //THEN
+    Assertions.assertEquals("rpc_time_some_metrics",
+        PrometheusMetricsSinkUtil.prometheusName("RpcTime", "SomeMetrics"));
+
+    Assertions.assertEquals("om_rpc_time_om_info_keys",
+        PrometheusMetricsSinkUtil.prometheusName("OMRpcTime", "OMInfoKeys"));
+
+    Assertions.assertEquals("rpc_time_small",
+        PrometheusMetricsSinkUtil.prometheusName("RpcTime", "small"));
+  }
+
+  @Test
+  void testNamingRocksDB() {
+    //RocksDB metrics are handled differently.
+    // THEN
+    Assertions.assertEquals("rocksdb_om_db_num_open_connections",
+        PrometheusMetricsSinkUtil.prometheusName("Rocksdb_om.db",
+            "num_open_connections"));
+  }
+
+  @Test
+  void testNamingPipeline() {
+    // GIVEN
+    String recordName = "SCMPipelineMetrics";
+    String metricName = "NumBlocksAllocated-"
+        + "RATIS-THREE-47659e3d-40c9-43b3-9792-4982fc279aba";
+
+    // THEN
+    Assertions.assertEquals(
+        "scm_pipeline_metrics_" + "num_blocks_allocated_"
+            + "ratis_three_47659e3d_40c9_43b3_9792_4982fc279aba",
+        PrometheusMetricsSinkUtil.prometheusName(recordName, metricName));
+  }
+
+  @Test
+  void testNamingSpaces() {
+    //GIVEN
+    String recordName = "JvmMetrics";
+    String metricName = "GcTimeMillisG1 Young Generation";
+
+    // THEN
+    Assertions.assertEquals(
+        "jvm_metrics_gc_time_millis_g1_young_generation",
+        PrometheusMetricsSinkUtil.prometheusName(recordName, metricName));
+  }
+
+  @Test
+  void testGetMetricName() {
+    // GIVEN
+    final String recordName = "record_name";
+    final String metricName = "metric_name";
+
+    // WHEN
+    String newMetricName = PrometheusMetricsSinkUtil.getMetricName(recordName,
+        metricName);
+
+    // THEN
+    Assertions.assertEquals(metricName, newMetricName);
+  }
+
+  @Test
+  void testGetUsername() {
+    // GIVEN
+    final String recordName = "record_name";
+    final String metricName = "metric_name";
+
+    // WHEN
+    String username = PrometheusMetricsSinkUtil.getUsername(recordName,
+        metricName);
+
+    // THEN
+    Assertions.assertNull(username);
+  }
+
+}
\ No newline at end of file
diff --git 
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestUgiMetricsUtil.java
 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestUgiMetricsUtil.java
new file mode 100644
index 0000000000..75ee8cd694
--- /dev/null
+++ 
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/TestUgiMetricsUtil.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.hadoop.hdds.utils;
+
+import java.util.Optional;
+import org.apache.hadoop.metrics2.MetricsTag;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Class for unit tests for {@link UgiMetricsUtil}.
+ */
+class TestUgiMetricsUtil {
+
+  @Test
+  void testCreateServernameTagWithNonCompatibleKey() {
+    // GIVEN
+    final String key = "non_ugi";
+    final String servername = "servername";
+
+    // WHEN
+    Optional<MetricsTag> optionalMetricsTag =
+        UgiMetricsUtil.createServernameTag(key, servername);
+
+    // THEN
+    Assertions.assertFalse(optionalMetricsTag.isPresent());
+  }
+
+  @Test
+  void testCreateServernameTagWithCompatibleKey() {
+    // GIVEN
+    final String key = "ugi_metrics";
+    final String servername = "servername";
+
+    // WHEN
+    Optional<MetricsTag> optionalMetricsTag =
+        UgiMetricsUtil.createServernameTag(key, servername);
+
+    // THEN
+    Assertions.assertTrue(optionalMetricsTag.isPresent());
+    Assertions.assertEquals(servername, optionalMetricsTag.get().value());
+    Assertions.assertEquals(servername, optionalMetricsTag.get().name());
+    Assertions.assertEquals("name of the server",
+        optionalMetricsTag.get().description());
+  }
+
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to