View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.protobuf;
19  
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.regex.Pattern;
23  
24  import org.apache.hadoop.hbase.CellScannable;
25  import org.apache.hadoop.hbase.DoNotRetryIOException;
26  import org.apache.hadoop.hbase.HColumnDescriptor;
27  import org.apache.hadoop.hbase.HConstants;
28  import org.apache.hadoop.hbase.HRegionInfo;
29  import org.apache.hadoop.hbase.HTableDescriptor;
30  import org.apache.hadoop.hbase.ServerName;
31  import org.apache.hadoop.hbase.TableName;
32  import org.apache.hadoop.hbase.classification.InterfaceAudience;
33  import org.apache.hadoop.hbase.client.Action;
34  import org.apache.hadoop.hbase.client.Append;
35  import org.apache.hadoop.hbase.client.Delete;
36  import org.apache.hadoop.hbase.client.Durability;
37  import org.apache.hadoop.hbase.client.Get;
38  import org.apache.hadoop.hbase.client.Increment;
39  import org.apache.hadoop.hbase.client.Mutation;
40  import org.apache.hadoop.hbase.client.Put;
41  import org.apache.hadoop.hbase.client.RegionCoprocessorServiceExec;
42  import org.apache.hadoop.hbase.client.Row;
43  import org.apache.hadoop.hbase.client.RowMutations;
44  import org.apache.hadoop.hbase.client.Scan;
45  import org.apache.hadoop.hbase.exceptions.DeserializationException;
46  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
47  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
48  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
49  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
50  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
51  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest.RegionUpdateInfo;
63  import org.apache.hadoop.hbase.protobuf.generated.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.GetTableNamesRequest;
93  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableStateRequest;
94  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
95  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
96  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
97  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
98  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
99  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
103 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
104 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest;
105 import org.apache.hadoop.hbase.util.ByteStringer;
106 import org.apache.hadoop.hbase.util.Bytes;
107 import org.apache.hadoop.hbase.util.Pair;
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<Pair<HRegionInfo,
759          List<ServerName>>> regionOpenInfos, Boolean openForReplay) {
760    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
761    for (Pair<HRegionInfo, List<ServerName>> regionOpenInfo: regionOpenInfos) {
762      builder.addOpenInfo(buildRegionOpenInfo(regionOpenInfo.getFirst(),
763        regionOpenInfo.getSecond(), openForReplay));
764    }
765    if (server != null) {
766      builder.setServerStartCode(server.getStartcode());
767    }
768    return builder.build();
769  }
770 
771  /**
772   * Create a protocol buffer OpenRegionRequest for a given region
773   *
774   * @param server the serverName for the RPC
775   * @param region the region to open
776   * @param favoredNodes
777   * @param openForReplay
778   * @return a protocol buffer OpenRegionRequest
779   */
780  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
781      final HRegionInfo region, List<ServerName> favoredNodes,
782      Boolean openForReplay) {
783    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
784    builder.addOpenInfo(buildRegionOpenInfo(region, favoredNodes,
785      openForReplay));
786    if (server != null) {
787      builder.setServerStartCode(server.getStartcode());
788    }
789    return builder.build();
790  }
791 
792  /**
793   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
794   * @param updateRegionInfos
795   * @return a protocol buffer UpdateFavoredNodesRequest
796   */
797  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
798      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
799    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
800    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
801      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
802      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
803      for (ServerName server : pair.getSecond()) {
804        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
805      }
806      ubuilder.addUpdateInfo(builder.build());
807    }
808    return ubuilder.build();
809  }
810 
811  /**
812   * Create a CloseRegionRequest for a given region name
813   *
814   * @param regionName the name of the region to close
815   * @return a CloseRegionRequest
816   */
817  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
818      final byte[] regionName) {
819    return buildCloseRegionRequest(server, regionName, null);
820  }
821 
822   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
823     final byte[] regionName, ServerName destinationServer) {
824     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
825     RegionSpecifier region = buildRegionSpecifier(
826       RegionSpecifierType.REGION_NAME, regionName);
827     builder.setRegion(region);
828     if (destinationServer != null){
829       builder.setDestinationServer(ProtobufUtil.toServerName(destinationServer));
830     }
831     if (server != null) {
832       builder.setServerStartCode(server.getStartcode());
833     }
834     return builder.build();
835   }
836 
837  /**
838   * Create a CloseRegionRequest for a given encoded region name
839   *
840   * @param encodedRegionName the name of the region to close
841   * @return a CloseRegionRequest
842   */
843  public static CloseRegionRequest
844      buildCloseRegionRequest(ServerName server, final String encodedRegionName) {
845    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
846    RegionSpecifier region = buildRegionSpecifier(
847      RegionSpecifierType.ENCODED_REGION_NAME,
848      Bytes.toBytes(encodedRegionName));
849    builder.setRegion(region);
850    if (server != null) {
851      builder.setServerStartCode(server.getStartcode());
852    }
853    return builder.build();
854  }
855 
856  /**
857   * Create a SplitRegionRequest for a given region name
858   *
859   * @param regionName the name of the region to split
860   * @param splitPoint the split point
861   * @return a SplitRegionRequest
862   */
863  public static SplitRegionRequest buildSplitRegionRequest(
864      final byte[] regionName, final byte[] splitPoint) {
865    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
866    RegionSpecifier region = buildRegionSpecifier(
867      RegionSpecifierType.REGION_NAME, regionName);
868    builder.setRegion(region);
869    if (splitPoint != null) {
870      builder.setSplitPoint(ByteStringer.wrap(splitPoint));
871    }
872    return builder.build();
873  }
874 
875   /**
876    * Create a MergeRegionsRequest for the given regions
877    * @param regionA name of region a
878    * @param regionB name of region b
879    * @param forcible true if it is a compulsory merge
880    * @return a MergeRegionsRequest
881    */
882   public static MergeRegionsRequest buildMergeRegionsRequest(
883       final byte[] regionA, final byte[] regionB, final boolean forcible) {
884     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
885     RegionSpecifier regionASpecifier = buildRegionSpecifier(
886         RegionSpecifierType.REGION_NAME, regionA);
887     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
888         RegionSpecifierType.REGION_NAME, regionB);
889     builder.setRegionA(regionASpecifier);
890     builder.setRegionB(regionBSpecifier);
891     builder.setForcible(forcible);
892     return builder.build();
893   }
894 
895  /**
896   * Create a  CompactRegionRequest for a given region name
897   *
898   * @param regionName the name of the region to get info
899   * @param major indicator if it is a major compaction
900   * @return a CompactRegionRequest
901   */
902  public static CompactRegionRequest buildCompactRegionRequest(
903      final byte[] regionName, final boolean major, final byte [] family) {
904    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
905    RegionSpecifier region = buildRegionSpecifier(
906      RegionSpecifierType.REGION_NAME, regionName);
907    builder.setRegion(region);
908    builder.setMajor(major);
909    if (family != null) {
910      builder.setFamily(ByteStringer.wrap(family));
911    }
912    return builder.build();
913  }
914 
915  /**
916   * @see {@link #buildRollWALWriterRequest()
917   */
918  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
919      RollWALWriterRequest.newBuilder().build();
920 
921   /**
922   * Create a new RollWALWriterRequest
923   *
924   * @return a ReplicateWALEntryRequest
925   */
926  public static RollWALWriterRequest buildRollWALWriterRequest() {
927    return ROLL_WAL_WRITER_REQUEST;
928  }
929 
930  /**
931   * @see {@link #buildGetServerInfoRequest()}
932   */
933  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
934    GetServerInfoRequest.newBuilder().build();
935 
936  /**
937   * Create a new GetServerInfoRequest
938   *
939   * @return a GetServerInfoRequest
940   */
941  public static GetServerInfoRequest buildGetServerInfoRequest() {
942    return GET_SERVER_INFO_REQUEST;
943  }
944 
945  /**
946   * Create a new StopServerRequest
947   *
948   * @param reason the reason to stop the server
949   * @return a StopServerRequest
950   */
951  public static StopServerRequest buildStopServerRequest(final String reason) {
952    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
953    builder.setReason(reason);
954    return builder.build();
955  }
956 
957 //End utilities for Admin
958 
959   /**
960    * Convert a byte array to a protocol buffer RegionSpecifier
961    *
962    * @param type the region specifier type
963    * @param value the region specifier byte array value
964    * @return a protocol buffer RegionSpecifier
965    */
966   public static RegionSpecifier buildRegionSpecifier(
967       final RegionSpecifierType type, final byte[] value) {
968     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
969     regionBuilder.setValue(ByteStringer.wrap(value));
970     regionBuilder.setType(type);
971     return regionBuilder.build();
972   }
973 
974   /**
975    * Create a protocol buffer Condition
976    *
977    * @param row
978    * @param family
979    * @param qualifier
980    * @param comparator
981    * @param compareType
982    * @return a Condition
983    * @throws IOException
984    */
985   private static Condition buildCondition(final byte[] row,
986       final byte[] family, final byte [] qualifier,
987       final ByteArrayComparable comparator,
988       final CompareType compareType) throws IOException {
989     Condition.Builder builder = Condition.newBuilder();
990     builder.setRow(ByteStringer.wrap(row));
991     builder.setFamily(ByteStringer.wrap(family));
992     builder.setQualifier(ByteStringer.wrap(qualifier));
993     builder.setComparator(ProtobufUtil.toComparator(comparator));
994     builder.setCompareType(compareType);
995     return builder.build();
996   }
997 
998   /**
999    * Create a protocol buffer AddColumnRequest
1000    *
1001    * @param tableName
1002    * @param column
1003    * @return an AddColumnRequest
1004    */
1005   public static AddColumnRequest buildAddColumnRequest(
1006       final TableName tableName, final HColumnDescriptor column) {
1007     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
1008     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1009     builder.setColumnFamilies(column.convert());
1010     return builder.build();
1011   }
1012 
1013   /**
1014    * Create a protocol buffer DeleteColumnRequest
1015    *
1016    * @param tableName
1017    * @param columnName
1018    * @return a DeleteColumnRequest
1019    */
1020   public static DeleteColumnRequest buildDeleteColumnRequest(
1021       final TableName tableName, final byte [] columnName) {
1022     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
1023     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1024     builder.setColumnName(ByteStringer.wrap(columnName));
1025     return builder.build();
1026   }
1027 
1028   /**
1029    * Create a protocol buffer ModifyColumnRequest
1030    *
1031    * @param tableName
1032    * @param column
1033    * @return an ModifyColumnRequest
1034    */
1035   public static ModifyColumnRequest buildModifyColumnRequest(
1036       final TableName tableName, final HColumnDescriptor column) {
1037     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
1038     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1039     builder.setColumnFamilies(column.convert());
1040     return builder.build();
1041   }
1042 
1043   /**
1044    * Create a protocol buffer MoveRegionRequest
1045    *
1046    * @param encodedRegionName
1047    * @param destServerName
1048    * @return A MoveRegionRequest
1049    * @throws DeserializationException
1050    */
1051   public static MoveRegionRequest buildMoveRegionRequest(
1052       final byte [] encodedRegionName, final byte [] destServerName) throws
1053       DeserializationException {
1054     MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1055     builder.setRegion(
1056       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1057     if (destServerName != null) {
1058       builder.setDestServerName(
1059         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1060     }
1061     return builder.build();
1062   }
1063 
1064   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1065       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1066       final boolean forcible) throws DeserializationException {
1067     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1068     builder.setRegionA(buildRegionSpecifier(
1069         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1070     builder.setRegionB(buildRegionSpecifier(
1071         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1072     builder.setForcible(forcible);
1073     return builder.build();
1074   }
1075 
1076   /**
1077    * Create a protocol buffer AssignRegionRequest
1078    *
1079    * @param regionName
1080    * @return an AssignRegionRequest
1081    */
1082   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1083     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1084     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1085     return builder.build();
1086   }
1087 
1088   /**
1089    * Creates a protocol buffer UnassignRegionRequest
1090    *
1091    * @param regionName
1092    * @param force
1093    * @return an UnassignRegionRequest
1094    */
1095   public static UnassignRegionRequest buildUnassignRegionRequest(
1096       final byte [] regionName, final boolean force) {
1097     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1098     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1099     builder.setForce(force);
1100     return builder.build();
1101   }
1102 
1103   /**
1104    * Creates a protocol buffer OfflineRegionRequest
1105    *
1106    * @param regionName
1107    * @return an OfflineRegionRequest
1108    */
1109   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1110     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1111     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1112     return builder.build();
1113   }
1114 
1115   /**
1116    * Creates a protocol buffer DeleteTableRequest
1117    *
1118    * @param tableName
1119    * @return a DeleteTableRequest
1120    */
1121   public static DeleteTableRequest buildDeleteTableRequest(final TableName tableName) {
1122     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1123     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1124     return builder.build();
1125   }
1126 
1127   /**
1128    * Creates a protocol buffer TruncateTableRequest
1129    *
1130    * @param tableName name of table to truncate
1131    * @param preserveSplits True if the splits should be preserved
1132    * @return a TruncateTableRequest
1133    */
1134   public static TruncateTableRequest buildTruncateTableRequest(final TableName tableName,
1135         boolean preserveSplits) {
1136     TruncateTableRequest.Builder builder = TruncateTableRequest.newBuilder();
1137     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1138     builder.setPreserveSplits(preserveSplits);
1139     return builder.build();
1140   }
1141 
1142   /**
1143    * Creates a protocol buffer EnableTableRequest
1144    *
1145    * @param tableName
1146    * @return an EnableTableRequest
1147    */
1148   public static EnableTableRequest buildEnableTableRequest(final TableName tableName) {
1149     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1150     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1151     return builder.build();
1152   }
1153 
1154   /**
1155    * Creates a protocol buffer DisableTableRequest
1156    *
1157    * @param tableName
1158    * @return a DisableTableRequest
1159    */
1160   public static DisableTableRequest buildDisableTableRequest(final TableName tableName) {
1161     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1162     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1163     return builder.build();
1164   }
1165 
1166   /**
1167    * Creates a protocol buffer CreateTableRequest
1168    *
1169    * @param hTableDesc
1170    * @param splitKeys
1171    * @return a CreateTableRequest
1172    */
1173   public static CreateTableRequest buildCreateTableRequest(
1174       final HTableDescriptor hTableDesc, final byte [][] splitKeys) {
1175     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1176     builder.setTableSchema(hTableDesc.convert());
1177     if (splitKeys != null) {
1178       for (byte [] splitKey : splitKeys) {
1179         builder.addSplitKeys(ByteStringer.wrap(splitKey));
1180       }
1181     }
1182     return builder.build();
1183   }
1184 
1185 
1186   /**
1187    * Creates a protocol buffer ModifyTableRequest
1188    *
1189    * @param tableName
1190    * @param hTableDesc
1191    * @return a ModifyTableRequest
1192    */
1193   public static ModifyTableRequest buildModifyTableRequest(
1194       final TableName tableName, final HTableDescriptor hTableDesc) {
1195     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1196     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1197     builder.setTableSchema(hTableDesc.convert());
1198     return builder.build();
1199   }
1200 
1201   /**
1202    * Creates a protocol buffer GetSchemaAlterStatusRequest
1203    *
1204    * @param tableName
1205    * @return a GetSchemaAlterStatusRequest
1206    */
1207   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1208       final TableName tableName) {
1209     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1210     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1211     return builder.build();
1212   }
1213 
1214   /**
1215    * Creates a protocol buffer GetTableDescriptorsRequest
1216    *
1217    * @param tableNames
1218    * @return a GetTableDescriptorsRequest
1219    */
1220   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1221       final List<TableName> tableNames) {
1222     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1223     if (tableNames != null) {
1224       for (TableName tableName : tableNames) {
1225         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1226       }
1227     }
1228     return builder.build();
1229   }
1230 
1231   /**
1232    * Creates a protocol buffer GetTableDescriptorsRequest
1233    *
1234    * @param pattern The compiled regular expression to match against
1235    * @param includeSysTables False to match only against userspace tables
1236    * @return a GetTableDescriptorsRequest
1237    */
1238   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final Pattern pattern,
1239       boolean includeSysTables) {
1240     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1241     if (pattern != null) builder.setRegex(pattern.toString());
1242     builder.setIncludeSysTables(includeSysTables);
1243     return builder.build();
1244   }
1245 
1246   /**
1247    * Creates a protocol buffer GetTableNamesRequest
1248    *
1249    * @param pattern The compiled regular expression to match against
1250    * @param includeSysTables False to match only against userspace tables
1251    * @return a GetTableNamesRequest
1252    */
1253   public static GetTableNamesRequest buildGetTableNamesRequest(final Pattern pattern,
1254       boolean includeSysTables) {
1255     GetTableNamesRequest.Builder builder = GetTableNamesRequest.newBuilder();
1256     if (pattern != null) builder.setRegex(pattern.toString());
1257     builder.setIncludeSysTables(includeSysTables);
1258     return builder.build();
1259   }
1260 
1261   /**
1262    * Creates a protocol buffer GetTableStateRequest
1263    *
1264    * @param tableName table to get request for
1265    * @return a GetTableStateRequest
1266    */
1267   public static GetTableStateRequest buildGetTableStateRequest(
1268           final TableName tableName) {
1269     return GetTableStateRequest.newBuilder()
1270             .setTableName(ProtobufUtil.toProtoTableName(tableName))
1271             .build();
1272   }
1273 
1274   /**
1275    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1276    *
1277    * @param tableName the table name
1278    * @return a GetTableDescriptorsRequest
1279    */
1280   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1281       final TableName tableName) {
1282     return GetTableDescriptorsRequest.newBuilder()
1283       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1284       .build();
1285   }
1286 
1287   /**
1288    * Creates a protocol buffer IsMasterRunningRequest
1289    *
1290    * @return a IsMasterRunningRequest
1291    */
1292   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1293     return IsMasterRunningRequest.newBuilder().build();
1294   }
1295 
1296   /**
1297    * Creates a protocol buffer BalanceRequest
1298    *
1299    * @return a BalanceRequest
1300    */
1301   public static BalanceRequest buildBalanceRequest() {
1302     return BalanceRequest.newBuilder().build();
1303   }
1304 
1305   /**
1306    * Creates a protocol buffer SetBalancerRunningRequest
1307    *
1308    * @param on
1309    * @param synchronous
1310    * @return a SetBalancerRunningRequest
1311    */
1312   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(boolean on, boolean synchronous) {
1313     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1314   }
1315 
1316   /**
1317    * @see {@link #buildGetClusterStatusRequest}
1318    */
1319   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1320       GetClusterStatusRequest.newBuilder().build();
1321 
1322   /**
1323    * Creates a protocol buffer GetClusterStatusRequest
1324    *
1325    * @return A GetClusterStatusRequest
1326    */
1327   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1328     return GET_CLUSTER_STATUS_REQUEST;
1329   }
1330 
1331   /**
1332    * @see {@link #buildCatalogScanRequest}
1333    */
1334   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1335     RunCatalogScanRequest.newBuilder().build();
1336 
1337   /**
1338    * Creates a request for running a catalog scan
1339    * @return A {@link RunCatalogScanRequest}
1340    */
1341   public static RunCatalogScanRequest buildCatalogScanRequest() {
1342     return CATALOG_SCAN_REQUEST;
1343   }
1344 
1345   /**
1346    * Creates a request for enabling/disabling the catalog janitor
1347    * @return A {@link EnableCatalogJanitorRequest}
1348    */
1349   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1350     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1351   }
1352 
1353   /**
1354    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1355    */
1356   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1357     IsCatalogJanitorEnabledRequest.newBuilder().build();
1358 
1359   /**
1360    * Creates a request for querying the master whether the catalog janitor is enabled
1361    * @return A {@link IsCatalogJanitorEnabledRequest}
1362    */
1363   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1364     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1365   }
1366 
1367   /**
1368    * Creates a request for querying the master the last flushed sequence Id for a region
1369    * @param regionName
1370    * @return A {@link GetLastFlushedSequenceIdRequest}
1371    */
1372   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1373       byte[] regionName) {
1374     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1375         ByteStringer.wrap(regionName)).build();
1376   }
1377 
1378   /**
1379    * Create a request to grant user permissions.
1380    *
1381    * @param username the short user name who to grant permissions
1382    * @param actions the permissions to be granted
1383    * @return A {@link AccessControlProtos} GrantRequest
1384    */
1385   public static AccessControlProtos.GrantRequest buildGrantRequest(
1386       String username, AccessControlProtos.Permission.Action... actions) {
1387     AccessControlProtos.Permission.Builder ret =
1388         AccessControlProtos.Permission.newBuilder();
1389     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1390         AccessControlProtos.GlobalPermission.newBuilder();
1391     for (AccessControlProtos.Permission.Action a : actions) {
1392       permissionBuilder.addAction(a);
1393     }
1394     ret.setType(AccessControlProtos.Permission.Type.Global)
1395        .setGlobalPermission(permissionBuilder);
1396     return AccessControlProtos.GrantRequest.newBuilder()
1397       .setUserPermission(
1398           AccessControlProtos.UserPermission.newBuilder()
1399               .setUser(ByteString.copyFromUtf8(username))
1400               .setPermission(ret)
1401       ).build();
1402   }
1403 
1404   /**
1405    * Create a request to grant user permissions.
1406    *
1407    * @param username the short user name who to grant permissions
1408    * @param tableName optional table name the permissions apply
1409    * @param family optional column family
1410    * @param qualifier optional qualifier
1411    * @param actions the permissions to be granted
1412    * @return A {@link AccessControlProtos} GrantRequest
1413    */
1414   public static AccessControlProtos.GrantRequest buildGrantRequest(
1415       String username, TableName tableName, byte[] family, byte[] qualifier,
1416       AccessControlProtos.Permission.Action... actions) {
1417     AccessControlProtos.Permission.Builder ret =
1418         AccessControlProtos.Permission.newBuilder();
1419     AccessControlProtos.TablePermission.Builder permissionBuilder =
1420         AccessControlProtos.TablePermission.newBuilder();
1421     for (AccessControlProtos.Permission.Action a : actions) {
1422       permissionBuilder.addAction(a);
1423     }
1424     if (tableName == null) {
1425       throw new NullPointerException("TableName cannot be null");
1426     }
1427     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1428 
1429     if (family != null) {
1430       permissionBuilder.setFamily(ByteStringer.wrap(family));
1431     }
1432     if (qualifier != null) {
1433       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1434     }
1435     ret.setType(AccessControlProtos.Permission.Type.Table)
1436        .setTablePermission(permissionBuilder);
1437     return AccessControlProtos.GrantRequest.newBuilder()
1438       .setUserPermission(
1439           AccessControlProtos.UserPermission.newBuilder()
1440               .setUser(ByteString.copyFromUtf8(username))
1441               .setPermission(ret)
1442       ).build();
1443   }
1444 
1445   /**
1446    * Create a request to grant user permissions.
1447    *
1448    * @param username the short user name who to grant permissions
1449    * @param namespace optional table name the permissions apply
1450    * @param actions the permissions to be granted
1451    * @return A {@link AccessControlProtos} GrantRequest
1452    */
1453   public static AccessControlProtos.GrantRequest buildGrantRequest(
1454       String username, String namespace,
1455       AccessControlProtos.Permission.Action... actions) {
1456     AccessControlProtos.Permission.Builder ret =
1457         AccessControlProtos.Permission.newBuilder();
1458     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1459         AccessControlProtos.NamespacePermission.newBuilder();
1460     for (AccessControlProtos.Permission.Action a : actions) {
1461       permissionBuilder.addAction(a);
1462     }
1463     if (namespace != null) {
1464       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1465     }
1466     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1467        .setNamespacePermission(permissionBuilder);
1468     return AccessControlProtos.GrantRequest.newBuilder()
1469       .setUserPermission(
1470           AccessControlProtos.UserPermission.newBuilder()
1471               .setUser(ByteString.copyFromUtf8(username))
1472               .setPermission(ret)
1473       ).build();
1474   }
1475 
1476   /**
1477    * Create a request to revoke user permissions.
1478    *
1479    * @param username the short user name whose permissions to be revoked
1480    * @param actions the permissions to be revoked
1481    * @return A {@link AccessControlProtos} RevokeRequest
1482    */
1483   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1484       String username, AccessControlProtos.Permission.Action... actions) {
1485     AccessControlProtos.Permission.Builder ret =
1486         AccessControlProtos.Permission.newBuilder();
1487     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1488         AccessControlProtos.GlobalPermission.newBuilder();
1489     for (AccessControlProtos.Permission.Action a : actions) {
1490       permissionBuilder.addAction(a);
1491     }
1492     ret.setType(AccessControlProtos.Permission.Type.Global)
1493        .setGlobalPermission(permissionBuilder);
1494     return AccessControlProtos.RevokeRequest.newBuilder()
1495       .setUserPermission(
1496           AccessControlProtos.UserPermission.newBuilder()
1497               .setUser(ByteString.copyFromUtf8(username))
1498               .setPermission(ret)
1499       ).build();
1500   }
1501 
1502   /**
1503    * Create a request to revoke user permissions.
1504    *
1505    * @param username the short user name whose permissions to be revoked
1506    * @param tableName optional table name the permissions apply
1507    * @param family optional column family
1508    * @param qualifier optional qualifier
1509    * @param actions the permissions to be revoked
1510    * @return A {@link AccessControlProtos} RevokeRequest
1511    */
1512   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1513       String username, TableName tableName, byte[] family, byte[] qualifier,
1514       AccessControlProtos.Permission.Action... actions) {
1515     AccessControlProtos.Permission.Builder ret =
1516         AccessControlProtos.Permission.newBuilder();
1517     AccessControlProtos.TablePermission.Builder permissionBuilder =
1518         AccessControlProtos.TablePermission.newBuilder();
1519     for (AccessControlProtos.Permission.Action a : actions) {
1520       permissionBuilder.addAction(a);
1521     }
1522     if (tableName != null) {
1523       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1524     }
1525     if (family != null) {
1526       permissionBuilder.setFamily(ByteStringer.wrap(family));
1527     }
1528     if (qualifier != null) {
1529       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1530     }
1531     ret.setType(AccessControlProtos.Permission.Type.Table)
1532        .setTablePermission(permissionBuilder);
1533     return AccessControlProtos.RevokeRequest.newBuilder()
1534       .setUserPermission(
1535           AccessControlProtos.UserPermission.newBuilder()
1536               .setUser(ByteString.copyFromUtf8(username))
1537               .setPermission(ret)
1538       ).build();
1539   }
1540 
1541   /**
1542    * Create a request to revoke user permissions.
1543    *
1544    * @param username the short user name whose permissions to be revoked
1545    * @param namespace optional table name the permissions apply
1546    * @param actions the permissions to be revoked
1547    * @return A {@link AccessControlProtos} RevokeRequest
1548    */
1549   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1550       String username, String namespace,
1551       AccessControlProtos.Permission.Action... actions) {
1552     AccessControlProtos.Permission.Builder ret =
1553         AccessControlProtos.Permission.newBuilder();
1554     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1555         AccessControlProtos.NamespacePermission.newBuilder();
1556     for (AccessControlProtos.Permission.Action a : actions) {
1557       permissionBuilder.addAction(a);
1558     }
1559     if (namespace != null) {
1560       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1561     }
1562     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1563        .setNamespacePermission(permissionBuilder);
1564     return AccessControlProtos.RevokeRequest.newBuilder()
1565       .setUserPermission(
1566           AccessControlProtos.UserPermission.newBuilder()
1567               .setUser(ByteString.copyFromUtf8(username))
1568               .setPermission(ret)
1569       ).build();
1570   }
1571 
1572   /**
1573    * Create a RegionOpenInfo based on given region info and version of offline node
1574    */
1575   private static RegionOpenInfo buildRegionOpenInfo(
1576       final HRegionInfo region,
1577       final List<ServerName> favoredNodes, Boolean openForReplay) {
1578     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1579     builder.setRegion(HRegionInfo.convert(region));
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 }