001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.master.http;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021
022import java.lang.reflect.Method;
023import java.util.ArrayList;
024import java.util.Arrays;
025import java.util.Collections;
026import java.util.List;
027import java.util.Objects;
028import java.util.Random;
029import java.util.stream.Collectors;
030import org.apache.hadoop.hbase.RegionMetrics;
031import org.apache.hadoop.hbase.RegionMetricsBuilder;
032import org.apache.hadoop.hbase.ServerName;
033import org.apache.hadoop.hbase.TableName;
034import org.apache.hadoop.hbase.client.RegionInfo;
035import org.apache.hadoop.hbase.client.RegionInfoBuilder;
036import org.apache.hadoop.hbase.master.http.RegionVisualizer.RegionDetails;
037import org.apache.hadoop.hbase.testclassification.MasterTests;
038import org.apache.hadoop.hbase.testclassification.SmallTests;
039import org.junit.jupiter.api.BeforeAll;
040import org.junit.jupiter.api.Tag;
041import org.junit.jupiter.api.Test;
042
043import org.apache.hbase.thirdparty.com.google.gson.Gson;
044import org.apache.hbase.thirdparty.com.google.gson.JsonObject;
045
046@Tag(MasterTests.TAG)
047@Tag(SmallTests.TAG)
048public class TestRegionVisualizer {
049
050  private static final Random rand = new Random();
051  private static List<Method> regionMetricsBuilderLongValueSetters;
052
053  @BeforeAll
054  public static void beforeClass() {
055    regionMetricsBuilderLongValueSetters =
056      Arrays.stream(RegionMetricsBuilder.class.getDeclaredMethods())
057        .filter(method -> method.getName().startsWith("set"))
058        .filter(method -> method.getParameterTypes().length == 1)
059        .filter(method -> Objects.equals(method.getParameterTypes()[0], long.class))
060        .collect(Collectors.toList());
061  }
062
063  @Test
064  public void testRegionDetailsJsonSerialization() throws Exception {
065    final ServerName serverName =
066      ServerName.valueOf("example.org", 1234, System.currentTimeMillis());
067    final TableName tableName = TableName.valueOf("foo", "bar");
068    final RegionDetails regionDetails =
069      new RegionDetails(serverName, tableName, buildRegionMetrics(tableName));
070
071    final Gson gson = RegionVisualizer.buildGson();
072    final JsonObject result = gson.fromJson(gson.toJson(regionDetails), JsonObject.class);
073    assertEquals(serverName.toShortString(), result.get("server_name").getAsString());
074    assertEquals(tableName.getNameAsString(), result.get("table_name").getAsString());
075  }
076
077  /**
078   * Build a {@link RegionMetrics} object for {@code tableName}. Populates a couple random fields
079   * with non-empty values.
080   */
081  final RegionMetrics buildRegionMetrics(final TableName tableName) throws Exception {
082    final List<Method> setters = new ArrayList<>(regionMetricsBuilderLongValueSetters);
083    Collections.shuffle(setters, rand);
084
085    final RegionInfo regionInfo = RegionInfoBuilder.newBuilder(tableName).build();
086    final RegionMetricsBuilder builder =
087      RegionMetricsBuilder.newBuilder(regionInfo.getRegionName());
088    for (final Method setter : setters.subList(0, 3)) {
089      setter.invoke(builder, rand.nextLong());
090    }
091    return builder.build();
092  }
093}