1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.protobuf;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import edu.umd.cs.findbugs.annotations.Nullable;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.hbase.classification.InterfaceAudience;
30 import org.apache.hadoop.hbase.Cell;
31 import org.apache.hadoop.hbase.CellScanner;
32 import org.apache.hadoop.hbase.DoNotRetryIOException;
33 import org.apache.hadoop.hbase.HRegionInfo;
34 import org.apache.hadoop.hbase.ServerName;
35 import org.apache.hadoop.hbase.client.Result;
36 import org.apache.hadoop.hbase.ipc.ServerRpcController;
37 import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GetUserPermissionsResponse;
38 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionResponse;
39 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionResponse;
40 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoResponse;
41 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionResponse;
42 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ServerInfo;
43 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
44 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiRequest;
45 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
46 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
47 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrException;
48 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse;
49 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiResponse;
50 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.RegionStoreSequenceIds;
51 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
52 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameBytesPair;
53 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameInt64Pair;
54 import org.apache.hadoop.hbase.protobuf.generated.MapReduceProtos.ScanMetrics;
55 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorResponse;
56 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanResponse;
57 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreResponse;
58 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdResponse;
59 import org.apache.hadoop.hbase.regionserver.RegionOpeningState;
60 import org.apache.hadoop.hbase.security.access.UserPermission;
61 import org.apache.hadoop.util.StringUtils;
62
63 import com.google.protobuf.ByteString;
64 import com.google.protobuf.RpcController;
65
66
67
68
69
70 @InterfaceAudience.Private
71 public final class ResponseConverter {
72 private static final Log LOG = LogFactory.getLog(ResponseConverter.class);
73
74 private ResponseConverter() {
75 }
76
77
78
79
80
81
82
83
84
85
86
87
88 public static org.apache.hadoop.hbase.client.MultiResponse getResults(final MultiRequest request,
89 final MultiResponse response, final CellScanner cells)
90 throws IOException {
91 return getResults(request, null, response, cells);
92 }
93
94
95
96
97
98
99
100
101
102
103
104 public static org.apache.hadoop.hbase.client.MultiResponse getResults(final MultiRequest request,
105 Map<Integer, Integer> rowMutationsIndexMap, final MultiResponse response, final CellScanner cells)
106 throws IOException {
107 int requestRegionActionCount = request.getRegionActionCount();
108 int responseRegionActionResultCount = response.getRegionActionResultCount();
109 if (requestRegionActionCount != responseRegionActionResultCount) {
110 throw new IllegalStateException("Request mutation count=" + requestRegionActionCount +
111 " does not match response mutation result count=" + responseRegionActionResultCount);
112 }
113
114 org.apache.hadoop.hbase.client.MultiResponse results =
115 new org.apache.hadoop.hbase.client.MultiResponse();
116
117 for (int i = 0; i < responseRegionActionResultCount; i++) {
118 RegionAction actions = request.getRegionAction(i);
119 RegionActionResult actionResult = response.getRegionActionResult(i);
120 HBaseProtos.RegionSpecifier rs = actions.getRegion();
121 if (rs.hasType() &&
122 (rs.getType() != HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME)){
123 throw new IllegalArgumentException(
124 "We support only encoded types for protobuf multi response.");
125 }
126 byte[] regionName = rs.getValue().toByteArray();
127
128 if (actionResult.hasException()) {
129 Throwable regionException = ProtobufUtil.toException(actionResult.getException());
130 results.addException(regionName, regionException);
131 continue;
132 }
133
134 if (actions.getActionCount() != actionResult.getResultOrExceptionCount()) {
135 throw new IllegalStateException("actions.getActionCount=" + actions.getActionCount() +
136 ", actionResult.getResultOrExceptionCount=" +
137 actionResult.getResultOrExceptionCount() + " for region " + actions.getRegion());
138 }
139
140 Object responseValue;
141
142 Integer rowMutationsIndex =
143 (rowMutationsIndexMap == null ? null : rowMutationsIndexMap.get(i));
144 if (rowMutationsIndex != null) {
145
146
147
148 responseValue = response.getProcessed() ?
149 ProtobufUtil.EMPTY_RESULT_EXISTS_TRUE :
150 ProtobufUtil.EMPTY_RESULT_EXISTS_FALSE;
151 results.add(regionName, rowMutationsIndex, responseValue);
152 continue;
153 }
154
155 for (ResultOrException roe : actionResult.getResultOrExceptionList()) {
156 if (roe.hasException()) {
157 responseValue = ProtobufUtil.toException(roe.getException());
158 } else if (roe.hasResult()) {
159 responseValue = ProtobufUtil.toResult(roe.getResult(), cells);
160 } else if (roe.hasServiceResult()) {
161 responseValue = roe.getServiceResult();
162 } else{
163
164
165
166 responseValue = response.getProcessed() ?
167 ProtobufUtil.EMPTY_RESULT_EXISTS_TRUE :
168 ProtobufUtil.EMPTY_RESULT_EXISTS_FALSE;
169 }
170 results.add(regionName, roe.getIndex(), responseValue);
171 }
172 }
173
174 if (response.hasRegionStatistics()) {
175 ClientProtos.MultiRegionLoadStats stats = response.getRegionStatistics();
176 for (int i = 0; i < stats.getRegionCount(); i++) {
177 results.addStatistic(stats.getRegion(i).getValue().toByteArray(), stats.getStat(i));
178 }
179 }
180
181 return results;
182 }
183
184
185
186
187
188
189
190 public static ResultOrException.Builder buildActionResult(final Throwable t) {
191 ResultOrException.Builder builder = ResultOrException.newBuilder();
192 if (t != null) builder.setException(buildException(t));
193 return builder;
194 }
195
196
197
198
199
200
201
202 public static ResultOrException.Builder buildActionResult(final ClientProtos.Result r) {
203 ResultOrException.Builder builder = ResultOrException.newBuilder();
204 if (r != null) builder.setResult(r);
205 return builder;
206 }
207
208
209
210
211
212 public static NameBytesPair buildException(final Throwable t) {
213 NameBytesPair.Builder parameterBuilder = NameBytesPair.newBuilder();
214 parameterBuilder.setName(t.getClass().getName());
215 parameterBuilder.setValue(
216 ByteString.copyFromUtf8(StringUtils.stringifyException(t)));
217 return parameterBuilder.build();
218 }
219
220
221
222
223 public static GetUserPermissionsResponse buildGetUserPermissionsResponse(
224 final List<UserPermission> permissions) {
225 GetUserPermissionsResponse.Builder builder = GetUserPermissionsResponse.newBuilder();
226 for (UserPermission perm : permissions) {
227 builder.addUserPermission(ProtobufUtil.toUserPermission(perm));
228 }
229 return builder.build();
230 }
231
232
233
234
235
236
237
238
239
240
241 public static List<HRegionInfo> getRegionInfos(final GetOnlineRegionResponse proto) {
242 if (proto == null || proto.getRegionInfoCount() == 0) return null;
243 return ProtobufUtil.getRegionInfos(proto);
244 }
245
246
247
248
249
250
251
252 public static RegionOpeningState getRegionOpeningState
253 (final OpenRegionResponse proto) {
254 if (proto == null || proto.getOpeningStateCount() != 1) return null;
255 return RegionOpeningState.valueOf(
256 proto.getOpeningState(0).name());
257 }
258
259
260
261
262
263
264
265 public static List<RegionOpeningState> getRegionOpeningStateList(
266 final OpenRegionResponse proto) {
267 if (proto == null) return null;
268 List<RegionOpeningState> regionOpeningStates = new ArrayList<RegionOpeningState>();
269 for (int i = 0; i < proto.getOpeningStateCount(); i++) {
270 regionOpeningStates.add(RegionOpeningState.valueOf(
271 proto.getOpeningState(i).name()));
272 }
273 return regionOpeningStates;
274 }
275
276
277
278
279
280
281
282 public static boolean isClosed
283 (final CloseRegionResponse proto) {
284 if (proto == null || !proto.hasClosed()) return false;
285 return proto.getClosed();
286 }
287
288
289
290
291
292
293
294
295 public static GetServerInfoResponse buildGetServerInfoResponse(
296 final ServerName serverName, final int webuiPort) {
297 GetServerInfoResponse.Builder builder = GetServerInfoResponse.newBuilder();
298 ServerInfo.Builder serverInfoBuilder = ServerInfo.newBuilder();
299 serverInfoBuilder.setServerName(ProtobufUtil.toServerName(serverName));
300 if (webuiPort >= 0) {
301 serverInfoBuilder.setWebuiPort(webuiPort);
302 }
303 builder.setServerInfo(serverInfoBuilder.build());
304 return builder.build();
305 }
306
307
308
309
310
311
312
313 public static GetOnlineRegionResponse buildGetOnlineRegionResponse(
314 final List<HRegionInfo> regions) {
315 GetOnlineRegionResponse.Builder builder = GetOnlineRegionResponse.newBuilder();
316 for (HRegionInfo region: regions) {
317 builder.addRegionInfo(HRegionInfo.convert(region));
318 }
319 return builder.build();
320 }
321
322
323
324
325
326 public static RunCatalogScanResponse buildRunCatalogScanResponse(int numCleaned) {
327 return RunCatalogScanResponse.newBuilder().setScanResult(numCleaned).build();
328 }
329
330
331
332
333
334 public static EnableCatalogJanitorResponse buildEnableCatalogJanitorResponse(boolean prevValue) {
335 return EnableCatalogJanitorResponse.newBuilder().setPrevValue(prevValue).build();
336 }
337
338
339
340
341
342 public static RunCleanerChoreResponse buildRunCleanerChoreResponse(boolean ran) {
343 return RunCleanerChoreResponse.newBuilder().setCleanerChoreRan(ran).build();
344 }
345
346
347
348
349
350
351
352 public static GetLastFlushedSequenceIdResponse buildGetLastFlushedSequenceIdResponse(
353 RegionStoreSequenceIds ids) {
354 return GetLastFlushedSequenceIdResponse.newBuilder()
355 .setLastFlushedSequenceId(ids.getLastFlushedSequenceId())
356 .addAllStoreLastFlushedSequenceId(ids.getStoreSequenceIdList()).build();
357 }
358
359
360
361
362
363
364
365 public static void setControllerException(RpcController controller, IOException ioe) {
366 if (controller != null) {
367 if (controller instanceof ServerRpcController) {
368 ((ServerRpcController)controller).setFailedOn(ioe);
369 } else {
370 controller.setFailed(StringUtils.stringifyException(ioe));
371 }
372 }
373 }
374
375
376
377
378
379
380
381 @Nullable
382 public static IOException getControllerException(RpcController controller) throws IOException {
383 if (controller != null && controller.failed()) {
384 if (controller instanceof ServerRpcController) {
385 return ((ServerRpcController)controller).getFailedOn();
386 } else {
387 return new DoNotRetryIOException(controller.errorText());
388 }
389 }
390 return null;
391 }
392
393
394
395
396
397
398
399
400 public static Result[] getResults(CellScanner cellScanner, ScanResponse response)
401 throws IOException {
402 if (response == null) return null;
403
404
405 int noOfResults = cellScanner != null?
406 response.getCellsPerResultCount(): response.getResultsCount();
407 Result[] results = new Result[noOfResults];
408 for (int i = 0; i < noOfResults; i++) {
409 if (cellScanner != null) {
410
411
412 int noOfCells = response.getCellsPerResult(i);
413 boolean isPartial =
414 response.getPartialFlagPerResultCount() > i ?
415 response.getPartialFlagPerResult(i) : false;
416 List<Cell> cells = new ArrayList<Cell>(noOfCells);
417 for (int j = 0; j < noOfCells; j++) {
418 try {
419 if (cellScanner.advance() == false) {
420
421
422
423 String msg = "Results sent from server=" + noOfResults + ". But only got " + i
424 + " results completely at client. Resetting the scanner to scan again.";
425 LOG.error(msg);
426 throw new DoNotRetryIOException(msg);
427 }
428 } catch (IOException ioe) {
429
430
431
432 LOG.error("Exception while reading cells from result."
433 + "Resetting the scanner to scan again.", ioe);
434 throw new DoNotRetryIOException("Resetting the scanner.", ioe);
435 }
436 cells.add(cellScanner.current());
437 }
438 results[i] = Result.create(cells, null, response.getStale(), isPartial);
439 } else {
440
441 results[i] = ProtobufUtil.toResult(response.getResults(i));
442 }
443 }
444 return results;
445 }
446
447 public static Map<String, Long> getScanMetrics(ScanResponse response) {
448 Map<String, Long> metricMap = new HashMap<String, Long>();
449 if (response == null || !response.hasScanMetrics()) {
450 return metricMap;
451 }
452 ScanMetrics metrics = response.getScanMetrics();
453 int numberOfMetrics = metrics.getMetricsCount();
454 for (int i = 0; i < numberOfMetrics; i++) {
455 NameInt64Pair metricPair = metrics.getMetrics(i);
456 if (metricPair != null) {
457 String name = metricPair.getName();
458 Long value = metricPair.getValue();
459 if (name != null && value != null) {
460 metricMap.put(name, value);
461 }
462 }
463 }
464
465 return metricMap;
466 }
467 }