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