View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.protobuf;
19  
20  import java.io.IOException;
21  import java.util.List;
22  
23  import org.apache.hadoop.hbase.util.ByteStringer;
24  
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.CellScannable;
27  import org.apache.hadoop.hbase.DoNotRetryIOException;
28  import org.apache.hadoop.hbase.HColumnDescriptor;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.HRegionInfo;
31  import org.apache.hadoop.hbase.HTableDescriptor;
32  import org.apache.hadoop.hbase.ServerName;
33  import org.apache.hadoop.hbase.TableName;
34  import org.apache.hadoop.hbase.client.Action;
35  import org.apache.hadoop.hbase.client.Append;
36  import org.apache.hadoop.hbase.client.Delete;
37  import org.apache.hadoop.hbase.client.Durability;
38  import org.apache.hadoop.hbase.client.Get;
39  import org.apache.hadoop.hbase.client.Increment;
40  import org.apache.hadoop.hbase.client.Mutation;
41  import org.apache.hadoop.hbase.client.Put;
42  import org.apache.hadoop.hbase.client.RegionCoprocessorServiceExec;
43  import org.apache.hadoop.hbase.client.Row;
44  import org.apache.hadoop.hbase.client.RowMutations;
45  import org.apache.hadoop.hbase.client.Scan;
46  import org.apache.hadoop.hbase.exceptions.DeserializationException;
47  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
48  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
49  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
50  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
51  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest;
63  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest.RegionUpdateInfo;
64  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
65  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest;
66  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest.FamilyPath;
67  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Column;
68  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Condition;
69  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
70  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
71  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
72  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue;
73  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue;
74  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType;
75  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
76  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
77  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType;
78  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
79  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
80  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AddColumnRequest;
81  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AssignRegionRequest;
82  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.BalanceRequest;
83  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
84  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteColumnRequest;
85  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableRequest;
86  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableRequest;
87  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
88  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest;
89  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
90  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
91  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
92  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
93  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
94  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
95  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
96  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
97  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
98  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
99  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
103 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest;
104 import org.apache.hadoop.hbase.util.ByteStringer;
105 import org.apache.hadoop.hbase.util.Bytes;
106 import org.apache.hadoop.hbase.util.Pair;
107 import org.apache.hadoop.hbase.util.Triple;
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     return builder.build();
490   }
491 
492   /**
493    * Create a protocol buffer ScanRequest for a scanner id
494    *
495    * @param scannerId
496    * @param numberOfRows
497    * @param closeScanner
498    * @return a scan request
499    */
500   public static ScanRequest buildScanRequest(final long scannerId,
501       final int numberOfRows, final boolean closeScanner) {
502     ScanRequest.Builder builder = ScanRequest.newBuilder();
503     builder.setNumberOfRows(numberOfRows);
504     builder.setCloseScanner(closeScanner);
505     builder.setScannerId(scannerId);
506     return builder.build();
507   }
508 
509   /**
510    * Create a protocol buffer ScanRequest for a scanner id
511    *
512    * @param scannerId
513    * @param numberOfRows
514    * @param closeScanner
515    * @param nextCallSeq
516    * @return a scan request
517    */
518   public static ScanRequest buildScanRequest(final long scannerId, final int numberOfRows,
519       final boolean closeScanner, final long nextCallSeq) {
520     ScanRequest.Builder builder = ScanRequest.newBuilder();
521     builder.setNumberOfRows(numberOfRows);
522     builder.setCloseScanner(closeScanner);
523     builder.setScannerId(scannerId);
524     builder.setNextCallSeq(nextCallSeq);
525     return builder.build();
526   }
527 
528   /**
529    * Create a protocol buffer bulk load request
530    *
531    * @param familyPaths
532    * @param regionName
533    * @param assignSeqNum
534    * @return a bulk load request
535    */
536   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
537       final List<Pair<byte[], String>> familyPaths,
538       final byte[] regionName, boolean assignSeqNum) {
539     BulkLoadHFileRequest.Builder builder = BulkLoadHFileRequest.newBuilder();
540     RegionSpecifier region = buildRegionSpecifier(
541       RegionSpecifierType.REGION_NAME, regionName);
542     builder.setRegion(region);
543     FamilyPath.Builder familyPathBuilder = FamilyPath.newBuilder();
544     for (Pair<byte[], String> familyPath: familyPaths) {
545       familyPathBuilder.setFamily(ByteStringer.wrap(familyPath.getFirst()));
546       familyPathBuilder.setPath(familyPath.getSecond());
547       builder.addFamilyPath(familyPathBuilder.build());
548     }
549     builder.setAssignSeqNum(assignSeqNum);
550     return builder.build();
551   }
552 
553   /**
554    * Create a protocol buffer multi request for a list of actions.
555    * Propagates Actions original index.
556    *
557    * @param regionName
558    * @param actions
559    * @return a multi request
560    * @throws IOException
561    */
562   public static <R> RegionAction.Builder buildRegionAction(final byte[] regionName,
563       final List<Action<R>> actions, final RegionAction.Builder regionActionBuilder,
564       final ClientProtos.Action.Builder actionBuilder,
565       final MutationProto.Builder mutationBuilder) throws IOException {
566     for (Action<R> action: actions) {
567       Row row = action.getAction();
568       actionBuilder.clear();
569       actionBuilder.setIndex(action.getOriginalIndex());
570       mutationBuilder.clear();
571       if (row instanceof Get) {
572         Get g = (Get)row;
573         regionActionBuilder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
574       } else if (row instanceof Put) {
575         regionActionBuilder.addAction(actionBuilder.
576           setMutation(ProtobufUtil.toMutation(MutationType.PUT, (Put)row, mutationBuilder)));
577       } else if (row instanceof Delete) {
578         regionActionBuilder.addAction(actionBuilder.
579           setMutation(ProtobufUtil.toMutation(MutationType.DELETE, (Delete)row, mutationBuilder)));
580       } else if (row instanceof Append) {
581         regionActionBuilder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutation(
582             MutationType.APPEND, (Append)row, mutationBuilder, action.getNonce())));
583       } else if (row instanceof Increment) {
584         regionActionBuilder.addAction(actionBuilder.setMutation(
585             ProtobufUtil.toMutation((Increment)row, mutationBuilder, action.getNonce())));
586       } else if (row instanceof RegionCoprocessorServiceExec) {
587         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
588         regionActionBuilder.addAction(actionBuilder.setServiceCall(
589             ClientProtos.CoprocessorServiceCall.newBuilder()
590               .setRow(ByteStringer.wrap(exec.getRow()))
591               .setServiceName(exec.getMethod().getService().getFullName())
592               .setMethodName(exec.getMethod().getName())
593               .setRequest(exec.getRequest().toByteString())));
594       } else if (row instanceof RowMutations) {
595         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
596       } else {
597         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
598       }
599     }
600     return regionActionBuilder;
601   }
602 
603   /**
604    * Create a protocol buffer multirequest with NO data for a list of actions (data is carried
605    * otherwise than via protobuf).  This means it just notes attributes, whether to write the
606    * WAL, etc., and the presence in protobuf serves as place holder for the data which is
607    * coming along otherwise.  Note that Get is different.  It does not contain 'data' and is always
608    * carried by protobuf.  We return references to the data by adding them to the passed in
609    * <code>data</code> param.
610    *
611    * <p>Propagates Actions original index.
612    *
613    * @param regionName
614    * @param actions
615    * @param cells Place to stuff references to actual data.
616    * @return a multi request that does not carry any data.
617    * @throws IOException
618    */
619   public static <R> RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
620       final List<Action<R>> actions, final List<CellScannable> cells,
621       final RegionAction.Builder regionActionBuilder,
622       final ClientProtos.Action.Builder actionBuilder,
623       final MutationProto.Builder mutationBuilder) throws IOException {
624     RegionAction.Builder builder = getRegionActionBuilderWithRegion(
625       RegionAction.newBuilder(), regionName);
626     for (Action<R> action: actions) {
627       Row row = action.getAction();
628       actionBuilder.clear();
629       actionBuilder.setIndex(action.getOriginalIndex());
630       mutationBuilder.clear();
631       if (row instanceof Get) {
632         Get g = (Get)row;
633         builder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
634       } else if (row instanceof Put) {
635         Put p = (Put)row;
636         cells.add(p);
637         builder.addAction(actionBuilder.
638           setMutation(ProtobufUtil.toMutationNoData(MutationType.PUT, p, mutationBuilder)));
639       } else if (row instanceof Delete) {
640         Delete d = (Delete)row;
641         int size = d.size();
642         // Note that a legitimate Delete may have a size of zero; i.e. a Delete that has nothing
643         // in it but the row to delete.  In this case, the current implementation does not make
644         // a KeyValue to represent a delete-of-all-the-row until we serialize... For such cases
645         // where the size returned is zero, we will send the Delete fully pb'd rather than have
646         // metadata only in the pb and then send the kv along the side in cells.
647         if (size > 0) {
648           cells.add(d);
649           builder.addAction(actionBuilder.
650             setMutation(ProtobufUtil.toMutationNoData(MutationType.DELETE, d, mutationBuilder)));
651         } else {
652           builder.addAction(actionBuilder.
653             setMutation(ProtobufUtil.toMutation(MutationType.DELETE, d, mutationBuilder)));
654         }
655       } else if (row instanceof Append) {
656         Append a = (Append)row;
657         cells.add(a);
658         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
659           MutationType.APPEND, a, mutationBuilder, action.getNonce())));
660       } else if (row instanceof Increment) {
661         Increment i = (Increment)row;
662         cells.add(i);
663         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
664           MutationType.INCREMENT, i, mutationBuilder, action.getNonce())));
665       } else if (row instanceof RowMutations) {
666         continue; // ignore RowMutations
667       } else {
668         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
669       }
670     }
671     return builder;
672   }
673 
674 // End utilities for Client
675 //Start utilities for Admin
676 
677   /**
678    * Create a protocol buffer GetRegionInfoRequest for a given region name
679    *
680    * @param regionName the name of the region to get info
681    * @return a protocol buffer GetRegionInfoRequest
682    */
683   public static GetRegionInfoRequest
684       buildGetRegionInfoRequest(final byte[] regionName) {
685     return buildGetRegionInfoRequest(regionName, false);
686   }
687 
688   /**
689    * Create a protocol buffer GetRegionInfoRequest for a given region name
690    *
691    * @param regionName the name of the region to get info
692    * @param includeCompactionState indicate if the compaction state is requested
693    * @return a protocol buffer GetRegionInfoRequest
694    */
695   public static GetRegionInfoRequest
696       buildGetRegionInfoRequest(final byte[] regionName,
697         final boolean includeCompactionState) {
698     GetRegionInfoRequest.Builder builder = GetRegionInfoRequest.newBuilder();
699     RegionSpecifier region = buildRegionSpecifier(
700       RegionSpecifierType.REGION_NAME, regionName);
701     builder.setRegion(region);
702     if (includeCompactionState) {
703       builder.setCompactionState(includeCompactionState);
704     }
705     return builder.build();
706   }
707 
708  /**
709   * Create a protocol buffer GetStoreFileRequest for a given region name
710   *
711   * @param regionName the name of the region to get info
712   * @param family the family to get store file list
713   * @return a protocol buffer GetStoreFileRequest
714   */
715  public static GetStoreFileRequest
716      buildGetStoreFileRequest(final byte[] regionName, final byte[] family) {
717    GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder();
718    RegionSpecifier region = buildRegionSpecifier(
719      RegionSpecifierType.REGION_NAME, regionName);
720    builder.setRegion(region);
721    builder.addFamily(ByteStringer.wrap(family));
722    return builder.build();
723  }
724 
725  /**
726   * Create a protocol buffer GetOnlineRegionRequest
727   *
728   * @return a protocol buffer GetOnlineRegionRequest
729   */
730  public static GetOnlineRegionRequest buildGetOnlineRegionRequest() {
731    return GetOnlineRegionRequest.newBuilder().build();
732  }
733 
734  /**
735   * Create a protocol buffer FlushRegionRequest for a given region name
736   *
737   * @param regionName the name of the region to get info
738   * @return a protocol buffer FlushRegionRequest
739   */
740  public static FlushRegionRequest
741      buildFlushRegionRequest(final byte[] regionName) {
742    FlushRegionRequest.Builder builder = FlushRegionRequest.newBuilder();
743    RegionSpecifier region = buildRegionSpecifier(
744      RegionSpecifierType.REGION_NAME, regionName);
745    builder.setRegion(region);
746    return builder.build();
747  }
748 
749  /**
750   * Create a protocol buffer OpenRegionRequest to open a list of regions
751   *
752   * @param server the serverName for the RPC
753   * @param regionOpenInfos info of a list of regions to open
754   * @param openForReplay
755   * @return a protocol buffer OpenRegionRequest
756   */
757  public static OpenRegionRequest
758      buildOpenRegionRequest(ServerName server, final List<Triple<HRegionInfo, Integer,
759          List<ServerName>>> regionOpenInfos, Boolean openForReplay) {
760    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
761    for (Triple<HRegionInfo, Integer, List<ServerName>> regionOpenInfo: regionOpenInfos) {
762      Integer second = regionOpenInfo.getSecond();
763      int versionOfOfflineNode = second == null ? -1 : second.intValue();
764      builder.addOpenInfo(buildRegionOpenInfo(regionOpenInfo.getFirst(), versionOfOfflineNode, 
765        regionOpenInfo.getThird(), openForReplay));
766    }
767    if (server != null) {
768      builder.setServerStartCode(server.getStartcode());
769    }
770    return builder.build();
771  }
772 
773  /**
774   * Create a protocol buffer OpenRegionRequest for a given region
775   *
776   * @param server the serverName for the RPC
777   * @param region the region to open
778   * @param versionOfOfflineNode that needs to be present in the offline node
779   * @param favoredNodes
780   * @param openForReplay
781   * @return a protocol buffer OpenRegionRequest
782   */
783  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
784      final HRegionInfo region, final int versionOfOfflineNode, List<ServerName> favoredNodes,
785      Boolean openForReplay) {
786    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
787    builder.addOpenInfo(buildRegionOpenInfo(region, versionOfOfflineNode, favoredNodes, 
788      openForReplay));
789    if (server != null) {
790      builder.setServerStartCode(server.getStartcode());
791    }
792    return builder.build();
793  }
794 
795  /**
796   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
797   * @param updateRegionInfos
798   * @return a protocol buffer UpdateFavoredNodesRequest
799   */
800  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
801      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
802    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
803    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
804      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
805      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
806      for (ServerName server : pair.getSecond()) {
807        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
808      }
809      ubuilder.addUpdateInfo(builder.build());
810    }
811    return ubuilder.build();
812  }
813 
814  /**
815   * Create a CloseRegionRequest for a given region name
816   *
817   * @param regionName the name of the region to close
818   * @param transitionInZK indicator if to transition in ZK
819   * @return a CloseRegionRequest
820   */
821  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
822      final byte[] regionName, final boolean transitionInZK) {
823    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
824    RegionSpecifier region = buildRegionSpecifier(
825      RegionSpecifierType.REGION_NAME, regionName);
826    builder.setRegion(region);
827    builder.setTransitionInZK(transitionInZK);
828    if (server != null) {
829      builder.setServerStartCode(server.getStartcode());
830    }
831    return builder.build();
832  }
833 
834   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
835     final byte[] regionName, final int versionOfClosingNode,
836     ServerName destinationServer, final boolean transitionInZK) {
837     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
838     RegionSpecifier region = buildRegionSpecifier(
839       RegionSpecifierType.REGION_NAME, regionName);
840     builder.setRegion(region);
841     builder.setVersionOfClosingNode(versionOfClosingNode);
842     builder.setTransitionInZK(transitionInZK);
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   * @param transitionInZK indicator if to transition in ZK
857   * @return a CloseRegionRequest
858   */
859  public static CloseRegionRequest
860      buildCloseRegionRequest(ServerName server, final String encodedRegionName,
861        final boolean transitionInZK) {
862    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
863    RegionSpecifier region = buildRegionSpecifier(
864      RegionSpecifierType.ENCODED_REGION_NAME,
865      Bytes.toBytes(encodedRegionName));
866    builder.setRegion(region);
867    builder.setTransitionInZK(transitionInZK);
868    if (server != null) {
869      builder.setServerStartCode(server.getStartcode());
870    }
871    return builder.build();
872  }
873 
874  /**
875   * Create a SplitRegionRequest for a given region name
876   *
877   * @param regionName the name of the region to split
878   * @param splitPoint the split point
879   * @return a SplitRegionRequest
880   */
881  public static SplitRegionRequest buildSplitRegionRequest(
882      final byte[] regionName, final byte[] splitPoint) {
883    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
884    RegionSpecifier region = buildRegionSpecifier(
885      RegionSpecifierType.REGION_NAME, regionName);
886    builder.setRegion(region);
887    if (splitPoint != null) {
888      builder.setSplitPoint(ByteStringer.wrap(splitPoint));
889    }
890    return builder.build();
891  }
892 
893   /**
894    * Create a MergeRegionsRequest for the given regions
895    * @param regionA name of region a
896    * @param regionB name of region b
897    * @param forcible true if it is a compulsory merge
898    * @return a MergeRegionsRequest
899    */
900   public static MergeRegionsRequest buildMergeRegionsRequest(
901       final byte[] regionA, final byte[] regionB, final boolean forcible) {
902     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
903     RegionSpecifier regionASpecifier = buildRegionSpecifier(
904         RegionSpecifierType.REGION_NAME, regionA);
905     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
906         RegionSpecifierType.REGION_NAME, regionB);
907     builder.setRegionA(regionASpecifier);
908     builder.setRegionB(regionBSpecifier);
909     builder.setForcible(forcible);
910     return builder.build();
911   }
912 
913  /**
914   * Create a  CompactRegionRequest for a given region name
915   *
916   * @param regionName the name of the region to get info
917   * @param major indicator if it is a major compaction
918   * @return a CompactRegionRequest
919   */
920  public static CompactRegionRequest buildCompactRegionRequest(
921      final byte[] regionName, final boolean major, final byte [] family) {
922    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
923    RegionSpecifier region = buildRegionSpecifier(
924      RegionSpecifierType.REGION_NAME, regionName);
925    builder.setRegion(region);
926    builder.setMajor(major);
927    if (family != null) {
928      builder.setFamily(ByteStringer.wrap(family));
929    }
930    return builder.build();
931  }
932 
933  /**
934   * @see {@link #buildRollWALWriterRequest()
935   */
936  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
937      RollWALWriterRequest.newBuilder().build();
938 
939   /**
940   * Create a new RollWALWriterRequest
941   *
942   * @return a ReplicateWALEntryRequest
943   */
944  public static RollWALWriterRequest buildRollWALWriterRequest() {
945    return ROLL_WAL_WRITER_REQUEST;
946  }
947 
948  /**
949   * @see {@link #buildGetServerInfoRequest()}
950   */
951  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
952    GetServerInfoRequest.newBuilder().build();
953 
954  /**
955   * Create a new GetServerInfoRequest
956   *
957   * @return a GetServerInfoRequest
958   */
959  public static GetServerInfoRequest buildGetServerInfoRequest() {
960    return GET_SERVER_INFO_REQUEST;
961  }
962 
963  /**
964   * Create a new StopServerRequest
965   *
966   * @param reason the reason to stop the server
967   * @return a StopServerRequest
968   */
969  public static StopServerRequest buildStopServerRequest(final String reason) {
970    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
971    builder.setReason(reason);
972    return builder.build();
973  }
974 
975 //End utilities for Admin
976 
977   /**
978    * Convert a byte array to a protocol buffer RegionSpecifier
979    *
980    * @param type the region specifier type
981    * @param value the region specifier byte array value
982    * @return a protocol buffer RegionSpecifier
983    */
984   public static RegionSpecifier buildRegionSpecifier(
985       final RegionSpecifierType type, final byte[] value) {
986     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
987     regionBuilder.setValue(ByteStringer.wrap(value));
988     regionBuilder.setType(type);
989     return regionBuilder.build();
990   }
991 
992   /**
993    * Create a protocol buffer Condition
994    *
995    * @param row
996    * @param family
997    * @param qualifier
998    * @param comparator
999    * @param compareType
1000    * @return a Condition
1001    * @throws IOException
1002    */
1003   private static Condition buildCondition(final byte[] row,
1004       final byte[] family, final byte [] qualifier,
1005       final ByteArrayComparable comparator,
1006       final CompareType compareType) throws IOException {
1007     Condition.Builder builder = Condition.newBuilder();
1008     builder.setRow(ByteStringer.wrap(row));
1009     builder.setFamily(ByteStringer.wrap(family));
1010     builder.setQualifier(ByteStringer.wrap(qualifier));
1011     builder.setComparator(ProtobufUtil.toComparator(comparator));
1012     builder.setCompareType(compareType);
1013     return builder.build();
1014   }
1015 
1016   /**
1017    * Create a protocol buffer AddColumnRequest
1018    *
1019    * @param tableName
1020    * @param column
1021    * @return an AddColumnRequest
1022    */
1023   public static AddColumnRequest buildAddColumnRequest(
1024       final TableName tableName, final HColumnDescriptor column) {
1025     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
1026     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1027     builder.setColumnFamilies(column.convert());
1028     return builder.build();
1029   }
1030 
1031   /**
1032    * Create a protocol buffer DeleteColumnRequest
1033    *
1034    * @param tableName
1035    * @param columnName
1036    * @return a DeleteColumnRequest
1037    */
1038   public static DeleteColumnRequest buildDeleteColumnRequest(
1039       final TableName tableName, final byte [] columnName) {
1040     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
1041     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1042     builder.setColumnName(ByteStringer.wrap(columnName));
1043     return builder.build();
1044   }
1045 
1046   /**
1047    * Create a protocol buffer ModifyColumnRequest
1048    *
1049    * @param tableName
1050    * @param column
1051    * @return an ModifyColumnRequest
1052    */
1053   public static ModifyColumnRequest buildModifyColumnRequest(
1054       final TableName tableName, final HColumnDescriptor column) {
1055     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
1056     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1057     builder.setColumnFamilies(column.convert());
1058     return builder.build();
1059   }
1060 
1061   /**
1062    * Create a protocol buffer MoveRegionRequest
1063    *
1064    * @param encodedRegionName
1065    * @param destServerName
1066    * @return A MoveRegionRequest
1067    * @throws DeserializationException
1068    */
1069   public static MoveRegionRequest buildMoveRegionRequest(
1070       final byte [] encodedRegionName, final byte [] destServerName) throws
1071       DeserializationException {
1072 	MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1073     builder.setRegion(
1074       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1075     if (destServerName != null) {
1076       builder.setDestServerName(
1077         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1078     }
1079     return builder.build();
1080   }
1081 
1082   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1083       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1084       final boolean forcible) throws DeserializationException {
1085     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1086     builder.setRegionA(buildRegionSpecifier(
1087         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1088     builder.setRegionB(buildRegionSpecifier(
1089         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1090     builder.setForcible(forcible);
1091     return builder.build();
1092   }
1093 
1094   /**
1095    * Create a protocol buffer AssignRegionRequest
1096    *
1097    * @param regionName
1098    * @return an AssignRegionRequest
1099    */
1100   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1101     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1102     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1103     return builder.build();
1104   }
1105 
1106   /**
1107    * Creates a protocol buffer UnassignRegionRequest
1108    *
1109    * @param regionName
1110    * @param force
1111    * @return an UnassignRegionRequest
1112    */
1113   public static UnassignRegionRequest buildUnassignRegionRequest(
1114       final byte [] regionName, final boolean force) {
1115     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1116     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1117     builder.setForce(force);
1118     return builder.build();
1119   }
1120 
1121   /**
1122    * Creates a protocol buffer OfflineRegionRequest
1123    *
1124    * @param regionName
1125    * @return an OfflineRegionRequest
1126    */
1127   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1128     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1129     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1130     return builder.build();
1131   }
1132 
1133   /**
1134    * Creates a protocol buffer DeleteTableRequest
1135    *
1136    * @param tableName
1137    * @return a DeleteTableRequest
1138    */
1139   public static DeleteTableRequest buildDeleteTableRequest(final TableName tableName) {
1140     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1141     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1142     return builder.build();
1143   }
1144 
1145   /**
1146    * Creates a protocol buffer TruncateTableRequest
1147    *
1148    * @param tableName name of table to truncate
1149    * @param preserveSplits True if the splits should be preserved
1150    * @return a TruncateTableRequest
1151    */
1152   public static TruncateTableRequest buildTruncateTableRequest(final TableName tableName,
1153         boolean preserveSplits) {
1154     TruncateTableRequest.Builder builder = TruncateTableRequest.newBuilder();
1155     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1156     builder.setPreserveSplits(preserveSplits);
1157     return builder.build();
1158   }
1159 
1160   /**
1161    * Creates a protocol buffer EnableTableRequest
1162    *
1163    * @param tableName
1164    * @return an EnableTableRequest
1165    */
1166   public static EnableTableRequest buildEnableTableRequest(final TableName tableName) {
1167     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1168     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1169     return builder.build();
1170   }
1171 
1172   /**
1173    * Creates a protocol buffer DisableTableRequest
1174    *
1175    * @param tableName
1176    * @return a DisableTableRequest
1177    */
1178   public static DisableTableRequest buildDisableTableRequest(final TableName tableName) {
1179     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1180     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1181     return builder.build();
1182   }
1183 
1184   /**
1185    * Creates a protocol buffer CreateTableRequest
1186    *
1187    * @param hTableDesc
1188    * @param splitKeys
1189    * @return a CreateTableRequest
1190    */
1191   public static CreateTableRequest buildCreateTableRequest(
1192       final HTableDescriptor hTableDesc, final byte [][] splitKeys) {
1193     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1194     builder.setTableSchema(hTableDesc.convert());
1195     if (splitKeys != null) {
1196       for (byte [] splitKey : splitKeys) {
1197         builder.addSplitKeys(ByteStringer.wrap(splitKey));
1198       }
1199     }
1200     return builder.build();
1201   }
1202 
1203 
1204   /**
1205    * Creates a protocol buffer ModifyTableRequest
1206    *
1207    * @param tableName
1208    * @param hTableDesc
1209    * @return a ModifyTableRequest
1210    */
1211   public static ModifyTableRequest buildModifyTableRequest(
1212       final TableName tableName, final HTableDescriptor hTableDesc) {
1213     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1214     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1215     builder.setTableSchema(hTableDesc.convert());
1216     return builder.build();
1217   }
1218 
1219   /**
1220    * Creates a protocol buffer GetSchemaAlterStatusRequest
1221    *
1222    * @param tableName
1223    * @return a GetSchemaAlterStatusRequest
1224    */
1225   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1226       final TableName tableName) {
1227     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1228     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1229     return builder.build();
1230   }
1231 
1232   /**
1233    * Creates a protocol buffer GetTableDescriptorsRequest
1234    *
1235    * @param tableNames
1236    * @return a GetTableDescriptorsRequest
1237    */
1238   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1239       final List<TableName> tableNames) {
1240     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1241     if (tableNames != null) {
1242       for (TableName tableName : tableNames) {
1243         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1244       }
1245     }
1246     return builder.build();
1247   }
1248 
1249   /**
1250    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1251    *
1252    * @param tableName the table name
1253    * @return a GetTableDescriptorsRequest
1254    */
1255   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1256       final TableName tableName) {
1257     return GetTableDescriptorsRequest.newBuilder()
1258       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1259       .build();
1260   }
1261 
1262   /**
1263    * Creates a protocol buffer IsMasterRunningRequest
1264    *
1265    * @return a IsMasterRunningRequest
1266    */
1267   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1268     return IsMasterRunningRequest.newBuilder().build();
1269   }
1270 
1271   /**
1272    * Creates a protocol buffer BalanceRequest
1273    *
1274    * @return a BalanceRequest
1275    */
1276   public static BalanceRequest buildBalanceRequest() {
1277     return BalanceRequest.newBuilder().build();
1278   }
1279 
1280   /**
1281    * Creates a protocol buffer SetBalancerRunningRequest
1282    *
1283    * @param on
1284    * @param synchronous
1285    * @return a SetBalancerRunningRequest
1286    */
1287   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(boolean on, boolean synchronous) {
1288     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1289   }
1290 
1291   /**
1292    * @see {@link #buildGetClusterStatusRequest}
1293    */
1294   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1295       GetClusterStatusRequest.newBuilder().build();
1296 
1297   /**
1298    * Creates a protocol buffer GetClusterStatusRequest
1299    *
1300    * @return A GetClusterStatusRequest
1301    */
1302   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1303     return GET_CLUSTER_STATUS_REQUEST;
1304   }
1305 
1306   /**
1307    * @see {@link #buildCatalogScanRequest}
1308    */
1309   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1310     RunCatalogScanRequest.newBuilder().build();
1311 
1312   /**
1313    * Creates a request for running a catalog scan
1314    * @return A {@link RunCatalogScanRequest}
1315    */
1316   public static RunCatalogScanRequest buildCatalogScanRequest() {
1317     return CATALOG_SCAN_REQUEST;
1318   }
1319 
1320   /**
1321    * Creates a request for enabling/disabling the catalog janitor
1322    * @return A {@link EnableCatalogJanitorRequest}
1323    */
1324   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1325     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1326   }
1327 
1328   /**
1329    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1330    */
1331   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1332     IsCatalogJanitorEnabledRequest.newBuilder().build();
1333 
1334   /**
1335    * Creates a request for querying the master whether the catalog janitor is enabled
1336    * @return A {@link IsCatalogJanitorEnabledRequest}
1337    */
1338   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1339     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1340   }
1341 
1342   /**
1343    * Creates a request for querying the master the last flushed sequence Id for a region
1344    * @param regionName
1345    * @return A {@link GetLastFlushedSequenceIdRequest}
1346    */
1347   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1348       byte[] regionName) {
1349     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1350         ByteStringer.wrap(regionName)).build();
1351   }
1352 
1353   /**
1354    * Create a request to grant user permissions.
1355    *
1356    * @param username the short user name who to grant permissions
1357    * @param actions the permissions to be granted
1358    * @return A {@link AccessControlProtos} GrantRequest
1359    */
1360   public static AccessControlProtos.GrantRequest buildGrantRequest(
1361       String username, AccessControlProtos.Permission.Action... actions) {
1362     AccessControlProtos.Permission.Builder ret =
1363         AccessControlProtos.Permission.newBuilder();
1364     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1365         AccessControlProtos.GlobalPermission.newBuilder();
1366     for (AccessControlProtos.Permission.Action a : actions) {
1367       permissionBuilder.addAction(a);
1368     }
1369     ret.setType(AccessControlProtos.Permission.Type.Global)
1370        .setGlobalPermission(permissionBuilder);
1371     return AccessControlProtos.GrantRequest.newBuilder()
1372       .setUserPermission(
1373           AccessControlProtos.UserPermission.newBuilder()
1374               .setUser(ByteString.copyFromUtf8(username))
1375               .setPermission(ret)
1376       ).build();
1377   }
1378 
1379   /**
1380    * Create a request to grant user permissions.
1381    *
1382    * @param username the short user name who to grant permissions
1383    * @param tableName optional table name the permissions apply
1384    * @param family optional column family
1385    * @param qualifier optional qualifier
1386    * @param actions the permissions to be granted
1387    * @return A {@link AccessControlProtos} GrantRequest
1388    */
1389   public static AccessControlProtos.GrantRequest buildGrantRequest(
1390       String username, TableName tableName, byte[] family, byte[] qualifier,
1391       AccessControlProtos.Permission.Action... actions) {
1392     AccessControlProtos.Permission.Builder ret =
1393         AccessControlProtos.Permission.newBuilder();
1394     AccessControlProtos.TablePermission.Builder permissionBuilder =
1395         AccessControlProtos.TablePermission.newBuilder();
1396     for (AccessControlProtos.Permission.Action a : actions) {
1397       permissionBuilder.addAction(a);
1398     }
1399     if (tableName == null) {
1400       throw new NullPointerException("TableName cannot be null");
1401     }
1402     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1403 
1404     if (family != null) {
1405       permissionBuilder.setFamily(ByteStringer.wrap(family));
1406     }
1407     if (qualifier != null) {
1408       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1409     }
1410     ret.setType(AccessControlProtos.Permission.Type.Table)
1411        .setTablePermission(permissionBuilder);
1412     return AccessControlProtos.GrantRequest.newBuilder()
1413       .setUserPermission(
1414           AccessControlProtos.UserPermission.newBuilder()
1415               .setUser(ByteString.copyFromUtf8(username))
1416               .setPermission(ret)
1417       ).build();
1418   }
1419 
1420   /**
1421    * Create a request to grant user permissions.
1422    *
1423    * @param username the short user name who to grant permissions
1424    * @param namespace optional table name the permissions apply
1425    * @param actions the permissions to be granted
1426    * @return A {@link AccessControlProtos} GrantRequest
1427    */
1428   public static AccessControlProtos.GrantRequest buildGrantRequest(
1429       String username, String namespace,
1430       AccessControlProtos.Permission.Action... actions) {
1431     AccessControlProtos.Permission.Builder ret =
1432         AccessControlProtos.Permission.newBuilder();
1433     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1434         AccessControlProtos.NamespacePermission.newBuilder();
1435     for (AccessControlProtos.Permission.Action a : actions) {
1436       permissionBuilder.addAction(a);
1437     }
1438     if (namespace != null) {
1439       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1440     }
1441     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1442        .setNamespacePermission(permissionBuilder);
1443     return AccessControlProtos.GrantRequest.newBuilder()
1444       .setUserPermission(
1445           AccessControlProtos.UserPermission.newBuilder()
1446               .setUser(ByteString.copyFromUtf8(username))
1447               .setPermission(ret)
1448       ).build();
1449   }
1450 
1451   /**
1452    * Create a request to revoke user permissions.
1453    *
1454    * @param username the short user name whose permissions to be revoked
1455    * @param actions the permissions to be revoked
1456    * @return A {@link AccessControlProtos} RevokeRequest
1457    */
1458   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1459       String username, AccessControlProtos.Permission.Action... actions) {
1460     AccessControlProtos.Permission.Builder ret =
1461         AccessControlProtos.Permission.newBuilder();
1462     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1463         AccessControlProtos.GlobalPermission.newBuilder();
1464     for (AccessControlProtos.Permission.Action a : actions) {
1465       permissionBuilder.addAction(a);
1466     }
1467     ret.setType(AccessControlProtos.Permission.Type.Global)
1468        .setGlobalPermission(permissionBuilder);
1469     return AccessControlProtos.RevokeRequest.newBuilder()
1470       .setUserPermission(
1471           AccessControlProtos.UserPermission.newBuilder()
1472               .setUser(ByteString.copyFromUtf8(username))
1473               .setPermission(ret)
1474       ).build();
1475   }
1476 
1477   /**
1478    * Create a request to revoke user permissions.
1479    *
1480    * @param username the short user name whose permissions to be revoked
1481    * @param tableName optional table name the permissions apply
1482    * @param family optional column family
1483    * @param qualifier optional qualifier
1484    * @param actions the permissions to be revoked
1485    * @return A {@link AccessControlProtos} RevokeRequest
1486    */
1487   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1488       String username, TableName tableName, byte[] family, byte[] qualifier,
1489       AccessControlProtos.Permission.Action... actions) {
1490     AccessControlProtos.Permission.Builder ret =
1491         AccessControlProtos.Permission.newBuilder();
1492     AccessControlProtos.TablePermission.Builder permissionBuilder =
1493         AccessControlProtos.TablePermission.newBuilder();
1494     for (AccessControlProtos.Permission.Action a : actions) {
1495       permissionBuilder.addAction(a);
1496     }
1497     if (tableName != null) {
1498       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1499     }
1500     if (family != null) {
1501       permissionBuilder.setFamily(ByteStringer.wrap(family));
1502     }
1503     if (qualifier != null) {
1504       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1505     }
1506     ret.setType(AccessControlProtos.Permission.Type.Table)
1507        .setTablePermission(permissionBuilder);
1508     return AccessControlProtos.RevokeRequest.newBuilder()
1509       .setUserPermission(
1510           AccessControlProtos.UserPermission.newBuilder()
1511               .setUser(ByteString.copyFromUtf8(username))
1512               .setPermission(ret)
1513       ).build();
1514   }
1515 
1516   /**
1517    * Create a request to revoke user permissions.
1518    *
1519    * @param username the short user name whose permissions to be revoked
1520    * @param namespace optional table name the permissions apply
1521    * @param actions the permissions to be revoked
1522    * @return A {@link AccessControlProtos} RevokeRequest
1523    */
1524   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1525       String username, String namespace,
1526       AccessControlProtos.Permission.Action... actions) {
1527     AccessControlProtos.Permission.Builder ret =
1528         AccessControlProtos.Permission.newBuilder();
1529     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1530         AccessControlProtos.NamespacePermission.newBuilder();
1531     for (AccessControlProtos.Permission.Action a : actions) {
1532       permissionBuilder.addAction(a);
1533     }
1534     if (namespace != null) {
1535       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1536     }
1537     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1538        .setNamespacePermission(permissionBuilder);
1539     return AccessControlProtos.RevokeRequest.newBuilder()
1540       .setUserPermission(
1541           AccessControlProtos.UserPermission.newBuilder()
1542               .setUser(ByteString.copyFromUtf8(username))
1543               .setPermission(ret)
1544       ).build();
1545   }
1546 
1547   /**
1548    * Create a RegionOpenInfo based on given region info and version of offline node
1549    */
1550   private static RegionOpenInfo buildRegionOpenInfo(
1551       final HRegionInfo region, final int versionOfOfflineNode,
1552       final List<ServerName> favoredNodes, Boolean openForReplay) {
1553     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1554     builder.setRegion(HRegionInfo.convert(region));
1555     if (versionOfOfflineNode >= 0) {
1556       builder.setVersionOfOfflineNode(versionOfOfflineNode);
1557     }
1558     if (favoredNodes != null) {
1559       for (ServerName server : favoredNodes) {
1560         builder.addFavoredNodes(ProtobufUtil.toServerName(server));
1561       }
1562     }
1563     if(openForReplay != null) {
1564       builder.setOpenForDistributedLogReplay(openForReplay);
1565     }
1566     return builder.build();
1567   }
1568 }