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