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