1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.hbtop.screen.top;
19
20 import edu.umd.cs.findbugs.annotations.Nullable;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.List;
25 import java.util.Objects;
26 import org.apache.commons.lang3.time.DateFormatUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.hbase.ClusterStatus;
30 import org.apache.hadoop.hbase.ServerLoad;
31 import org.apache.hadoop.hbase.ServerName;
32 import org.apache.hadoop.hbase.classification.InterfaceAudience;
33 import org.apache.hadoop.hbase.client.Admin;
34 import org.apache.hadoop.hbase.hbtop.Record;
35 import org.apache.hadoop.hbase.hbtop.RecordFilter;
36 import org.apache.hadoop.hbase.hbtop.field.Field;
37 import org.apache.hadoop.hbase.hbtop.field.FieldInfo;
38 import org.apache.hadoop.hbase.hbtop.field.FieldValue;
39 import org.apache.hadoop.hbase.hbtop.mode.DrillDownInfo;
40 import org.apache.hadoop.hbase.hbtop.mode.Mode;
41
42
43
44
45 @InterfaceAudience.Private
46 public class TopScreenModel {
47
48 private static final Log LOG = LogFactory.getLog(TopScreenModel.class);
49
50 private final Admin admin;
51
52 private Mode currentMode;
53 private Field currentSortField;
54 private List<FieldInfo> fieldInfos;
55 private List<Field> fields;
56
57 private Summary summary;
58 private List<Record> records;
59
60 private final List<RecordFilter> filters = new ArrayList<>();
61 private final List<String> filterHistories = new ArrayList<>();
62
63 private boolean ascendingSort;
64
65 public TopScreenModel(Admin admin, Mode initialMode, @Nullable List<Field> initialFields,
66 @Nullable Field initialSortField, @Nullable Boolean initialAscendingSort,
67 @Nullable List<RecordFilter> initialFilters) {
68 this.admin = Objects.requireNonNull(admin);
69 switchMode(Objects.requireNonNull(initialMode), initialSortField, false, initialFields,
70 initialAscendingSort, initialFilters);
71 }
72
73 public void switchMode(Mode nextMode, boolean keepSortFieldAndSortOrderIfPossible,
74 List<RecordFilter> initialFilters) {
75 switchMode(nextMode, null, keepSortFieldAndSortOrderIfPossible, null, null, initialFilters);
76 }
77
78 public void switchMode(Mode nextMode, Field initialSortField,
79 boolean keepSortFieldAndSortOrderIfPossible, @Nullable List<Field> initialFields,
80 @Nullable Boolean initialAscendingSort, @Nullable List<RecordFilter> initialFilters) {
81 currentMode = nextMode;
82 fieldInfos = Collections.unmodifiableList(new ArrayList<>(currentMode.getFieldInfos()));
83
84 fields = new ArrayList<>();
85 for (FieldInfo fieldInfo : currentMode.getFieldInfos()) {
86 if (initialFields != null) {
87 if (initialFields.contains(fieldInfo.getField())) {
88 fields.add(fieldInfo.getField());
89 }
90 } else {
91 fields.add(fieldInfo.getField());
92 }
93 }
94 fields = Collections.unmodifiableList(fields);
95
96 if (keepSortFieldAndSortOrderIfPossible) {
97 boolean match = false;
98 for (Field field : fields) {
99 if (field == currentSortField) {
100 match = true;
101 break;
102 }
103 }
104
105 if (!match) {
106 if (initialSortField != null && initialAscendingSort != null) {
107 currentSortField = initialSortField;
108 ascendingSort = initialAscendingSort;
109 } else {
110 currentSortField = nextMode.getDefaultSortField();
111 ascendingSort = false;
112 }
113 }
114 } else {
115 if (initialSortField != null && initialAscendingSort != null) {
116 currentSortField = initialSortField;
117 ascendingSort = initialAscendingSort;
118 } else {
119 currentSortField = nextMode.getDefaultSortField();
120 ascendingSort = false;
121 }
122 }
123
124 clearFilters();
125 if (initialFilters != null) {
126 filters.addAll(initialFilters);
127 }
128 }
129
130 public void setSortFieldAndFields(Field sortField, List<Field> fields) {
131 this.currentSortField = sortField;
132 this.fields = Collections.unmodifiableList(new ArrayList<>(fields));
133 }
134
135
136
137
138
139 public void refreshMetricsData() {
140 ClusterStatus clusterStatus;
141 try {
142 clusterStatus = admin.getClusterStatus();
143 } catch (Exception e) {
144 LOG.error("Unable to get cluster status", e);
145 return;
146 }
147
148 refreshSummary(clusterStatus);
149 refreshRecords(clusterStatus);
150 }
151
152 private void refreshSummary(ClusterStatus clusterStatus) {
153 String currentTime = DateFormatUtils.ISO_8601_EXTENDED_TIME_FORMAT
154 .format(System.currentTimeMillis());
155 String version = clusterStatus.getHBaseVersion();
156 String clusterId = clusterStatus.getClusterId();
157 int liveServers = clusterStatus.getServersSize();
158 int deadServers = clusterStatus.getDeadServerNames().size();
159 int regionCount = clusterStatus.getRegionsCount();
160 int ritCount = clusterStatus.getRegionsInTransition().size();
161 double averageLoad = clusterStatus.getAverageLoad();
162 long aggregateRequestPerSecond = 0;
163 for (ServerName sn: clusterStatus.getServers()) {
164 ServerLoad sl = clusterStatus.getLoad(sn);
165 aggregateRequestPerSecond += sl.getNumberOfRequests();
166 }
167 summary = new Summary(currentTime, version, clusterId, liveServers + deadServers,
168 liveServers, deadServers, regionCount, ritCount, averageLoad, aggregateRequestPerSecond);
169 }
170
171 private void refreshRecords(ClusterStatus clusterStatus) {
172
173 List<Record> records = new ArrayList<>();
174 for (Record record : currentMode.getRecords(clusterStatus)) {
175 boolean filter = false;
176 for (RecordFilter recordFilter : filters) {
177 if (!recordFilter.execute(record)) {
178 filter = true;
179 break;
180 }
181 }
182 if (!filter) {
183 records.add(record);
184 }
185 }
186
187
188 Collections.sort(records, new Comparator<Record>() {
189 @Override
190 public int compare(Record recordLeft, Record recordRight) {
191 FieldValue left = recordLeft.get(currentSortField);
192 FieldValue right = recordRight.get(currentSortField);
193 return (ascendingSort ? 1 : -1) * left.compareTo(right);
194 }
195 });
196
197 this.records = Collections.unmodifiableList(records);
198 }
199
200 public void switchSortOrder() {
201 ascendingSort = !ascendingSort;
202 }
203
204 public boolean addFilter(String filterString, boolean ignoreCase) {
205 RecordFilter filter = RecordFilter.parse(filterString, fields, ignoreCase);
206 if (filter == null) {
207 return false;
208 }
209
210 filters.add(filter);
211 filterHistories.add(filterString);
212 return true;
213 }
214
215 public void clearFilters() {
216 filters.clear();
217 }
218
219 public boolean drillDown(Record selectedRecord) {
220 DrillDownInfo drillDownInfo = currentMode.drillDown(selectedRecord);
221 if (drillDownInfo == null) {
222 return false;
223 }
224 switchMode(drillDownInfo.getNextMode(), true, drillDownInfo.getInitialFilters());
225 return true;
226 }
227
228 public Mode getCurrentMode() {
229 return currentMode;
230 }
231
232 public Field getCurrentSortField() {
233 return currentSortField;
234 }
235
236 public List<FieldInfo> getFieldInfos() {
237 return fieldInfos;
238 }
239
240 public List<Field> getFields() {
241 return fields;
242 }
243
244 public Summary getSummary() {
245 return summary;
246 }
247
248 public List<Record> getRecords() {
249 return records;
250 }
251
252 public List<RecordFilter> getFilters() {
253 return Collections.unmodifiableList(filters);
254 }
255
256 public List<String> getFilterHistories() {
257 return Collections.unmodifiableList(filterHistories);
258 }
259 }