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