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