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