View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.protobuf;
19  
20  import java.io.IOException;
21  import java.util.List;
22  
23  import com.google.protobuf.HBaseZeroCopyByteString;
24  import org.apache.hadoop.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.CellScannable;
26  import org.apache.hadoop.hbase.DoNotRetryIOException;
27  import org.apache.hadoop.hbase.HColumnDescriptor;
28  import org.apache.hadoop.hbase.HConstants;
29  import org.apache.hadoop.hbase.HRegionInfo;
30  import org.apache.hadoop.hbase.HTableDescriptor;
31  import org.apache.hadoop.hbase.ServerName;
32  import org.apache.hadoop.hbase.TableName;
33  import org.apache.hadoop.hbase.client.Action;
34  import org.apache.hadoop.hbase.client.Append;
35  import org.apache.hadoop.hbase.client.Delete;
36  import org.apache.hadoop.hbase.client.Durability;
37  import org.apache.hadoop.hbase.client.Get;
38  import org.apache.hadoop.hbase.client.Increment;
39  import org.apache.hadoop.hbase.client.Mutation;
40  import org.apache.hadoop.hbase.client.Put;
41  import org.apache.hadoop.hbase.client.RegionCoprocessorServiceExec;
42  import org.apache.hadoop.hbase.client.Row;
43  import org.apache.hadoop.hbase.client.RowMutations;
44  import org.apache.hadoop.hbase.client.Scan;
45  import org.apache.hadoop.hbase.exceptions.DeserializationException;
46  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
47  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
48  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
49  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
50  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
51  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest.RegionUpdateInfo;
63  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
64  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest;
65  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest.FamilyPath;
66  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Column;
67  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Condition;
68  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
69  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
70  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
71  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue;
72  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue;
73  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType;
74  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
75  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
76  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType;
77  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
78  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
79  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AddColumnRequest;
80  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AssignRegionRequest;
81  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.BalanceRequest;
82  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
83  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteColumnRequest;
84  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableRequest;
85  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableRequest;
86  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
87  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest;
88  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
89  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
90  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
91  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
92  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
93  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
94  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
95  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
96  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
97  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
98  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
99  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
101 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest;
102 import org.apache.hadoop.hbase.util.Bytes;
103 import org.apache.hadoop.hbase.util.Pair;
104 import org.apache.hadoop.hbase.util.Triple;
105 
106 import com.google.protobuf.ByteString;
107 
108 /**
109  * Helper utility to build protocol buffer requests,
110  * or build components for protocol buffer requests.
111  */
112 @InterfaceAudience.Private
113 public final class RequestConverter {
114 
115   private RequestConverter() {
116   }
117 
118 // Start utilities for Client
119 
120 /**
121    * Create a new protocol buffer GetRequest to get a row, all columns in a family.
122    * If there is no such row, return the closest row before it.
123    *
124    * @param regionName the name of the region to get
125    * @param row the row to get
126    * @param family the column family to get
127    * should return the immediate row before
128    * @return a protocol buffer GetReuqest
129    */
130   public static GetRequest buildGetRowOrBeforeRequest(
131       final byte[] regionName, final byte[] row, final byte[] family) {
132     GetRequest.Builder builder = GetRequest.newBuilder();
133     RegionSpecifier region = buildRegionSpecifier(
134       RegionSpecifierType.REGION_NAME, regionName);
135     builder.setRegion(region);
136 
137     Column.Builder columnBuilder = Column.newBuilder();
138     columnBuilder.setFamily(HBaseZeroCopyByteString.wrap(family));
139     ClientProtos.Get.Builder getBuilder =
140       ClientProtos.Get.newBuilder();
141     getBuilder.setRow(HBaseZeroCopyByteString.wrap(row));
142     getBuilder.addColumn(columnBuilder.build());
143     getBuilder.setClosestRowBefore(true);
144     builder.setGet(getBuilder.build());
145     return builder.build();
146   }
147 
148 
149   /**
150    * Create a protocol buffer GetRequest for a client Get
151    *
152    * @param regionName the name of the region to get
153    * @param get the client Get
154    * @return a protocol buffer GetRequest
155    */
156   public static GetRequest buildGetRequest(final byte[] regionName,
157       final Get get) throws IOException {
158     GetRequest.Builder builder = GetRequest.newBuilder();
159     RegionSpecifier region = buildRegionSpecifier(
160       RegionSpecifierType.REGION_NAME, regionName);
161     builder.setRegion(region);
162     builder.setGet(ProtobufUtil.toGet(get));
163     return builder.build();
164   }
165 
166   /**
167    * Create a protocol buffer MutateRequest for a client increment
168    *
169    * @param regionName
170    * @param row
171    * @param family
172    * @param qualifier
173    * @param amount
174    * @param durability
175    * @return a mutate request
176    */
177   public static MutateRequest buildIncrementRequest(
178       final byte[] regionName, final byte[] row, final byte[] family, final byte[] qualifier,
179       final long amount, final Durability durability, long nonceGroup, long nonce) {
180     MutateRequest.Builder builder = MutateRequest.newBuilder();
181     RegionSpecifier region = buildRegionSpecifier(
182       RegionSpecifierType.REGION_NAME, regionName);
183     builder.setRegion(region);
184 
185     MutationProto.Builder mutateBuilder = MutationProto.newBuilder();
186     mutateBuilder.setRow(HBaseZeroCopyByteString.wrap(row));
187     mutateBuilder.setMutateType(MutationType.INCREMENT);
188     mutateBuilder.setDurability(ProtobufUtil.toDurability(durability));
189     ColumnValue.Builder columnBuilder = ColumnValue.newBuilder();
190     columnBuilder.setFamily(HBaseZeroCopyByteString.wrap(family));
191     QualifierValue.Builder valueBuilder = QualifierValue.newBuilder();
192     valueBuilder.setValue(HBaseZeroCopyByteString.wrap(Bytes.toBytes(amount)));
193     valueBuilder.setQualifier(HBaseZeroCopyByteString.wrap(qualifier));
194     columnBuilder.addQualifierValue(valueBuilder.build());
195     mutateBuilder.addColumnValue(columnBuilder.build());
196     if (nonce != HConstants.NO_NONCE) {
197       mutateBuilder.setNonce(nonce);
198     }
199     builder.setMutation(mutateBuilder.build());
200     if (nonceGroup != HConstants.NO_NONCE) {
201       builder.setNonceGroup(nonceGroup);
202     }
203     return builder.build();
204   }
205 
206   /**
207    * Create a protocol buffer MutateRequest for a conditioned put
208    *
209    * @param regionName
210    * @param row
211    * @param family
212    * @param qualifier
213    * @param comparator
214    * @param compareType
215    * @param put
216    * @return a mutate request
217    * @throws IOException
218    */
219   public static MutateRequest buildMutateRequest(
220       final byte[] regionName, final byte[] row, final byte[] family,
221       final byte [] qualifier, final ByteArrayComparable comparator,
222       final CompareType compareType, final Put put) throws IOException {
223     MutateRequest.Builder builder = MutateRequest.newBuilder();
224     RegionSpecifier region = buildRegionSpecifier(
225       RegionSpecifierType.REGION_NAME, regionName);
226     builder.setRegion(region);
227     Condition condition = buildCondition(
228       row, family, qualifier, comparator, compareType);
229     builder.setMutation(ProtobufUtil.toMutation(MutationType.PUT, put, MutationProto.newBuilder()));
230     builder.setCondition(condition);
231     return builder.build();
232   }
233 
234   /**
235    * Create a protocol buffer MutateRequest for a conditioned delete
236    *
237    * @param regionName
238    * @param row
239    * @param family
240    * @param qualifier
241    * @param comparator
242    * @param compareType
243    * @param delete
244    * @return a mutate request
245    * @throws IOException
246    */
247   public static MutateRequest buildMutateRequest(
248       final byte[] regionName, final byte[] row, final byte[] family,
249       final byte [] qualifier, final ByteArrayComparable comparator,
250       final CompareType compareType, final Delete delete) throws IOException {
251     MutateRequest.Builder builder = MutateRequest.newBuilder();
252     RegionSpecifier region = buildRegionSpecifier(
253       RegionSpecifierType.REGION_NAME, regionName);
254     builder.setRegion(region);
255     Condition condition = buildCondition(
256       row, family, qualifier, comparator, compareType);
257     builder.setMutation(ProtobufUtil.toMutation(MutationType.DELETE, delete,
258       MutationProto.newBuilder()));
259     builder.setCondition(condition);
260     return builder.build();
261   }
262 
263   /**
264    * Create a protocol buffer MutateRequest for a put
265    *
266    * @param regionName
267    * @param put
268    * @return a mutate request
269    * @throws IOException
270    */
271   public static MutateRequest buildMutateRequest(
272       final byte[] regionName, final Put put) throws IOException {
273     MutateRequest.Builder builder = MutateRequest.newBuilder();
274     RegionSpecifier region = buildRegionSpecifier(
275       RegionSpecifierType.REGION_NAME, regionName);
276     builder.setRegion(region);
277     builder.setMutation(ProtobufUtil.toMutation(MutationType.PUT, put, MutationProto.newBuilder()));
278     return builder.build();
279   }
280 
281   /**
282    * Create a protocol buffer MutateRequest for an append
283    *
284    * @param regionName
285    * @param append
286    * @return a mutate request
287    * @throws IOException
288    */
289   public static MutateRequest buildMutateRequest(final byte[] regionName,
290       final Append append, long nonceGroup, long nonce) throws IOException {
291     MutateRequest.Builder builder = MutateRequest.newBuilder();
292     RegionSpecifier region = buildRegionSpecifier(
293       RegionSpecifierType.REGION_NAME, regionName);
294     builder.setRegion(region);
295     if (nonce != HConstants.NO_NONCE && nonceGroup != HConstants.NO_NONCE) {
296       builder.setNonceGroup(nonceGroup);
297     }
298     builder.setMutation(ProtobufUtil.toMutation(MutationType.APPEND, append,
299       MutationProto.newBuilder(), nonce));
300     return builder.build();
301   }
302 
303   /**
304    * Create a protocol buffer MutateRequest for a client increment
305    *
306    * @param regionName
307    * @param increment
308    * @return a mutate request
309    */
310   public static MutateRequest buildMutateRequest(final byte[] regionName,
311       final Increment increment, final long nonceGroup, final long nonce) {
312     MutateRequest.Builder builder = MutateRequest.newBuilder();
313     RegionSpecifier region = buildRegionSpecifier(
314       RegionSpecifierType.REGION_NAME, regionName);
315     builder.setRegion(region);
316     if (nonce != HConstants.NO_NONCE && nonceGroup != HConstants.NO_NONCE) {
317       builder.setNonceGroup(nonceGroup);
318     }
319     builder.setMutation(ProtobufUtil.toMutation(increment, MutationProto.newBuilder(), nonce));
320     return builder.build();
321   }
322 
323   /**
324    * Create a protocol buffer MutateRequest for a delete
325    *
326    * @param regionName
327    * @param delete
328    * @return a mutate request
329    * @throws IOException
330    */
331   public static MutateRequest buildMutateRequest(
332       final byte[] regionName, final Delete delete) throws IOException {
333     MutateRequest.Builder builder = MutateRequest.newBuilder();
334     RegionSpecifier region = buildRegionSpecifier(
335       RegionSpecifierType.REGION_NAME, regionName);
336     builder.setRegion(region);
337     builder.setMutation(ProtobufUtil.toMutation(MutationType.DELETE, delete,
338       MutationProto.newBuilder()));
339     return builder.build();
340   }
341 
342   /**
343    * Create a protocol buffer MultiRequest for row mutations.
344    * Does not propagate Action absolute position.  Does not set atomic action on the created
345    * RegionAtomic.  Caller should do that if wanted.
346    * @param regionName
347    * @param rowMutations
348    * @return a data-laden RegionMutation.Builder
349    * @throws IOException
350    */
351   public static RegionAction.Builder buildRegionAction(final byte [] regionName,
352       final RowMutations rowMutations)
353   throws IOException {
354     RegionAction.Builder builder =
355       getRegionActionBuilderWithRegion(RegionAction.newBuilder(), regionName);
356     ClientProtos.Action.Builder actionBuilder = ClientProtos.Action.newBuilder();
357     MutationProto.Builder mutationBuilder = MutationProto.newBuilder();
358     for (Mutation mutation: rowMutations.getMutations()) {
359       MutationType mutateType = null;
360       if (mutation instanceof Put) {
361         mutateType = MutationType.PUT;
362       } else if (mutation instanceof Delete) {
363         mutateType = MutationType.DELETE;
364       } else {
365         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
366           mutation.getClass().getName());
367       }
368       mutationBuilder.clear();
369       MutationProto mp = ProtobufUtil.toMutation(mutateType, mutation, mutationBuilder);
370       actionBuilder.clear();
371       actionBuilder.setMutation(mp);
372       builder.addAction(actionBuilder.build());
373     }
374     return builder;
375   }
376 
377   /**
378    * Create a protocol buffer MultiRequest for row mutations that does not hold data.  Data/Cells
379    * are carried outside of protobuf.  Return references to the Cells in <code>cells</code> param.
380     * Does not propagate Action absolute position.  Does not set atomic action on the created
381    * RegionAtomic.  Caller should do that if wanted.
382    * @param regionName
383    * @param rowMutations
384    * @param cells Return in here a list of Cells as CellIterable.
385    * @return a region mutation minus data
386    * @throws IOException
387    */
388   public static RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
389       final RowMutations rowMutations, final List<CellScannable> cells,
390       final RegionAction.Builder regionActionBuilder,
391       final ClientProtos.Action.Builder actionBuilder,
392       final MutationProto.Builder mutationBuilder)
393   throws IOException {
394     for (Mutation mutation: rowMutations.getMutations()) {
395       MutationType type = null;
396       if (mutation instanceof Put) {
397         type = MutationType.PUT;
398       } else if (mutation instanceof Delete) {
399         type = MutationType.DELETE;
400       } else {
401         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
402           mutation.getClass().getName());
403       }
404       mutationBuilder.clear();
405       MutationProto mp = ProtobufUtil.toMutationNoData(type, mutation, mutationBuilder);
406       cells.add(mutation);
407       actionBuilder.clear();
408       regionActionBuilder.addAction(actionBuilder.setMutation(mp).build());
409     }
410     return regionActionBuilder;
411   }
412 
413   private static RegionAction.Builder getRegionActionBuilderWithRegion(
414       final RegionAction.Builder regionActionBuilder, final byte [] regionName) {
415     RegionSpecifier region = buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName);
416     regionActionBuilder.setRegion(region);
417     return regionActionBuilder;
418   }
419 
420   /**
421    * Create a protocol buffer ScanRequest for a client Scan
422    *
423    * @param regionName
424    * @param scan
425    * @param numberOfRows
426    * @param closeScanner
427    * @return a scan request
428    * @throws IOException
429    */
430   public static ScanRequest buildScanRequest(final byte[] regionName,
431       final Scan scan, final int numberOfRows,
432         final boolean closeScanner) throws IOException {
433     ScanRequest.Builder builder = ScanRequest.newBuilder();
434     RegionSpecifier region = buildRegionSpecifier(
435       RegionSpecifierType.REGION_NAME, regionName);
436     builder.setNumberOfRows(numberOfRows);
437     builder.setCloseScanner(closeScanner);
438     builder.setRegion(region);
439     builder.setScan(ProtobufUtil.toScan(scan));
440     return builder.build();
441   }
442 
443   /**
444    * Create a protocol buffer ScanRequest for a scanner id
445    *
446    * @param scannerId
447    * @param numberOfRows
448    * @param closeScanner
449    * @return a scan request
450    */
451   public static ScanRequest buildScanRequest(final long scannerId,
452       final int numberOfRows, final boolean closeScanner) {
453     ScanRequest.Builder builder = ScanRequest.newBuilder();
454     builder.setNumberOfRows(numberOfRows);
455     builder.setCloseScanner(closeScanner);
456     builder.setScannerId(scannerId);
457     return builder.build();
458   }
459 
460   /**
461    * Create a protocol buffer ScanRequest for a scanner id
462    *
463    * @param scannerId
464    * @param numberOfRows
465    * @param closeScanner
466    * @param nextCallSeq
467    * @return a scan request
468    */
469   public static ScanRequest buildScanRequest(final long scannerId, final int numberOfRows,
470       final boolean closeScanner, final long nextCallSeq) {
471     ScanRequest.Builder builder = ScanRequest.newBuilder();
472     builder.setNumberOfRows(numberOfRows);
473     builder.setCloseScanner(closeScanner);
474     builder.setScannerId(scannerId);
475     builder.setNextCallSeq(nextCallSeq);
476     return builder.build();
477   }
478 
479   /**
480    * Create a protocol buffer bulk load request
481    *
482    * @param familyPaths
483    * @param regionName
484    * @param assignSeqNum
485    * @return a bulk load request
486    */
487   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
488       final List<Pair<byte[], String>> familyPaths,
489       final byte[] regionName, boolean assignSeqNum) {
490     BulkLoadHFileRequest.Builder builder = BulkLoadHFileRequest.newBuilder();
491     RegionSpecifier region = buildRegionSpecifier(
492       RegionSpecifierType.REGION_NAME, regionName);
493     builder.setRegion(region);
494     FamilyPath.Builder familyPathBuilder = FamilyPath.newBuilder();
495     for (Pair<byte[], String> familyPath: familyPaths) {
496       familyPathBuilder.setFamily(HBaseZeroCopyByteString.wrap(familyPath.getFirst()));
497       familyPathBuilder.setPath(familyPath.getSecond());
498       builder.addFamilyPath(familyPathBuilder.build());
499     }
500     builder.setAssignSeqNum(assignSeqNum);
501     return builder.build();
502   }
503 
504   /**
505    * Create a protocol buffer multi request for a list of actions.
506    * Propagates Actions original index.
507    *
508    * @param regionName
509    * @param actions
510    * @return a multi request
511    * @throws IOException
512    */
513   public static <R> RegionAction.Builder buildRegionAction(final byte[] regionName,
514       final List<Action<R>> actions, final RegionAction.Builder regionActionBuilder,
515       final ClientProtos.Action.Builder actionBuilder,
516       final MutationProto.Builder mutationBuilder) throws IOException {
517     for (Action<R> action: actions) {
518       Row row = action.getAction();
519       actionBuilder.clear();
520       actionBuilder.setIndex(action.getOriginalIndex());
521       mutationBuilder.clear();
522       if (row instanceof Get) {
523         Get g = (Get)row;
524         regionActionBuilder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
525       } else if (row instanceof Put) {
526         regionActionBuilder.addAction(actionBuilder.
527           setMutation(ProtobufUtil.toMutation(MutationType.PUT, (Put)row, mutationBuilder)));
528       } else if (row instanceof Delete) {
529         regionActionBuilder.addAction(actionBuilder.
530           setMutation(ProtobufUtil.toMutation(MutationType.DELETE, (Delete)row, mutationBuilder)));
531       } else if (row instanceof Append) {
532         regionActionBuilder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutation(
533             MutationType.APPEND, (Append)row, mutationBuilder, action.getNonce())));
534       } else if (row instanceof Increment) {
535         regionActionBuilder.addAction(actionBuilder.setMutation(
536             ProtobufUtil.toMutation((Increment)row, mutationBuilder, action.getNonce())));
537       } else if (row instanceof RegionCoprocessorServiceExec) {
538         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
539         regionActionBuilder.addAction(actionBuilder.setServiceCall(
540             ClientProtos.CoprocessorServiceCall.newBuilder()
541               .setRow(HBaseZeroCopyByteString.wrap(exec.getRow()))
542               .setServiceName(exec.getMethod().getService().getFullName())
543               .setMethodName(exec.getMethod().getName())
544               .setRequest(exec.getRequest().toByteString())));
545       } else if (row instanceof RowMutations) {
546         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
547       } else {
548         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
549       }
550     }
551     return regionActionBuilder;
552   }
553 
554   /**
555    * Create a protocol buffer multirequest with NO data for a list of actions (data is carried
556    * otherwise than via protobuf).  This means it just notes attributes, whether to write the
557    * WAL, etc., and the presence in protobuf serves as place holder for the data which is
558    * coming along otherwise.  Note that Get is different.  It does not contain 'data' and is always
559    * carried by protobuf.  We return references to the data by adding them to the passed in
560    * <code>data</code> param.
561    *
562    * <p>Propagates Actions original index.
563    *
564    * @param regionName
565    * @param actions
566    * @param cells Place to stuff references to actual data.
567    * @return a multi request that does not carry any data.
568    * @throws IOException
569    */
570   public static <R> RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
571       final List<Action<R>> actions, final List<CellScannable> cells,
572       final RegionAction.Builder regionActionBuilder,
573       final ClientProtos.Action.Builder actionBuilder,
574       final MutationProto.Builder mutationBuilder) throws IOException {
575     RegionAction.Builder builder = getRegionActionBuilderWithRegion(
576       RegionAction.newBuilder(), regionName);
577     for (Action<R> action: actions) {
578       Row row = action.getAction();
579       actionBuilder.clear();
580       actionBuilder.setIndex(action.getOriginalIndex());
581       mutationBuilder.clear();
582       if (row instanceof Get) {
583         Get g = (Get)row;
584         builder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
585       } else if (row instanceof Put) {
586         Put p = (Put)row;
587         cells.add(p);
588         builder.addAction(actionBuilder.
589           setMutation(ProtobufUtil.toMutationNoData(MutationType.PUT, p, mutationBuilder)));
590       } else if (row instanceof Delete) {
591         Delete d = (Delete)row;
592         int size = d.size();
593         // Note that a legitimate Delete may have a size of zero; i.e. a Delete that has nothing
594         // in it but the row to delete.  In this case, the current implementation does not make
595         // a KeyValue to represent a delete-of-all-the-row until we serialize... For such cases
596         // where the size returned is zero, we will send the Delete fully pb'd rather than have
597         // metadata only in the pb and then send the kv along the side in cells.
598         if (size > 0) {
599           cells.add(d);
600           builder.addAction(actionBuilder.
601             setMutation(ProtobufUtil.toMutationNoData(MutationType.DELETE, d, mutationBuilder)));
602         } else {
603           builder.addAction(actionBuilder.
604             setMutation(ProtobufUtil.toMutation(MutationType.DELETE, d, mutationBuilder)));
605         }
606       } else if (row instanceof Append) {
607         Append a = (Append)row;
608         cells.add(a);
609         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
610           MutationType.APPEND, a, mutationBuilder, action.getNonce())));
611       } else if (row instanceof Increment) {
612         Increment i = (Increment)row;
613         cells.add(i);
614         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
615           MutationType.INCREMENT, i, mutationBuilder, action.getNonce())));
616       } else if (row instanceof RowMutations) {
617         continue; // ignore RowMutations
618       } else {
619         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
620       }
621     }
622     return builder;
623   }
624 
625 // End utilities for Client
626 //Start utilities for Admin
627 
628   /**
629    * Create a protocol buffer GetRegionInfoRequest for a given region name
630    *
631    * @param regionName the name of the region to get info
632    * @return a protocol buffer GetRegionInfoRequest
633    */
634   public static GetRegionInfoRequest
635       buildGetRegionInfoRequest(final byte[] regionName) {
636     return buildGetRegionInfoRequest(regionName, false);
637   }
638 
639   /**
640    * Create a protocol buffer GetRegionInfoRequest for a given region name
641    *
642    * @param regionName the name of the region to get info
643    * @param includeCompactionState indicate if the compaction state is requested
644    * @return a protocol buffer GetRegionInfoRequest
645    */
646   public static GetRegionInfoRequest
647       buildGetRegionInfoRequest(final byte[] regionName,
648         final boolean includeCompactionState) {
649     GetRegionInfoRequest.Builder builder = GetRegionInfoRequest.newBuilder();
650     RegionSpecifier region = buildRegionSpecifier(
651       RegionSpecifierType.REGION_NAME, regionName);
652     builder.setRegion(region);
653     if (includeCompactionState) {
654       builder.setCompactionState(includeCompactionState);
655     }
656     return builder.build();
657   }
658 
659  /**
660   * Create a protocol buffer GetStoreFileRequest for a given region name
661   *
662   * @param regionName the name of the region to get info
663   * @param family the family to get store file list
664   * @return a protocol buffer GetStoreFileRequest
665   */
666  public static GetStoreFileRequest
667      buildGetStoreFileRequest(final byte[] regionName, final byte[] family) {
668    GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder();
669    RegionSpecifier region = buildRegionSpecifier(
670      RegionSpecifierType.REGION_NAME, regionName);
671    builder.setRegion(region);
672    builder.addFamily(HBaseZeroCopyByteString.wrap(family));
673    return builder.build();
674  }
675 
676  /**
677   * Create a protocol buffer GetOnlineRegionRequest
678   *
679   * @return a protocol buffer GetOnlineRegionRequest
680   */
681  public static GetOnlineRegionRequest buildGetOnlineRegionRequest() {
682    return GetOnlineRegionRequest.newBuilder().build();
683  }
684 
685  /**
686   * Create a protocol buffer FlushRegionRequest for a given region name
687   *
688   * @param regionName the name of the region to get info
689   * @return a protocol buffer FlushRegionRequest
690   */
691  public static FlushRegionRequest
692      buildFlushRegionRequest(final byte[] regionName) {
693    FlushRegionRequest.Builder builder = FlushRegionRequest.newBuilder();
694    RegionSpecifier region = buildRegionSpecifier(
695      RegionSpecifierType.REGION_NAME, regionName);
696    builder.setRegion(region);
697    return builder.build();
698  }
699 
700  /**
701   * Create a protocol buffer OpenRegionRequest to open a list of regions
702   *
703   * @param regionOpenInfos info of a list of regions to open
704   * @return a protocol buffer OpenRegionRequest
705   */
706  public static OpenRegionRequest
707      buildOpenRegionRequest(final List<Triple<HRegionInfo, Integer,
708          List<ServerName>>> regionOpenInfos) {
709    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
710    for (Triple<HRegionInfo, Integer, List<ServerName>> regionOpenInfo: regionOpenInfos) {
711      Integer second = regionOpenInfo.getSecond();
712      int versionOfOfflineNode = second == null ? -1 : second.intValue();
713      builder.addOpenInfo(buildRegionOpenInfo(
714        regionOpenInfo.getFirst(), versionOfOfflineNode, regionOpenInfo.getThird()));
715    }
716    return builder.build();
717  }
718 
719  /**
720   * Create a protocol buffer OpenRegionRequest for a given region
721   *
722   * @param server the serverName for the RPC
723   * @param region the region to open
724   * @param versionOfOfflineNode that needs to be present in the offline node
725   * @param favoredNodes
726   * @return a protocol buffer OpenRegionRequest
727   */
728  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
729      final HRegionInfo region, final int versionOfOfflineNode, List<ServerName> favoredNodes) {
730    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
731    builder.addOpenInfo(buildRegionOpenInfo(region, versionOfOfflineNode, favoredNodes));
732    if (server != null) {
733      builder.setServerStartCode(server.getStartcode());
734    }
735    return builder.build();
736  }
737 
738  /**
739   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
740   * @param updateRegionInfos
741   * @return a protocol buffer UpdateFavoredNodesRequest
742   */
743  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
744      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
745    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
746    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
747      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
748      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
749      for (ServerName server : pair.getSecond()) {
750        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
751      }
752      ubuilder.addUpdateInfo(builder.build());
753    }
754    return ubuilder.build();
755  }
756 
757  /**
758   * Create a CloseRegionRequest for a given region name
759   *
760   * @param regionName the name of the region to close
761   * @param transitionInZK indicator if to transition in ZK
762   * @return a CloseRegionRequest
763   */
764  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
765      final byte[] regionName, final boolean transitionInZK) {
766    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
767    RegionSpecifier region = buildRegionSpecifier(
768      RegionSpecifierType.REGION_NAME, regionName);
769    builder.setRegion(region);
770    builder.setTransitionInZK(transitionInZK);
771    if (server != null) {
772      builder.setServerStartCode(server.getStartcode());
773    }
774    return builder.build();
775  }
776 
777   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
778     final byte[] regionName, final int versionOfClosingNode,
779     ServerName destinationServer, final boolean transitionInZK) {
780     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
781     RegionSpecifier region = buildRegionSpecifier(
782       RegionSpecifierType.REGION_NAME, regionName);
783     builder.setRegion(region);
784     builder.setVersionOfClosingNode(versionOfClosingNode);
785     builder.setTransitionInZK(transitionInZK);
786     if (destinationServer != null){
787       builder.setDestinationServer(ProtobufUtil.toServerName( destinationServer) );
788     }
789     if (server != null) {
790       builder.setServerStartCode(server.getStartcode());
791     }
792     return builder.build();
793   }
794 
795  /**
796   * Create a CloseRegionRequest for a given encoded region name
797   *
798   * @param encodedRegionName the name of the region to close
799   * @param transitionInZK indicator if to transition in ZK
800   * @return a CloseRegionRequest
801   */
802  public static CloseRegionRequest
803      buildCloseRegionRequest(ServerName server, final String encodedRegionName,
804        final boolean transitionInZK) {
805    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
806    RegionSpecifier region = buildRegionSpecifier(
807      RegionSpecifierType.ENCODED_REGION_NAME,
808      Bytes.toBytes(encodedRegionName));
809    builder.setRegion(region);
810    builder.setTransitionInZK(transitionInZK);
811    if (server != null) {
812      builder.setServerStartCode(server.getStartcode());
813    }
814    return builder.build();
815  }
816 
817  /**
818   * Create a SplitRegionRequest for a given region name
819   *
820   * @param regionName the name of the region to split
821   * @param splitPoint the split point
822   * @return a SplitRegionRequest
823   */
824  public static SplitRegionRequest buildSplitRegionRequest(
825      final byte[] regionName, final byte[] splitPoint) {
826    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
827    RegionSpecifier region = buildRegionSpecifier(
828      RegionSpecifierType.REGION_NAME, regionName);
829    builder.setRegion(region);
830    if (splitPoint != null) {
831      builder.setSplitPoint(HBaseZeroCopyByteString.wrap(splitPoint));
832    }
833    return builder.build();
834  }
835 
836   /**
837    * Create a MergeRegionsRequest for the given regions
838    * @param regionA name of region a
839    * @param regionB name of region b
840    * @param forcible true if it is a compulsory merge
841    * @return a MergeRegionsRequest
842    */
843   public static MergeRegionsRequest buildMergeRegionsRequest(
844       final byte[] regionA, final byte[] regionB, final boolean forcible) {
845     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
846     RegionSpecifier regionASpecifier = buildRegionSpecifier(
847         RegionSpecifierType.REGION_NAME, regionA);
848     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
849         RegionSpecifierType.REGION_NAME, regionB);
850     builder.setRegionA(regionASpecifier);
851     builder.setRegionB(regionBSpecifier);
852     builder.setForcible(forcible);
853     return builder.build();
854   }
855 
856  /**
857   * Create a  CompactRegionRequest for a given region name
858   *
859   * @param regionName the name of the region to get info
860   * @param major indicator if it is a major compaction
861   * @return a CompactRegionRequest
862   */
863  public static CompactRegionRequest buildCompactRegionRequest(
864      final byte[] regionName, final boolean major, final byte [] family) {
865    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
866    RegionSpecifier region = buildRegionSpecifier(
867      RegionSpecifierType.REGION_NAME, regionName);
868    builder.setRegion(region);
869    builder.setMajor(major);
870    if (family != null) {
871      builder.setFamily(HBaseZeroCopyByteString.wrap(family));
872    }
873    return builder.build();
874  }
875 
876  /**
877   * @see {@link #buildRollWALWriterRequest()
878   */
879  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
880      RollWALWriterRequest.newBuilder().build();
881 
882   /**
883   * Create a new RollWALWriterRequest
884   *
885   * @return a ReplicateWALEntryRequest
886   */
887  public static RollWALWriterRequest buildRollWALWriterRequest() {
888    return ROLL_WAL_WRITER_REQUEST;
889  }
890 
891  /**
892   * @see {@link #buildGetServerInfoRequest()}
893   */
894  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
895    GetServerInfoRequest.newBuilder().build();
896 
897  /**
898   * Create a new GetServerInfoRequest
899   *
900   * @return a GetServerInfoRequest
901   */
902  public static GetServerInfoRequest buildGetServerInfoRequest() {
903    return GET_SERVER_INFO_REQUEST;
904  }
905 
906  /**
907   * Create a new StopServerRequest
908   *
909   * @param reason the reason to stop the server
910   * @return a StopServerRequest
911   */
912  public static StopServerRequest buildStopServerRequest(final String reason) {
913    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
914    builder.setReason(reason);
915    return builder.build();
916  }
917 
918 //End utilities for Admin
919 
920   /**
921    * Convert a byte array to a protocol buffer RegionSpecifier
922    *
923    * @param type the region specifier type
924    * @param value the region specifier byte array value
925    * @return a protocol buffer RegionSpecifier
926    */
927   public static RegionSpecifier buildRegionSpecifier(
928       final RegionSpecifierType type, final byte[] value) {
929     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
930     regionBuilder.setValue(HBaseZeroCopyByteString.wrap(value));
931     regionBuilder.setType(type);
932     return regionBuilder.build();
933   }
934 
935   /**
936    * Create a protocol buffer Condition
937    *
938    * @param row
939    * @param family
940    * @param qualifier
941    * @param comparator
942    * @param compareType
943    * @return a Condition
944    * @throws IOException
945    */
946   private static Condition buildCondition(final byte[] row,
947       final byte[] family, final byte [] qualifier,
948       final ByteArrayComparable comparator,
949       final CompareType compareType) throws IOException {
950     Condition.Builder builder = Condition.newBuilder();
951     builder.setRow(HBaseZeroCopyByteString.wrap(row));
952     builder.setFamily(HBaseZeroCopyByteString.wrap(family));
953     builder.setQualifier(HBaseZeroCopyByteString.wrap(qualifier));
954     builder.setComparator(ProtobufUtil.toComparator(comparator));
955     builder.setCompareType(compareType);
956     return builder.build();
957   }
958 
959   /**
960    * Create a protocol buffer AddColumnRequest
961    *
962    * @param tableName
963    * @param column
964    * @return an AddColumnRequest
965    */
966   public static AddColumnRequest buildAddColumnRequest(
967       final TableName tableName, final HColumnDescriptor column) {
968     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
969     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
970     builder.setColumnFamilies(column.convert());
971     return builder.build();
972   }
973 
974   /**
975    * Create a protocol buffer DeleteColumnRequest
976    *
977    * @param tableName
978    * @param columnName
979    * @return a DeleteColumnRequest
980    */
981   public static DeleteColumnRequest buildDeleteColumnRequest(
982       final TableName tableName, final byte [] columnName) {
983     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
984     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
985     builder.setColumnName(HBaseZeroCopyByteString.wrap(columnName));
986     return builder.build();
987   }
988 
989   /**
990    * Create a protocol buffer ModifyColumnRequest
991    *
992    * @param tableName
993    * @param column
994    * @return an ModifyColumnRequest
995    */
996   public static ModifyColumnRequest buildModifyColumnRequest(
997       final TableName tableName, final HColumnDescriptor column) {
998     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
999     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1000     builder.setColumnFamilies(column.convert());
1001     return builder.build();
1002   }
1003 
1004   /**
1005    * Create a protocol buffer MoveRegionRequest
1006    *
1007    * @param encodedRegionName
1008    * @param destServerName
1009    * @return A MoveRegionRequest
1010    * @throws DeserializationException
1011    */
1012   public static MoveRegionRequest buildMoveRegionRequest(
1013       final byte [] encodedRegionName, final byte [] destServerName) throws
1014       DeserializationException {
1015 	MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1016     builder.setRegion(
1017       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1018     if (destServerName != null) {
1019       builder.setDestServerName(
1020         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1021     }
1022     return builder.build();
1023   }
1024 
1025   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1026       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1027       final boolean forcible) throws DeserializationException {
1028     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1029     builder.setRegionA(buildRegionSpecifier(
1030         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1031     builder.setRegionB(buildRegionSpecifier(
1032         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1033     builder.setForcible(forcible);
1034     return builder.build();
1035   }
1036 
1037   /**
1038    * Create a protocol buffer AssignRegionRequest
1039    *
1040    * @param regionName
1041    * @return an AssignRegionRequest
1042    */
1043   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1044     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1045     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1046     return builder.build();
1047   }
1048 
1049   /**
1050    * Creates a protocol buffer UnassignRegionRequest
1051    *
1052    * @param regionName
1053    * @param force
1054    * @return an UnassignRegionRequest
1055    */
1056   public static UnassignRegionRequest buildUnassignRegionRequest(
1057       final byte [] regionName, final boolean force) {
1058     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1059     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1060     builder.setForce(force);
1061     return builder.build();
1062   }
1063 
1064   /**
1065    * Creates a protocol buffer OfflineRegionRequest
1066    *
1067    * @param regionName
1068    * @return an OfflineRegionRequest
1069    */
1070   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1071     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1072     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1073     return builder.build();
1074   }
1075 
1076   /**
1077    * Creates a protocol buffer DeleteTableRequest
1078    *
1079    * @param tableName
1080    * @return a DeleteTableRequest
1081    */
1082   public static DeleteTableRequest buildDeleteTableRequest(final TableName tableName) {
1083     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1084     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1085     return builder.build();
1086   }
1087 
1088   /**
1089    * Creates a protocol buffer EnableTableRequest
1090    *
1091    * @param tableName
1092    * @return an EnableTableRequest
1093    */
1094   public static EnableTableRequest buildEnableTableRequest(final TableName tableName) {
1095     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1096     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1097     return builder.build();
1098   }
1099 
1100   /**
1101    * Creates a protocol buffer DisableTableRequest
1102    *
1103    * @param tableName
1104    * @return a DisableTableRequest
1105    */
1106   public static DisableTableRequest buildDisableTableRequest(final TableName tableName) {
1107     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1108     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1109     return builder.build();
1110   }
1111 
1112   /**
1113    * Creates a protocol buffer CreateTableRequest
1114    *
1115    * @param hTableDesc
1116    * @param splitKeys
1117    * @return a CreateTableRequest
1118    */
1119   public static CreateTableRequest buildCreateTableRequest(
1120       final HTableDescriptor hTableDesc, final byte [][] splitKeys) {
1121     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1122     builder.setTableSchema(hTableDesc.convert());
1123     if (splitKeys != null) {
1124       for (byte [] splitKey : splitKeys) {
1125         builder.addSplitKeys(HBaseZeroCopyByteString.wrap(splitKey));
1126       }
1127     }
1128     return builder.build();
1129   }
1130 
1131 
1132   /**
1133    * Creates a protocol buffer ModifyTableRequest
1134    *
1135    * @param tableName
1136    * @param hTableDesc
1137    * @return a ModifyTableRequest
1138    */
1139   public static ModifyTableRequest buildModifyTableRequest(
1140       final TableName tableName, final HTableDescriptor hTableDesc) {
1141     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1142     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1143     builder.setTableSchema(hTableDesc.convert());
1144     return builder.build();
1145   }
1146 
1147   /**
1148    * Creates a protocol buffer GetSchemaAlterStatusRequest
1149    *
1150    * @param tableName
1151    * @return a GetSchemaAlterStatusRequest
1152    */
1153   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1154       final TableName tableName) {
1155     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1156     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1157     return builder.build();
1158   }
1159 
1160   /**
1161    * Creates a protocol buffer GetTableDescriptorsRequest
1162    *
1163    * @param tableNames
1164    * @return a GetTableDescriptorsRequest
1165    */
1166   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1167       final List<TableName> tableNames) {
1168     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1169     if (tableNames != null) {
1170       for (TableName tableName : tableNames) {
1171         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1172       }
1173     }
1174     return builder.build();
1175   }
1176 
1177   /**
1178    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1179    *
1180    * @param tableName the table name
1181    * @return a GetTableDescriptorsRequest
1182    */
1183   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1184       final TableName tableName) {
1185     return GetTableDescriptorsRequest.newBuilder()
1186       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1187       .build();
1188   }
1189 
1190   /**
1191    * Creates a protocol buffer IsMasterRunningRequest
1192    *
1193    * @return a IsMasterRunningRequest
1194    */
1195   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1196     return IsMasterRunningRequest.newBuilder().build();
1197   }
1198 
1199   /**
1200    * Creates a protocol buffer BalanceRequest
1201    *
1202    * @return a BalanceRequest
1203    */
1204   public static BalanceRequest buildBalanceRequest() {
1205     return BalanceRequest.newBuilder().build();
1206   }
1207 
1208   /**
1209    * Creates a protocol buffer SetBalancerRunningRequest
1210    *
1211    * @param on
1212    * @param synchronous
1213    * @return a SetBalancerRunningRequest
1214    */
1215   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(boolean on, boolean synchronous) {
1216     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1217   }
1218 
1219   /**
1220    * @see {@link #buildGetClusterStatusRequest}
1221    */
1222   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1223       GetClusterStatusRequest.newBuilder().build();
1224 
1225   /**
1226    * Creates a protocol buffer GetClusterStatusRequest
1227    *
1228    * @return A GetClusterStatusRequest
1229    */
1230   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1231     return GET_CLUSTER_STATUS_REQUEST;
1232   }
1233 
1234   /**
1235    * @see {@link #buildCatalogScanRequest}
1236    */
1237   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1238     RunCatalogScanRequest.newBuilder().build();
1239 
1240   /**
1241    * Creates a request for running a catalog scan
1242    * @return A {@link RunCatalogScanRequest}
1243    */
1244   public static RunCatalogScanRequest buildCatalogScanRequest() {
1245     return CATALOG_SCAN_REQUEST;
1246   }
1247 
1248   /**
1249    * Creates a request for enabling/disabling the catalog janitor
1250    * @return A {@link EnableCatalogJanitorRequest}
1251    */
1252   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1253     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1254   }
1255 
1256   /**
1257    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1258    */
1259   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1260     IsCatalogJanitorEnabledRequest.newBuilder().build();
1261 
1262   /**
1263    * Creates a request for querying the master whether the catalog janitor is enabled
1264    * @return A {@link IsCatalogJanitorEnabledRequest}
1265    */
1266   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1267     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1268   }
1269 
1270   /**
1271    * Creates a request for querying the master the last flushed sequence Id for a region
1272    * @param regionName
1273    * @return A {@link GetLastFlushedSequenceIdRequest}
1274    */
1275   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1276       byte[] regionName) {
1277     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1278         HBaseZeroCopyByteString.wrap(regionName)).build();
1279   }
1280 
1281   /**
1282    * Create a request to grant user permissions.
1283    *
1284    * @param username the short user name who to grant permissions
1285    * @param actions the permissions to be granted
1286    * @return A {@link AccessControlProtos} GrantRequest
1287    */
1288   public static AccessControlProtos.GrantRequest buildGrantRequest(
1289       String username, AccessControlProtos.Permission.Action... actions) {
1290     AccessControlProtos.Permission.Builder ret =
1291         AccessControlProtos.Permission.newBuilder();
1292     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1293         AccessControlProtos.GlobalPermission.newBuilder();
1294     for (AccessControlProtos.Permission.Action a : actions) {
1295       permissionBuilder.addAction(a);
1296     }
1297     ret.setType(AccessControlProtos.Permission.Type.Global)
1298        .setGlobalPermission(permissionBuilder);
1299     return AccessControlProtos.GrantRequest.newBuilder()
1300       .setUserPermission(
1301           AccessControlProtos.UserPermission.newBuilder()
1302               .setUser(ByteString.copyFromUtf8(username))
1303               .setPermission(ret)
1304       ).build();
1305   }
1306 
1307   /**
1308    * Create a request to grant user permissions.
1309    *
1310    * @param username the short user name who to grant permissions
1311    * @param tableName optional table name the permissions apply
1312    * @param family optional column family
1313    * @param qualifier optional qualifier
1314    * @param actions the permissions to be granted
1315    * @return A {@link AccessControlProtos} GrantRequest
1316    */
1317   public static AccessControlProtos.GrantRequest buildGrantRequest(
1318       String username, TableName tableName, byte[] family, byte[] qualifier,
1319       AccessControlProtos.Permission.Action... actions) {
1320     AccessControlProtos.Permission.Builder ret =
1321         AccessControlProtos.Permission.newBuilder();
1322     AccessControlProtos.TablePermission.Builder permissionBuilder =
1323         AccessControlProtos.TablePermission.newBuilder();
1324     for (AccessControlProtos.Permission.Action a : actions) {
1325       permissionBuilder.addAction(a);
1326     }
1327     if (tableName == null) {
1328       throw new NullPointerException("TableName cannot be null");
1329     }
1330     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1331 
1332     if (family != null) {
1333       permissionBuilder.setFamily(HBaseZeroCopyByteString.wrap(family));
1334     }
1335     if (qualifier != null) {
1336       permissionBuilder.setQualifier(HBaseZeroCopyByteString.wrap(qualifier));
1337     }
1338     ret.setType(AccessControlProtos.Permission.Type.Table)
1339        .setTablePermission(permissionBuilder);
1340     return AccessControlProtos.GrantRequest.newBuilder()
1341       .setUserPermission(
1342           AccessControlProtos.UserPermission.newBuilder()
1343               .setUser(ByteString.copyFromUtf8(username))
1344               .setPermission(ret)
1345       ).build();
1346   }
1347 
1348   /**
1349    * Create a request to grant user permissions.
1350    *
1351    * @param username the short user name who to grant permissions
1352    * @param namespace optional table name the permissions apply
1353    * @param actions the permissions to be granted
1354    * @return A {@link AccessControlProtos} GrantRequest
1355    */
1356   public static AccessControlProtos.GrantRequest buildGrantRequest(
1357       String username, String namespace,
1358       AccessControlProtos.Permission.Action... actions) {
1359     AccessControlProtos.Permission.Builder ret =
1360         AccessControlProtos.Permission.newBuilder();
1361     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1362         AccessControlProtos.NamespacePermission.newBuilder();
1363     for (AccessControlProtos.Permission.Action a : actions) {
1364       permissionBuilder.addAction(a);
1365     }
1366     if (namespace != null) {
1367       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1368     }
1369     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1370        .setNamespacePermission(permissionBuilder);
1371     return AccessControlProtos.GrantRequest.newBuilder()
1372       .setUserPermission(
1373           AccessControlProtos.UserPermission.newBuilder()
1374               .setUser(ByteString.copyFromUtf8(username))
1375               .setPermission(ret)
1376       ).build();
1377   }
1378 
1379   /**
1380    * Create a request to revoke user permissions.
1381    *
1382    * @param username the short user name whose permissions to be revoked
1383    * @param actions the permissions to be revoked
1384    * @return A {@link AccessControlProtos} RevokeRequest
1385    */
1386   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1387       String username, AccessControlProtos.Permission.Action... actions) {
1388     AccessControlProtos.Permission.Builder ret =
1389         AccessControlProtos.Permission.newBuilder();
1390     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1391         AccessControlProtos.GlobalPermission.newBuilder();
1392     for (AccessControlProtos.Permission.Action a : actions) {
1393       permissionBuilder.addAction(a);
1394     }
1395     ret.setType(AccessControlProtos.Permission.Type.Global)
1396        .setGlobalPermission(permissionBuilder);
1397     return AccessControlProtos.RevokeRequest.newBuilder()
1398       .setUserPermission(
1399           AccessControlProtos.UserPermission.newBuilder()
1400               .setUser(ByteString.copyFromUtf8(username))
1401               .setPermission(ret)
1402       ).build();
1403   }
1404 
1405   /**
1406    * Create a request to revoke user permissions.
1407    *
1408    * @param username the short user name whose permissions to be revoked
1409    * @param tableName optional table name the permissions apply
1410    * @param family optional column family
1411    * @param qualifier optional qualifier
1412    * @param actions the permissions to be revoked
1413    * @return A {@link AccessControlProtos} RevokeRequest
1414    */
1415   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1416       String username, TableName tableName, byte[] family, byte[] qualifier,
1417       AccessControlProtos.Permission.Action... actions) {
1418     AccessControlProtos.Permission.Builder ret =
1419         AccessControlProtos.Permission.newBuilder();
1420     AccessControlProtos.TablePermission.Builder permissionBuilder =
1421         AccessControlProtos.TablePermission.newBuilder();
1422     for (AccessControlProtos.Permission.Action a : actions) {
1423       permissionBuilder.addAction(a);
1424     }
1425     if (tableName != null) {
1426       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1427     }
1428     if (family != null) {
1429       permissionBuilder.setFamily(HBaseZeroCopyByteString.wrap(family));
1430     }
1431     if (qualifier != null) {
1432       permissionBuilder.setQualifier(HBaseZeroCopyByteString.wrap(qualifier));
1433     }
1434     ret.setType(AccessControlProtos.Permission.Type.Table)
1435        .setTablePermission(permissionBuilder);
1436     return AccessControlProtos.RevokeRequest.newBuilder()
1437       .setUserPermission(
1438           AccessControlProtos.UserPermission.newBuilder()
1439               .setUser(ByteString.copyFromUtf8(username))
1440               .setPermission(ret)
1441       ).build();
1442   }
1443 
1444   /**
1445    * Create a request to revoke user permissions.
1446    *
1447    * @param username the short user name whose permissions to be revoked
1448    * @param namespace optional table name the permissions apply
1449    * @param actions the permissions to be revoked
1450    * @return A {@link AccessControlProtos} RevokeRequest
1451    */
1452   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1453       String username, String namespace,
1454       AccessControlProtos.Permission.Action... actions) {
1455     AccessControlProtos.Permission.Builder ret =
1456         AccessControlProtos.Permission.newBuilder();
1457     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1458         AccessControlProtos.NamespacePermission.newBuilder();
1459     for (AccessControlProtos.Permission.Action a : actions) {
1460       permissionBuilder.addAction(a);
1461     }
1462     if (namespace != null) {
1463       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1464     }
1465     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1466        .setNamespacePermission(permissionBuilder);
1467     return AccessControlProtos.RevokeRequest.newBuilder()
1468       .setUserPermission(
1469           AccessControlProtos.UserPermission.newBuilder()
1470               .setUser(ByteString.copyFromUtf8(username))
1471               .setPermission(ret)
1472       ).build();
1473   }
1474 
1475   /**
1476    * Create a RegionOpenInfo based on given region info and version of offline node
1477    */
1478   private static RegionOpenInfo buildRegionOpenInfo(
1479       final HRegionInfo region, final int versionOfOfflineNode,
1480       final List<ServerName> favoredNodes) {
1481     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1482     builder.setRegion(HRegionInfo.convert(region));
1483     if (versionOfOfflineNode >= 0) {
1484       builder.setVersionOfOfflineNode(versionOfOfflineNode);
1485     }
1486     if (favoredNodes != null) {
1487       for (ServerName server : favoredNodes) {
1488         builder.addFavoredNodes(ProtobufUtil.toServerName(server));
1489       }
1490     }
1491     return builder.build();
1492   }
1493 }