View Javadoc

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