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  import java.util.regex.Pattern;
23  
24  import org.apache.hadoop.hbase.backup.BackupType;
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.CellScannable;
27  import org.apache.hadoop.hbase.DoNotRetryIOException;
28  import org.apache.hadoop.hbase.HColumnDescriptor;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.HRegionInfo;
31  import org.apache.hadoop.hbase.HTableDescriptor;
32  import org.apache.hadoop.hbase.ServerName;
33  import org.apache.hadoop.hbase.TableName;
34  import org.apache.hadoop.hbase.client.Action;
35  import org.apache.hadoop.hbase.client.Admin;
36  import org.apache.hadoop.hbase.client.Append;
37  import org.apache.hadoop.hbase.client.Delete;
38  import org.apache.hadoop.hbase.client.Durability;
39  import org.apache.hadoop.hbase.client.Get;
40  import org.apache.hadoop.hbase.client.Increment;
41  import org.apache.hadoop.hbase.client.Mutation;
42  import org.apache.hadoop.hbase.client.Put;
43  import org.apache.hadoop.hbase.client.RegionCoprocessorServiceExec;
44  import org.apache.hadoop.hbase.client.Row;
45  import org.apache.hadoop.hbase.client.RowMutations;
46  import org.apache.hadoop.hbase.client.Scan;
47  import org.apache.hadoop.hbase.exceptions.DeserializationException;
48  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
49  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
50  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
51  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.WarmupRegionRequest;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
63  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
64  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest;
65  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest.RegionUpdateInfo;
66  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
67  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest;
68  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest.FamilyPath;
69  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Column;
70  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Condition;
71  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
72  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
73  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
74  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue;
75  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue;
76  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType;
77  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
78  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
79  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType;
80  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
81  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
82  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
83  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AddColumnRequest;
84  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AssignRegionRequest;
85  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.BackupTablesRequest;
86  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.BalanceRequest;
87  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
88  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteColumnRequest;
89  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableRequest;
90  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableRequest;
91  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
92  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest;
93  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
94  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
95  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
96  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
97  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
98  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
99  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsNormalizerEnabledRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSplitOrMergeEnabledRequest;
103 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
104 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
105 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
106 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.NormalizeRequest;
107 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
108 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
109 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
110 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningRequest;
111 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledRequest;
112 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
113 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
114 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.GetQuotaStatesRequest;
115 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.GetSpaceQuotaRegionSizesRequest;
116 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.GetSpaceQuotaSnapshotsRequest;
117 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest;
118 import org.apache.hadoop.hbase.util.ByteStringer;
119 import org.apache.hadoop.hbase.util.Bytes;
120 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
121 import org.apache.hadoop.hbase.util.Pair;
122 import org.apache.hadoop.hbase.util.Triple;
123 
124 import com.google.protobuf.ByteString;
125 
126 /**
127  * Helper utility to build protocol buffer requests,
128  * or build components for protocol buffer requests.
129  */
130 @InterfaceAudience.Private
131 public final class RequestConverter {
132 
133   private RequestConverter() {
134   }
135 
136 // Start utilities for Client
137 
138 /**
139    * Create a new protocol buffer GetRequest to get a row, all columns in a family.
140    * If there is no such row, return the closest row before it.
141    *
142    * @param regionName the name of the region to get
143    * @param row the row to get
144    * @param family the column family to get
145    * should return the immediate row before
146    * @return a protocol buffer GetReuqest
147    */
148   public static GetRequest buildGetRowOrBeforeRequest(
149       final byte[] regionName, final byte[] row, final byte[] family) {
150     GetRequest.Builder builder = GetRequest.newBuilder();
151     RegionSpecifier region = buildRegionSpecifier(
152       RegionSpecifierType.REGION_NAME, regionName);
153     builder.setRegion(region);
154 
155     Column.Builder columnBuilder = Column.newBuilder();
156     columnBuilder.setFamily(ByteStringer.wrap(family));
157     ClientProtos.Get.Builder getBuilder =
158       ClientProtos.Get.newBuilder();
159     getBuilder.setRow(ByteStringer.wrap(row));
160     getBuilder.addColumn(columnBuilder.build());
161     getBuilder.setClosestRowBefore(true);
162     builder.setGet(getBuilder.build());
163     return builder.build();
164   }
165 
166 
167   /**
168    * Create a protocol buffer GetRequest for a client Get
169    *
170    * @param regionName the name of the region to get
171    * @param get the client Get
172    * @return a protocol buffer GetRequest
173    */
174   public static GetRequest buildGetRequest(final byte[] regionName,
175       final Get get) throws IOException {
176     GetRequest.Builder builder = GetRequest.newBuilder();
177     RegionSpecifier region = buildRegionSpecifier(
178       RegionSpecifierType.REGION_NAME, regionName);
179     builder.setRegion(region);
180     builder.setGet(ProtobufUtil.toGet(get));
181     return builder.build();
182   }
183 
184   /**
185    * Create a protocol buffer MutateRequest for a client increment
186    *
187    * @param regionName
188    * @param row
189    * @param family
190    * @param qualifier
191    * @param amount
192    * @param durability
193    * @return a mutate request
194    */
195   public static MutateRequest buildIncrementRequest(
196       final byte[] regionName, final byte[] row, final byte[] family, final byte[] qualifier,
197       final long amount, final Durability durability, long nonceGroup, long nonce) {
198     MutateRequest.Builder builder = MutateRequest.newBuilder();
199     RegionSpecifier region = buildRegionSpecifier(
200       RegionSpecifierType.REGION_NAME, regionName);
201     builder.setRegion(region);
202 
203     MutationProto.Builder mutateBuilder = MutationProto.newBuilder();
204     mutateBuilder.setRow(ByteStringer.wrap(row));
205     mutateBuilder.setMutateType(MutationType.INCREMENT);
206     mutateBuilder.setDurability(ProtobufUtil.toDurability(durability));
207     ColumnValue.Builder columnBuilder = ColumnValue.newBuilder();
208     columnBuilder.setFamily(ByteStringer.wrap(family));
209     QualifierValue.Builder valueBuilder = QualifierValue.newBuilder();
210     valueBuilder.setValue(ByteStringer.wrap(Bytes.toBytes(amount)));
211     valueBuilder.setQualifier(ByteStringer.wrap(qualifier));
212     columnBuilder.addQualifierValue(valueBuilder.build());
213     mutateBuilder.addColumnValue(columnBuilder.build());
214     if (nonce != HConstants.NO_NONCE) {
215       mutateBuilder.setNonce(nonce);
216     }
217     builder.setMutation(mutateBuilder.build());
218     if (nonceGroup != HConstants.NO_NONCE) {
219       builder.setNonceGroup(nonceGroup);
220     }
221     return builder.build();
222   }
223 
224   /**
225    * Create a protocol buffer MutateRequest for a conditioned put
226    *
227    * @param regionName
228    * @param row
229    * @param family
230    * @param qualifier
231    * @param comparator
232    * @param compareType
233    * @param put
234    * @return a mutate request
235    * @throws IOException
236    */
237   public static MutateRequest buildMutateRequest(
238       final byte[] regionName, final byte[] row, final byte[] family,
239       final byte [] qualifier, final ByteArrayComparable comparator,
240       final CompareType compareType, final Put put) throws IOException {
241     MutateRequest.Builder builder = MutateRequest.newBuilder();
242     RegionSpecifier region = buildRegionSpecifier(
243       RegionSpecifierType.REGION_NAME, regionName);
244     builder.setRegion(region);
245     Condition condition = buildCondition(
246       row, family, qualifier, comparator, compareType);
247     builder.setMutation(ProtobufUtil.toMutation(MutationType.PUT, put, MutationProto.newBuilder()));
248     builder.setCondition(condition);
249     return builder.build();
250   }
251 
252   /**
253    * Create a protocol buffer MutateRequest for a conditioned delete
254    *
255    * @param regionName
256    * @param row
257    * @param family
258    * @param qualifier
259    * @param comparator
260    * @param compareType
261    * @param delete
262    * @return a mutate request
263    * @throws IOException
264    */
265   public static MutateRequest buildMutateRequest(
266       final byte[] regionName, final byte[] row, final byte[] family,
267       final byte [] qualifier, final ByteArrayComparable comparator,
268       final CompareType compareType, final Delete delete) throws IOException {
269     MutateRequest.Builder builder = MutateRequest.newBuilder();
270     RegionSpecifier region = buildRegionSpecifier(
271       RegionSpecifierType.REGION_NAME, regionName);
272     builder.setRegion(region);
273     Condition condition = buildCondition(
274       row, family, qualifier, comparator, compareType);
275     builder.setMutation(ProtobufUtil.toMutation(MutationType.DELETE, delete,
276       MutationProto.newBuilder()));
277     builder.setCondition(condition);
278     return builder.build();
279   }
280 
281   /**
282    * Create a protocol buffer MutateRequest for conditioned row mutations
283    *
284    * @param regionName
285    * @param row
286    * @param family
287    * @param qualifier
288    * @param comparator
289    * @param compareType
290    * @param rowMutations
291    * @return a mutate request
292    * @throws IOException
293    */
294   public static ClientProtos.MultiRequest buildMutateRequest(
295       final byte[] regionName, final byte[] row, final byte[] family,
296       final byte [] qualifier, final ByteArrayComparable comparator,
297       final CompareType compareType, final RowMutations rowMutations) throws IOException {
298     RegionAction.Builder builder =
299         getRegionActionBuilderWithRegion(RegionAction.newBuilder(), regionName);
300     builder.setAtomic(true);
301     ClientProtos.Action.Builder actionBuilder = ClientProtos.Action.newBuilder();
302     MutationProto.Builder mutationBuilder = MutationProto.newBuilder();
303     Condition condition = buildCondition(
304         row, family, qualifier, comparator, compareType);
305     for (Mutation mutation: rowMutations.getMutations()) {
306       MutationType mutateType = null;
307       if (mutation instanceof Put) {
308         mutateType = MutationType.PUT;
309       } else if (mutation instanceof Delete) {
310         mutateType = MutationType.DELETE;
311       } else {
312         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
313             mutation.getClass().getName());
314       }
315       mutationBuilder.clear();
316       MutationProto mp = ProtobufUtil.toMutation(mutateType, mutation, mutationBuilder);
317       actionBuilder.clear();
318       actionBuilder.setMutation(mp);
319       builder.addAction(actionBuilder.build());
320     }
321     ClientProtos.MultiRequest request =
322         ClientProtos.MultiRequest.newBuilder().addRegionAction(builder.build())
323             .setCondition(condition).build();
324     return request;
325   }
326 
327   /**
328    * Create a protocol buffer MutateRequest for a put
329    *
330    * @param regionName
331    * @param put
332    * @return a mutate request
333    * @throws IOException
334    */
335   public static MutateRequest buildMutateRequest(
336       final byte[] regionName, final Put put) throws IOException {
337     MutateRequest.Builder builder = MutateRequest.newBuilder();
338     RegionSpecifier region = buildRegionSpecifier(
339       RegionSpecifierType.REGION_NAME, regionName);
340     builder.setRegion(region);
341     builder.setMutation(ProtobufUtil.toMutation(MutationType.PUT, put, MutationProto.newBuilder()));
342     return builder.build();
343   }
344 
345   /**
346    * Create a protocol buffer MutateRequest for an append
347    *
348    * @param regionName
349    * @param append
350    * @return a mutate request
351    * @throws IOException
352    */
353   public static MutateRequest buildMutateRequest(final byte[] regionName,
354       final Append append, long nonceGroup, long nonce) throws IOException {
355     MutateRequest.Builder builder = MutateRequest.newBuilder();
356     RegionSpecifier region = buildRegionSpecifier(
357       RegionSpecifierType.REGION_NAME, regionName);
358     builder.setRegion(region);
359     if (nonce != HConstants.NO_NONCE && nonceGroup != HConstants.NO_NONCE) {
360       builder.setNonceGroup(nonceGroup);
361     }
362     builder.setMutation(ProtobufUtil.toMutation(MutationType.APPEND, append,
363       MutationProto.newBuilder(), nonce));
364     return builder.build();
365   }
366 
367   /**
368    * Create a protocol buffer MutateRequest for a client increment
369    *
370    * @param regionName
371    * @param increment
372    * @return a mutate request
373    */
374   public static MutateRequest buildMutateRequest(final byte[] regionName,
375       final Increment increment, final long nonceGroup, final long nonce) {
376     MutateRequest.Builder builder = MutateRequest.newBuilder();
377     RegionSpecifier region = buildRegionSpecifier(
378       RegionSpecifierType.REGION_NAME, regionName);
379     builder.setRegion(region);
380     if (nonce != HConstants.NO_NONCE && nonceGroup != HConstants.NO_NONCE) {
381       builder.setNonceGroup(nonceGroup);
382     }
383     builder.setMutation(ProtobufUtil.toMutation(increment, MutationProto.newBuilder(), nonce));
384     return builder.build();
385   }
386 
387   /**
388    * Create a protocol buffer MutateRequest for a delete
389    *
390    * @param regionName
391    * @param delete
392    * @return a mutate request
393    * @throws IOException
394    */
395   public static MutateRequest buildMutateRequest(
396       final byte[] regionName, final Delete delete) throws IOException {
397     MutateRequest.Builder builder = MutateRequest.newBuilder();
398     RegionSpecifier region = buildRegionSpecifier(
399       RegionSpecifierType.REGION_NAME, regionName);
400     builder.setRegion(region);
401     builder.setMutation(ProtobufUtil.toMutation(MutationType.DELETE, delete,
402       MutationProto.newBuilder()));
403     return builder.build();
404   }
405 
406   /**
407    * Create a protocol buffer MultiRequest for row mutations.
408    * Does not propagate Action absolute position.  Does not set atomic action on the created
409    * RegionAtomic.  Caller should do that if wanted.
410    * @param regionName
411    * @param rowMutations
412    * @return a data-laden RegionMutation.Builder
413    * @throws IOException
414    */
415   public static RegionAction.Builder buildRegionAction(final byte [] regionName,
416       final RowMutations rowMutations)
417   throws IOException {
418     RegionAction.Builder builder =
419       getRegionActionBuilderWithRegion(RegionAction.newBuilder(), regionName);
420     ClientProtos.Action.Builder actionBuilder = ClientProtos.Action.newBuilder();
421     MutationProto.Builder mutationBuilder = MutationProto.newBuilder();
422     for (Mutation mutation: rowMutations.getMutations()) {
423       MutationType mutateType = null;
424       if (mutation instanceof Put) {
425         mutateType = MutationType.PUT;
426       } else if (mutation instanceof Delete) {
427         mutateType = MutationType.DELETE;
428       } else {
429         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
430           mutation.getClass().getName());
431       }
432       mutationBuilder.clear();
433       MutationProto mp = ProtobufUtil.toMutation(mutateType, mutation, mutationBuilder);
434       actionBuilder.clear();
435       actionBuilder.setMutation(mp);
436       builder.addAction(actionBuilder.build());
437     }
438     return builder;
439   }
440 
441   /**
442    * Create a protocol buffer MultiRequest for row mutations that does not hold data.  Data/Cells
443    * are carried outside of protobuf.  Return references to the Cells in <code>cells</code> param.
444     * Does not propagate Action absolute position.  Does not set atomic action on the created
445    * RegionAtomic.  Caller should do that if wanted.
446    * @param regionName
447    * @param rowMutations
448    * @param cells Return in here a list of Cells as CellIterable.
449    * @return a region mutation minus data
450    * @throws IOException
451    */
452   public static RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
453       final RowMutations rowMutations, final List<CellScannable> cells,
454       final RegionAction.Builder regionActionBuilder,
455       final ClientProtos.Action.Builder actionBuilder,
456       final MutationProto.Builder mutationBuilder)
457   throws IOException {
458     for (Mutation mutation: rowMutations.getMutations()) {
459       MutationType type = null;
460       if (mutation instanceof Put) {
461         type = MutationType.PUT;
462       } else if (mutation instanceof Delete) {
463         type = MutationType.DELETE;
464       } else {
465         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
466           mutation.getClass().getName());
467       }
468       mutationBuilder.clear();
469       MutationProto mp = ProtobufUtil.toMutationNoData(type, mutation, mutationBuilder);
470       cells.add(mutation);
471       actionBuilder.clear();
472       regionActionBuilder.addAction(actionBuilder.setMutation(mp).build());
473     }
474     return regionActionBuilder;
475   }
476 
477   private static RegionAction.Builder getRegionActionBuilderWithRegion(
478       final RegionAction.Builder regionActionBuilder, final byte [] regionName) {
479     RegionSpecifier region = buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName);
480     regionActionBuilder.setRegion(region);
481     return regionActionBuilder;
482   }
483 
484   /**
485    * Create a protocol buffer ScanRequest for a client Scan
486    *
487    * @param regionName
488    * @param scan
489    * @param numberOfRows
490    * @param closeScanner
491    * @return a scan request
492    * @throws IOException
493    */
494   public static ScanRequest buildScanRequest(final byte[] regionName,
495       final Scan scan, final int numberOfRows,
496         final boolean closeScanner) throws IOException {
497     ScanRequest.Builder builder = ScanRequest.newBuilder();
498     RegionSpecifier region = buildRegionSpecifier(
499       RegionSpecifierType.REGION_NAME, regionName);
500     builder.setNumberOfRows(numberOfRows);
501     builder.setCloseScanner(closeScanner);
502     builder.setRegion(region);
503     builder.setScan(ProtobufUtil.toScan(scan));
504     builder.setClientHandlesPartials(true);
505     builder.setClientHandlesHeartbeats(true);
506     return builder.build();
507   }
508 
509   /**
510    * Create a protocol buffer ScanRequest for a scanner id
511    *
512    * @param scannerId
513    * @param numberOfRows
514    * @param closeScanner
515    * @return a scan request
516    */
517   public static ScanRequest buildScanRequest(final long scannerId,
518       final int numberOfRows, final boolean closeScanner) {
519     ScanRequest.Builder builder = ScanRequest.newBuilder();
520     builder.setNumberOfRows(numberOfRows);
521     builder.setCloseScanner(closeScanner);
522     builder.setScannerId(scannerId);
523     builder.setClientHandlesPartials(true);
524     builder.setClientHandlesHeartbeats(true);
525     return builder.build();
526   }
527 
528   /**
529    * Create a protocol buffer ScanRequest for a scanner id
530    *
531    * @param scannerId
532    * @param numberOfRows
533    * @param closeScanner
534    * @param nextCallSeq
535    * @return a scan request
536    */
537   public static ScanRequest buildScanRequest(final long scannerId, final int numberOfRows,
538       final boolean closeScanner, final long nextCallSeq, final boolean renew) {
539     ScanRequest.Builder builder = ScanRequest.newBuilder();
540     builder.setNumberOfRows(numberOfRows);
541     builder.setCloseScanner(closeScanner);
542     builder.setScannerId(scannerId);
543     builder.setNextCallSeq(nextCallSeq);
544     builder.setClientHandlesPartials(true);
545     builder.setClientHandlesHeartbeats(true);
546     builder.setRenew(renew);
547     return builder.build();
548   }
549 
550   /**
551    * Create a protocol buffer bulk load request
552    *
553    * @param familyPaths
554    * @param regionName
555    * @param assignSeqNum
556    * @return a bulk load request
557    */
558   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
559       final List<Pair<byte[], String>> familyPaths,
560       final byte[] regionName, boolean assignSeqNum) {
561     return buildBulkLoadHFileRequest(familyPaths, regionName, assignSeqNum, false);
562   }
563 
564   /**
565    * Create a protocol buffer bulk load request
566    *
567    * @param familyPaths
568    * @param regionName
569    * @param assignSeqNum
570    * @return a bulk load request
571    */
572   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
573       final List<Pair<byte[], String>> familyPaths,
574       final byte[] regionName, boolean assignSeqNum, boolean copyFiles) {
575     BulkLoadHFileRequest.Builder builder = BulkLoadHFileRequest.newBuilder();
576     RegionSpecifier region = buildRegionSpecifier(
577       RegionSpecifierType.REGION_NAME, regionName);
578     builder.setRegion(region);
579     FamilyPath.Builder familyPathBuilder = FamilyPath.newBuilder();
580     for (Pair<byte[], String> familyPath: familyPaths) {
581       familyPathBuilder.setFamily(ByteStringer.wrap(familyPath.getFirst()));
582       familyPathBuilder.setPath(familyPath.getSecond());
583       builder.addFamilyPath(familyPathBuilder.build());
584     }
585     builder.setAssignSeqNum(assignSeqNum);
586     builder.setCopyFile(copyFiles);
587     return builder.build();
588   }
589 
590   /**
591    * Create a protocol buffer multi request for a list of actions.
592    * Propagates Actions original index.
593    *
594    * @param regionName
595    * @param actions
596    * @return a multi request
597    * @throws IOException
598    */
599   public static <R> RegionAction.Builder buildRegionAction(final byte[] regionName,
600       final List<Action<R>> actions, final RegionAction.Builder regionActionBuilder,
601       final ClientProtos.Action.Builder actionBuilder,
602       final MutationProto.Builder mutationBuilder) throws IOException {
603     for (Action<R> action: actions) {
604       Row row = action.getAction();
605       actionBuilder.clear();
606       actionBuilder.setIndex(action.getOriginalIndex());
607       mutationBuilder.clear();
608       if (row instanceof Get) {
609         Get g = (Get)row;
610         regionActionBuilder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
611       } else if (row instanceof Put) {
612         regionActionBuilder.addAction(actionBuilder.
613           setMutation(ProtobufUtil.toMutation(MutationType.PUT, (Put)row, mutationBuilder)));
614       } else if (row instanceof Delete) {
615         regionActionBuilder.addAction(actionBuilder.
616           setMutation(ProtobufUtil.toMutation(MutationType.DELETE, (Delete)row, mutationBuilder)));
617       } else if (row instanceof Append) {
618         regionActionBuilder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutation(
619             MutationType.APPEND, (Append)row, mutationBuilder, action.getNonce())));
620       } else if (row instanceof Increment) {
621         regionActionBuilder.addAction(actionBuilder.setMutation(
622             ProtobufUtil.toMutation((Increment)row, mutationBuilder, action.getNonce())));
623       } else if (row instanceof RegionCoprocessorServiceExec) {
624         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
625         regionActionBuilder.addAction(actionBuilder.setServiceCall(
626             ClientProtos.CoprocessorServiceCall.newBuilder()
627               .setRow(ByteStringer.wrap(exec.getRow()))
628               .setServiceName(exec.getMethod().getService().getFullName())
629               .setMethodName(exec.getMethod().getName())
630               .setRequest(exec.getRequest().toByteString())));
631       } else if (row instanceof RowMutations) {
632         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
633       } else {
634         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
635       }
636     }
637     return regionActionBuilder;
638   }
639 
640   /**
641    * Create a protocol buffer multirequest with NO data for a list of actions (data is carried
642    * otherwise than via protobuf).  This means it just notes attributes, whether to write the
643    * WAL, etc., and the presence in protobuf serves as place holder for the data which is
644    * coming along otherwise.  Note that Get is different.  It does not contain 'data' and is always
645    * carried by protobuf.  We return references to the data by adding them to the passed in
646    * <code>data</code> param.
647    *
648    * <p>Propagates Actions original index.
649    *
650    * @param regionName
651    * @param actions
652    * @param cells Place to stuff references to actual data.
653    * @return a multi request that does not carry any data.
654    * @throws IOException
655    */
656   public static <R> RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
657       final List<Action<R>> actions, final List<CellScannable> cells,
658       final RegionAction.Builder regionActionBuilder,
659       final ClientProtos.Action.Builder actionBuilder,
660       final MutationProto.Builder mutationBuilder) throws IOException {
661     RegionAction.Builder builder = getRegionActionBuilderWithRegion(
662       RegionAction.newBuilder(), regionName);
663     for (Action<R> action: actions) {
664       Row row = action.getAction();
665       actionBuilder.clear();
666       actionBuilder.setIndex(action.getOriginalIndex());
667       mutationBuilder.clear();
668       if (row instanceof Get) {
669         Get g = (Get)row;
670         builder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
671       } else if (row instanceof Put) {
672         Put p = (Put)row;
673         cells.add(p);
674         builder.addAction(actionBuilder.
675           setMutation(ProtobufUtil.toMutationNoData(MutationType.PUT, p, mutationBuilder)));
676       } else if (row instanceof Delete) {
677         Delete d = (Delete)row;
678         int size = d.size();
679         // Note that a legitimate Delete may have a size of zero; i.e. a Delete that has nothing
680         // in it but the row to delete.  In this case, the current implementation does not make
681         // a KeyValue to represent a delete-of-all-the-row until we serialize... For such cases
682         // where the size returned is zero, we will send the Delete fully pb'd rather than have
683         // metadata only in the pb and then send the kv along the side in cells.
684         if (size > 0) {
685           cells.add(d);
686           builder.addAction(actionBuilder.
687             setMutation(ProtobufUtil.toMutationNoData(MutationType.DELETE, d, mutationBuilder)));
688         } else {
689           builder.addAction(actionBuilder.
690             setMutation(ProtobufUtil.toMutation(MutationType.DELETE, d, mutationBuilder)));
691         }
692       } else if (row instanceof Append) {
693         Append a = (Append)row;
694         cells.add(a);
695         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
696           MutationType.APPEND, a, mutationBuilder, action.getNonce())));
697       } else if (row instanceof Increment) {
698         Increment i = (Increment)row;
699         cells.add(i);
700         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
701           MutationType.INCREMENT, i, mutationBuilder, action.getNonce())));
702       } else if (row instanceof RegionCoprocessorServiceExec) {
703         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
704         builder.addAction(actionBuilder.setServiceCall(ClientProtos.CoprocessorServiceCall
705             .newBuilder().setRow(ByteStringer.wrap(exec.getRow()))
706             .setServiceName(exec.getMethod().getService().getFullName())
707             .setMethodName(exec.getMethod().getName())
708             .setRequest(exec.getRequest().toByteString())));
709       } else if (row instanceof RowMutations) {
710         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
711       } else {
712         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
713       }
714     }
715     return builder;
716   }
717 
718 // End utilities for Client
719 //Start utilities for Admin
720 
721   /**
722    * Create a protocol buffer GetRegionInfoRequest for a given region name
723    *
724    * @param regionName the name of the region to get info
725    * @return a protocol buffer GetRegionInfoRequest
726    */
727   public static GetRegionInfoRequest
728       buildGetRegionInfoRequest(final byte[] regionName) {
729     return buildGetRegionInfoRequest(regionName, false);
730   }
731 
732   /**
733    * Create a protocol buffer GetRegionInfoRequest for a given region name
734    *
735    * @param regionName the name of the region to get info
736    * @param includeCompactionState indicate if the compaction state is requested
737    * @return a protocol buffer GetRegionInfoRequest
738    */
739   public static GetRegionInfoRequest
740       buildGetRegionInfoRequest(final byte[] regionName,
741         final boolean includeCompactionState) {
742     GetRegionInfoRequest.Builder builder = GetRegionInfoRequest.newBuilder();
743     RegionSpecifier region = buildRegionSpecifier(
744       RegionSpecifierType.REGION_NAME, regionName);
745     builder.setRegion(region);
746     if (includeCompactionState) {
747       builder.setCompactionState(includeCompactionState);
748     }
749     return builder.build();
750   }
751 
752  /**
753   * Create a protocol buffer GetStoreFileRequest for a given region name
754   *
755   * @param regionName the name of the region to get info
756   * @param family the family to get store file list
757   * @return a protocol buffer GetStoreFileRequest
758   */
759  public static GetStoreFileRequest
760      buildGetStoreFileRequest(final byte[] regionName, final byte[] family) {
761    GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder();
762    RegionSpecifier region = buildRegionSpecifier(
763      RegionSpecifierType.REGION_NAME, regionName);
764    builder.setRegion(region);
765    builder.addFamily(ByteStringer.wrap(family));
766    return builder.build();
767  }
768 
769  /**
770   * Create a protocol buffer GetOnlineRegionRequest
771   *
772   * @return a protocol buffer GetOnlineRegionRequest
773   */
774  public static GetOnlineRegionRequest buildGetOnlineRegionRequest() {
775    return GetOnlineRegionRequest.newBuilder().build();
776  }
777 
778  /**
779   * Create a protocol buffer FlushRegionRequest for a given region name
780   *
781   * @param regionName the name of the region to get info
782   * @return a protocol buffer FlushRegionRequest
783   */
784  public static FlushRegionRequest
785      buildFlushRegionRequest(final byte[] regionName) {
786    return buildFlushRegionRequest(regionName, false);
787  }
788 
789  /**
790   * Create a protocol buffer FlushRegionRequest for a given region name
791   *
792   * @param regionName the name of the region to get info
793   * @return a protocol buffer FlushRegionRequest
794   */
795  public static FlushRegionRequest
796      buildFlushRegionRequest(final byte[] regionName, boolean writeFlushWALMarker) {
797    FlushRegionRequest.Builder builder = FlushRegionRequest.newBuilder();
798    RegionSpecifier region = buildRegionSpecifier(
799      RegionSpecifierType.REGION_NAME, regionName);
800    builder.setRegion(region);
801    builder.setWriteFlushWalMarker(writeFlushWALMarker);
802    return builder.build();
803  }
804 
805  /**
806   * Create a protocol buffer OpenRegionRequest to open a list of regions
807   *
808   * @param server the serverName for the RPC
809   * @param regionOpenInfos info of a list of regions to open
810   * @param openForReplay
811   * @return a protocol buffer OpenRegionRequest
812   */
813  public static OpenRegionRequest
814      buildOpenRegionRequest(ServerName server, final List<Triple<HRegionInfo, Integer,
815          List<ServerName>>> regionOpenInfos, Boolean openForReplay) {
816    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
817    for (Triple<HRegionInfo, Integer, List<ServerName>> regionOpenInfo: regionOpenInfos) {
818      Integer second = regionOpenInfo.getSecond();
819      int versionOfOfflineNode = second == null ? -1 : second.intValue();
820      builder.addOpenInfo(buildRegionOpenInfo(regionOpenInfo.getFirst(), versionOfOfflineNode,
821        regionOpenInfo.getThird(), openForReplay));
822    }
823    if (server != null) {
824      builder.setServerStartCode(server.getStartcode());
825    }
826    // send the master's wall clock time as well, so that the RS can refer to it
827    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
828    return builder.build();
829  }
830 
831  /**
832   * Create a protocol buffer OpenRegionRequest for a given region
833   *
834   * @param server the serverName for the RPC
835   * @param region the region to open
836   * @param versionOfOfflineNode that needs to be present in the offline node
837   * @param favoredNodes
838   * @param openForReplay
839   * @return a protocol buffer OpenRegionRequest
840   */
841  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
842      final HRegionInfo region, final int versionOfOfflineNode, List<ServerName> favoredNodes,
843      Boolean openForReplay) {
844    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
845    builder.addOpenInfo(buildRegionOpenInfo(region, versionOfOfflineNode, favoredNodes,
846      openForReplay));
847    if (server != null) {
848      builder.setServerStartCode(server.getStartcode());
849    }
850    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
851    return builder.build();
852  }
853 
854  /**
855   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
856   * @param updateRegionInfos
857   * @return a protocol buffer UpdateFavoredNodesRequest
858   */
859  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
860      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
861    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
862    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
863      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
864      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
865      for (ServerName server : pair.getSecond()) {
866        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
867      }
868      ubuilder.addUpdateInfo(builder.build());
869    }
870    return ubuilder.build();
871  }
872 
873  /**
874   * Create a CloseRegionRequest for a given region name
875   *
876   * @param regionName the name of the region to close
877   * @param transitionInZK indicator if to transition in ZK
878   * @return a CloseRegionRequest
879   */
880  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
881      final byte[] regionName, final boolean transitionInZK) {
882    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
883    RegionSpecifier region = buildRegionSpecifier(
884      RegionSpecifierType.REGION_NAME, regionName);
885    builder.setRegion(region);
886    builder.setTransitionInZK(transitionInZK);
887    if (server != null) {
888      builder.setServerStartCode(server.getStartcode());
889    }
890    return builder.build();
891  }
892 
893   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
894     final byte[] regionName, final int versionOfClosingNode,
895     ServerName destinationServer, final boolean transitionInZK) {
896     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
897     RegionSpecifier region = buildRegionSpecifier(
898       RegionSpecifierType.REGION_NAME, regionName);
899     builder.setRegion(region);
900     builder.setVersionOfClosingNode(versionOfClosingNode);
901     builder.setTransitionInZK(transitionInZK);
902     if (destinationServer != null){
903       builder.setDestinationServer(ProtobufUtil.toServerName( destinationServer) );
904     }
905     if (server != null) {
906       builder.setServerStartCode(server.getStartcode());
907     }
908     return builder.build();
909   }
910 
911   /**
912    *  Create a WarmupRegionRequest for a given region name
913    *
914    *  @param regionInfo Region we are warming up
915    */
916   public static WarmupRegionRequest buildWarmupRegionRequest(final HRegionInfo regionInfo) {
917     WarmupRegionRequest.Builder builder = WarmupRegionRequest.newBuilder();
918     builder.setRegionInfo(HRegionInfo.convert(regionInfo));
919     return builder.build();
920   }
921  /**
922   * Create a CloseRegionRequest for a given encoded region name
923   *
924   * @param encodedRegionName the name of the region to close
925   * @param transitionInZK indicator if to transition in ZK
926   * @return a CloseRegionRequest
927   */
928  public static CloseRegionRequest
929      buildCloseRegionRequest(ServerName server, final String encodedRegionName,
930        final boolean transitionInZK) {
931    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
932    RegionSpecifier region = buildRegionSpecifier(
933      RegionSpecifierType.ENCODED_REGION_NAME,
934      Bytes.toBytes(encodedRegionName));
935    builder.setRegion(region);
936    builder.setTransitionInZK(transitionInZK);
937    if (server != null) {
938      builder.setServerStartCode(server.getStartcode());
939    }
940    return builder.build();
941  }
942 
943  /**
944   * Create a SplitRegionRequest for a given region name
945   *
946   * @param regionName the name of the region to split
947   * @param splitPoint the split point
948   * @return a SplitRegionRequest
949   */
950  public static SplitRegionRequest buildSplitRegionRequest(
951      final byte[] regionName, final byte[] splitPoint) {
952    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
953    RegionSpecifier region = buildRegionSpecifier(
954      RegionSpecifierType.REGION_NAME, regionName);
955    builder.setRegion(region);
956    if (splitPoint != null) {
957      builder.setSplitPoint(ByteStringer.wrap(splitPoint));
958    }
959    return builder.build();
960  }
961 
962   /**
963    * Create a MergeRegionsRequest for the given regions
964    * @param regionA name of region a
965    * @param regionB name of region b
966    * @param forcible true if it is a compulsory merge
967    * @return a MergeRegionsRequest
968    */
969   public static MergeRegionsRequest buildMergeRegionsRequest(
970       final byte[] regionA, final byte[] regionB, final boolean forcible) {
971     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
972     RegionSpecifier regionASpecifier = buildRegionSpecifier(
973         RegionSpecifierType.REGION_NAME, regionA);
974     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
975         RegionSpecifierType.REGION_NAME, regionB);
976     builder.setRegionA(regionASpecifier);
977     builder.setRegionB(regionBSpecifier);
978     builder.setForcible(forcible);
979     // send the master's wall clock time as well, so that the RS can refer to it
980     builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
981     return builder.build();
982   }
983 
984  /**
985   * Create a  CompactRegionRequest for a given region name
986   *
987   * @param regionName the name of the region to get info
988   * @param major indicator if it is a major compaction
989   * @return a CompactRegionRequest
990   */
991  public static CompactRegionRequest buildCompactRegionRequest(
992      final byte[] regionName, final boolean major, final byte [] family) {
993    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
994    RegionSpecifier region = buildRegionSpecifier(
995      RegionSpecifierType.REGION_NAME, regionName);
996    builder.setRegion(region);
997    builder.setMajor(major);
998    if (family != null) {
999      builder.setFamily(ByteStringer.wrap(family));
1000    }
1001    return builder.build();
1002  }
1003 
1004  /**
1005   * @see {@link #buildRollWALWriterRequest()
1006   */
1007  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
1008      RollWALWriterRequest.newBuilder().build();
1009 
1010   /**
1011   * Create a new RollWALWriterRequest
1012   *
1013   * @return a ReplicateWALEntryRequest
1014   */
1015  public static RollWALWriterRequest buildRollWALWriterRequest() {
1016    return ROLL_WAL_WRITER_REQUEST;
1017  }
1018 
1019  /**
1020   * @see {@link #buildGetServerInfoRequest()}
1021   */
1022  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
1023    GetServerInfoRequest.newBuilder().build();
1024 
1025  /**
1026   * Create a new GetServerInfoRequest
1027   *
1028   * @return a GetServerInfoRequest
1029   */
1030  public static GetServerInfoRequest buildGetServerInfoRequest() {
1031    return GET_SERVER_INFO_REQUEST;
1032  }
1033 
1034  /**
1035   * Create a new StopServerRequest
1036   *
1037   * @param reason the reason to stop the server
1038   * @return a StopServerRequest
1039   */
1040  public static StopServerRequest buildStopServerRequest(final String reason) {
1041    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
1042    builder.setReason(reason);
1043    return builder.build();
1044  }
1045 
1046 //End utilities for Admin
1047 
1048   /**
1049    * Convert a byte array to a protocol buffer RegionSpecifier
1050    *
1051    * @param type the region specifier type
1052    * @param value the region specifier byte array value
1053    * @return a protocol buffer RegionSpecifier
1054    */
1055   public static RegionSpecifier buildRegionSpecifier(
1056       final RegionSpecifierType type, final byte[] value) {
1057     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
1058     regionBuilder.setValue(ByteStringer.wrap(value));
1059     regionBuilder.setType(type);
1060     return regionBuilder.build();
1061   }
1062 
1063   /**
1064    * Create a protocol buffer Condition
1065    *
1066    * @param row
1067    * @param family
1068    * @param qualifier
1069    * @param comparator
1070    * @param compareType
1071    * @return a Condition
1072    * @throws IOException
1073    */
1074   private static Condition buildCondition(final byte[] row,
1075       final byte[] family, final byte [] qualifier,
1076       final ByteArrayComparable comparator,
1077       final CompareType compareType) throws IOException {
1078     Condition.Builder builder = Condition.newBuilder();
1079     builder.setRow(ByteStringer.wrap(row));
1080     builder.setFamily(ByteStringer.wrap(family));
1081     builder.setQualifier(ByteStringer.wrap(qualifier));
1082     builder.setComparator(ProtobufUtil.toComparator(comparator));
1083     builder.setCompareType(compareType);
1084     return builder.build();
1085   }
1086 
1087   /**
1088    * Create a protocol buffer AddColumnRequest
1089    *
1090    * @param tableName
1091    * @param column
1092    * @return an AddColumnRequest
1093    */
1094   public static AddColumnRequest buildAddColumnRequest(
1095       final TableName tableName,
1096       final HColumnDescriptor column,
1097       final long nonceGroup,
1098       final long nonce) {
1099     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
1100     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1101     builder.setColumnFamilies(column.convert());
1102     builder.setNonceGroup(nonceGroup);
1103     builder.setNonce(nonce);
1104     return builder.build();
1105   }
1106 
1107   /**
1108    * Create a protocol buffer DeleteColumnRequest
1109    *
1110    * @param tableName
1111    * @param columnName
1112    * @return a DeleteColumnRequest
1113    */
1114   public static DeleteColumnRequest buildDeleteColumnRequest(
1115       final TableName tableName,
1116       final byte [] columnName,
1117       final long nonceGroup,
1118       final long nonce) {
1119     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
1120     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1121     builder.setColumnName(ByteStringer.wrap(columnName));
1122     builder.setNonceGroup(nonceGroup);
1123     builder.setNonce(nonce);
1124     return builder.build();
1125   }
1126 
1127   /**
1128    * Create a protocol buffer ModifyColumnRequest
1129    *
1130    * @param tableName
1131    * @param column
1132    * @return an ModifyColumnRequest
1133    */
1134   public static ModifyColumnRequest buildModifyColumnRequest(
1135       final TableName tableName,
1136       final HColumnDescriptor column,
1137       final long nonceGroup,
1138       final long nonce) {
1139     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
1140     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1141     builder.setColumnFamilies(column.convert());
1142     builder.setNonceGroup(nonceGroup);
1143     builder.setNonce(nonce);
1144     return builder.build();
1145   }
1146 
1147   /**
1148    * Create a protocol buffer MoveRegionRequest
1149    *
1150    * @param encodedRegionName
1151    * @param destServerName
1152    * @return A MoveRegionRequest
1153    * @throws DeserializationException
1154    */
1155   public static MoveRegionRequest buildMoveRegionRequest(
1156       final byte [] encodedRegionName, final byte [] destServerName) throws
1157       DeserializationException {
1158     MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1159     builder.setRegion(
1160       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1161     if (destServerName != null) {
1162       builder.setDestServerName(
1163         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1164     }
1165     return builder.build();
1166   }
1167 
1168   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1169       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1170       final boolean forcible) throws DeserializationException {
1171     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1172     builder.setRegionA(buildRegionSpecifier(
1173         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1174     builder.setRegionB(buildRegionSpecifier(
1175         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1176     builder.setForcible(forcible);
1177     return builder.build();
1178   }
1179 
1180   /**
1181    * Create a protocol buffer AssignRegionRequest
1182    *
1183    * @param regionName
1184    * @return an AssignRegionRequest
1185    */
1186   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1187     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1188     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1189     return builder.build();
1190   }
1191 
1192   /**
1193    * Creates a protocol buffer UnassignRegionRequest
1194    *
1195    * @param regionName
1196    * @param force
1197    * @return an UnassignRegionRequest
1198    */
1199   public static UnassignRegionRequest buildUnassignRegionRequest(
1200       final byte [] regionName, final boolean force) {
1201     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1202     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1203     builder.setForce(force);
1204     return builder.build();
1205   }
1206 
1207   /**
1208    * Creates a protocol buffer OfflineRegionRequest
1209    *
1210    * @param regionName
1211    * @return an OfflineRegionRequest
1212    */
1213   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1214     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1215     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1216     return builder.build();
1217   }
1218 
1219   /**
1220    * Creates a protocol buffer DeleteTableRequest
1221    *
1222    * @param tableName
1223    * @return a DeleteTableRequest
1224    */
1225   public static DeleteTableRequest buildDeleteTableRequest(
1226       final TableName tableName,
1227       final long nonceGroup,
1228       final long nonce) {
1229     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1230     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1231     builder.setNonceGroup(nonceGroup);
1232     builder.setNonce(nonce);
1233     return builder.build();
1234   }
1235 
1236   /**
1237    * Creates a protocol buffer TruncateTableRequest
1238    *
1239    * @param tableName name of table to truncate
1240    * @param preserveSplits True if the splits should be preserved
1241    * @return a TruncateTableRequest
1242    */
1243   public static TruncateTableRequest buildTruncateTableRequest(
1244       final TableName tableName,
1245       final boolean preserveSplits,
1246       final long nonceGroup,
1247       final long nonce) {
1248     TruncateTableRequest.Builder builder = TruncateTableRequest.newBuilder();
1249     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1250     builder.setPreserveSplits(preserveSplits);
1251     builder.setNonceGroup(nonceGroup);
1252     builder.setNonce(nonce);
1253     return builder.build();
1254   }
1255 
1256   /**
1257    * Creates a protocol buffer EnableTableRequest
1258    *
1259    * @param tableName
1260    * @return an EnableTableRequest
1261    */
1262   public static EnableTableRequest buildEnableTableRequest(
1263       final TableName tableName,
1264       final long nonceGroup,
1265       final long nonce) {
1266     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1267     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1268     builder.setNonceGroup(nonceGroup);
1269     builder.setNonce(nonce);
1270     return builder.build();
1271   }
1272 
1273   /**
1274    * Creates a protocol buffer DisableTableRequest
1275    *
1276    * @param tableName
1277    * @return a DisableTableRequest
1278    */
1279   public static DisableTableRequest buildDisableTableRequest(
1280       final TableName tableName,
1281       final long nonceGroup,
1282       final long nonce) {
1283     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1284     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1285     builder.setNonceGroup(nonceGroup);
1286     builder.setNonce(nonce);
1287     return builder.build();
1288   }
1289 
1290   /**
1291    * Creates a protocol buffer CreateTableRequest
1292    *
1293    * @param hTableDesc
1294    * @param splitKeys
1295    * @return a CreateTableRequest
1296    */
1297   public static CreateTableRequest buildCreateTableRequest(
1298       final HTableDescriptor hTableDesc,
1299       final byte [][] splitKeys,
1300       final long nonceGroup,
1301       final long nonce) {
1302     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1303     builder.setTableSchema(hTableDesc.convert());
1304     if (splitKeys != null) {
1305       for (byte [] splitKey : splitKeys) {
1306         builder.addSplitKeys(ByteStringer.wrap(splitKey));
1307       }
1308     }
1309     builder.setNonceGroup(nonceGroup);
1310     builder.setNonce(nonce);
1311     return builder.build();
1312   }
1313 
1314 
1315   /**
1316    * Creates a protocol buffer ModifyTableRequest
1317    *
1318    * @param tableName
1319    * @param hTableDesc
1320    * @return a ModifyTableRequest
1321    */
1322   public static ModifyTableRequest buildModifyTableRequest(
1323       final TableName tableName,
1324       final HTableDescriptor hTableDesc,
1325       final long nonceGroup,
1326       final long nonce) {
1327     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1328     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1329     builder.setTableSchema(hTableDesc.convert());
1330     builder.setNonceGroup(nonceGroup);
1331     builder.setNonce(nonce);
1332     return builder.build();
1333   }
1334 
1335   public static BackupTablesRequest buildBackupTablesRequest(
1336       final BackupType type, List<TableName> tableList, String targetRootDir, final int workers,
1337       final long bandwidth) {
1338     BackupTablesRequest.Builder builder = BackupTablesRequest.newBuilder();
1339     builder.setType(ProtobufUtil.toProtoBackupType(type));
1340     builder.setTargetRootDir(targetRootDir);
1341     builder.setWorkers(workers);
1342     builder.setBandwidth(bandwidth);
1343     if (tableList != null) {
1344       for (TableName table : tableList) {
1345         builder.addTables(ProtobufUtil.toProtoTableName(table));
1346       }
1347     }
1348     return builder.build();
1349   }
1350 
1351   /**
1352    * Creates a protocol buffer GetSchemaAlterStatusRequest
1353    *
1354    * @param tableName
1355    * @return a GetSchemaAlterStatusRequest
1356    */
1357   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1358       final TableName tableName) {
1359     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1360     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1361     return builder.build();
1362   }
1363 
1364   /**
1365    * Creates a protocol buffer GetTableDescriptorsRequest
1366    *
1367    * @param tableNames
1368    * @return a GetTableDescriptorsRequest
1369    */
1370   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1371       final List<TableName> tableNames) {
1372     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1373     if (tableNames != null) {
1374       for (TableName tableName : tableNames) {
1375         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1376       }
1377     }
1378     return builder.build();
1379   }
1380 
1381   /**
1382    * Creates a protocol buffer GetTableDescriptorsRequest
1383    *
1384    * @param pattern The compiled regular expression to match against
1385    * @param includeSysTables False to match only against userspace tables
1386    * @return a GetTableDescriptorsRequest
1387    */
1388   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final Pattern pattern,
1389       boolean includeSysTables) {
1390     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1391     if (pattern != null) builder.setRegex(pattern.toString());
1392     builder.setIncludeSysTables(includeSysTables);
1393     return builder.build();
1394   }
1395 
1396   /**
1397    * Creates a protocol buffer GetTableNamesRequest
1398    *
1399    * @param pattern The compiled regular expression to match against
1400    * @param includeSysTables False to match only against userspace tables
1401    * @return a GetTableNamesRequest
1402    */
1403   public static GetTableNamesRequest buildGetTableNamesRequest(final Pattern pattern,
1404       boolean includeSysTables) {
1405     GetTableNamesRequest.Builder builder = GetTableNamesRequest.newBuilder();
1406     if (pattern != null) builder.setRegex(pattern.toString());
1407     builder.setIncludeSysTables(includeSysTables);
1408     return builder.build();
1409   }
1410 
1411   /**
1412    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1413    *
1414    * @param tableName the table name
1415    * @return a GetTableDescriptorsRequest
1416    */
1417   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1418       final TableName tableName) {
1419     return GetTableDescriptorsRequest.newBuilder()
1420       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1421       .build();
1422   }
1423 
1424   /**
1425    * Creates a protocol buffer IsMasterRunningRequest
1426    *
1427    * @return a IsMasterRunningRequest
1428    */
1429   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1430     return IsMasterRunningRequest.newBuilder().build();
1431   }
1432 
1433   /**
1434    * Creates a protocol buffer BalanceRequest
1435    *
1436    * @return a BalanceRequest
1437    */
1438   public static BalanceRequest buildBalanceRequest(boolean force) {
1439     return BalanceRequest.newBuilder().setForce(force).build();
1440   }
1441 
1442   /**
1443    * Creates a protocol buffer SetBalancerRunningRequest
1444    *
1445    * @param on
1446    * @param synchronous
1447    * @return a SetBalancerRunningRequest
1448    */
1449   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(
1450       boolean on,
1451       boolean synchronous) {
1452     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1453   }
1454 
1455   /**
1456    * Creates a protocol buffer IsBalancerEnabledRequest
1457    *
1458    * @return a IsBalancerEnabledRequest
1459    */
1460   public static IsBalancerEnabledRequest buildIsBalancerEnabledRequest() {
1461     return IsBalancerEnabledRequest.newBuilder().build();
1462   }
1463 
1464   /**
1465    * @see {@link #buildGetClusterStatusRequest}
1466    */
1467   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1468       GetClusterStatusRequest.newBuilder().build();
1469 
1470   /**
1471    * Creates a protocol buffer GetClusterStatusRequest
1472    *
1473    * @return A GetClusterStatusRequest
1474    */
1475   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1476     return GET_CLUSTER_STATUS_REQUEST;
1477   }
1478 
1479   /**
1480    * @see {@link #buildCatalogScanRequest}
1481    */
1482   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1483     RunCatalogScanRequest.newBuilder().build();
1484 
1485   /**
1486    * Creates a request for running a catalog scan
1487    * @return A {@link RunCatalogScanRequest}
1488    */
1489   public static RunCatalogScanRequest buildCatalogScanRequest() {
1490     return CATALOG_SCAN_REQUEST;
1491   }
1492 
1493   /**
1494    * Creates a request for enabling/disabling the catalog janitor
1495    * @return A {@link EnableCatalogJanitorRequest}
1496    */
1497   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1498     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1499   }
1500 
1501   /**
1502    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1503    */
1504   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1505     IsCatalogJanitorEnabledRequest.newBuilder().build();
1506 
1507   /**
1508    * Creates a request for querying the master whether the catalog janitor is enabled
1509    * @return A {@link IsCatalogJanitorEnabledRequest}
1510    */
1511   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1512     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1513   }
1514 
1515   /**
1516    * Creates a request for querying the master the last flushed sequence Id for a region
1517    * @param regionName
1518    * @return A {@link GetLastFlushedSequenceIdRequest}
1519    */
1520   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1521       byte[] regionName) {
1522     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1523         ByteStringer.wrap(regionName)).build();
1524   }
1525 
1526   /**
1527    * Create a request to grant user permissions.
1528    *
1529    * @param username the short user name who to grant permissions
1530    * @param actions the permissions to be granted
1531    * @return A {@link AccessControlProtos} GrantRequest
1532    */
1533   public static AccessControlProtos.GrantRequest buildGrantRequest(
1534       String username, AccessControlProtos.Permission.Action... actions) {
1535     AccessControlProtos.Permission.Builder ret =
1536         AccessControlProtos.Permission.newBuilder();
1537     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1538         AccessControlProtos.GlobalPermission.newBuilder();
1539     for (AccessControlProtos.Permission.Action a : actions) {
1540       permissionBuilder.addAction(a);
1541     }
1542     ret.setType(AccessControlProtos.Permission.Type.Global)
1543        .setGlobalPermission(permissionBuilder);
1544     return AccessControlProtos.GrantRequest.newBuilder()
1545       .setUserPermission(
1546           AccessControlProtos.UserPermission.newBuilder()
1547               .setUser(ByteString.copyFromUtf8(username))
1548               .setPermission(ret)
1549       ).build();
1550   }
1551 
1552   /**
1553    * Create a request to grant user permissions.
1554    *
1555    * @param username the short user name who to grant permissions
1556    * @param tableName optional table name the permissions apply
1557    * @param family optional column family
1558    * @param qualifier optional qualifier
1559    * @param actions the permissions to be granted
1560    * @return A {@link AccessControlProtos} GrantRequest
1561    */
1562   public static AccessControlProtos.GrantRequest buildGrantRequest(
1563       String username, TableName tableName, byte[] family, byte[] qualifier,
1564       AccessControlProtos.Permission.Action... actions) {
1565     AccessControlProtos.Permission.Builder ret =
1566         AccessControlProtos.Permission.newBuilder();
1567     AccessControlProtos.TablePermission.Builder permissionBuilder =
1568         AccessControlProtos.TablePermission.newBuilder();
1569     for (AccessControlProtos.Permission.Action a : actions) {
1570       permissionBuilder.addAction(a);
1571     }
1572     if (tableName == null) {
1573       throw new NullPointerException("TableName cannot be null");
1574     }
1575     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1576 
1577     if (family != null) {
1578       permissionBuilder.setFamily(ByteStringer.wrap(family));
1579     }
1580     if (qualifier != null) {
1581       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1582     }
1583     ret.setType(AccessControlProtos.Permission.Type.Table)
1584        .setTablePermission(permissionBuilder);
1585     return AccessControlProtos.GrantRequest.newBuilder()
1586       .setUserPermission(
1587           AccessControlProtos.UserPermission.newBuilder()
1588               .setUser(ByteString.copyFromUtf8(username))
1589               .setPermission(ret)
1590       ).build();
1591   }
1592 
1593   /**
1594    * Create a request to grant user permissions.
1595    *
1596    * @param username the short user name who to grant permissions
1597    * @param namespace optional table name the permissions apply
1598    * @param actions the permissions to be granted
1599    * @return A {@link AccessControlProtos} GrantRequest
1600    */
1601   public static AccessControlProtos.GrantRequest buildGrantRequest(
1602       String username, String namespace,
1603       AccessControlProtos.Permission.Action... actions) {
1604     AccessControlProtos.Permission.Builder ret =
1605         AccessControlProtos.Permission.newBuilder();
1606     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1607         AccessControlProtos.NamespacePermission.newBuilder();
1608     for (AccessControlProtos.Permission.Action a : actions) {
1609       permissionBuilder.addAction(a);
1610     }
1611     if (namespace != null) {
1612       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1613     }
1614     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1615        .setNamespacePermission(permissionBuilder);
1616     return AccessControlProtos.GrantRequest.newBuilder()
1617       .setUserPermission(
1618           AccessControlProtos.UserPermission.newBuilder()
1619               .setUser(ByteString.copyFromUtf8(username))
1620               .setPermission(ret)
1621       ).build();
1622   }
1623 
1624   /**
1625    * Create a request to revoke user permissions.
1626    *
1627    * @param username the short user name whose permissions to be revoked
1628    * @param actions the permissions to be revoked
1629    * @return A {@link AccessControlProtos} RevokeRequest
1630    */
1631   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1632       String username, AccessControlProtos.Permission.Action... actions) {
1633     AccessControlProtos.Permission.Builder ret =
1634         AccessControlProtos.Permission.newBuilder();
1635     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1636         AccessControlProtos.GlobalPermission.newBuilder();
1637     for (AccessControlProtos.Permission.Action a : actions) {
1638       permissionBuilder.addAction(a);
1639     }
1640     ret.setType(AccessControlProtos.Permission.Type.Global)
1641        .setGlobalPermission(permissionBuilder);
1642     return AccessControlProtos.RevokeRequest.newBuilder()
1643       .setUserPermission(
1644           AccessControlProtos.UserPermission.newBuilder()
1645               .setUser(ByteString.copyFromUtf8(username))
1646               .setPermission(ret)
1647       ).build();
1648   }
1649 
1650   /**
1651    * Create a request to revoke user permissions.
1652    *
1653    * @param username the short user name whose permissions to be revoked
1654    * @param tableName optional table name the permissions apply
1655    * @param family optional column family
1656    * @param qualifier optional qualifier
1657    * @param actions the permissions to be revoked
1658    * @return A {@link AccessControlProtos} RevokeRequest
1659    */
1660   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1661       String username, TableName tableName, byte[] family, byte[] qualifier,
1662       AccessControlProtos.Permission.Action... actions) {
1663     AccessControlProtos.Permission.Builder ret =
1664         AccessControlProtos.Permission.newBuilder();
1665     AccessControlProtos.TablePermission.Builder permissionBuilder =
1666         AccessControlProtos.TablePermission.newBuilder();
1667     for (AccessControlProtos.Permission.Action a : actions) {
1668       permissionBuilder.addAction(a);
1669     }
1670     if (tableName != null) {
1671       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1672     }
1673     if (family != null) {
1674       permissionBuilder.setFamily(ByteStringer.wrap(family));
1675     }
1676     if (qualifier != null) {
1677       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1678     }
1679     ret.setType(AccessControlProtos.Permission.Type.Table)
1680        .setTablePermission(permissionBuilder);
1681     return AccessControlProtos.RevokeRequest.newBuilder()
1682       .setUserPermission(
1683           AccessControlProtos.UserPermission.newBuilder()
1684               .setUser(ByteString.copyFromUtf8(username))
1685               .setPermission(ret)
1686       ).build();
1687   }
1688 
1689   /**
1690    * Create a request to revoke user permissions.
1691    *
1692    * @param username the short user name whose permissions to be revoked
1693    * @param namespace optional table name the permissions apply
1694    * @param actions the permissions to be revoked
1695    * @return A {@link AccessControlProtos} RevokeRequest
1696    */
1697   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1698       String username, String namespace,
1699       AccessControlProtos.Permission.Action... actions) {
1700     AccessControlProtos.Permission.Builder ret =
1701         AccessControlProtos.Permission.newBuilder();
1702     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1703         AccessControlProtos.NamespacePermission.newBuilder();
1704     for (AccessControlProtos.Permission.Action a : actions) {
1705       permissionBuilder.addAction(a);
1706     }
1707     if (namespace != null) {
1708       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1709     }
1710     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1711        .setNamespacePermission(permissionBuilder);
1712     return AccessControlProtos.RevokeRequest.newBuilder()
1713       .setUserPermission(
1714           AccessControlProtos.UserPermission.newBuilder()
1715               .setUser(ByteString.copyFromUtf8(username))
1716               .setPermission(ret)
1717       ).build();
1718   }
1719 
1720   /**
1721    * Create a RegionOpenInfo based on given region info and version of offline node
1722    */
1723   private static RegionOpenInfo buildRegionOpenInfo(
1724       final HRegionInfo region, final int versionOfOfflineNode,
1725       final List<ServerName> favoredNodes, Boolean openForReplay) {
1726     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1727     builder.setRegion(HRegionInfo.convert(region));
1728     if (versionOfOfflineNode >= 0) {
1729       builder.setVersionOfOfflineNode(versionOfOfflineNode);
1730     }
1731     if (favoredNodes != null) {
1732       for (ServerName server : favoredNodes) {
1733         builder.addFavoredNodes(ProtobufUtil.toServerName(server));
1734       }
1735     }
1736     if(openForReplay != null) {
1737       builder.setOpenForDistributedLogReplay(openForReplay);
1738     }
1739     return builder.build();
1740   }
1741 
1742   /**
1743    * Creates a protocol buffer NormalizeRequest
1744    *
1745    * @return a NormalizeRequest
1746    */
1747   public static NormalizeRequest buildNormalizeRequest() {
1748     return NormalizeRequest.newBuilder().build();
1749   }
1750 
1751   /**
1752    * Creates a protocol buffer IsNormalizerEnabledRequest
1753    *
1754    * @return a IsNormalizerEnabledRequest
1755    */
1756   public static IsNormalizerEnabledRequest buildIsNormalizerEnabledRequest() {
1757     return IsNormalizerEnabledRequest.newBuilder().build();
1758   }
1759 
1760   /**
1761    * Creates a protocol buffer SetNormalizerRunningRequest
1762    *
1763    * @param on
1764    * @return a SetNormalizerRunningRequest
1765    */
1766   public static SetNormalizerRunningRequest buildSetNormalizerRunningRequest(boolean on) {
1767     return SetNormalizerRunningRequest.newBuilder().setOn(on).build();
1768   }
1769 
1770   /**
1771    * Creates a protocol buffer IsSplitOrMergeEnabledRequest
1772    *
1773    * @param switchType see {@link org.apache.hadoop.hbase.client.Admin.MasterSwitchType}
1774    * @return a IsSplitOrMergeEnabledRequest
1775    */
1776   public static IsSplitOrMergeEnabledRequest buildIsSplitOrMergeEnabledRequest(
1777     Admin.MasterSwitchType switchType) {
1778     IsSplitOrMergeEnabledRequest.Builder builder = IsSplitOrMergeEnabledRequest.newBuilder();
1779     builder.setSwitchType(convert(switchType));
1780     return builder.build();
1781   }
1782 
1783   /**
1784    * Creates a protocol buffer SetSplitOrMergeEnabledRequest
1785    *
1786    * @param enabled switch is enabled or not
1787    * @param synchronous set switch sync?
1788    * @param switchTypes see {@link org.apache.hadoop.hbase.client.Admin.MasterSwitchType}, it is
1789    *                    a list.
1790    * @return a SetSplitOrMergeEnabledRequest
1791    */
1792   public static SetSplitOrMergeEnabledRequest buildSetSplitOrMergeEnabledRequest(boolean enabled,
1793     boolean synchronous, Admin.MasterSwitchType... switchTypes) {
1794     SetSplitOrMergeEnabledRequest.Builder builder = SetSplitOrMergeEnabledRequest.newBuilder();
1795     builder.setEnabled(enabled);
1796     builder.setSynchronous(synchronous);
1797     for (Admin.MasterSwitchType switchType : switchTypes) {
1798       builder.addSwitchTypes(convert(switchType));
1799     }
1800     return builder.build();
1801   }
1802 
1803   private static MasterProtos.MasterSwitchType convert(Admin.MasterSwitchType switchType) {
1804     switch (switchType) {
1805       case SPLIT:
1806         return MasterProtos.MasterSwitchType.SPLIT;
1807       case MERGE:
1808         return MasterProtos.MasterSwitchType.MERGE;
1809       default:
1810         break;
1811     }
1812     throw new UnsupportedOperationException("Unsupport switch type:" + switchType);
1813   }
1814 
1815   private static final GetSpaceQuotaRegionSizesRequest GET_SPACE_QUOTA_REGION_SIZES_REQUEST =
1816       GetSpaceQuotaRegionSizesRequest.newBuilder().build();
1817 
1818   /**
1819    * Returns a {@link GetSpaceQuotaRegionSizesRequest} object.
1820    */
1821   public static GetSpaceQuotaRegionSizesRequest buildGetSpaceQuotaRegionSizesRequest() {
1822     return GET_SPACE_QUOTA_REGION_SIZES_REQUEST;
1823   }
1824 
1825   private static final GetSpaceQuotaSnapshotsRequest GET_SPACE_QUOTA_SNAPSHOTS_REQUEST =
1826       GetSpaceQuotaSnapshotsRequest.newBuilder().build();
1827 
1828   /**
1829    * Returns a {@link GetSpaceQuotaSnapshotsRequest} object.
1830    */
1831   public static GetSpaceQuotaSnapshotsRequest buildGetSpaceQuotaSnapshotsRequest() {
1832     return GET_SPACE_QUOTA_SNAPSHOTS_REQUEST;
1833   }
1834 
1835   private static final GetQuotaStatesRequest GET_QUOTA_STATES_REQUEST =
1836       GetQuotaStatesRequest.newBuilder().build();
1837 
1838   /**
1839    * Returns a {@link GetQuotaStatesRequest} object.
1840    */
1841   public static GetQuotaStatesRequest buildGetQuotaStatesRequest() {
1842     return GET_QUOTA_STATES_REQUEST;
1843   }
1844 }