View Javadoc

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