1
2
3
4
5
6
7
8
9
10
11
12 package org.apache.hadoop.hbase.coprocessor;
13
14 import static org.junit.Assert.assertEquals;
15 import static org.junit.Assert.assertNotNull;
16
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.Hashtable;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Random;
24 import java.util.Set;
25
26 import javax.management.MBeanAttributeInfo;
27 import javax.management.MBeanInfo;
28 import javax.management.MBeanServerConnection;
29 import javax.management.ObjectInstance;
30 import javax.management.ObjectName;
31 import javax.management.remote.JMXConnector;
32 import javax.management.remote.JMXConnectorFactory;
33
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.JMXListener;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.client.Put;
39 import org.apache.hadoop.hbase.client.Table;
40 import org.apache.hadoop.hbase.testclassification.CoprocessorTests;
41 import org.apache.hadoop.hbase.testclassification.MediumTests;
42 import org.apache.hadoop.hbase.util.Bytes;
43 import org.apache.hadoop.hbase.util.Threads;
44 import org.junit.AfterClass;
45 import org.junit.BeforeClass;
46 import org.junit.Test;
47 import org.junit.experimental.categories.Category;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52 @Category({ CoprocessorTests.class, MediumTests.class })
53 public class TestMetaTableMetrics {
54
55 private static final Logger LOG = LoggerFactory.getLogger(TestMetaTableMetrics.class);
56
57 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
58 private static final TableName NAME1 = TableName.valueOf("TestExampleMetaTableMetricsOne");
59 private static final byte[] FAMILY = Bytes.toBytes("f");
60 private static final byte[] QUALIFIER = Bytes.toBytes("q");
61 private static final int NUM_ROWS = 5;
62 private static final String value = "foo";
63 private static Configuration conf = null;
64 private static int connectorPort = 61120;
65
66 @BeforeClass
67 public static void setupBeforeClass() throws Exception {
68
69 conf = UTIL.getConfiguration();
70
71 UTIL.getConfiguration().set("hbase.coprocessor.region.classes",
72 MetaTableMetrics.class.getName());
73 conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY, JMXListener.class.getName());
74 Random rand = new Random();
75 for (int i = 0; i < 10; i++) {
76 do {
77 int sign = i % 2 == 0 ? 1 : -1;
78 connectorPort += sign * rand.nextInt(100);
79 } while (!HBaseTestingUtility.available(connectorPort));
80 try {
81 conf.setInt("regionserver.rmi.registry.port", connectorPort);
82 UTIL.startMiniCluster(1);
83 UTIL.createTable(NAME1, new byte[][]{FAMILY});
84 LOG.error("util to string" + UTIL.toString());
85 break;
86 } catch (Exception e) {
87 LOG.debug("Encountered exception when starting cluster. Trying port " + connectorPort, e);
88 try {
89
90 UTIL.shutdownMiniCluster();
91 } catch (Exception ex) {
92 LOG.debug("Encountered exception shutting down cluster", ex);
93 }
94 }
95 }
96 }
97
98 @AfterClass
99 public static void tearDown() throws Exception {
100 UTIL.shutdownMiniCluster();
101 }
102
103 private void writeData(Table t) throws IOException {
104 List<Put> puts = new ArrayList<>(NUM_ROWS);
105 for (int i = 0; i < NUM_ROWS; i++) {
106 Put p = new Put(Bytes.toBytes(i + 1));
107 p.addColumn(FAMILY, QUALIFIER, Bytes.toBytes(value));
108 puts.add(p);
109 }
110 t.put(puts);
111 }
112
113 private Set<String> readJmxMetricsWithRetry() throws IOException {
114 final int count = 0;
115 for (int i = 0; i < 10; i++) {
116 Set<String> metrics = readJmxMetrics();
117 if (metrics != null) {
118 return metrics;
119 }
120 LOG.warn("Failed to get jmxmetrics... sleeping, retrying; " + i + " of " + count + " times");
121 Threads.sleep(1000);
122 }
123 return null;
124 }
125
126
127
128
129
130
131 private Set<String> readJmxMetrics() throws IOException {
132 JMXConnector connector = null;
133 ObjectName target = null;
134 MBeanServerConnection mb = null;
135 try {
136 connector =
137 JMXConnectorFactory.connect(JMXListener.buildJMXServiceURL(connectorPort, connectorPort));
138 mb = connector.getMBeanServerConnection();
139
140 @SuppressWarnings("JdkObsolete")
141 Hashtable<String, String> pairs = new Hashtable<>();
142 pairs.put("service", "HBase");
143 pairs.put("name", "RegionServer");
144 pairs.put("sub",
145 "Coprocessor.Region.CP_org.apache.hadoop.hbase.coprocessor"
146 + ".MetaTableMetrics");
147 target = new ObjectName("Hadoop", pairs);
148 MBeanInfo beanInfo = mb.getMBeanInfo(target);
149
150 Set<String> existingAttrs = new HashSet<>();
151 for (MBeanAttributeInfo attrInfo : beanInfo.getAttributes()) {
152 existingAttrs.add(attrInfo.getName());
153 }
154 return existingAttrs;
155 } catch (Exception e) {
156 LOG.warn("Failed to get bean." + target, e);
157 if (mb != null) {
158 Set<ObjectInstance> instances = mb.queryMBeans(null, null);
159 Iterator<ObjectInstance> iterator = instances.iterator();
160 LOG.warn("MBean Found:");
161 while (iterator.hasNext()) {
162 ObjectInstance instance = iterator.next();
163 LOG.warn("Class Name: " + instance.getClassName());
164 LOG.warn("Object Name: " + instance.getObjectName());
165 }
166 }
167 } finally {
168 if (connector != null) {
169 try {
170 connector.close();
171 } catch (Exception e) {
172 e.printStackTrace();
173 }
174 }
175 }
176 return null;
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 @Test
193 public void test() throws IOException, InterruptedException {
194 try (Table t = UTIL.getConnection().getTable(NAME1)) {
195 writeData(t);
196
197 UTIL.flush(NAME1);
198
199 UTIL.compact(NAME1, true);
200 Thread.sleep(2000);
201 }
202 Set<String> jmxMetrics = readJmxMetricsWithRetry();
203 assertNotNull(jmxMetrics);
204
205 long name1TableMetricsCount = 0;
206 for(String metric : jmxMetrics) {
207 if (metric.contains("MetaTable_table_" + NAME1)){
208 name1TableMetricsCount++;
209 }
210 }
211 assertEquals(5L, name1TableMetricsCount);
212
213 String putWithClientMetricNameRegex = "MetaTable_client_.+_put_request.*";
214 long putWithClientMetricsCount = 0;
215 for(String metric : jmxMetrics) {
216 if(metric.matches(putWithClientMetricNameRegex)) {
217 putWithClientMetricsCount++;
218 }
219 }
220 assertEquals(5L, putWithClientMetricsCount);
221 }
222
223 }