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, final boolean renew) {
520     ScanRequest.Builder builder = ScanRequest.newBuilder();
521     builder.setNumberOfRows(numberOfRows);
522     builder.setCloseScanner(closeScanner);
523     builder.setScannerId(scannerId);
524     builder.setNextCallSeq(nextCallSeq);
525     builder.setRenew(renew);
526     return builder.build();
527   }
528 
529   /**
530    * Create a protocol buffer bulk load request
531    *
532    * @param familyPaths
533    * @param regionName
534    * @param assignSeqNum
535    * @return a bulk load request
536    */
537   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
538       final List<Pair<byte[], String>> familyPaths,
539       final byte[] regionName, boolean assignSeqNum) {
540     BulkLoadHFileRequest.Builder builder = BulkLoadHFileRequest.newBuilder();
541     RegionSpecifier region = buildRegionSpecifier(
542       RegionSpecifierType.REGION_NAME, regionName);
543     builder.setRegion(region);
544     FamilyPath.Builder familyPathBuilder = FamilyPath.newBuilder();
545     for (Pair<byte[], String> familyPath: familyPaths) {
546       familyPathBuilder.setFamily(ByteStringer.wrap(familyPath.getFirst()));
547       familyPathBuilder.setPath(familyPath.getSecond());
548       builder.addFamilyPath(familyPathBuilder.build());
549     }
550     builder.setAssignSeqNum(assignSeqNum);
551     return builder.build();
552   }
553 
554   /**
555    * Create a protocol buffer multi request for a list of actions.
556    * Propagates Actions original index.
557    *
558    * @param regionName
559    * @param actions
560    * @return a multi request
561    * @throws IOException
562    */
563   public static <R> RegionAction.Builder buildRegionAction(final byte[] regionName,
564       final List<Action<R>> actions, final RegionAction.Builder regionActionBuilder,
565       final ClientProtos.Action.Builder actionBuilder,
566       final MutationProto.Builder mutationBuilder) throws IOException {
567     for (Action<R> action: actions) {
568       Row row = action.getAction();
569       actionBuilder.clear();
570       actionBuilder.setIndex(action.getOriginalIndex());
571       mutationBuilder.clear();
572       if (row instanceof Get) {
573         Get g = (Get)row;
574         regionActionBuilder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
575       } else if (row instanceof Put) {
576         regionActionBuilder.addAction(actionBuilder.
577           setMutation(ProtobufUtil.toMutation(MutationType.PUT, (Put)row, mutationBuilder)));
578       } else if (row instanceof Delete) {
579         regionActionBuilder.addAction(actionBuilder.
580           setMutation(ProtobufUtil.toMutation(MutationType.DELETE, (Delete)row, mutationBuilder)));
581       } else if (row instanceof Append) {
582         regionActionBuilder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutation(
583             MutationType.APPEND, (Append)row, mutationBuilder, action.getNonce())));
584       } else if (row instanceof Increment) {
585         regionActionBuilder.addAction(actionBuilder.setMutation(
586             ProtobufUtil.toMutation((Increment)row, mutationBuilder, action.getNonce())));
587       } else if (row instanceof RegionCoprocessorServiceExec) {
588         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
589         regionActionBuilder.addAction(actionBuilder.setServiceCall(
590             ClientProtos.CoprocessorServiceCall.newBuilder()
591               .setRow(ByteStringer.wrap(exec.getRow()))
592               .setServiceName(exec.getMethod().getService().getFullName())
593               .setMethodName(exec.getMethod().getName())
594               .setRequest(exec.getRequest().toByteString())));
595       } else if (row instanceof RowMutations) {
596         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
597       } else {
598         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
599       }
600     }
601     return regionActionBuilder;
602   }
603 
604   /**
605    * Create a protocol buffer multirequest with NO data for a list of actions (data is carried
606    * otherwise than via protobuf).  This means it just notes attributes, whether to write the
607    * WAL, etc., and the presence in protobuf serves as place holder for the data which is
608    * coming along otherwise.  Note that Get is different.  It does not contain 'data' and is always
609    * carried by protobuf.  We return references to the data by adding them to the passed in
610    * <code>data</code> param.
611    *
612    * <p>Propagates Actions original index.
613    *
614    * @param regionName
615    * @param actions
616    * @param cells Place to stuff references to actual data.
617    * @return a multi request that does not carry any data.
618    * @throws IOException
619    */
620   public static <R> RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
621       final List<Action<R>> actions, final List<CellScannable> cells,
622       final RegionAction.Builder regionActionBuilder,
623       final ClientProtos.Action.Builder actionBuilder,
624       final MutationProto.Builder mutationBuilder) throws IOException {
625     RegionAction.Builder builder = getRegionActionBuilderWithRegion(
626       RegionAction.newBuilder(), regionName);
627     for (Action<R> action: actions) {
628       Row row = action.getAction();
629       actionBuilder.clear();
630       actionBuilder.setIndex(action.getOriginalIndex());
631       mutationBuilder.clear();
632       if (row instanceof Get) {
633         Get g = (Get)row;
634         builder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
635       } else if (row instanceof Put) {
636         Put p = (Put)row;
637         cells.add(p);
638         builder.addAction(actionBuilder.
639           setMutation(ProtobufUtil.toMutationNoData(MutationType.PUT, p, mutationBuilder)));
640       } else if (row instanceof Delete) {
641         Delete d = (Delete)row;
642         int size = d.size();
643         // Note that a legitimate Delete may have a size of zero; i.e. a Delete that has nothing
644         // in it but the row to delete.  In this case, the current implementation does not make
645         // a KeyValue to represent a delete-of-all-the-row until we serialize... For such cases
646         // where the size returned is zero, we will send the Delete fully pb'd rather than have
647         // metadata only in the pb and then send the kv along the side in cells.
648         if (size > 0) {
649           cells.add(d);
650           builder.addAction(actionBuilder.
651             setMutation(ProtobufUtil.toMutationNoData(MutationType.DELETE, d, mutationBuilder)));
652         } else {
653           builder.addAction(actionBuilder.
654             setMutation(ProtobufUtil.toMutation(MutationType.DELETE, d, mutationBuilder)));
655         }
656       } else if (row instanceof Append) {
657         Append a = (Append)row;
658         cells.add(a);
659         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
660           MutationType.APPEND, a, mutationBuilder, action.getNonce())));
661       } else if (row instanceof Increment) {
662         Increment i = (Increment)row;
663         cells.add(i);
664         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
665           MutationType.INCREMENT, i, mutationBuilder, action.getNonce())));
666       } else if (row instanceof RegionCoprocessorServiceExec) {
667         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
668         builder.addAction(actionBuilder.setServiceCall(ClientProtos.CoprocessorServiceCall
669             .newBuilder().setRow(ByteStringer.wrap(exec.getRow()))
670             .setServiceName(exec.getMethod().getService().getFullName())
671             .setMethodName(exec.getMethod().getName())
672             .setRequest(exec.getRequest().toByteString())));
673       } else if (row instanceof RowMutations) {
674         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
675       } else {
676         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
677       }
678     }
679     return builder;
680   }
681 
682 // End utilities for Client
683 //Start utilities for Admin
684 
685   /**
686    * Create a protocol buffer GetRegionInfoRequest for a given region name
687    *
688    * @param regionName the name of the region to get info
689    * @return a protocol buffer GetRegionInfoRequest
690    */
691   public static GetRegionInfoRequest
692       buildGetRegionInfoRequest(final byte[] regionName) {
693     return buildGetRegionInfoRequest(regionName, false);
694   }
695 
696   /**
697    * Create a protocol buffer GetRegionInfoRequest for a given region name
698    *
699    * @param regionName the name of the region to get info
700    * @param includeCompactionState indicate if the compaction state is requested
701    * @return a protocol buffer GetRegionInfoRequest
702    */
703   public static GetRegionInfoRequest
704       buildGetRegionInfoRequest(final byte[] regionName,
705         final boolean includeCompactionState) {
706     GetRegionInfoRequest.Builder builder = GetRegionInfoRequest.newBuilder();
707     RegionSpecifier region = buildRegionSpecifier(
708       RegionSpecifierType.REGION_NAME, regionName);
709     builder.setRegion(region);
710     if (includeCompactionState) {
711       builder.setCompactionState(includeCompactionState);
712     }
713     return builder.build();
714   }
715 
716  /**
717   * Create a protocol buffer GetStoreFileRequest for a given region name
718   *
719   * @param regionName the name of the region to get info
720   * @param family the family to get store file list
721   * @return a protocol buffer GetStoreFileRequest
722   */
723  public static GetStoreFileRequest
724      buildGetStoreFileRequest(final byte[] regionName, final byte[] family) {
725    GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder();
726    RegionSpecifier region = buildRegionSpecifier(
727      RegionSpecifierType.REGION_NAME, regionName);
728    builder.setRegion(region);
729    builder.addFamily(ByteStringer.wrap(family));
730    return builder.build();
731  }
732 
733  /**
734   * Create a protocol buffer GetOnlineRegionRequest
735   *
736   * @return a protocol buffer GetOnlineRegionRequest
737   */
738  public static GetOnlineRegionRequest buildGetOnlineRegionRequest() {
739    return GetOnlineRegionRequest.newBuilder().build();
740  }
741 
742  /**
743   * Create a protocol buffer FlushRegionRequest for a given region name
744   *
745   * @param regionName the name of the region to get info
746   * @return a protocol buffer FlushRegionRequest
747   */
748  public static FlushRegionRequest
749      buildFlushRegionRequest(final byte[] regionName) {
750    FlushRegionRequest.Builder builder = FlushRegionRequest.newBuilder();
751    RegionSpecifier region = buildRegionSpecifier(
752      RegionSpecifierType.REGION_NAME, regionName);
753    builder.setRegion(region);
754    return builder.build();
755  }
756 
757  /**
758   * Create a protocol buffer OpenRegionRequest to open a list of regions
759   *
760   * @param server the serverName for the RPC
761   * @param regionOpenInfos info of a list of regions to open
762   * @param openForReplay
763   * @return a protocol buffer OpenRegionRequest
764   */
765  public static OpenRegionRequest
766      buildOpenRegionRequest(ServerName server, final List<Triple<HRegionInfo, Integer,
767          List<ServerName>>> regionOpenInfos, Boolean openForReplay) {
768    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
769    for (Triple<HRegionInfo, Integer, List<ServerName>> regionOpenInfo: regionOpenInfos) {
770      Integer second = regionOpenInfo.getSecond();
771      int versionOfOfflineNode = second == null ? -1 : second.intValue();
772      builder.addOpenInfo(buildRegionOpenInfo(regionOpenInfo.getFirst(), versionOfOfflineNode, 
773        regionOpenInfo.getThird(), openForReplay));
774    }
775    if (server != null) {
776      builder.setServerStartCode(server.getStartcode());
777    }
778    // send the master's wall clock time as well, so that the RS can refer to it
779    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTimeMillis());
780    return builder.build();
781  }
782 
783  /**
784   * Create a protocol buffer OpenRegionRequest for a given region
785   *
786   * @param server the serverName for the RPC
787   * @param region the region to open
788   * @param versionOfOfflineNode that needs to be present in the offline node
789   * @param favoredNodes
790   * @param openForReplay
791   * @return a protocol buffer OpenRegionRequest
792   */
793  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
794      final HRegionInfo region, final int versionOfOfflineNode, List<ServerName> favoredNodes,
795      Boolean openForReplay) {
796    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
797    builder.addOpenInfo(buildRegionOpenInfo(region, versionOfOfflineNode, favoredNodes, 
798      openForReplay));
799    if (server != null) {
800      builder.setServerStartCode(server.getStartcode());
801    }
802    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTimeMillis());
803    return builder.build();
804  }
805 
806  /**
807   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
808   * @param updateRegionInfos
809   * @return a protocol buffer UpdateFavoredNodesRequest
810   */
811  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
812      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
813    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
814    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
815      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
816      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
817      for (ServerName server : pair.getSecond()) {
818        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
819      }
820      ubuilder.addUpdateInfo(builder.build());
821    }
822    return ubuilder.build();
823  }
824 
825  /**
826   * Create a CloseRegionRequest for a given region name
827   *
828   * @param regionName the name of the region to close
829   * @param transitionInZK indicator if to transition in ZK
830   * @return a CloseRegionRequest
831   */
832  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
833      final byte[] regionName, final boolean transitionInZK) {
834    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
835    RegionSpecifier region = buildRegionSpecifier(
836      RegionSpecifierType.REGION_NAME, regionName);
837    builder.setRegion(region);
838    builder.setTransitionInZK(transitionInZK);
839    if (server != null) {
840      builder.setServerStartCode(server.getStartcode());
841    }
842    return builder.build();
843  }
844 
845   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
846     final byte[] regionName, final int versionOfClosingNode,
847     ServerName destinationServer, final boolean transitionInZK) {
848     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
849     RegionSpecifier region = buildRegionSpecifier(
850       RegionSpecifierType.REGION_NAME, regionName);
851     builder.setRegion(region);
852     builder.setVersionOfClosingNode(versionOfClosingNode);
853     builder.setTransitionInZK(transitionInZK);
854     if (destinationServer != null){
855       builder.setDestinationServer(ProtobufUtil.toServerName( destinationServer) );
856     }
857     if (server != null) {
858       builder.setServerStartCode(server.getStartcode());
859     }
860     return builder.build();
861   }
862 
863  /**
864   * Create a CloseRegionRequest for a given encoded region name
865   *
866   * @param encodedRegionName the name of the region to close
867   * @param transitionInZK indicator if to transition in ZK
868   * @return a CloseRegionRequest
869   */
870  public static CloseRegionRequest
871      buildCloseRegionRequest(ServerName server, final String encodedRegionName,
872        final boolean transitionInZK) {
873    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
874    RegionSpecifier region = buildRegionSpecifier(
875      RegionSpecifierType.ENCODED_REGION_NAME,
876      Bytes.toBytes(encodedRegionName));
877    builder.setRegion(region);
878    builder.setTransitionInZK(transitionInZK);
879    if (server != null) {
880      builder.setServerStartCode(server.getStartcode());
881    }
882    return builder.build();
883  }
884 
885  /**
886   * Create a SplitRegionRequest for a given region name
887   *
888   * @param regionName the name of the region to split
889   * @param splitPoint the split point
890   * @return a SplitRegionRequest
891   */
892  public static SplitRegionRequest buildSplitRegionRequest(
893      final byte[] regionName, final byte[] splitPoint) {
894    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
895    RegionSpecifier region = buildRegionSpecifier(
896      RegionSpecifierType.REGION_NAME, regionName);
897    builder.setRegion(region);
898    if (splitPoint != null) {
899      builder.setSplitPoint(ByteStringer.wrap(splitPoint));
900    }
901    return builder.build();
902  }
903 
904   /**
905    * Create a MergeRegionsRequest for the given regions
906    * @param regionA name of region a
907    * @param regionB name of region b
908    * @param forcible true if it is a compulsory merge
909    * @return a MergeRegionsRequest
910    */
911   public static MergeRegionsRequest buildMergeRegionsRequest(
912       final byte[] regionA, final byte[] regionB, final boolean forcible) {
913     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
914     RegionSpecifier regionASpecifier = buildRegionSpecifier(
915         RegionSpecifierType.REGION_NAME, regionA);
916     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
917         RegionSpecifierType.REGION_NAME, regionB);
918     builder.setRegionA(regionASpecifier);
919     builder.setRegionB(regionBSpecifier);
920     builder.setForcible(forcible);
921     // send the master's wall clock time as well, so that the RS can refer to it
922     builder.setMasterSystemTime(EnvironmentEdgeManager.currentTimeMillis());
923     return builder.build();
924   }
925 
926  /**
927   * Create a  CompactRegionRequest for a given region name
928   *
929   * @param regionName the name of the region to get info
930   * @param major indicator if it is a major compaction
931   * @return a CompactRegionRequest
932   */
933  public static CompactRegionRequest buildCompactRegionRequest(
934      final byte[] regionName, final boolean major, final byte [] family) {
935    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
936    RegionSpecifier region = buildRegionSpecifier(
937      RegionSpecifierType.REGION_NAME, regionName);
938    builder.setRegion(region);
939    builder.setMajor(major);
940    if (family != null) {
941      builder.setFamily(ByteStringer.wrap(family));
942    }
943    return builder.build();
944  }
945 
946  /**
947   * @see {@link #buildRollWALWriterRequest()
948   */
949  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
950      RollWALWriterRequest.newBuilder().build();
951 
952   /**
953   * Create a new RollWALWriterRequest
954   *
955   * @return a ReplicateWALEntryRequest
956   */
957  public static RollWALWriterRequest buildRollWALWriterRequest() {
958    return ROLL_WAL_WRITER_REQUEST;
959  }
960 
961  /**
962   * @see {@link #buildGetServerInfoRequest()}
963   */
964  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
965    GetServerInfoRequest.newBuilder().build();
966 
967  /**
968   * Create a new GetServerInfoRequest
969   *
970   * @return a GetServerInfoRequest
971   */
972  public static GetServerInfoRequest buildGetServerInfoRequest() {
973    return GET_SERVER_INFO_REQUEST;
974  }
975 
976  /**
977   * Create a new StopServerRequest
978   *
979   * @param reason the reason to stop the server
980   * @return a StopServerRequest
981   */
982  public static StopServerRequest buildStopServerRequest(final String reason) {
983    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
984    builder.setReason(reason);
985    return builder.build();
986  }
987 
988 //End utilities for Admin
989 
990   /**
991    * Convert a byte array to a protocol buffer RegionSpecifier
992    *
993    * @param type the region specifier type
994    * @param value the region specifier byte array value
995    * @return a protocol buffer RegionSpecifier
996    */
997   public static RegionSpecifier buildRegionSpecifier(
998       final RegionSpecifierType type, final byte[] value) {
999     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
1000     regionBuilder.setValue(ByteStringer.wrap(value));
1001     regionBuilder.setType(type);
1002     return regionBuilder.build();
1003   }
1004 
1005   /**
1006    * Create a protocol buffer Condition
1007    *
1008    * @param row
1009    * @param family
1010    * @param qualifier
1011    * @param comparator
1012    * @param compareType
1013    * @return a Condition
1014    * @throws IOException
1015    */
1016   private static Condition buildCondition(final byte[] row,
1017       final byte[] family, final byte [] qualifier,
1018       final ByteArrayComparable comparator,
1019       final CompareType compareType) throws IOException {
1020     Condition.Builder builder = Condition.newBuilder();
1021     builder.setRow(ByteStringer.wrap(row));
1022     builder.setFamily(ByteStringer.wrap(family));
1023     builder.setQualifier(ByteStringer.wrap(qualifier));
1024     builder.setComparator(ProtobufUtil.toComparator(comparator));
1025     builder.setCompareType(compareType);
1026     return builder.build();
1027   }
1028 
1029   /**
1030    * Create a protocol buffer AddColumnRequest
1031    *
1032    * @param tableName
1033    * @param column
1034    * @return an AddColumnRequest
1035    */
1036   public static AddColumnRequest buildAddColumnRequest(
1037       final TableName tableName, final HColumnDescriptor column) {
1038     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
1039     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1040     builder.setColumnFamilies(column.convert());
1041     return builder.build();
1042   }
1043 
1044   /**
1045    * Create a protocol buffer DeleteColumnRequest
1046    *
1047    * @param tableName
1048    * @param columnName
1049    * @return a DeleteColumnRequest
1050    */
1051   public static DeleteColumnRequest buildDeleteColumnRequest(
1052       final TableName tableName, final byte [] columnName) {
1053     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
1054     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1055     builder.setColumnName(ByteStringer.wrap(columnName));
1056     return builder.build();
1057   }
1058 
1059   /**
1060    * Create a protocol buffer ModifyColumnRequest
1061    *
1062    * @param tableName
1063    * @param column
1064    * @return an ModifyColumnRequest
1065    */
1066   public static ModifyColumnRequest buildModifyColumnRequest(
1067       final TableName tableName, final HColumnDescriptor column) {
1068     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
1069     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1070     builder.setColumnFamilies(column.convert());
1071     return builder.build();
1072   }
1073 
1074   /**
1075    * Create a protocol buffer MoveRegionRequest
1076    *
1077    * @param encodedRegionName
1078    * @param destServerName
1079    * @return A MoveRegionRequest
1080    * @throws DeserializationException
1081    */
1082   public static MoveRegionRequest buildMoveRegionRequest(
1083       final byte [] encodedRegionName, final byte [] destServerName) throws
1084       DeserializationException {
1085 	MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1086     builder.setRegion(
1087       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1088     if (destServerName != null) {
1089       builder.setDestServerName(
1090         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1091     }
1092     return builder.build();
1093   }
1094 
1095   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1096       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1097       final boolean forcible) throws DeserializationException {
1098     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1099     builder.setRegionA(buildRegionSpecifier(
1100         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1101     builder.setRegionB(buildRegionSpecifier(
1102         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1103     builder.setForcible(forcible);
1104     return builder.build();
1105   }
1106 
1107   /**
1108    * Create a protocol buffer AssignRegionRequest
1109    *
1110    * @param regionName
1111    * @return an AssignRegionRequest
1112    */
1113   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1114     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1115     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1116     return builder.build();
1117   }
1118 
1119   /**
1120    * Creates a protocol buffer UnassignRegionRequest
1121    *
1122    * @param regionName
1123    * @param force
1124    * @return an UnassignRegionRequest
1125    */
1126   public static UnassignRegionRequest buildUnassignRegionRequest(
1127       final byte [] regionName, final boolean force) {
1128     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1129     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1130     builder.setForce(force);
1131     return builder.build();
1132   }
1133 
1134   /**
1135    * Creates a protocol buffer OfflineRegionRequest
1136    *
1137    * @param regionName
1138    * @return an OfflineRegionRequest
1139    */
1140   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1141     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1142     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1143     return builder.build();
1144   }
1145 
1146   /**
1147    * Creates a protocol buffer DeleteTableRequest
1148    *
1149    * @param tableName
1150    * @return a DeleteTableRequest
1151    */
1152   public static DeleteTableRequest buildDeleteTableRequest(final TableName tableName) {
1153     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1154     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1155     return builder.build();
1156   }
1157 
1158   /**
1159    * Creates a protocol buffer TruncateTableRequest
1160    *
1161    * @param tableName name of table to truncate
1162    * @param preserveSplits True if the splits should be preserved
1163    * @return a TruncateTableRequest
1164    */
1165   public static TruncateTableRequest buildTruncateTableRequest(final TableName tableName,
1166         boolean preserveSplits) {
1167     TruncateTableRequest.Builder builder = TruncateTableRequest.newBuilder();
1168     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1169     builder.setPreserveSplits(preserveSplits);
1170     return builder.build();
1171   }
1172 
1173   /**
1174    * Creates a protocol buffer EnableTableRequest
1175    *
1176    * @param tableName
1177    * @return an EnableTableRequest
1178    */
1179   public static EnableTableRequest buildEnableTableRequest(final TableName tableName) {
1180     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1181     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1182     return builder.build();
1183   }
1184 
1185   /**
1186    * Creates a protocol buffer DisableTableRequest
1187    *
1188    * @param tableName
1189    * @return a DisableTableRequest
1190    */
1191   public static DisableTableRequest buildDisableTableRequest(final TableName tableName) {
1192     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1193     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1194     return builder.build();
1195   }
1196 
1197   /**
1198    * Creates a protocol buffer CreateTableRequest
1199    *
1200    * @param hTableDesc
1201    * @param splitKeys
1202    * @return a CreateTableRequest
1203    */
1204   public static CreateTableRequest buildCreateTableRequest(
1205       final HTableDescriptor hTableDesc, final byte [][] splitKeys) {
1206     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1207     builder.setTableSchema(hTableDesc.convert());
1208     if (splitKeys != null) {
1209       for (byte [] splitKey : splitKeys) {
1210         builder.addSplitKeys(ByteStringer.wrap(splitKey));
1211       }
1212     }
1213     return builder.build();
1214   }
1215 
1216 
1217   /**
1218    * Creates a protocol buffer ModifyTableRequest
1219    *
1220    * @param tableName
1221    * @param hTableDesc
1222    * @return a ModifyTableRequest
1223    */
1224   public static ModifyTableRequest buildModifyTableRequest(
1225       final TableName tableName, final HTableDescriptor hTableDesc) {
1226     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1227     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1228     builder.setTableSchema(hTableDesc.convert());
1229     return builder.build();
1230   }
1231 
1232   /**
1233    * Creates a protocol buffer GetSchemaAlterStatusRequest
1234    *
1235    * @param tableName
1236    * @return a GetSchemaAlterStatusRequest
1237    */
1238   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1239       final TableName tableName) {
1240     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1241     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1242     return builder.build();
1243   }
1244 
1245   /**
1246    * Creates a protocol buffer GetTableDescriptorsRequest
1247    *
1248    * @param tableNames
1249    * @return a GetTableDescriptorsRequest
1250    */
1251   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1252       final List<TableName> tableNames) {
1253     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1254     if (tableNames != null) {
1255       for (TableName tableName : tableNames) {
1256         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1257       }
1258     }
1259     return builder.build();
1260   }
1261 
1262   /**
1263    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1264    *
1265    * @param tableName the table name
1266    * @return a GetTableDescriptorsRequest
1267    */
1268   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1269       final TableName tableName) {
1270     return GetTableDescriptorsRequest.newBuilder()
1271       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1272       .build();
1273   }
1274 
1275   /**
1276    * Creates a protocol buffer IsMasterRunningRequest
1277    *
1278    * @return a IsMasterRunningRequest
1279    */
1280   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1281     return IsMasterRunningRequest.newBuilder().build();
1282   }
1283 
1284   /**
1285    * Creates a protocol buffer BalanceRequest
1286    *
1287    * @return a BalanceRequest
1288    */
1289   public static BalanceRequest buildBalanceRequest() {
1290     return BalanceRequest.newBuilder().build();
1291   }
1292 
1293   /**
1294    * Creates a protocol buffer SetBalancerRunningRequest
1295    *
1296    * @param on
1297    * @param synchronous
1298    * @return a SetBalancerRunningRequest
1299    */
1300   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(boolean on, boolean synchronous) {
1301     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1302   }
1303 
1304   /**
1305    * Creates a protocol buffer IsBalancerEnabledRequest
1306    *
1307    * @return a IsBalancerEnabledRequest
1308    */
1309   public static IsBalancerEnabledRequest buildIsBalancerEnabledRequest() {
1310     return IsBalancerEnabledRequest.newBuilder().build();
1311   }
1312 
1313   /**
1314    * @see {@link #buildGetClusterStatusRequest}
1315    */
1316   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1317       GetClusterStatusRequest.newBuilder().build();
1318 
1319   /**
1320    * Creates a protocol buffer GetClusterStatusRequest
1321    *
1322    * @return A GetClusterStatusRequest
1323    */
1324   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1325     return GET_CLUSTER_STATUS_REQUEST;
1326   }
1327 
1328   /**
1329    * @see {@link #buildCatalogScanRequest}
1330    */
1331   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1332     RunCatalogScanRequest.newBuilder().build();
1333 
1334   /**
1335    * Creates a request for running a catalog scan
1336    * @return A {@link RunCatalogScanRequest}
1337    */
1338   public static RunCatalogScanRequest buildCatalogScanRequest() {
1339     return CATALOG_SCAN_REQUEST;
1340   }
1341 
1342   /**
1343    * Creates a request for enabling/disabling the catalog janitor
1344    * @return A {@link EnableCatalogJanitorRequest}
1345    */
1346   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1347     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1348   }
1349 
1350   /**
1351    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1352    */
1353   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1354     IsCatalogJanitorEnabledRequest.newBuilder().build();
1355 
1356   /**
1357    * Creates a request for querying the master whether the catalog janitor is enabled
1358    * @return A {@link IsCatalogJanitorEnabledRequest}
1359    */
1360   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1361     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1362   }
1363 
1364   /**
1365    * Creates a request for querying the master the last flushed sequence Id for a region
1366    * @param regionName
1367    * @return A {@link GetLastFlushedSequenceIdRequest}
1368    */
1369   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1370       byte[] regionName) {
1371     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1372         ByteStringer.wrap(regionName)).build();
1373   }
1374 
1375   /**
1376    * Create a request to grant user permissions.
1377    *
1378    * @param username the short user name who to grant permissions
1379    * @param actions the permissions to be granted
1380    * @return A {@link AccessControlProtos} GrantRequest
1381    */
1382   public static AccessControlProtos.GrantRequest buildGrantRequest(
1383       String username, AccessControlProtos.Permission.Action... actions) {
1384     AccessControlProtos.Permission.Builder ret =
1385         AccessControlProtos.Permission.newBuilder();
1386     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1387         AccessControlProtos.GlobalPermission.newBuilder();
1388     for (AccessControlProtos.Permission.Action a : actions) {
1389       permissionBuilder.addAction(a);
1390     }
1391     ret.setType(AccessControlProtos.Permission.Type.Global)
1392        .setGlobalPermission(permissionBuilder);
1393     return AccessControlProtos.GrantRequest.newBuilder()
1394       .setUserPermission(
1395           AccessControlProtos.UserPermission.newBuilder()
1396               .setUser(ByteString.copyFromUtf8(username))
1397               .setPermission(ret)
1398       ).build();
1399   }
1400 
1401   /**
1402    * Create a request to grant user permissions.
1403    *
1404    * @param username the short user name who to grant permissions
1405    * @param tableName optional table name the permissions apply
1406    * @param family optional column family
1407    * @param qualifier optional qualifier
1408    * @param actions the permissions to be granted
1409    * @return A {@link AccessControlProtos} GrantRequest
1410    */
1411   public static AccessControlProtos.GrantRequest buildGrantRequest(
1412       String username, TableName tableName, byte[] family, byte[] qualifier,
1413       AccessControlProtos.Permission.Action... actions) {
1414     AccessControlProtos.Permission.Builder ret =
1415         AccessControlProtos.Permission.newBuilder();
1416     AccessControlProtos.TablePermission.Builder permissionBuilder =
1417         AccessControlProtos.TablePermission.newBuilder();
1418     for (AccessControlProtos.Permission.Action a : actions) {
1419       permissionBuilder.addAction(a);
1420     }
1421     if (tableName == null) {
1422       throw new NullPointerException("TableName cannot be null");
1423     }
1424     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1425 
1426     if (family != null) {
1427       permissionBuilder.setFamily(ByteStringer.wrap(family));
1428     }
1429     if (qualifier != null) {
1430       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1431     }
1432     ret.setType(AccessControlProtos.Permission.Type.Table)
1433        .setTablePermission(permissionBuilder);
1434     return AccessControlProtos.GrantRequest.newBuilder()
1435       .setUserPermission(
1436           AccessControlProtos.UserPermission.newBuilder()
1437               .setUser(ByteString.copyFromUtf8(username))
1438               .setPermission(ret)
1439       ).build();
1440   }
1441 
1442   /**
1443    * Create a request to grant user permissions.
1444    *
1445    * @param username the short user name who to grant permissions
1446    * @param namespace optional table name the permissions apply
1447    * @param actions the permissions to be granted
1448    * @return A {@link AccessControlProtos} GrantRequest
1449    */
1450   public static AccessControlProtos.GrantRequest buildGrantRequest(
1451       String username, String namespace,
1452       AccessControlProtos.Permission.Action... actions) {
1453     AccessControlProtos.Permission.Builder ret =
1454         AccessControlProtos.Permission.newBuilder();
1455     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1456         AccessControlProtos.NamespacePermission.newBuilder();
1457     for (AccessControlProtos.Permission.Action a : actions) {
1458       permissionBuilder.addAction(a);
1459     }
1460     if (namespace != null) {
1461       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1462     }
1463     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1464        .setNamespacePermission(permissionBuilder);
1465     return AccessControlProtos.GrantRequest.newBuilder()
1466       .setUserPermission(
1467           AccessControlProtos.UserPermission.newBuilder()
1468               .setUser(ByteString.copyFromUtf8(username))
1469               .setPermission(ret)
1470       ).build();
1471   }
1472 
1473   /**
1474    * Create a request to revoke user permissions.
1475    *
1476    * @param username the short user name whose permissions to be revoked
1477    * @param actions the permissions to be revoked
1478    * @return A {@link AccessControlProtos} RevokeRequest
1479    */
1480   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1481       String username, AccessControlProtos.Permission.Action... actions) {
1482     AccessControlProtos.Permission.Builder ret =
1483         AccessControlProtos.Permission.newBuilder();
1484     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1485         AccessControlProtos.GlobalPermission.newBuilder();
1486     for (AccessControlProtos.Permission.Action a : actions) {
1487       permissionBuilder.addAction(a);
1488     }
1489     ret.setType(AccessControlProtos.Permission.Type.Global)
1490        .setGlobalPermission(permissionBuilder);
1491     return AccessControlProtos.RevokeRequest.newBuilder()
1492       .setUserPermission(
1493           AccessControlProtos.UserPermission.newBuilder()
1494               .setUser(ByteString.copyFromUtf8(username))
1495               .setPermission(ret)
1496       ).build();
1497   }
1498 
1499   /**
1500    * Create a request to revoke user permissions.
1501    *
1502    * @param username the short user name whose permissions to be revoked
1503    * @param tableName optional table name the permissions apply
1504    * @param family optional column family
1505    * @param qualifier optional qualifier
1506    * @param actions the permissions to be revoked
1507    * @return A {@link AccessControlProtos} RevokeRequest
1508    */
1509   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1510       String username, TableName tableName, byte[] family, byte[] qualifier,
1511       AccessControlProtos.Permission.Action... actions) {
1512     AccessControlProtos.Permission.Builder ret =
1513         AccessControlProtos.Permission.newBuilder();
1514     AccessControlProtos.TablePermission.Builder permissionBuilder =
1515         AccessControlProtos.TablePermission.newBuilder();
1516     for (AccessControlProtos.Permission.Action a : actions) {
1517       permissionBuilder.addAction(a);
1518     }
1519     if (tableName != null) {
1520       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1521     }
1522     if (family != null) {
1523       permissionBuilder.setFamily(ByteStringer.wrap(family));
1524     }
1525     if (qualifier != null) {
1526       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1527     }
1528     ret.setType(AccessControlProtos.Permission.Type.Table)
1529        .setTablePermission(permissionBuilder);
1530     return AccessControlProtos.RevokeRequest.newBuilder()
1531       .setUserPermission(
1532           AccessControlProtos.UserPermission.newBuilder()
1533               .setUser(ByteString.copyFromUtf8(username))
1534               .setPermission(ret)
1535       ).build();
1536   }
1537 
1538   /**
1539    * Create a request to revoke user permissions.
1540    *
1541    * @param username the short user name whose permissions to be revoked
1542    * @param namespace optional table name the permissions apply
1543    * @param actions the permissions to be revoked
1544    * @return A {@link AccessControlProtos} RevokeRequest
1545    */
1546   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1547       String username, String namespace,
1548       AccessControlProtos.Permission.Action... actions) {
1549     AccessControlProtos.Permission.Builder ret =
1550         AccessControlProtos.Permission.newBuilder();
1551     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1552         AccessControlProtos.NamespacePermission.newBuilder();
1553     for (AccessControlProtos.Permission.Action a : actions) {
1554       permissionBuilder.addAction(a);
1555     }
1556     if (namespace != null) {
1557       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1558     }
1559     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1560        .setNamespacePermission(permissionBuilder);
1561     return AccessControlProtos.RevokeRequest.newBuilder()
1562       .setUserPermission(
1563           AccessControlProtos.UserPermission.newBuilder()
1564               .setUser(ByteString.copyFromUtf8(username))
1565               .setPermission(ret)
1566       ).build();
1567   }
1568 
1569   /**
1570    * Create a RegionOpenInfo based on given region info and version of offline node
1571    */
1572   private static RegionOpenInfo buildRegionOpenInfo(
1573       final HRegionInfo region, final int versionOfOfflineNode,
1574       final List<ServerName> favoredNodes, Boolean openForReplay) {
1575     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1576     builder.setRegion(HRegionInfo.convert(region));
1577     if (versionOfOfflineNode >= 0) {
1578       builder.setVersionOfOfflineNode(versionOfOfflineNode);
1579     }
1580     if (favoredNodes != null) {
1581       for (ServerName server : favoredNodes) {
1582         builder.addFavoredNodes(ProtobufUtil.toServerName(server));
1583       }
1584     }
1585     if(openForReplay != null) {
1586       builder.setOpenForDistributedLogReplay(openForReplay);
1587     }
1588     return builder.build();
1589   }
1590 }