Repository: skiptests/astraea
Pull request #463 (2022-07-09 09:34:34)

Refactor metrics code
1. `KafkaMetrics`從`org.astraea.app.metrics.kafka`移動到`org.astraea.app.metrics`
2. `getAttributes` and `getProperties`的前綴字移除
3. `org.astraea.app.metrics.kafka`更名成`org.astraea.app.metrics.broker`
3. `org.astraea.app.metrics.java`更名成`org.astraea.app.metrics.platform`


Patch:
diff --git a/app/src/main/java/org/astraea/app/admin/ClusterBean.java b/app/src/main/java/org/astraea/app/admin/ClusterBean.java
index 63c5d667..788b7654 100644
--- a/app/src/main/java/org/astraea/app/admin/ClusterBean.java
+++ b/app/src/main/java/org/astraea/app/admin/ClusterBean.java
@@ -43,18 +43,18 @@ public interface ClusterBean {
                         .filter(
                             x ->
                                 x.beanObject() != null
-                                    && x.beanObject().getProperties().containsKey("topic")
-                                    && x.beanObject().getProperties().containsKey("partition"))
+                                    && x.beanObject().properties().containsKey("topic")
+                                    && x.beanObject().properties().containsKey("partition"))
                         .filter(
                             hasBeanObject ->
-                                hasBeanObject.beanObject().getProperties().containsKey("topic")
+                                hasBeanObject.beanObject().properties().containsKey("topic")
                                     && hasBeanObject
                                         .beanObject()
-                                        .getProperties()
+                                        .properties()
                                         .containsKey("partition"))
                         .map(
                             hasBeanObject -> {
-                              var properties = hasBeanObject.beanObject().getProperties();
+                              var properties = hasBeanObject.beanObject().properties();
                               var topic = properties.get("topic");
                               var partition = properties.get("partition");
                               return Map.entry(
@@ -71,11 +71,11 @@ public interface ClusterBean {
                         .filter(
                             x ->
                                 x.beanObject() != null
-                                    && x.beanObject().getProperties().containsKey("topic")
-                                    && x.beanObject().getProperties().containsKey("partition"))
+                                    && x.beanObject().properties().containsKey("topic")
+                                    && x.beanObject().properties().containsKey("partition"))
                         .map(
                             hasBeanObject -> {
-                              var properties = hasBeanObject.beanObject().getProperties();
+                              var properties = hasBeanObject.beanObject().properties();
                               var topic = properties.get("topic");
                               var partition = Integer.parseInt(properties.get("partition"));
                               return Map.entry(
diff --git a/app/src/main/java/org/astraea/app/cost/BrokerInputCost.java b/app/src/main/java/org/astraea/app/cost/BrokerInputCost.java
index f2825623..3103fd0a 100644
--- a/app/src/main/java/org/astraea/app/cost/BrokerInputCost.java
+++ b/app/src/main/java/org/astraea/app/cost/BrokerInputCost.java
@@ -22,9 +22,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 /**
  * The result is computed by "BytesInPerSec.count". "BytesInPerSec.count" responds to the input
@@ -53,7 +53,7 @@ public class BrokerInputCost implements HasBrokerCost {
                                 hasBeanObject ->
                                     KafkaMetrics.BrokerTopic.BytesInPerSec.metricName()
                                         .equals(
-                                            hasBeanObject.beanObject().getProperties().get("name")))
+                                            hasBeanObject.beanObject().properties().get("name")))
                             .findAny()
                             .orElseThrow()))
             .entrySet()
diff --git a/app/src/main/java/org/astraea/app/cost/BrokerOutputCost.java b/app/src/main/java/org/astraea/app/cost/BrokerOutputCost.java
index fee5a31e..43d8ea91 100644
--- a/app/src/main/java/org/astraea/app/cost/BrokerOutputCost.java
+++ b/app/src/main/java/org/astraea/app/cost/BrokerOutputCost.java
@@ -22,9 +22,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 /**
  * The result is computed by "BytesOutPerSec.count". "BytesOutPerSec.count" responds to the output
@@ -53,7 +53,7 @@ public class BrokerOutputCost implements HasBrokerCost {
                                 hasBeanObject ->
                                     KafkaMetrics.BrokerTopic.BytesOutPerSec.metricName()
                                         .equals(
-                                            hasBeanObject.beanObject().getProperties().get("name")))
+                                            hasBeanObject.beanObject().properties().get("name")))
                             .findAny()
                             .orElseThrow()))
             .entrySet()
diff --git a/app/src/main/java/org/astraea/app/cost/CpuCost.java b/app/src/main/java/org/astraea/app/cost/CpuCost.java
index 37d90138..a8b99954 100644
--- a/app/src/main/java/org/astraea/app/cost/CpuCost.java
+++ b/app/src/main/java/org/astraea/app/cost/CpuCost.java
@@ -22,9 +22,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.java.OperatingSystemInfo;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
+import org.astraea.app.metrics.platform.OperatingSystemInfo;
 
 /**
  * The result is computed by "OperatingSystemInfo.systemCpuLoad".
diff --git a/app/src/main/java/org/astraea/app/cost/LoadCost.java b/app/src/main/java/org/astraea/app/cost/LoadCost.java
index 6e2f9994..7605db4f 100644
--- a/app/src/main/java/org/astraea/app/cost/LoadCost.java
+++ b/app/src/main/java/org/astraea/app/cost/LoadCost.java
@@ -24,9 +24,9 @@ import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.partitioner.PartitionerUtils;
 
 public class LoadCost implements HasBrokerCost {
@@ -92,7 +92,7 @@ public class LoadCost implements HasBrokerCost {
                       brokersMetric
                           .get(brokerID)
                           .updateCount(
-                              result.beanObject().getProperties().get("name"), result.count()));
+                              result.beanObject().properties().get("name"), result.count()));
         });
 
     // Sum all count with the same mbean name
diff --git a/app/src/main/java/org/astraea/app/cost/MemoryCost.java b/app/src/main/java/org/astraea/app/cost/MemoryCost.java
index 5a33a9f8..1e4b4f69 100644
--- a/app/src/main/java/org/astraea/app/cost/MemoryCost.java
+++ b/app/src/main/java/org/astraea/app/cost/MemoryCost.java
@@ -22,9 +22,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.java.HasJvmMemory;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
+import org.astraea.app.metrics.platform.HasJvmMemory;
 
 public class MemoryCost extends Periodic<Map<Integer, Double>> implements HasBrokerCost {
   private final Map<Integer, BrokerMetric> brokersMetric = new HashMap<>();
diff --git a/app/src/main/java/org/astraea/app/cost/ReplicaDiskInCost.java b/app/src/main/java/org/astraea/app/cost/ReplicaDiskInCost.java
index eb6e25b9..28f7d59a 100644
--- a/app/src/main/java/org/astraea/app/cost/ReplicaDiskInCost.java
+++ b/app/src/main/java/org/astraea/app/cost/ReplicaDiskInCost.java
@@ -26,9 +26,9 @@ import java.util.stream.Collectors;
 import org.astraea.app.admin.TopicPartition;
 import org.astraea.app.admin.TopicPartitionReplica;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 /**
  * The result is computed by "Size.Value" ,and createdTimestamp in the metrics. "Size.Value"
@@ -201,8 +201,8 @@ public class ReplicaDiskInCost implements HasBrokerCost, HasPartitionCost {
               var sizeTimeSeries =
                   metrics.getValue().stream()
                       .filter(bean -> bean instanceof HasValue)
-                      .filter(bean -> bean.beanObject().getProperties().get("type").equals("Log"))
-                      .filter(bean -> bean.beanObject().getProperties().get("name").equals("Size"))
+                      .filter(bean -> bean.beanObject().properties().get("type").equals("Log"))
+                      .filter(bean -> bean.beanObject().properties().get("name").equals("Size"))
                       .map(bean -> (HasValue) bean)
                       .sorted(Comparator.comparingLong(HasBeanObject::createdTimestamp).reversed())
                       .collect(Collectors.toUnmodifiableList());
diff --git a/app/src/main/java/org/astraea/app/cost/ReplicaLeaderCost.java b/app/src/main/java/org/astraea/app/cost/ReplicaLeaderCost.java
index 9fe1a952..9c99c86d 100644
--- a/app/src/main/java/org/astraea/app/cost/ReplicaLeaderCost.java
+++ b/app/src/main/java/org/astraea/app/cost/ReplicaLeaderCost.java
@@ -21,9 +21,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 /** more replica leaders -> higher cost */
 public class ReplicaLeaderCost implements HasBrokerCost {
@@ -42,9 +42,8 @@ public class ReplicaLeaderCost implements HasBrokerCost {
             e ->
                 e.getValue().stream()
                     .filter(x -> x instanceof HasValue)
-                    .filter(x -> "LeaderCount".equals(x.beanObject().getProperties().get("name")))
-                    .filter(
-                        x -> "ReplicaManager".equals(x.beanObject().getProperties().get("type")))
+                    .filter(x -> "LeaderCount".equals(x.beanObject().properties().get("name")))
+                    .filter(x -> "ReplicaManager".equals(x.beanObject().properties().get("type")))
                     .sorted(Comparator.comparing(HasBeanObject::createdTimestamp).reversed())
                     .map(x -> (HasValue) x)
                     .limit(1)
diff --git a/app/src/main/java/org/astraea/app/cost/ReplicaSizeCost.java b/app/src/main/java/org/astraea/app/cost/ReplicaSizeCost.java
index 7d7e50fa..47ab2983 100644
--- a/app/src/main/java/org/astraea/app/cost/ReplicaSizeCost.java
+++ b/app/src/main/java/org/astraea/app/cost/ReplicaSizeCost.java
@@ -23,9 +23,9 @@ import java.util.TreeMap;
 import java.util.stream.Collectors;
 import org.astraea.app.admin.TopicPartition;
 import org.astraea.app.admin.TopicPartitionReplica;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 /**
  * The result is computed by "Size.Value". "Size.Value" responds to the replica log size of brokers.
@@ -170,8 +170,8 @@ public class ReplicaSizeCost implements HasBrokerCost, HasPartitionCost {
                 e.getValue().stream()
                     .filter(x -> x instanceof HasValue)
                     .filter(x -> x.beanObject().domainName().equals("kafka.log"))
-                    .filter(x -> x.beanObject().getProperties().get("type").equals("Log"))
-                    .filter(x -> x.beanObject().getProperties().get("name").equals("Size"))
+                    .filter(x -> x.beanObject().properties().get("type").equals("Log"))
+                    .filter(x -> x.beanObject().properties().get("name").equals("Size"))
                     .map(x -> (HasValue) x)
                     .map(x -> Map.entry(e.getKey(), x.value())))
         .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
diff --git a/app/src/main/java/org/astraea/app/cost/ThroughputCost.java b/app/src/main/java/org/astraea/app/cost/ThroughputCost.java
index 27d0434f..e1415a46 100644
--- a/app/src/main/java/org/astraea/app/cost/ThroughputCost.java
+++ b/app/src/main/java/org/astraea/app/cost/ThroughputCost.java
@@ -22,9 +22,9 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.collector.Fetcher;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 public class ThroughputCost implements HasBrokerCost {
 
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/KafkaMetrics.java b/app/src/main/java/org/astraea/app/metrics/KafkaMetrics.java
similarity index 94%
rename from app/src/main/java/org/astraea/app/metrics/kafka/KafkaMetrics.java
rename to app/src/main/java/org/astraea/app/metrics/KafkaMetrics.java
index 090aaf30..ddb0cb00 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/KafkaMetrics.java
+++ b/app/src/main/java/org/astraea/app/metrics/KafkaMetrics.java
@@ -14,18 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
 import java.util.stream.Collectors;
-import org.astraea.app.metrics.HasBeanObject;
-import org.astraea.app.metrics.java.JvmMemory;
-import org.astraea.app.metrics.java.OperatingSystemInfo;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
+import org.astraea.app.metrics.broker.HasValue;
+import org.astraea.app.metrics.broker.TotalTimeMs;
 import org.astraea.app.metrics.jmx.BeanObject;
 import org.astraea.app.metrics.jmx.BeanQuery;
 import org.astraea.app.metrics.jmx.MBeanClient;
+import org.astraea.app.metrics.platform.JvmMemory;
+import org.astraea.app.metrics.platform.OperatingSystemInfo;
 import org.astraea.app.metrics.producer.HasProducerNodeMetrics;
 import org.astraea.app.metrics.producer.HasProducerTopicMetrics;
 
@@ -123,7 +125,7 @@ public final class KafkaMetrics {
                       .property("type", "KafkaServer")
                       .property("name", "linux-disk-read-bytes")
                       .build())
-              .getAttributes()
+              .attributes()
               .get("Value");
     }
 
@@ -136,7 +138,7 @@ public final class KafkaMetrics {
                       .property("type", "KafkaServer")
                       .property("name", "linux-disk-write-bytes")
                       .build())
-              .getAttributes()
+              .attributes()
               .get("Value");
     }
   }
@@ -184,7 +186,7 @@ public final class KafkaMetrics {
                       .property("delayedOperation", this.name())
                       .property("name", "PurgatorySize")
                       .build())
-              .getAttributes()
+              .attributes()
               .get("Value");
     }
   }
@@ -296,7 +298,7 @@ public final class KafkaMetrics {
                       .property("type", "KafkaController")
                       .property("name", "GlobalPartitionCount")
                       .build())
-              .getAttributes()
+              .attributes()
               .get("Value");
     }
 
@@ -316,7 +318,7 @@ public final class KafkaMetrics {
                       .property("type", "ReplicaManager")
                       .property("name", "UnderReplicatedPartitions")
                       .build())
-              .getAttributes()
+              .attributes()
               .get("Value");
     }
 
@@ -341,8 +343,8 @@ public final class KafkaMetrics {
           .stream()
           .collect(
               Collectors.toMap(
-                  (BeanObject a) -> Integer.parseInt(a.getProperties().get("partition")),
-                  (BeanObject a) -> (Long) a.getAttributes().get("Value")));
+                  (BeanObject a) -> Integer.parseInt(a.properties().get("partition")),
+                  (BeanObject a) -> (Long) a.attributes().get("Value")));
     }
   }
 
@@ -395,7 +397,7 @@ public final class KafkaMetrics {
                   .build())
           .stream()
           .collect(
-              Collectors.toUnmodifiableMap(b -> b.getProperties().get("client-id"), b -> () -> b));
+              Collectors.toUnmodifiableMap(b -> b.properties().get("client-id"), b -> () -> b));
     }
 
     /**
@@ -417,7 +419,7 @@ public final class KafkaMetrics {
                   .build())
           .stream()
           .collect(
-              Collectors.toUnmodifiableMap(b -> b.getProperties().get("client-id"), b -> () -> b));
+              Collectors.toUnmodifiableMap(b -> b.properties().get("client-id"), b -> () -> b));
     }
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/MetricExplorer.java b/app/src/main/java/org/astraea/app/metrics/MetricExplorer.java
index 14da9dd5..a511704e 100644
--- a/app/src/main/java/org/astraea/app/metrics/MetricExplorer.java
+++ b/app/src/main/java/org/astraea/app/metrics/MetricExplorer.java
@@ -64,14 +64,14 @@ public class MetricExplorer {
 
     for (BeanObject beanObject : collect) {
       String properties =
-          beanObject.getProperties().entrySet().stream()
+          beanObject.properties().entrySet().stream()
               .sorted(Comparator.comparing(x -> propertyOrderMap.get(x.getKey())))
               .map(entry -> entry.getKey() + "=" + entry.getValue())
               .collect(Collectors.joining(","));
 
       System.out.printf("[%s:%s]\n", beanObject.domainName(), properties);
 
-      Stream<String> strings = DataUtils.elaborateData(beanObject.getAttributes());
+      Stream<String> strings = DataUtils.elaborateData(beanObject.attributes());
       strings = DataUtils.streamAppendWith(" ", 4, strings);
       strings.forEach(System.out::println);
     }
@@ -86,7 +86,7 @@ public class MetricExplorer {
             System.out.printf(
                 "%s:%s\n",
                 x.domainName(),
-                x.getProperties().entrySet().stream()
+                x.properties().entrySet().stream()
                     .sorted(Comparator.comparingLong(z -> propertyOrderMap.get(z.getKey())))
                     .map(z -> z.getKey() + "=" + z.getValue())
                     .collect(Collectors.joining(","))));
@@ -105,7 +105,7 @@ public class MetricExplorer {
     // property who has higher frequency will close to the tree root when printing result
     Map<String, Long> propertyFrequencyMap =
         beanObjects.stream()
-            .flatMap(x -> x.getProperties().entrySet().stream())
+            .flatMap(x -> x.properties().entrySet().stream())
             .map(Map.Entry::getKey)
             .collect(Collectors.groupingBy(x -> x, Collectors.counting()));
 
@@ -138,11 +138,11 @@ public class MetricExplorer {
                 .thenComparing(
                     (o1, o2) -> {
                       List<Map.Entry<String, String>> order1 =
-                          o1.getProperties().entrySet().stream()
+                          o1.properties().entrySet().stream()
                               .sorted(Comparator.comparing(x -> propertyOrderMap.get(x.getKey())))
                               .collect(Collectors.toList());
                       List<Map.Entry<String, String>> order2 =
-                          o2.getProperties().entrySet().stream()
+                          o2.properties().entrySet().stream()
                               .sorted(Comparator.comparing(x -> propertyOrderMap.get(x.getKey())))
                               .collect(Collectors.toList());
 
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/BrokerTopicMetricsResult.java b/app/src/main/java/org/astraea/app/metrics/broker/BrokerTopicMetricsResult.java
similarity index 88%
rename from app/src/main/java/org/astraea/app/metrics/kafka/BrokerTopicMetricsResult.java
rename to app/src/main/java/org/astraea/app/metrics/broker/BrokerTopicMetricsResult.java
index 93e490dc..19ff7dfd 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/BrokerTopicMetricsResult.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/BrokerTopicMetricsResult.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import java.util.Map;
 import java.util.Objects;
@@ -31,14 +31,14 @@ public class BrokerTopicMetricsResult implements HasCount, HasEventType, HasRate
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
-    for (Map.Entry<String, Object> e : beanObject().getAttributes().entrySet()) {
+    for (Map.Entry<String, Object> e : beanObject().attributes().entrySet()) {
       sb.append(System.lineSeparator())
           .append("  ")
           .append(e.getKey())
           .append("=")
           .append(e.getValue());
     }
-    return beanObject().getProperties().get("name") + "{" + sb + "}";
+    return beanObject().properties().get("name") + "{" + sb + "}";
   }
 
   @Override
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/HasCount.java b/app/src/main/java/org/astraea/app/metrics/broker/HasCount.java
similarity index 89%
rename from app/src/main/java/org/astraea/app/metrics/kafka/HasCount.java
rename to app/src/main/java/org/astraea/app/metrics/broker/HasCount.java
index 7a2d47a4..f7103932 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/HasCount.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/HasCount.java
@@ -14,12 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import org.astraea.app.metrics.HasBeanObject;
 
 public interface HasCount extends HasBeanObject {
   default long count() {
-    return (long) beanObject().getAttributes().getOrDefault("Count", 0);
+    return (long) beanObject().attributes().getOrDefault("Count", 0);
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/HasEventType.java b/app/src/main/java/org/astraea/app/metrics/broker/HasEventType.java
similarity index 89%
rename from app/src/main/java/org/astraea/app/metrics/kafka/HasEventType.java
rename to app/src/main/java/org/astraea/app/metrics/broker/HasEventType.java
index 093ccf47..131ee0bf 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/HasEventType.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/HasEventType.java
@@ -14,12 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import org.astraea.app.metrics.HasBeanObject;
 
 public interface HasEventType extends HasBeanObject {
   default String eventType() {
-    return (String) beanObject().getAttributes().get("EventType");
+    return (String) beanObject().attributes().get("EventType");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/HasPercentiles.java b/app/src/main/java/org/astraea/app/metrics/broker/HasPercentiles.java
similarity index 70%
rename from app/src/main/java/org/astraea/app/metrics/kafka/HasPercentiles.java
rename to app/src/main/java/org/astraea/app/metrics/broker/HasPercentiles.java
index ee07e2ab..4edaf564 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/HasPercentiles.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/HasPercentiles.java
@@ -14,33 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import org.astraea.app.metrics.HasBeanObject;
 
 public interface HasPercentiles extends HasBeanObject {
 
   default double percentile50() {
-    return (double) beanObject().getAttributes().get("50thPercentile");
+    return (double) beanObject().attributes().get("50thPercentile");
   }
 
   default double percentile75() {
-    return (double) beanObject().getAttributes().get("75thPercentile");
+    return (double) beanObject().attributes().get("75thPercentile");
   }
 
   default double percentile95() {
-    return (double) beanObject().getAttributes().get("95thPercentile");
+    return (double) beanObject().attributes().get("95thPercentile");
   }
 
   default double percentile98() {
-    return (double) beanObject().getAttributes().get("98thPercentile");
+    return (double) beanObject().attributes().get("98thPercentile");
   }
 
   default double percentile99() {
-    return (double) beanObject().getAttributes().get("99thPercentile");
+    return (double) beanObject().attributes().get("99thPercentile");
   }
 
   default double percentile999() {
-    return (double) beanObject().getAttributes().get("999thPercentile");
+    return (double) beanObject().attributes().get("999thPercentile");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/HasRate.java b/app/src/main/java/org/astraea/app/metrics/broker/HasRate.java
similarity index 72%
rename from app/src/main/java/org/astraea/app/metrics/kafka/HasRate.java
rename to app/src/main/java/org/astraea/app/metrics/broker/HasRate.java
index 88223568..08674d1b 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/HasRate.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/HasRate.java
@@ -14,29 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import java.util.concurrent.TimeUnit;
 import org.astraea.app.metrics.HasBeanObject;
 
 public interface HasRate extends HasBeanObject {
   default double meanRate() {
-    return (double) beanObject().getAttributes().getOrDefault("MeanRate", 0);
+    return (double) beanObject().attributes().getOrDefault("MeanRate", 0);
   }
 
   default double oneMinuteRate() {
-    return (double) beanObject().getAttributes().getOrDefault("OneMinuteRate", 0);
+    return (double) beanObject().attributes().getOrDefault("OneMinuteRate", 0);
   }
 
   default double fiveMinuteRate() {
-    return (double) beanObject().getAttributes().getOrDefault("FiveMinuteRate", 0);
+    return (double) beanObject().attributes().getOrDefault("FiveMinuteRate", 0);
   }
 
   default double fifteenMinuteRate() {
-    return (double) beanObject().getAttributes().getOrDefault("FifteenMinuteRate", 0);
+    return (double) beanObject().attributes().getOrDefault("FifteenMinuteRate", 0);
   }
 
   default TimeUnit rateUnit() {
-    return (TimeUnit) beanObject().getAttributes().get("RateUnit");
+    return (TimeUnit) beanObject().attributes().get("RateUnit");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/HasStatistics.java b/app/src/main/java/org/astraea/app/metrics/broker/HasStatistics.java
similarity index 78%
rename from app/src/main/java/org/astraea/app/metrics/kafka/HasStatistics.java
rename to app/src/main/java/org/astraea/app/metrics/broker/HasStatistics.java
index c0dd7859..d7e3425e 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/HasStatistics.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/HasStatistics.java
@@ -14,25 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import org.astraea.app.metrics.HasBeanObject;
 
 public interface HasStatistics extends HasBeanObject {
 
   default double max() {
-    return (double) beanObject().getAttributes().get("Max");
+    return (double) beanObject().attributes().get("Max");
   }
 
   default double min() {
-    return (double) beanObject().getAttributes().get("Min");
+    return (double) beanObject().attributes().get("Min");
   }
 
   default double mean() {
-    return (double) beanObject().getAttributes().get("Mean");
+    return (double) beanObject().attributes().get("Mean");
   }
 
   default double stdDev() {
-    return (double) beanObject().getAttributes().get("StdDev");
+    return (double) beanObject().attributes().get("StdDev");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/HasValue.java b/app/src/main/java/org/astraea/app/metrics/broker/HasValue.java
similarity index 90%
rename from app/src/main/java/org/astraea/app/metrics/kafka/HasValue.java
rename to app/src/main/java/org/astraea/app/metrics/broker/HasValue.java
index 97e3287c..b3dd5909 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/HasValue.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/HasValue.java
@@ -14,14 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import org.astraea.app.metrics.HasBeanObject;
 import org.astraea.app.metrics.jmx.BeanObject;
 
 public interface HasValue extends HasBeanObject {
   default long value() {
-    var value = beanObject().getAttributes().getOrDefault("Value", 0);
+    var value = beanObject().attributes().getOrDefault("Value", 0);
     return ((Number) value).longValue();
   }
 
diff --git a/app/src/main/java/org/astraea/app/metrics/kafka/TotalTimeMs.java b/app/src/main/java/org/astraea/app/metrics/broker/TotalTimeMs.java
similarity index 87%
rename from app/src/main/java/org/astraea/app/metrics/kafka/TotalTimeMs.java
rename to app/src/main/java/org/astraea/app/metrics/broker/TotalTimeMs.java
index b1feefec..ba0d7ea5 100644
--- a/app/src/main/java/org/astraea/app/metrics/kafka/TotalTimeMs.java
+++ b/app/src/main/java/org/astraea/app/metrics/broker/TotalTimeMs.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import java.util.Map;
 import org.astraea.app.metrics.jmx.BeanObject;
@@ -30,14 +30,14 @@ public class TotalTimeMs implements HasPercentiles, HasCount, HasStatistics {
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
-    for (Map.Entry<String, Object> e : beanObject().getAttributes().entrySet()) {
+    for (Map.Entry<String, Object> e : beanObject().attributes().entrySet()) {
       sb.append(System.lineSeparator())
           .append("  ")
           .append(e.getKey())
           .append("=")
           .append(e.getValue());
     }
-    return beanObject.getProperties().get("request") + " TotalTimeMs {" + sb + "}";
+    return beanObject.properties().get("request") + " TotalTimeMs {" + sb + "}";
   }
 
   @Override
diff --git a/app/src/main/java/org/astraea/app/metrics/collector/BeanCollector.java b/app/src/main/java/org/astraea/app/metrics/collector/BeanCollector.java
index bcd761dd..291bc0ae 100644
--- a/app/src/main/java/org/astraea/app/metrics/collector/BeanCollector.java
+++ b/app/src/main/java/org/astraea/app/metrics/collector/BeanCollector.java
@@ -31,8 +31,8 @@ import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.BiFunction;
 import org.astraea.app.common.Utils;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.jmx.MBeanClient;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 
 public class BeanCollector {
 
diff --git a/app/src/main/java/org/astraea/app/metrics/jmx/BeanObject.java b/app/src/main/java/org/astraea/app/metrics/jmx/BeanObject.java
index 4f95c363..3445da3f 100644
--- a/app/src/main/java/org/astraea/app/metrics/jmx/BeanObject.java
+++ b/app/src/main/java/org/astraea/app/metrics/jmx/BeanObject.java
@@ -74,11 +74,11 @@ public class BeanObject {
     return domainName;
   }
 
-  public Map<String, String> getProperties() {
+  public Map<String, String> properties() {
     return properties;
   }
 
-  public Map<String, Object> getAttributes() {
+  public Map<String, Object> attributes() {
     return attributes;
   }
 
diff --git a/app/src/main/java/org/astraea/app/metrics/java/HasJvmMemory.java b/app/src/main/java/org/astraea/app/metrics/platform/HasJvmMemory.java
similarity index 82%
rename from app/src/main/java/org/astraea/app/metrics/java/HasJvmMemory.java
rename to app/src/main/java/org/astraea/app/metrics/platform/HasJvmMemory.java
index 72086088..c0f6cb08 100644
--- a/app/src/main/java/org/astraea/app/metrics/java/HasJvmMemory.java
+++ b/app/src/main/java/org/astraea/app/metrics/platform/HasJvmMemory.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.java;
+package org.astraea.app.metrics.platform;
 
 import java.lang.management.MemoryUsage;
 import javax.management.openmbean.CompositeData;
@@ -23,10 +23,10 @@ import org.astraea.app.metrics.HasBeanObject;
 public interface HasJvmMemory extends HasBeanObject {
 
   default MemoryUsage heapMemoryUsage() {
-    return MemoryUsage.from((CompositeData) beanObject().getAttributes().get("HeapMemoryUsage"));
+    return MemoryUsage.from((CompositeData) beanObject().attributes().get("HeapMemoryUsage"));
   }
 
   default MemoryUsage nonHeapMemoryUsage() {
-    return MemoryUsage.from((CompositeData) beanObject().getAttributes().get("NonHeapMemoryUsage"));
+    return MemoryUsage.from((CompositeData) beanObject().attributes().get("NonHeapMemoryUsage"));
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/java/HasOperatingSystemInfo.java b/app/src/main/java/org/astraea/app/metrics/platform/HasOperatingSystemInfo.java
similarity index 72%
rename from app/src/main/java/org/astraea/app/metrics/java/HasOperatingSystemInfo.java
rename to app/src/main/java/org/astraea/app/metrics/platform/HasOperatingSystemInfo.java
index 20bfa9a6..6fb6561c 100644
--- a/app/src/main/java/org/astraea/app/metrics/java/HasOperatingSystemInfo.java
+++ b/app/src/main/java/org/astraea/app/metrics/platform/HasOperatingSystemInfo.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.java;
+package org.astraea.app.metrics.platform;
 
 import org.astraea.app.metrics.HasBeanObject;
 
@@ -22,12 +22,12 @@ public interface HasOperatingSystemInfo extends HasBeanObject {
 
   /** The operating system architecture. */
   default String arch() {
-    return (String) beanObject().getAttributes().get("Arch");
+    return (String) beanObject().attributes().get("Arch");
   }
 
   /** The number of processors available to the JVM. */
   default int availableProcessors() {
-    return (int) beanObject().getAttributes().get("AvailableProcessors");
+    return (int) beanObject().attributes().get("AvailableProcessors");
   }
 
   /**
@@ -35,32 +35,32 @@ public interface HasOperatingSystemInfo extends HasBeanObject {
    * if this operating is not supported.
    */
   default long committedVirtualMemorySize() {
-    return (long) beanObject().getAttributes().get("CommittedVirtualMemorySize");
+    return (long) beanObject().attributes().get("CommittedVirtualMemorySize");
   }
 
   /** The amount of free physical memory. */
   default long freePhysicalMemorySize() {
-    return (long) beanObject().getAttributes().get("FreePhysicalMemorySize");
+    return (long) beanObject().attributes().get("FreePhysicalMemorySize");
   }
 
   /** The amount of free swap memory space. */
   default long freeSwapSpaceSize() {
-    return (long) beanObject().getAttributes().get("FreeSwapSpaceSize");
+    return (long) beanObject().attributes().get("FreeSwapSpaceSize");
   }
 
   /** The maximum number of file descriptors. */
   default long maxFileDescriptorCount() {
-    return (long) beanObject().getAttributes().get("MaxFileDescriptorCount");
+    return (long) beanObject().attributes().get("MaxFileDescriptorCount");
   }
 
   /** The number of open file descriptors. */
   default long openFileDescriptorCount() {
-    return (long) beanObject().getAttributes().get("OpenFileDescriptorCount");
+    return (long) beanObject().attributes().get("OpenFileDescriptorCount");
   }
 
   /** The operating system name. */
   default String name() {
-    return (String) beanObject().getAttributes().get("Name");
+    return (String) beanObject().attributes().get("Name");
   }
 
   /**
@@ -69,7 +69,7 @@ public interface HasOperatingSystemInfo extends HasBeanObject {
    * negative.
    */
   default double processCpuLoad() {
-    return (double) beanObject().getAttributes().get("ProcessCpuLoad");
+    return (double) beanObject().attributes().get("ProcessCpuLoad");
   }
 
   /**
@@ -78,7 +78,7 @@ public interface HasOperatingSystemInfo extends HasBeanObject {
    * method returns -1 if the platform does not support this operation.
    */
   default long processCpuTime() {
-    return (long) beanObject().getAttributes().get("ProcessCpuTime");
+    return (long) beanObject().attributes().get("ProcessCpuTime");
   }
 
   /**
@@ -87,26 +87,26 @@ public interface HasOperatingSystemInfo extends HasBeanObject {
    * negative.
    */
   default double systemCpuLoad() {
-    return (double) beanObject().getAttributes().get("SystemCpuLoad");
+    return (double) beanObject().attributes().get("SystemCpuLoad");
   }
 
   /** The system load average for the last minute (or a negative value if not available). */
   default double systemLoadAverage() {
-    return (double) beanObject().getAttributes().get("SystemLoadAverage");
+    return (double) beanObject().attributes().get("SystemLoadAverage");
   }
 
   /** The total amount of physical memory */
   default long totalPhysicalMemorySize() {
-    return (long) beanObject().getAttributes().get("TotalPhysicalMemorySize");
+    return (long) beanObject().attributes().get("TotalPhysicalMemorySize");
   }
 
   /** The total amount of swap space memory. */
   default long totalSwapSpaceSize() {
-    return (long) beanObject().getAttributes().get("TotalSwapSpaceSize");
+    return (long) beanObject().attributes().get("TotalSwapSpaceSize");
   }
 
   /** The operating system version. */
   default String version() {
-    return (String) beanObject().getAttributes().get("Version");
+    return (String) beanObject().attributes().get("Version");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/java/JvmMemory.java b/app/src/main/java/org/astraea/app/metrics/platform/JvmMemory.java
similarity index 98%
rename from app/src/main/java/org/astraea/app/metrics/java/JvmMemory.java
rename to app/src/main/java/org/astraea/app/metrics/platform/JvmMemory.java
index bb1500c6..16d91df9 100644
--- a/app/src/main/java/org/astraea/app/metrics/java/JvmMemory.java
+++ b/app/src/main/java/org/astraea/app/metrics/platform/JvmMemory.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.java;
+package org.astraea.app.metrics.platform;
 
 import java.lang.management.MemoryUsage;
 import org.astraea.app.metrics.jmx.BeanObject;
diff --git a/app/src/main/java/org/astraea/app/metrics/java/OperatingSystemInfo.java b/app/src/main/java/org/astraea/app/metrics/platform/OperatingSystemInfo.java
similarity index 92%
rename from app/src/main/java/org/astraea/app/metrics/java/OperatingSystemInfo.java
rename to app/src/main/java/org/astraea/app/metrics/platform/OperatingSystemInfo.java
index ef767d7c..bb55490f 100644
--- a/app/src/main/java/org/astraea/app/metrics/java/OperatingSystemInfo.java
+++ b/app/src/main/java/org/astraea/app/metrics/platform/OperatingSystemInfo.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.java;
+package org.astraea.app.metrics.platform;
 
 import java.util.Map;
 import org.astraea.app.metrics.jmx.BeanObject;
@@ -35,7 +35,7 @@ public class OperatingSystemInfo implements HasOperatingSystemInfo {
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
-    for (Map.Entry<String, Object> e : beanObject().getAttributes().entrySet()) {
+    for (Map.Entry<String, Object> e : beanObject().attributes().entrySet()) {
       sb.append(System.lineSeparator())
           .append("  ")
           .append(e.getKey())
diff --git a/app/src/main/java/org/astraea/app/metrics/producer/HasProducerNodeMetrics.java b/app/src/main/java/org/astraea/app/metrics/producer/HasProducerNodeMetrics.java
index ee14bb52..12be7068 100644
--- a/app/src/main/java/org/astraea/app/metrics/producer/HasProducerNodeMetrics.java
+++ b/app/src/main/java/org/astraea/app/metrics/producer/HasProducerNodeMetrics.java
@@ -21,50 +21,50 @@ import org.astraea.app.metrics.HasBeanObject;
 public interface HasProducerNodeMetrics extends HasBeanObject {
 
   default double incomingByteRate() {
-    return (double) beanObject().getAttributes().get("incoming-byte-rate");
+    return (double) beanObject().attributes().get("incoming-byte-rate");
   }
 
   default double incomingByteTotal() {
-    return (double) beanObject().getAttributes().get("incoming-byte-total");
+    return (double) beanObject().attributes().get("incoming-byte-total");
   }
 
   default double outgoingByteRate() {
-    return (double) beanObject().getAttributes().get("outgoing-byte-rate");
+    return (double) beanObject().attributes().get("outgoing-byte-rate");
   }
 
   default double outgoingByteTotal() {
-    return (double) beanObject().getAttributes().get("outgoing-byte-total");
+    return (double) beanObject().attributes().get("outgoing-byte-total");
   }
 
   default double requestLatencyAvg() {
-    return (double) beanObject().getAttributes().get("request-latency-avg");
+    return (double) beanObject().attributes().get("request-latency-avg");
   }
 
   default double requestLatencyMax() {
-    return (double) beanObject().getAttributes().get("request-latency-max");
+    return (double) beanObject().attributes().get("request-latency-max");
   }
 
   default double requestRate() {
-    return (double) beanObject().getAttributes().get("request-rate");
+    return (double) beanObject().attributes().get("request-rate");
   }
 
   default double requestSizeAvg() {
-    return (double) beanObject().getAttributes().get("request-size-avg");
+    return (double) beanObject().attributes().get("request-size-avg");
   }
 
   default double requestSizeMax() {
-    return (double) beanObject().getAttributes().get("request-size-max");
+    return (double) beanObject().attributes().get("request-size-max");
   }
 
   default double requestTotal() {
-    return (double) beanObject().getAttributes().get("request-total");
+    return (double) beanObject().attributes().get("request-total");
   }
 
   default double responseRate() {
-    return (double) beanObject().getAttributes().get("response-rate");
+    return (double) beanObject().attributes().get("response-rate");
   }
 
   default double responseTotal() {
-    return (double) beanObject().getAttributes().get("response-total");
+    return (double) beanObject().attributes().get("response-total");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/metrics/producer/HasProducerTopicMetrics.java b/app/src/main/java/org/astraea/app/metrics/producer/HasProducerTopicMetrics.java
index 6f6d4abf..5b535871 100644
--- a/app/src/main/java/org/astraea/app/metrics/producer/HasProducerTopicMetrics.java
+++ b/app/src/main/java/org/astraea/app/metrics/producer/HasProducerTopicMetrics.java
@@ -21,38 +21,38 @@ import org.astraea.app.metrics.HasBeanObject;
 public interface HasProducerTopicMetrics extends HasBeanObject {
 
   default double byteRate() {
-    return (double) beanObject().getAttributes().get("byte-rate");
+    return (double) beanObject().attributes().get("byte-rate");
   }
 
   default double byteTotal() {
-    return (double) beanObject().getAttributes().get("byte-total");
+    return (double) beanObject().attributes().get("byte-total");
   }
 
   default double compressionRate() {
-    return (double) beanObject().getAttributes().get("compression-rate");
+    return (double) beanObject().attributes().get("compression-rate");
   }
 
   default double recordErrorRate() {
-    return (double) beanObject().getAttributes().get("record-error-rate");
+    return (double) beanObject().attributes().get("record-error-rate");
   }
 
   default double recordErrorTotal() {
-    return (double) beanObject().getAttributes().get("record-error-total");
+    return (double) beanObject().attributes().get("record-error-total");
   }
 
   default double recordRetryRate() {
-    return (double) beanObject().getAttributes().get("record-retry-rate");
+    return (double) beanObject().attributes().get("record-retry-rate");
   }
 
   default double recordRetryTotal() {
-    return (double) beanObject().getAttributes().get("record-retry-total");
+    return (double) beanObject().attributes().get("record-retry-total");
   }
 
   default double recordSendRate() {
-    return (double) beanObject().getAttributes().get("record-send-rate");
+    return (double) beanObject().attributes().get("record-send-rate");
   }
 
   default double recordSendTotal() {
-    return (double) beanObject().getAttributes().get("record-send-total");
+    return (double) beanObject().attributes().get("record-send-total");
   }
 }
diff --git a/app/src/main/java/org/astraea/app/web/BeanHandler.java b/app/src/main/java/org/astraea/app/web/BeanHandler.java
index 7e74b82a..4ea2ad13 100644
--- a/app/src/main/java/org/astraea/app/web/BeanHandler.java
+++ b/app/src/main/java/org/astraea/app/web/BeanHandler.java
@@ -80,11 +80,11 @@ public class BeanHandler implements Handler {
     Bean(BeanObject obj) {
       this.domainName = obj.domainName();
       this.properties =
-          obj.getProperties().entrySet().stream()
+          obj.properties().entrySet().stream()
               .map(e -> new Property(e.getKey(), e.getValue()))
               .collect(Collectors.toUnmodifiableList());
       this.attributes =
-          obj.getAttributes().entrySet().stream()
+          obj.attributes().entrySet().stream()
               .map(e -> new Attribute(e.getKey(), e.getValue().toString()))
               .collect(Collectors.toUnmodifiableList());
     }


Test patch:
diff --git a/app/src/test/java/org/astraea/app/admin/ClusterBeanTest.java b/app/src/test/java/org/astraea/app/admin/ClusterBeanTest.java
index 7265f779..f343f0cd 100644
--- a/app/src/test/java/org/astraea/app/admin/ClusterBeanTest.java
+++ b/app/src/test/java/org/astraea/app/admin/ClusterBeanTest.java
@@ -19,9 +19,9 @@ package org.astraea.app.admin;
 import java.util.List;
 import java.util.Map;
 import org.astraea.app.cost.ClusterInfo;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
diff --git a/app/src/test/java/org/astraea/app/cost/BrokerInputCostTest.java b/app/src/test/java/org/astraea/app/cost/BrokerInputCostTest.java
index ef70eac5..0191a1b7 100644
--- a/app/src/test/java/org/astraea/app/cost/BrokerInputCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/BrokerInputCostTest.java
@@ -21,11 +21,11 @@ import java.util.List;
 import java.util.Map;
 import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.collector.BeanCollector;
 import org.astraea.app.metrics.collector.Receiver;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.service.RequireBrokerCluster;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -79,7 +79,7 @@ public class BrokerInputCostTest extends RequireBrokerCluster {
                   o ->
                       (o instanceof BrokerTopicMetricsResult)
                           && (KafkaMetrics.BrokerTopic.BytesInPerSec.metricName()
-                              .equals(o.beanObject().getProperties().get("name")))));
+                              .equals(o.beanObject().properties().get("name")))));
 
       // Test the fetched object's value.
       Assertions.assertTrue(
@@ -109,7 +109,7 @@ public class BrokerInputCostTest extends RequireBrokerCluster {
     var result = Mockito.mock(BrokerTopicMetricsResult.class);
     var bean = Mockito.mock(BeanObject.class);
     Mockito.when(result.beanObject()).thenReturn(bean);
-    Mockito.when(bean.getProperties()).thenReturn(Map.of("name", name));
+    Mockito.when(bean.properties()).thenReturn(Map.of("name", name));
     Mockito.when(result.count()).thenReturn(count);
     return result;
   }
diff --git a/app/src/test/java/org/astraea/app/cost/BrokerOutPutCostTest.java b/app/src/test/java/org/astraea/app/cost/BrokerOutPutCostTest.java
index 3f258bfc..52afa386 100644
--- a/app/src/test/java/org/astraea/app/cost/BrokerOutPutCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/BrokerOutPutCostTest.java
@@ -21,11 +21,11 @@ import java.util.List;
 import java.util.Map;
 import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.collector.BeanCollector;
 import org.astraea.app.metrics.collector.Receiver;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.service.RequireBrokerCluster;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -68,7 +68,7 @@ public class BrokerOutPutCostTest extends RequireBrokerCluster {
                   o ->
                       (o instanceof BrokerTopicMetricsResult)
                           && (KafkaMetrics.BrokerTopic.BytesOutPerSec.metricName()
-                              .equals(o.beanObject().getProperties().get("name")))));
+                              .equals(o.beanObject().properties().get("name")))));
 
       // Test the fetched object's value.
       Assertions.assertTrue(
@@ -98,7 +98,7 @@ public class BrokerOutPutCostTest extends RequireBrokerCluster {
     var result = Mockito.mock(BrokerTopicMetricsResult.class);
     var bean = Mockito.mock(BeanObject.class);
     Mockito.when(result.beanObject()).thenReturn(bean);
-    Mockito.when(bean.getProperties()).thenReturn(Map.of("name", name));
+    Mockito.when(bean.properties()).thenReturn(Map.of("name", name));
     Mockito.when(result.count()).thenReturn(count);
     return result;
   }
diff --git a/app/src/test/java/org/astraea/app/cost/CpuCostTest.java b/app/src/test/java/org/astraea/app/cost/CpuCostTest.java
index 26959105..4823aa0c 100644
--- a/app/src/test/java/org/astraea/app/cost/CpuCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/CpuCostTest.java
@@ -24,7 +24,7 @@ import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.metrics.HasBeanObject;
 import org.astraea.app.metrics.collector.BeanCollector;
 import org.astraea.app.metrics.collector.Receiver;
-import org.astraea.app.metrics.java.OperatingSystemInfo;
+import org.astraea.app.metrics.platform.OperatingSystemInfo;
 import org.astraea.app.service.RequireBrokerCluster;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/app/src/test/java/org/astraea/app/cost/LoadCostTest.java b/app/src/test/java/org/astraea/app/cost/LoadCostTest.java
index 923fba9c..ff6b7c9d 100644
--- a/app/src/test/java/org/astraea/app/cost/LoadCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/LoadCostTest.java
@@ -21,9 +21,9 @@ import java.util.List;
 import java.util.Map;
 import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -70,7 +70,7 @@ public class LoadCostTest {
     var result = Mockito.mock(BrokerTopicMetricsResult.class);
     var bean = Mockito.mock(BeanObject.class);
     Mockito.when(result.beanObject()).thenReturn(bean);
-    Mockito.when(bean.getProperties()).thenReturn(Map.of("name", name));
+    Mockito.when(bean.properties()).thenReturn(Map.of("name", name));
     Mockito.when(result.count()).thenReturn(count);
     return result;
   }
diff --git a/app/src/test/java/org/astraea/app/cost/MemoryCostTest.java b/app/src/test/java/org/astraea/app/cost/MemoryCostTest.java
index ff41c0e2..54ca0bd6 100644
--- a/app/src/test/java/org/astraea/app/cost/MemoryCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/MemoryCostTest.java
@@ -25,8 +25,8 @@ import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.metrics.HasBeanObject;
 import org.astraea.app.metrics.collector.BeanCollector;
 import org.astraea.app.metrics.collector.Receiver;
-import org.astraea.app.metrics.java.HasJvmMemory;
-import org.astraea.app.metrics.java.JvmMemory;
+import org.astraea.app.metrics.platform.HasJvmMemory;
+import org.astraea.app.metrics.platform.JvmMemory;
 import org.astraea.app.service.RequireBrokerCluster;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/app/src/test/java/org/astraea/app/cost/ReplicaDiskInCostTest.java b/app/src/test/java/org/astraea/app/cost/ReplicaDiskInCostTest.java
index 16e2c42c..13cc3960 100644
--- a/app/src/test/java/org/astraea/app/cost/ReplicaDiskInCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/ReplicaDiskInCostTest.java
@@ -24,9 +24,9 @@ import java.util.Set;
 import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.admin.TopicPartition;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.service.RequireBrokerCluster;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/app/src/test/java/org/astraea/app/cost/ReplicaLeaderCostTest.java b/app/src/test/java/org/astraea/app/cost/ReplicaLeaderCostTest.java
index 3ce35a60..e53d1200 100644
--- a/app/src/test/java/org/astraea/app/cost/ReplicaLeaderCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/ReplicaLeaderCostTest.java
@@ -22,9 +22,9 @@ import java.util.Map;
 import java.util.Set;
 import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -75,7 +75,7 @@ public class ReplicaLeaderCostTest {
     var result = Mockito.mock(HasValue.class);
     var bean = Mockito.mock(BeanObject.class);
     Mockito.when(result.beanObject()).thenReturn(bean);
-    Mockito.when(bean.getProperties()).thenReturn(Map.of("name", name, "type", "ReplicaManager"));
+    Mockito.when(bean.properties()).thenReturn(Map.of("name", name, "type", "ReplicaManager"));
     Mockito.when(result.value()).thenReturn(count);
     return result;
   }
diff --git a/app/src/test/java/org/astraea/app/cost/ReplicaSizeCostTest.java b/app/src/test/java/org/astraea/app/cost/ReplicaSizeCostTest.java
index a2c30e3c..552ad2dd 100644
--- a/app/src/test/java/org/astraea/app/cost/ReplicaSizeCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/ReplicaSizeCostTest.java
@@ -29,10 +29,10 @@ import org.astraea.app.admin.Admin;
 import org.astraea.app.admin.ClusterBean;
 import org.astraea.app.admin.TopicPartition;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
+import org.astraea.app.metrics.broker.HasValue;
 import org.astraea.app.metrics.collector.BeanCollector;
 import org.astraea.app.metrics.jmx.BeanObject;
-import org.astraea.app.metrics.kafka.HasValue;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.producer.Producer;
 import org.astraea.app.service.RequireSingleBrokerCluster;
 import org.junit.jupiter.api.Assertions;
@@ -64,8 +64,8 @@ class ReplicaSizeCostTest extends RequireSingleBrokerCluster {
       var replicaSize =
           beanObjects.stream()
               .filter(x -> x instanceof HasValue)
-              .filter(x -> x.beanObject().getProperties().get("name").equals("Size"))
-              .filter(x -> x.beanObject().getProperties().get("type").equals("Log"))
+              .filter(x -> x.beanObject().properties().get("name").equals("Size"))
+              .filter(x -> x.beanObject().properties().get("type").equals("Log"))
               .sorted(Comparator.comparing(HasBeanObject::createdTimestamp).reversed())
               .map(x -> (HasValue) x)
               .limit(1)
diff --git a/app/src/test/java/org/astraea/app/cost/ThroughputCostTest.java b/app/src/test/java/org/astraea/app/cost/ThroughputCostTest.java
index 129336d6..83312bcb 100644
--- a/app/src/test/java/org/astraea/app/cost/ThroughputCostTest.java
+++ b/app/src/test/java/org/astraea/app/cost/ThroughputCostTest.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.astraea.app.admin.ClusterBean;
-import org.astraea.app.metrics.kafka.BrokerTopicMetricsResult;
+import org.astraea.app.metrics.broker.BrokerTopicMetricsResult;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
diff --git a/app/src/test/java/org/astraea/app/metrics/kafka/KafkaMetricsTest.java b/app/src/test/java/org/astraea/app/metrics/broker/KafkaMetricsTest.java
similarity index 97%
rename from app/src/test/java/org/astraea/app/metrics/kafka/KafkaMetricsTest.java
rename to app/src/test/java/org/astraea/app/metrics/broker/KafkaMetricsTest.java
index 19a7de18..979407d4 100644
--- a/app/src/test/java/org/astraea/app/metrics/kafka/KafkaMetricsTest.java
+++ b/app/src/test/java/org/astraea/app/metrics/broker/KafkaMetricsTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.astraea.app.metrics.kafka;
+package org.astraea.app.metrics.broker;
 
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -35,9 +35,10 @@ import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
 import org.astraea.app.admin.Admin;
 import org.astraea.app.common.Utils;
-import org.astraea.app.metrics.java.JvmMemory;
-import org.astraea.app.metrics.java.OperatingSystemInfo;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.jmx.MBeanClient;
+import org.astraea.app.metrics.platform.JvmMemory;
+import org.astraea.app.metrics.platform.OperatingSystemInfo;
 import org.astraea.app.service.RequireBrokerCluster;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/app/src/test/java/org/astraea/app/metrics/collector/BeanCollectorTest.java b/app/src/test/java/org/astraea/app/metrics/collector/BeanCollectorTest.java
index 5439a2a5..bed62529 100644
--- a/app/src/test/java/org/astraea/app/metrics/collector/BeanCollectorTest.java
+++ b/app/src/test/java/org/astraea/app/metrics/collector/BeanCollectorTest.java
@@ -30,9 +30,9 @@ import org.astraea.app.concurrent.Executor;
 import org.astraea.app.concurrent.State;
 import org.astraea.app.concurrent.ThreadPool;
 import org.astraea.app.metrics.HasBeanObject;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.jmx.BeanObject;
 import org.astraea.app.metrics.jmx.MBeanClient;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
diff --git a/app/src/test/java/org/astraea/app/metrics/jmx/BeanObjectTest.java b/app/src/test/java/org/astraea/app/metrics/jmx/BeanObjectTest.java
index 24bd9fe1..da017f70 100644
--- a/app/src/test/java/org/astraea/app/metrics/jmx/BeanObjectTest.java
+++ b/app/src/test/java/org/astraea/app/metrics/jmx/BeanObjectTest.java
@@ -42,7 +42,7 @@ class BeanObjectTest {
   void getPropertyView() {
     BeanObject beanObject = createBeanObject();
 
-    Map<String, String> propertyView = beanObject.getProperties();
+    Map<String, String> propertyView = beanObject.properties();
 
     assertEquals(Map.of("type", "Memory"), propertyView);
   }
@@ -51,7 +51,7 @@ class BeanObjectTest {
   void getAttributeView() {
     BeanObject beanObject = createBeanObject();
 
-    Map<String, Object> result = beanObject.getAttributes();
+    Map<String, Object> result = beanObject.attributes();
 
     assertEquals(Map.of("HeapMemoryUsage", "content"), result);
   }
diff --git a/app/src/test/java/org/astraea/app/metrics/jmx/MBeanClientTest.java b/app/src/test/java/org/astraea/app/metrics/jmx/MBeanClientTest.java
index b9ffa744..cf8e8553 100644
--- a/app/src/test/java/org/astraea/app/metrics/jmx/MBeanClientTest.java
+++ b/app/src/test/java/org/astraea/app/metrics/jmx/MBeanClientTest.java
@@ -106,9 +106,9 @@ class MBeanClientTest {
       BeanObject beanObject = client.queryBean(beanQuery);
 
       // assert
-      assertTrue(beanObject.getProperties().containsKey("type"));
-      assertTrue(beanObject.getAttributes().containsKey("HeapMemoryUsage"));
-      assertTrue(beanObject.getAttributes().containsKey("NonHeapMemoryUsage"));
+      assertTrue(beanObject.properties().containsKey("type"));
+      assertTrue(beanObject.attributes().containsKey("HeapMemoryUsage"));
+      assertTrue(beanObject.attributes().containsKey("NonHeapMemoryUsage"));
     }
   }
 
@@ -133,19 +133,19 @@ class MBeanClientTest {
       BeanObject beanObject2 = client.queryBean(query2);
 
       // assert
-      assertTrue(beanObject1.getProperties().containsKey("type"));
-      assertTrue(beanObject1.getProperties().containsKey("name"));
-      assertTrue(beanObject1.getAttributes().containsKey("MemoryPoolNames"));
-      assertTrue(beanObject1.getAttributes().containsKey("Name"));
-      assertTrue(beanObject1.getAttributes().containsKey("ObjectName"));
-      assertTrue(beanObject1.getAttributes().containsKey("Valid"));
-
-      assertTrue(beanObject2.getProperties().containsKey("type"));
-      assertTrue(beanObject2.getProperties().containsKey("name"));
-      assertTrue(beanObject2.getAttributes().containsKey("MemoryPoolNames"));
-      assertTrue(beanObject2.getAttributes().containsKey("Name"));
-      assertTrue(beanObject2.getAttributes().containsKey("ObjectName"));
-      assertTrue(beanObject2.getAttributes().containsKey("Valid"));
+      assertTrue(beanObject1.properties().containsKey("type"));
+      assertTrue(beanObject1.properties().containsKey("name"));
+      assertTrue(beanObject1.attributes().containsKey("MemoryPoolNames"));
+      assertTrue(beanObject1.attributes().containsKey("Name"));
+      assertTrue(beanObject1.attributes().containsKey("ObjectName"));
+      assertTrue(beanObject1.attributes().containsKey("Valid"));
+
+      assertTrue(beanObject2.properties().containsKey("type"));
+      assertTrue(beanObject2.properties().containsKey("name"));
+      assertTrue(beanObject2.attributes().containsKey("MemoryPoolNames"));
+      assertTrue(beanObject2.attributes().containsKey("Name"));
+      assertTrue(beanObject2.attributes().containsKey("ObjectName"));
+      assertTrue(beanObject2.attributes().containsKey("Valid"));
     }
   }
 
@@ -161,9 +161,9 @@ class MBeanClientTest {
       BeanObject beanObject = client.queryBean(beanQuery, selectedAttribute);
 
       // assert
-      assertTrue(beanObject.getProperties().containsKey("type"));
-      assertTrue(beanObject.getAttributes().containsKey("HeapMemoryUsage"));
-      assertFalse(beanObject.getAttributes().containsKey("NonHeapMemoryUsage"));
+      assertTrue(beanObject.properties().containsKey("type"));
+      assertTrue(beanObject.attributes().containsKey("HeapMemoryUsage"));
+      assertFalse(beanObject.attributes().containsKey("NonHeapMemoryUsage"));
     }
   }
 
@@ -180,28 +180,28 @@ class MBeanClientTest {
       // assert 1
       assertEquals(2, beanObjects.size());
       assertTrue(
-          beanObjects.stream().anyMatch(x -> x.getProperties().get("type").equals("ClassLoading")));
+          beanObjects.stream().anyMatch(x -> x.properties().get("type").equals("ClassLoading")));
       assertTrue(
-          beanObjects.stream().anyMatch(x -> x.getProperties().get("type").equals("Compilation")));
+          beanObjects.stream().anyMatch(x -> x.properties().get("type").equals("Compilation")));
 
       // arrange 2 look into ClassLoading content
 
       // act
       Optional<BeanObject> classLoading =
           beanObjects.stream()
-              .filter(x -> x.getProperties().get("type").equals("ClassLoading"))
+              .filter(x -> x.properties().get("type").equals("ClassLoading"))
               .findFirst();
 
       // assert
       assertTrue(classLoading.isPresent());
       assertEquals("java.lang", classLoading.get().domainName());
-      assertEquals(5, classLoading.get().getAttributes().size());
-      assertTrue(classLoading.get().getAttributes().containsKey("LoadedClassCount"));
-      assertTrue(classLoading.get().getAttributes().containsKey("ObjectName"));
-      assertTrue(classLoading.get().getAttributes().containsKey("TotalLoadedClassCount"));
-      assertTrue(classLoading.get().getAttributes().containsKey("UnloadedClassCount"));
-      assertTrue(classLoading.get().getAttributes().containsKey("Verbose"));
-      assertTrue(classLoading.get().getAttributes().get("Verbose") instanceof Boolean);
+      assertEquals(5, classLoading.get().attributes().size());
+      assertTrue(classLoading.get().attributes().containsKey("LoadedClassCount"));
+      assertTrue(classLoading.get().attributes().containsKey("ObjectName"));
+      assertTrue(classLoading.get().attributes().containsKey("TotalLoadedClassCount"));
+      assertTrue(classLoading.get().attributes().containsKey("UnloadedClassCount"));
+      assertTrue(classLoading.get().attributes().containsKey("Verbose"));
+      assertTrue(classLoading.get().attributes().get("Verbose") instanceof Boolean);
     }
   }
 
@@ -350,7 +350,7 @@ class MBeanClientTest {
       java.lang:{type=ClassLoading}
       Notice how everything with "type" is match, even those with "name"
       */
-      assertTrue(beanObjects.stream().anyMatch(x -> x.getProperties().containsKey("name")));
+      assertTrue(beanObjects.stream().anyMatch(x -> x.properties().containsKey("name")));
     }
   }
 
@@ -398,7 +398,7 @@ class MBeanClientTest {
       // assert
       Map<String, Object> mergedCollect =
           all.stream()
-              .flatMap(beanObject -> beanObject.getAttributes().entrySet().stream())
+              .flatMap(beanObject -> beanObject.attributes().entrySet().stream())
               .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
 
       assertEquals(500, mergedCollect.size());
@@ -425,7 +425,7 @@ class MBeanClientTest {
       // assert
       List<Map.Entry<String, String>> properties =
           all.stream()
-              .map(BeanObject::getProperties)
+              .map(BeanObject::properties)
               .map(Map::entrySet)
               .flatMap(Collection::stream)
               .collect(toList());
@@ -434,7 +434,7 @@ class MBeanClientTest {
 
       List<Map.Entry<String, Object>> attributes =
           all.stream()
-              .map(BeanObject::getAttributes)
+              .map(BeanObject::attributes)
               .map(Map::entrySet)
               .flatMap(Collection::stream)
               .collect(toList());
diff --git a/app/src/test/java/org/astraea/app/metrics/producer/HasProducerNodeMetricsTest.java b/app/src/test/java/org/astraea/app/metrics/producer/HasProducerNodeMetricsTest.java
index 4d4bc0af..ae8f0ec2 100644
--- a/app/src/test/java/org/astraea/app/metrics/producer/HasProducerNodeMetricsTest.java
+++ b/app/src/test/java/org/astraea/app/metrics/producer/HasProducerNodeMetricsTest.java
@@ -18,8 +18,8 @@ package org.astraea.app.metrics.producer;
 
 import java.util.concurrent.ExecutionException;
 import org.astraea.app.common.Utils;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.jmx.MBeanClient;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.producer.Producer;
 import org.astraea.app.service.RequireSingleBrokerCluster;
 import org.junit.jupiter.api.Assertions;
diff --git a/app/src/test/java/org/astraea/app/metrics/producer/HasProducerTopicMetricsTest.java b/app/src/test/java/org/astraea/app/metrics/producer/HasProducerTopicMetricsTest.java
index eab881af..067aeabb 100644
--- a/app/src/test/java/org/astraea/app/metrics/producer/HasProducerTopicMetricsTest.java
+++ b/app/src/test/java/org/astraea/app/metrics/producer/HasProducerTopicMetricsTest.java
@@ -18,8 +18,8 @@ package org.astraea.app.metrics.producer;
 
 import java.util.concurrent.ExecutionException;
 import org.astraea.app.common.Utils;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.jmx.MBeanClient;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.astraea.app.producer.Producer;
 import org.astraea.app.service.RequireSingleBrokerCluster;
 import org.junit.jupiter.api.Assertions;
diff --git a/app/src/test/java/org/astraea/app/service/RequireJmxServerTest.java b/app/src/test/java/org/astraea/app/service/RequireJmxServerTest.java
index 369ff54b..a121ceb6 100644
--- a/app/src/test/java/org/astraea/app/service/RequireJmxServerTest.java
+++ b/app/src/test/java/org/astraea/app/service/RequireJmxServerTest.java
@@ -17,9 +17,9 @@
 package org.astraea.app.service;
 
 import java.util.Set;
+import org.astraea.app.metrics.KafkaMetrics;
 import org.astraea.app.metrics.jmx.BeanQuery;
 import org.astraea.app.metrics.jmx.MBeanClient;
-import org.astraea.app.metrics.kafka.KafkaMetrics;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;