View Javadoc

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