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