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