View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.protobuf;
19  
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.regex.Pattern;
24  
25  import org.apache.commons.collections.MapUtils;
26  import org.apache.commons.lang.StringUtils;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.hbase.CellScannable;
29  import org.apache.hadoop.hbase.DoNotRetryIOException;
30  import org.apache.hadoop.hbase.HColumnDescriptor;
31  import org.apache.hadoop.hbase.HConstants;
32  import org.apache.hadoop.hbase.HRegionInfo;
33  import org.apache.hadoop.hbase.HTableDescriptor;
34  import org.apache.hadoop.hbase.ServerName;
35  import org.apache.hadoop.hbase.TableName;
36  import org.apache.hadoop.hbase.client.Action;
37  import org.apache.hadoop.hbase.client.Admin;
38  import org.apache.hadoop.hbase.client.Append;
39  import org.apache.hadoop.hbase.client.Delete;
40  import org.apache.hadoop.hbase.client.Durability;
41  import org.apache.hadoop.hbase.client.Get;
42  import org.apache.hadoop.hbase.client.Increment;
43  import org.apache.hadoop.hbase.client.Mutation;
44  import org.apache.hadoop.hbase.client.Put;
45  import org.apache.hadoop.hbase.client.RegionCoprocessorServiceExec;
46  import org.apache.hadoop.hbase.client.Row;
47  import org.apache.hadoop.hbase.client.RowMutations;
48  import org.apache.hadoop.hbase.client.Scan;
49  import org.apache.hadoop.hbase.exceptions.DeserializationException;
50  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
51  import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ClearSlowLogResponseRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
63  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
64  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SlowLogResponseRequest;
65  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
66  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
67  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest;
68  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest.RegionUpdateInfo;
69  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.WarmupRegionRequest;
70  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
71  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest;
72  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest.FamilyPath;
73  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Column;
74  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Condition;
75  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
76  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
77  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
78  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue;
79  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue;
80  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType;
81  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
82  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
83  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
84  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType;
85  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
86  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
87  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
88  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AddColumnRequest;
89  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.AssignRegionRequest;
90  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.BalanceRequest;
91  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ClearDeadServersRequest;
92  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.CreateTableRequest;
93  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteColumnRequest;
94  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DeleteTableRequest;
95  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableRequest;
96  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
97  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest;
98  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
99  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetCleanerChoreRunningRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
103 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
104 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
105 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
106 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCleanerChoreEnabledRequest;
107 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
108 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsNormalizerEnabledRequest;
109 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos
110   .IsSnapshotCleanupEnabledRequest;
111 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSplitOrMergeEnabledRequest;
112 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
113 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
114 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
115 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.NormalizeRequest;
116 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
117 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
118 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreRequest;
119 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
120 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningRequest;
121 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetSnapshotCleanupRequest;
122 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledRequest;
123 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
124 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
125 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest;
126 import org.apache.hadoop.hbase.util.ByteStringer;
127 import org.apache.hadoop.hbase.util.Bytes;
128 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
129 import org.apache.hadoop.hbase.util.Pair;
130 import org.apache.hadoop.hbase.util.Triple;
131 
132 import com.google.protobuf.ByteString;
133 
134 /**
135  * Helper utility to build protocol buffer requests,
136  * or build components for protocol buffer requests.
137  */
138 @InterfaceAudience.Private
139 public final class RequestConverter {
140 
141   private RequestConverter() {
142   }
143 
144 // Start utilities for Client
145 
146 /**
147    * Create a new protocol buffer GetRequest to get a row, all columns in a family.
148    * If there is no such row, return the closest row before it.
149    *
150    * @param regionName the name of the region to get
151    * @param row the row to get
152    * @param family the column family to get
153    * should return the immediate row before
154    * @return a protocol buffer GetReuqest
155    */
156   public static GetRequest buildGetRowOrBeforeRequest(
157       final byte[] regionName, final byte[] row, final byte[] family) {
158     GetRequest.Builder builder = GetRequest.newBuilder();
159     RegionSpecifier region = buildRegionSpecifier(
160       RegionSpecifierType.REGION_NAME, regionName);
161     builder.setRegion(region);
162 
163     Column.Builder columnBuilder = Column.newBuilder();
164     columnBuilder.setFamily(ByteStringer.wrap(family));
165     ClientProtos.Get.Builder getBuilder =
166       ClientProtos.Get.newBuilder();
167     getBuilder.setRow(ByteStringer.wrap(row));
168     getBuilder.addColumn(columnBuilder.build());
169     getBuilder.setClosestRowBefore(true);
170     builder.setGet(getBuilder.build());
171     return builder.build();
172   }
173 
174 
175   /**
176    * Create a protocol buffer GetRequest for a client Get
177    *
178    * @param regionName the name of the region to get
179    * @param get the client Get
180    * @return a protocol buffer GetRequest
181    */
182   public static GetRequest buildGetRequest(final byte[] regionName,
183       final Get get) throws IOException {
184     GetRequest.Builder builder = GetRequest.newBuilder();
185     RegionSpecifier region = buildRegionSpecifier(
186       RegionSpecifierType.REGION_NAME, regionName);
187     builder.setRegion(region);
188     builder.setGet(ProtobufUtil.toGet(get));
189     return builder.build();
190   }
191 
192   /**
193    * Create a protocol buffer MutateRequest for a client increment
194    *
195    * @param regionName
196    * @param row
197    * @param family
198    * @param qualifier
199    * @param amount
200    * @param durability
201    * @return a mutate request
202    */
203   public static MutateRequest buildIncrementRequest(
204       final byte[] regionName, final byte[] row, final byte[] family, final byte[] qualifier,
205       final long amount, final Durability durability, long nonceGroup, long nonce) {
206     MutateRequest.Builder builder = MutateRequest.newBuilder();
207     RegionSpecifier region = buildRegionSpecifier(
208       RegionSpecifierType.REGION_NAME, regionName);
209     builder.setRegion(region);
210 
211     MutationProto.Builder mutateBuilder = MutationProto.newBuilder();
212     mutateBuilder.setRow(ByteStringer.wrap(row));
213     mutateBuilder.setMutateType(MutationType.INCREMENT);
214     mutateBuilder.setDurability(ProtobufUtil.toDurability(durability));
215     ColumnValue.Builder columnBuilder = ColumnValue.newBuilder();
216     columnBuilder.setFamily(ByteStringer.wrap(family));
217     QualifierValue.Builder valueBuilder = QualifierValue.newBuilder();
218     valueBuilder.setValue(ByteStringer.wrap(Bytes.toBytes(amount)));
219     valueBuilder.setQualifier(ByteStringer.wrap(qualifier));
220     columnBuilder.addQualifierValue(valueBuilder.build());
221     mutateBuilder.addColumnValue(columnBuilder.build());
222     if (nonce != HConstants.NO_NONCE) {
223       mutateBuilder.setNonce(nonce);
224     }
225     builder.setMutation(mutateBuilder.build());
226     if (nonceGroup != HConstants.NO_NONCE) {
227       builder.setNonceGroup(nonceGroup);
228     }
229     return builder.build();
230   }
231 
232   /**
233    * Create a protocol buffer MutateRequest for a conditioned put
234    *
235    * @param regionName
236    * @param row
237    * @param family
238    * @param qualifier
239    * @param comparator
240    * @param compareType
241    * @param put
242    * @return a mutate request
243    * @throws IOException
244    */
245   public static MutateRequest buildMutateRequest(
246       final byte[] regionName, final byte[] row, final byte[] family,
247       final byte [] qualifier, final ByteArrayComparable comparator,
248       final CompareType compareType, final Put put) throws IOException {
249     MutateRequest.Builder builder = MutateRequest.newBuilder();
250     RegionSpecifier region = buildRegionSpecifier(
251       RegionSpecifierType.REGION_NAME, regionName);
252     builder.setRegion(region);
253     Condition condition = buildCondition(
254       row, family, qualifier, comparator, compareType);
255     builder.setMutation(ProtobufUtil.toMutation(MutationType.PUT, put, MutationProto.newBuilder()));
256     builder.setCondition(condition);
257     return builder.build();
258   }
259 
260   /**
261    * Create a protocol buffer MutateRequest for a conditioned delete
262    *
263    * @param regionName
264    * @param row
265    * @param family
266    * @param qualifier
267    * @param comparator
268    * @param compareType
269    * @param delete
270    * @return a mutate request
271    * @throws IOException
272    */
273   public static MutateRequest buildMutateRequest(
274       final byte[] regionName, final byte[] row, final byte[] family,
275       final byte [] qualifier, final ByteArrayComparable comparator,
276       final CompareType compareType, final Delete delete) throws IOException {
277     MutateRequest.Builder builder = MutateRequest.newBuilder();
278     RegionSpecifier region = buildRegionSpecifier(
279       RegionSpecifierType.REGION_NAME, regionName);
280     builder.setRegion(region);
281     Condition condition = buildCondition(
282       row, family, qualifier, comparator, compareType);
283     builder.setMutation(ProtobufUtil.toMutation(MutationType.DELETE, delete,
284       MutationProto.newBuilder()));
285     builder.setCondition(condition);
286     return builder.build();
287   }
288 
289   /**
290    * Create a protocol buffer MutateRequest for conditioned row mutations
291    *
292    * @param regionName
293    * @param row
294    * @param family
295    * @param qualifier
296    * @param comparator
297    * @param compareType
298    * @param rowMutations
299    * @return a mutate request
300    * @throws IOException
301    */
302   public static ClientProtos.MultiRequest buildMutateRequest(
303       final byte[] regionName, final byte[] row, final byte[] family,
304       final byte [] qualifier, final ByteArrayComparable comparator,
305       final CompareType compareType, final RowMutations rowMutations) throws IOException {
306     RegionAction.Builder builder =
307         getRegionActionBuilderWithRegion(RegionAction.newBuilder(), regionName);
308     builder.setAtomic(true);
309     ClientProtos.Action.Builder actionBuilder = ClientProtos.Action.newBuilder();
310     MutationProto.Builder mutationBuilder = MutationProto.newBuilder();
311     Condition condition = buildCondition(
312         row, family, qualifier, comparator, compareType);
313     for (Mutation mutation: rowMutations.getMutations()) {
314       MutationType mutateType = null;
315       if (mutation instanceof Put) {
316         mutateType = MutationType.PUT;
317       } else if (mutation instanceof Delete) {
318         mutateType = MutationType.DELETE;
319       } else {
320         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
321             mutation.getClass().getName());
322       }
323       mutationBuilder.clear();
324       MutationProto mp = ProtobufUtil.toMutation(mutateType, mutation, mutationBuilder);
325       actionBuilder.clear();
326       actionBuilder.setMutation(mp);
327       builder.addAction(actionBuilder.build());
328     }
329     ClientProtos.MultiRequest request =
330         ClientProtos.MultiRequest.newBuilder().addRegionAction(builder.build())
331             .setCondition(condition).build();
332     return request;
333   }
334 
335   /**
336    * Create a protocol buffer MutateRequest for a put
337    *
338    * @param regionName
339    * @param put
340    * @return a mutate request
341    * @throws IOException
342    */
343   public static MutateRequest buildMutateRequest(
344       final byte[] regionName, final Put put) throws IOException {
345     MutateRequest.Builder builder = MutateRequest.newBuilder();
346     RegionSpecifier region = buildRegionSpecifier(
347       RegionSpecifierType.REGION_NAME, regionName);
348     builder.setRegion(region);
349     builder.setMutation(ProtobufUtil.toMutation(MutationType.PUT, put, MutationProto.newBuilder()));
350     return builder.build();
351   }
352 
353   /**
354    * Create a protocol buffer MutateRequest for an append
355    *
356    * @param regionName
357    * @param append
358    * @return a mutate request
359    * @throws IOException
360    */
361   public static MutateRequest buildMutateRequest(final byte[] regionName,
362       final Append append, long nonceGroup, long nonce) throws IOException {
363     MutateRequest.Builder builder = MutateRequest.newBuilder();
364     RegionSpecifier region = buildRegionSpecifier(
365       RegionSpecifierType.REGION_NAME, regionName);
366     builder.setRegion(region);
367     if (nonce != HConstants.NO_NONCE && nonceGroup != HConstants.NO_NONCE) {
368       builder.setNonceGroup(nonceGroup);
369     }
370     builder.setMutation(ProtobufUtil.toMutation(MutationType.APPEND, append,
371       MutationProto.newBuilder(), nonce));
372     return builder.build();
373   }
374 
375   /**
376    * Create a protocol buffer MutateRequest for a client increment
377    *
378    * @param regionName
379    * @param increment
380    * @return a mutate request
381    */
382   public static MutateRequest buildMutateRequest(final byte[] regionName,
383       final Increment increment, final long nonceGroup, final long nonce) {
384     MutateRequest.Builder builder = MutateRequest.newBuilder();
385     RegionSpecifier region = buildRegionSpecifier(
386       RegionSpecifierType.REGION_NAME, regionName);
387     builder.setRegion(region);
388     if (nonce != HConstants.NO_NONCE && nonceGroup != HConstants.NO_NONCE) {
389       builder.setNonceGroup(nonceGroup);
390     }
391     builder.setMutation(ProtobufUtil.toMutation(increment, MutationProto.newBuilder(), nonce));
392     return builder.build();
393   }
394 
395   /**
396    * Create a protocol buffer MutateRequest for a delete
397    *
398    * @param regionName
399    * @param delete
400    * @return a mutate request
401    * @throws IOException
402    */
403   public static MutateRequest buildMutateRequest(
404       final byte[] regionName, final Delete delete) throws IOException {
405     MutateRequest.Builder builder = MutateRequest.newBuilder();
406     RegionSpecifier region = buildRegionSpecifier(
407       RegionSpecifierType.REGION_NAME, regionName);
408     builder.setRegion(region);
409     builder.setMutation(ProtobufUtil.toMutation(MutationType.DELETE, delete,
410       MutationProto.newBuilder()));
411     return builder.build();
412   }
413 
414   /**
415    * Create a protocol buffer MultiRequest for row mutations.
416    * Does not propagate Action absolute position.  Does not set atomic action on the created
417    * RegionAtomic.  Caller should do that if wanted.
418    * @param regionName
419    * @param rowMutations
420    * @return a data-laden RegionMutation.Builder
421    * @throws IOException
422    */
423   public static RegionAction.Builder buildRegionAction(final byte [] regionName,
424       final RowMutations rowMutations)
425   throws IOException {
426     RegionAction.Builder builder =
427       getRegionActionBuilderWithRegion(RegionAction.newBuilder(), regionName);
428     ClientProtos.Action.Builder actionBuilder = ClientProtos.Action.newBuilder();
429     MutationProto.Builder mutationBuilder = MutationProto.newBuilder();
430     for (Mutation mutation: rowMutations.getMutations()) {
431       MutationType mutateType = null;
432       if (mutation instanceof Put) {
433         mutateType = MutationType.PUT;
434       } else if (mutation instanceof Delete) {
435         mutateType = MutationType.DELETE;
436       } else {
437         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
438           mutation.getClass().getName());
439       }
440       mutationBuilder.clear();
441       MutationProto mp = ProtobufUtil.toMutation(mutateType, mutation, mutationBuilder);
442       actionBuilder.clear();
443       actionBuilder.setMutation(mp);
444       builder.addAction(actionBuilder.build());
445     }
446     return builder;
447   }
448 
449   /**
450    * Create a protocol buffer MultiRequest for row mutations that does not hold data.  Data/Cells
451    * are carried outside of protobuf.  Return references to the Cells in <code>cells</code> param.
452     * Does not propagate Action absolute position.  Does not set atomic action on the created
453    * RegionAtomic.  Caller should do that if wanted.
454    * @param regionName
455    * @param rowMutations
456    * @param cells Return in here a list of Cells as CellIterable.
457    * @return a region mutation minus data
458    * @throws IOException
459    */
460   public static RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
461       final RowMutations rowMutations, final List<CellScannable> cells,
462       final RegionAction.Builder regionActionBuilder,
463       final ClientProtos.Action.Builder actionBuilder,
464       final MutationProto.Builder mutationBuilder)
465   throws IOException {
466     for (Mutation mutation: rowMutations.getMutations()) {
467       MutationType type = null;
468       if (mutation instanceof Put) {
469         type = MutationType.PUT;
470       } else if (mutation instanceof Delete) {
471         type = MutationType.DELETE;
472       } else {
473         throw new DoNotRetryIOException("RowMutations supports only put and delete, not " +
474           mutation.getClass().getName());
475       }
476       mutationBuilder.clear();
477       MutationProto mp = ProtobufUtil.toMutationNoData(type, mutation, mutationBuilder);
478       cells.add(mutation);
479       actionBuilder.clear();
480       regionActionBuilder.addAction(actionBuilder.setMutation(mp).build());
481     }
482     return regionActionBuilder;
483   }
484 
485   public static RegionAction.Builder getRegionActionBuilderWithRegion(
486       final RegionAction.Builder regionActionBuilder, final byte [] regionName) {
487     RegionSpecifier region = buildRegionSpecifier(RegionSpecifierType.REGION_NAME, regionName);
488     regionActionBuilder.setRegion(region);
489     return regionActionBuilder;
490   }
491 
492   /**
493    * Create a protocol buffer ScanRequest for a client Scan
494    *
495    * @param regionName
496    * @param scan
497    * @param numberOfRows
498    * @param closeScanner
499    * @return a scan request
500    * @throws IOException
501    */
502   public static ScanRequest buildScanRequest(final byte[] regionName, final Scan scan,
503       final int numberOfRows, final boolean closeScanner) throws IOException {
504     ScanRequest.Builder builder = ScanRequest.newBuilder();
505     RegionSpecifier region = buildRegionSpecifier(
506       RegionSpecifierType.REGION_NAME, regionName);
507     builder.setNumberOfRows(numberOfRows);
508     builder.setCloseScanner(closeScanner);
509     builder.setRegion(region);
510     builder.setScan(ProtobufUtil.toScan(scan));
511     builder.setClientHandlesPartials(true);
512     builder.setClientHandlesHeartbeats(true);
513     builder.setTrackScanMetrics(scan.isScanMetricsEnabled());
514     if (scan.getLimit() > 0) {
515       builder.setLimitOfRows(scan.getLimit());
516     }
517     return builder.build();
518   }
519 
520   /**
521    * Create a protocol buffer ScanRequest for a scanner id
522    *
523    * @param scannerId
524    * @param numberOfRows
525    * @param closeScanner
526    * @return a scan request
527    */
528   public static ScanRequest buildScanRequest(final long scannerId, final int numberOfRows,
529       final boolean closeScanner, final boolean trackMetrics) {
530     ScanRequest.Builder builder = ScanRequest.newBuilder();
531     builder.setNumberOfRows(numberOfRows);
532     builder.setCloseScanner(closeScanner);
533     builder.setScannerId(scannerId);
534     builder.setClientHandlesPartials(true);
535     builder.setClientHandlesHeartbeats(true);
536     builder.setTrackScanMetrics(trackMetrics);
537     return builder.build();
538   }
539 
540   /**
541    * Create a protocol buffer ScanRequest for a scanner id
542    *
543    * @param scannerId
544    * @param numberOfRows
545    * @param closeScanner
546    * @param nextCallSeq
547    * @return a scan request
548    */
549   public static ScanRequest buildScanRequest(final long scannerId, final int numberOfRows,
550       final boolean closeScanner, final long nextCallSeq, final boolean trackMetrics,
551       final boolean renew, int limitOfRows) {
552     ScanRequest.Builder builder = ScanRequest.newBuilder();
553     builder.setNumberOfRows(numberOfRows);
554     builder.setCloseScanner(closeScanner);
555     builder.setScannerId(scannerId);
556     builder.setNextCallSeq(nextCallSeq);
557     builder.setClientHandlesPartials(true);
558     builder.setClientHandlesHeartbeats(true);
559     builder.setTrackScanMetrics(trackMetrics);
560     builder.setRenew(renew);
561     if (limitOfRows > 0) {
562       builder.setLimitOfRows(limitOfRows);
563     }
564     return builder.build();
565   }
566 
567   /**
568    * Create a protocol buffer bulk load request
569    *
570    * @deprecated use buildBulkLoadHFileRequest(final List<Pair<byte[], String>> familyPaths,
571    * final byte[] regionName, boolean assignSeqNum, List<String> clusterIds)
572    *
573    * @param familyPaths
574    * @param regionName
575    * @param assignSeqNum
576    * @return a bulk load request
577    */
578   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
579     final List<Pair<byte[], String>> familyPaths,
580     final byte[] regionName, boolean assignSeqNum) {
581     return buildBulkLoadHFileRequest(familyPaths, regionName, assignSeqNum, null);
582   }
583 
584   /**
585    * Create a protocol buffer bulk load request
586    *
587    * @param familyPaths
588    * @param regionName
589    * @param assignSeqNum
590    * @param clusterIds
591    * @return a bulk load request
592    */
593   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
594       final List<Pair<byte[], String>> familyPaths,
595       final byte[] regionName, boolean assignSeqNum, List<String> clusterIds) {
596     BulkLoadHFileRequest.Builder builder = BulkLoadHFileRequest.newBuilder();
597     RegionSpecifier region = buildRegionSpecifier(
598       RegionSpecifierType.REGION_NAME, regionName);
599     builder.setRegion(region);
600     FamilyPath.Builder familyPathBuilder = FamilyPath.newBuilder();
601     for (Pair<byte[], String> familyPath: familyPaths) {
602       familyPathBuilder.setFamily(ByteStringer.wrap(familyPath.getFirst()));
603       familyPathBuilder.setPath(familyPath.getSecond());
604       builder.addFamilyPath(familyPathBuilder.build());
605     }
606     if(clusterIds!=null) {
607       builder.addAllClusterIds(clusterIds);
608     }
609     builder.setAssignSeqNum(assignSeqNum);
610     return builder.build();
611   }
612 
613   /**
614    * Create a protocol buffer multi request for a list of actions.
615    * Propagates Actions original index.
616    *
617    * @param regionName
618    * @param actions
619    * @return a multi request
620    * @throws IOException
621    */
622   public static <R> RegionAction.Builder buildRegionAction(final byte[] regionName,
623       final List<Action<R>> actions, final RegionAction.Builder regionActionBuilder,
624       final ClientProtos.Action.Builder actionBuilder,
625       final MutationProto.Builder mutationBuilder) throws IOException {
626     for (Action<R> action: actions) {
627       Row row = action.getAction();
628       actionBuilder.clear();
629       actionBuilder.setIndex(action.getOriginalIndex());
630       mutationBuilder.clear();
631       if (row instanceof Get) {
632         Get g = (Get)row;
633         regionActionBuilder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
634       } else if (row instanceof Put) {
635         regionActionBuilder.addAction(actionBuilder.
636           setMutation(ProtobufUtil.toMutation(MutationType.PUT, (Put)row, mutationBuilder)));
637       } else if (row instanceof Delete) {
638         regionActionBuilder.addAction(actionBuilder.
639           setMutation(ProtobufUtil.toMutation(MutationType.DELETE, (Delete)row, mutationBuilder)));
640       } else if (row instanceof Append) {
641         regionActionBuilder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutation(
642             MutationType.APPEND, (Append)row, mutationBuilder, action.getNonce())));
643       } else if (row instanceof Increment) {
644         regionActionBuilder.addAction(actionBuilder.setMutation(
645             ProtobufUtil.toMutation((Increment)row, mutationBuilder, action.getNonce())));
646       } else if (row instanceof RegionCoprocessorServiceExec) {
647         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
648         regionActionBuilder.addAction(actionBuilder.setServiceCall(
649             ClientProtos.CoprocessorServiceCall.newBuilder()
650               .setRow(ByteStringer.wrap(exec.getRow()))
651               .setServiceName(exec.getMethod().getService().getFullName())
652               .setMethodName(exec.getMethod().getName())
653               .setRequest(exec.getRequest().toByteString())));
654       } else if (row instanceof RowMutations) {
655         // Skip RowMutations, which has been separately converted to RegionAction
656         continue;
657       } else {
658         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
659       }
660     }
661     return regionActionBuilder;
662   }
663 
664   /**
665    * Create a protocol buffer multirequest with NO data for a list of actions (data is carried
666    * otherwise than via protobuf).  This means it just notes attributes, whether to write the
667    * WAL, etc., and the presence in protobuf serves as place holder for the data which is
668    * coming along otherwise.  Note that Get is different.  It does not contain 'data' and is always
669    * carried by protobuf.  We return references to the data by adding them to the passed in
670    * <code>data</code> param.
671    *
672    * <p>Propagates Actions original index.
673    *
674    * @param regionName
675    * @param actions
676    * @param cells Place to stuff references to actual data.
677    * @return a multi request that does not carry any data.
678    * @throws IOException
679    */
680   public static <R> RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
681       final List<Action<R>> actions, final List<CellScannable> cells,
682       final RegionAction.Builder regionActionBuilder,
683       final ClientProtos.Action.Builder actionBuilder,
684       final MutationProto.Builder mutationBuilder) throws IOException {
685     RegionAction.Builder builder = getRegionActionBuilderWithRegion(
686       RegionAction.newBuilder(), regionName);
687     for (Action<R> action: actions) {
688       Row row = action.getAction();
689       actionBuilder.clear();
690       actionBuilder.setIndex(action.getOriginalIndex());
691       mutationBuilder.clear();
692       if (row instanceof Get) {
693         Get g = (Get)row;
694         builder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
695       } else if (row instanceof Put) {
696         Put p = (Put)row;
697         cells.add(p);
698         builder.addAction(actionBuilder.
699           setMutation(ProtobufUtil.toMutationNoData(MutationType.PUT, p, mutationBuilder)));
700       } else if (row instanceof Delete) {
701         Delete d = (Delete)row;
702         int size = d.size();
703         // Note that a legitimate Delete may have a size of zero; i.e. a Delete that has nothing
704         // in it but the row to delete.  In this case, the current implementation does not make
705         // a KeyValue to represent a delete-of-all-the-row until we serialize... For such cases
706         // where the size returned is zero, we will send the Delete fully pb'd rather than have
707         // metadata only in the pb and then send the kv along the side in cells.
708         if (size > 0) {
709           cells.add(d);
710           builder.addAction(actionBuilder.
711             setMutation(ProtobufUtil.toMutationNoData(MutationType.DELETE, d, mutationBuilder)));
712         } else {
713           builder.addAction(actionBuilder.
714             setMutation(ProtobufUtil.toMutation(MutationType.DELETE, d, mutationBuilder)));
715         }
716       } else if (row instanceof Append) {
717         Append a = (Append)row;
718         cells.add(a);
719         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
720           MutationType.APPEND, a, mutationBuilder, action.getNonce())));
721       } else if (row instanceof Increment) {
722         Increment i = (Increment)row;
723         cells.add(i);
724         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
725           MutationType.INCREMENT, i, mutationBuilder, action.getNonce())));
726       } else if (row instanceof RegionCoprocessorServiceExec) {
727         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
728         builder.addAction(actionBuilder.setServiceCall(ClientProtos.CoprocessorServiceCall
729             .newBuilder().setRow(ByteStringer.wrap(exec.getRow()))
730             .setServiceName(exec.getMethod().getService().getFullName())
731             .setMethodName(exec.getMethod().getName())
732             .setRequest(exec.getRequest().toByteString())));
733       } else if (row instanceof RowMutations) {
734         // Skip RowMutations, which has been separately converted to RegionAction
735         continue;
736       } else {
737         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
738       }
739     }
740     return builder;
741   }
742 
743 // End utilities for Client
744 //Start utilities for Admin
745 
746   /**
747    * Create a protocol buffer GetRegionInfoRequest for a given region name
748    *
749    * @param regionName the name of the region to get info
750    * @return a protocol buffer GetRegionInfoRequest
751    */
752   public static GetRegionInfoRequest
753       buildGetRegionInfoRequest(final byte[] regionName) {
754     return buildGetRegionInfoRequest(regionName, false);
755   }
756 
757   /**
758    * Create a protocol buffer GetRegionInfoRequest for a given region name
759    *
760    * @param regionName the name of the region to get info
761    * @param includeCompactionState indicate if the compaction state is requested
762    * @return a protocol buffer GetRegionInfoRequest
763    */
764   public static GetRegionInfoRequest
765       buildGetRegionInfoRequest(final byte[] regionName,
766         final boolean includeCompactionState) {
767     GetRegionInfoRequest.Builder builder = GetRegionInfoRequest.newBuilder();
768     RegionSpecifier region = buildRegionSpecifier(
769       RegionSpecifierType.REGION_NAME, regionName);
770     builder.setRegion(region);
771     if (includeCompactionState) {
772       builder.setCompactionState(includeCompactionState);
773     }
774     return builder.build();
775   }
776 
777  /**
778   * Create a protocol buffer GetStoreFileRequest for a given region name
779   *
780   * @param regionName the name of the region to get info
781   * @param family the family to get store file list
782   * @return a protocol buffer GetStoreFileRequest
783   */
784  public static GetStoreFileRequest
785      buildGetStoreFileRequest(final byte[] regionName, final byte[] family) {
786    GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder();
787    RegionSpecifier region = buildRegionSpecifier(
788      RegionSpecifierType.REGION_NAME, regionName);
789    builder.setRegion(region);
790    builder.addFamily(ByteStringer.wrap(family));
791    return builder.build();
792  }
793 
794  /**
795   * Create a protocol buffer GetOnlineRegionRequest
796   *
797   * @return a protocol buffer GetOnlineRegionRequest
798   */
799  public static GetOnlineRegionRequest buildGetOnlineRegionRequest() {
800    return GetOnlineRegionRequest.newBuilder().build();
801  }
802 
803  /**
804   * Create a protocol buffer FlushRegionRequest for a given region name
805   *
806   * @param regionName the name of the region to get info
807   * @return a protocol buffer FlushRegionRequest
808   */
809  public static FlushRegionRequest
810      buildFlushRegionRequest(final byte[] regionName) {
811    return buildFlushRegionRequest(regionName, false);
812  }
813 
814  /**
815   * Create a protocol buffer FlushRegionRequest for a given region name
816   *
817   * @param regionName the name of the region to get info
818   * @return a protocol buffer FlushRegionRequest
819   */
820  public static FlushRegionRequest
821      buildFlushRegionRequest(final byte[] regionName, boolean writeFlushWALMarker) {
822    FlushRegionRequest.Builder builder = FlushRegionRequest.newBuilder();
823    RegionSpecifier region = buildRegionSpecifier(
824      RegionSpecifierType.REGION_NAME, regionName);
825    builder.setRegion(region);
826    builder.setWriteFlushWalMarker(writeFlushWALMarker);
827    return builder.build();
828  }
829 
830  /**
831   * Create a protocol buffer OpenRegionRequest to open a list of regions
832   *
833   * @param server the serverName for the RPC
834   * @param regionOpenInfos info of a list of regions to open
835   * @param openForReplay
836   * @return a protocol buffer OpenRegionRequest
837   */
838  public static OpenRegionRequest
839      buildOpenRegionRequest(ServerName server, final List<Triple<HRegionInfo, Integer,
840          List<ServerName>>> regionOpenInfos, Boolean openForReplay) {
841    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
842    for (Triple<HRegionInfo, Integer, List<ServerName>> regionOpenInfo: regionOpenInfos) {
843      Integer second = regionOpenInfo.getSecond();
844      int versionOfOfflineNode = second == null ? -1 : second.intValue();
845      builder.addOpenInfo(buildRegionOpenInfo(regionOpenInfo.getFirst(), versionOfOfflineNode,
846        regionOpenInfo.getThird(), openForReplay));
847    }
848    if (server != null) {
849      builder.setServerStartCode(server.getStartcode());
850    }
851    // send the master's wall clock time as well, so that the RS can refer to it
852    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
853    return builder.build();
854  }
855 
856  /**
857   * Create a protocol buffer OpenRegionRequest for a given region
858   *
859   * @param server the serverName for the RPC
860   * @param region the region to open
861   * @param versionOfOfflineNode that needs to be present in the offline node
862   * @param favoredNodes
863   * @param openForReplay
864   * @return a protocol buffer OpenRegionRequest
865   */
866  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
867      final HRegionInfo region, final int versionOfOfflineNode, List<ServerName> favoredNodes,
868      Boolean openForReplay) {
869    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
870    builder.addOpenInfo(buildRegionOpenInfo(region, versionOfOfflineNode, favoredNodes,
871      openForReplay));
872    if (server != null) {
873      builder.setServerStartCode(server.getStartcode());
874    }
875    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
876    return builder.build();
877  }
878 
879  /**
880   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
881   * @param updateRegionInfos
882   * @return a protocol buffer UpdateFavoredNodesRequest
883   */
884  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
885      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
886    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
887    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
888      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
889      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
890      for (ServerName server : pair.getSecond()) {
891        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
892      }
893      ubuilder.addUpdateInfo(builder.build());
894    }
895    return ubuilder.build();
896  }
897 
898  /**
899   * Create a CloseRegionRequest for a given region name
900   *
901   * @param regionName the name of the region to close
902   * @param transitionInZK indicator if to transition in ZK
903   * @return a CloseRegionRequest
904   */
905  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
906      final byte[] regionName, final boolean transitionInZK) {
907    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
908    RegionSpecifier region = buildRegionSpecifier(
909      RegionSpecifierType.REGION_NAME, regionName);
910    builder.setRegion(region);
911    builder.setTransitionInZK(transitionInZK);
912    if (server != null) {
913      builder.setServerStartCode(server.getStartcode());
914    }
915    return builder.build();
916  }
917 
918   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
919     final byte[] regionName, final int versionOfClosingNode,
920     ServerName destinationServer, final boolean transitionInZK) {
921     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
922     RegionSpecifier region = buildRegionSpecifier(
923       RegionSpecifierType.REGION_NAME, regionName);
924     builder.setRegion(region);
925     builder.setVersionOfClosingNode(versionOfClosingNode);
926     builder.setTransitionInZK(transitionInZK);
927     if (destinationServer != null){
928       builder.setDestinationServer(ProtobufUtil.toServerName( destinationServer) );
929     }
930     if (server != null) {
931       builder.setServerStartCode(server.getStartcode());
932     }
933     return builder.build();
934   }
935 
936   /**
937    *  Create a WarmupRegionRequest for a given region name
938    *
939    *  @param regionInfo Region we are warming up
940    */
941   public static WarmupRegionRequest buildWarmupRegionRequest(final HRegionInfo regionInfo) {
942     WarmupRegionRequest.Builder builder = WarmupRegionRequest.newBuilder();
943     builder.setRegionInfo(HRegionInfo.convert(regionInfo));
944     return builder.build();
945   }
946  /**
947   * Create a CloseRegionRequest for a given encoded region name
948   *
949   * @param encodedRegionName the name of the region to close
950   * @param transitionInZK indicator if to transition in ZK
951   * @return a CloseRegionRequest
952   */
953  public static CloseRegionRequest
954      buildCloseRegionRequest(ServerName server, final String encodedRegionName,
955        final boolean transitionInZK) {
956    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
957    RegionSpecifier region = buildRegionSpecifier(
958      RegionSpecifierType.ENCODED_REGION_NAME,
959      Bytes.toBytes(encodedRegionName));
960    builder.setRegion(region);
961    builder.setTransitionInZK(transitionInZK);
962    if (server != null) {
963      builder.setServerStartCode(server.getStartcode());
964    }
965    return builder.build();
966  }
967 
968  /**
969   * Create a SplitRegionRequest for a given region name
970   *
971   * @param regionName the name of the region to split
972   * @param splitPoint the split point
973   * @return a SplitRegionRequest
974   */
975  public static SplitRegionRequest buildSplitRegionRequest(
976      final byte[] regionName, final byte[] splitPoint) {
977    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
978    RegionSpecifier region = buildRegionSpecifier(
979      RegionSpecifierType.REGION_NAME, regionName);
980    builder.setRegion(region);
981    if (splitPoint != null) {
982      builder.setSplitPoint(ByteStringer.wrap(splitPoint));
983    }
984    return builder.build();
985  }
986 
987   /**
988    * Create a MergeRegionsRequest for the given regions
989    * @param regionA name of region a
990    * @param regionB name of region b
991    * @param forcible true if it is a compulsory merge
992    * @return a MergeRegionsRequest
993    */
994   public static MergeRegionsRequest buildMergeRegionsRequest(
995       final byte[] regionA, final byte[] regionB, final boolean forcible) {
996     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
997     RegionSpecifier regionASpecifier = buildRegionSpecifier(
998         RegionSpecifierType.REGION_NAME, regionA);
999     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
1000         RegionSpecifierType.REGION_NAME, regionB);
1001     builder.setRegionA(regionASpecifier);
1002     builder.setRegionB(regionBSpecifier);
1003     builder.setForcible(forcible);
1004     // send the master's wall clock time as well, so that the RS can refer to it
1005     builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
1006     return builder.build();
1007   }
1008 
1009  /**
1010   * Create a  CompactRegionRequest for a given region name
1011   *
1012   * @param regionName the name of the region to get info
1013   * @param major indicator if it is a major compaction
1014   * @return a CompactRegionRequest
1015   */
1016  public static CompactRegionRequest buildCompactRegionRequest(
1017      final byte[] regionName, final boolean major, final byte [] family) {
1018    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
1019    RegionSpecifier region = buildRegionSpecifier(
1020      RegionSpecifierType.REGION_NAME, regionName);
1021    builder.setRegion(region);
1022    builder.setMajor(major);
1023    if (family != null) {
1024      builder.setFamily(ByteStringer.wrap(family));
1025    }
1026    return builder.build();
1027  }
1028 
1029  /**
1030   * @see {@link #buildRollWALWriterRequest()}
1031   */
1032  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
1033      RollWALWriterRequest.newBuilder().build();
1034 
1035   /**
1036   * Create a new RollWALWriterRequest
1037   *
1038   * @return a ReplicateWALEntryRequest
1039   */
1040  public static RollWALWriterRequest buildRollWALWriterRequest() {
1041    return ROLL_WAL_WRITER_REQUEST;
1042  }
1043 
1044  /**
1045   * @see {@link #buildGetServerInfoRequest()}
1046   */
1047  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
1048    GetServerInfoRequest.newBuilder().build();
1049 
1050  /**
1051   * Create a new GetServerInfoRequest
1052   *
1053   * @return a GetServerInfoRequest
1054   */
1055  public static GetServerInfoRequest buildGetServerInfoRequest() {
1056    return GET_SERVER_INFO_REQUEST;
1057  }
1058 
1059  /**
1060   * Create a new StopServerRequest
1061   *
1062   * @param reason the reason to stop the server
1063   * @return a StopServerRequest
1064   */
1065  public static StopServerRequest buildStopServerRequest(final String reason) {
1066    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
1067    builder.setReason(reason);
1068    return builder.build();
1069  }
1070 
1071 //End utilities for Admin
1072 
1073   /**
1074    * Convert a byte array to a protocol buffer RegionSpecifier
1075    *
1076    * @param type the region specifier type
1077    * @param value the region specifier byte array value
1078    * @return a protocol buffer RegionSpecifier
1079    */
1080   public static RegionSpecifier buildRegionSpecifier(
1081       final RegionSpecifierType type, final byte[] value) {
1082     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
1083     regionBuilder.setValue(ByteStringer.wrap(value));
1084     regionBuilder.setType(type);
1085     return regionBuilder.build();
1086   }
1087 
1088   /**
1089    * Create a protocol buffer Condition
1090    *
1091    * @param row
1092    * @param family
1093    * @param qualifier
1094    * @param comparator
1095    * @param compareType
1096    * @return a Condition
1097    * @throws IOException
1098    */
1099   public static Condition buildCondition(final byte[] row,
1100       final byte[] family, final byte [] qualifier,
1101       final ByteArrayComparable comparator,
1102       final CompareType compareType) throws IOException {
1103     Condition.Builder builder = Condition.newBuilder();
1104     builder.setRow(ByteStringer.wrap(row));
1105     builder.setFamily(ByteStringer.wrap(family));
1106     builder.setQualifier(ByteStringer.wrap(qualifier));
1107     builder.setComparator(ProtobufUtil.toComparator(comparator));
1108     builder.setCompareType(compareType);
1109     return builder.build();
1110   }
1111 
1112   /**
1113    * Create a protocol buffer AddColumnRequest
1114    *
1115    * @param tableName
1116    * @param column
1117    * @return an AddColumnRequest
1118    */
1119   public static AddColumnRequest buildAddColumnRequest(
1120       final TableName tableName,
1121       final HColumnDescriptor column,
1122       final long nonceGroup,
1123       final long nonce) {
1124     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
1125     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1126     builder.setColumnFamilies(column.convert());
1127     builder.setNonceGroup(nonceGroup);
1128     builder.setNonce(nonce);
1129     return builder.build();
1130   }
1131 
1132   /**
1133    * Create a protocol buffer DeleteColumnRequest
1134    *
1135    * @param tableName
1136    * @param columnName
1137    * @return a DeleteColumnRequest
1138    */
1139   public static DeleteColumnRequest buildDeleteColumnRequest(
1140       final TableName tableName,
1141       final byte [] columnName,
1142       final long nonceGroup,
1143       final long nonce) {
1144     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
1145     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1146     builder.setColumnName(ByteStringer.wrap(columnName));
1147     builder.setNonceGroup(nonceGroup);
1148     builder.setNonce(nonce);
1149     return builder.build();
1150   }
1151 
1152   /**
1153    * Create a protocol buffer ModifyColumnRequest
1154    *
1155    * @param tableName
1156    * @param column
1157    * @return an ModifyColumnRequest
1158    */
1159   public static ModifyColumnRequest buildModifyColumnRequest(
1160       final TableName tableName,
1161       final HColumnDescriptor column,
1162       final long nonceGroup,
1163       final long nonce) {
1164     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
1165     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1166     builder.setColumnFamilies(column.convert());
1167     builder.setNonceGroup(nonceGroup);
1168     builder.setNonce(nonce);
1169     return builder.build();
1170   }
1171 
1172   /**
1173    * Create a protocol buffer MoveRegionRequest
1174    *
1175    * @param encodedRegionName
1176    * @param destServerName
1177    * @return A MoveRegionRequest
1178    * @throws DeserializationException
1179    */
1180   public static MoveRegionRequest buildMoveRegionRequest(
1181       final byte [] encodedRegionName, final byte [] destServerName) throws
1182       DeserializationException {
1183     MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1184     builder.setRegion(
1185       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1186     if (destServerName != null) {
1187       builder.setDestServerName(
1188         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1189     }
1190     return builder.build();
1191   }
1192 
1193   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1194       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1195       final boolean forcible) throws DeserializationException {
1196     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1197     builder.setRegionA(buildRegionSpecifier(
1198         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1199     builder.setRegionB(buildRegionSpecifier(
1200         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1201     builder.setForcible(forcible);
1202     return builder.build();
1203   }
1204 
1205   /**
1206    * Create a protocol buffer AssignRegionRequest
1207    *
1208    * @param regionName
1209    * @return an AssignRegionRequest
1210    */
1211   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1212     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1213     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1214     return builder.build();
1215   }
1216 
1217   /**
1218    * Creates a protocol buffer UnassignRegionRequest
1219    *
1220    * @param regionName
1221    * @param force
1222    * @return an UnassignRegionRequest
1223    */
1224   public static UnassignRegionRequest buildUnassignRegionRequest(
1225       final byte [] regionName, final boolean force) {
1226     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1227     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1228     builder.setForce(force);
1229     return builder.build();
1230   }
1231 
1232   /**
1233    * Creates a protocol buffer OfflineRegionRequest
1234    *
1235    * @param regionName
1236    * @return an OfflineRegionRequest
1237    */
1238   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1239     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1240     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1241     return builder.build();
1242   }
1243 
1244   /**
1245    * Creates a protocol buffer DeleteTableRequest
1246    *
1247    * @param tableName
1248    * @return a DeleteTableRequest
1249    */
1250   public static DeleteTableRequest buildDeleteTableRequest(
1251       final TableName tableName,
1252       final long nonceGroup,
1253       final long nonce) {
1254     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1255     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1256     builder.setNonceGroup(nonceGroup);
1257     builder.setNonce(nonce);
1258     return builder.build();
1259   }
1260 
1261   /**
1262    * Creates a protocol buffer TruncateTableRequest
1263    *
1264    * @param tableName name of table to truncate
1265    * @param preserveSplits True if the splits should be preserved
1266    * @return a TruncateTableRequest
1267    */
1268   public static TruncateTableRequest buildTruncateTableRequest(
1269       final TableName tableName,
1270       final boolean preserveSplits,
1271       final long nonceGroup,
1272       final long nonce) {
1273     TruncateTableRequest.Builder builder = TruncateTableRequest.newBuilder();
1274     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1275     builder.setPreserveSplits(preserveSplits);
1276     builder.setNonceGroup(nonceGroup);
1277     builder.setNonce(nonce);
1278     return builder.build();
1279   }
1280 
1281   /**
1282    * Creates a protocol buffer EnableTableRequest
1283    *
1284    * @param tableName
1285    * @return an EnableTableRequest
1286    */
1287   public static EnableTableRequest buildEnableTableRequest(
1288       final TableName tableName,
1289       final long nonceGroup,
1290       final long nonce) {
1291     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1292     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1293     builder.setNonceGroup(nonceGroup);
1294     builder.setNonce(nonce);
1295     return builder.build();
1296   }
1297 
1298   /**
1299    * Creates a protocol buffer DisableTableRequest
1300    *
1301    * @param tableName
1302    * @return a DisableTableRequest
1303    */
1304   public static DisableTableRequest buildDisableTableRequest(
1305       final TableName tableName,
1306       final long nonceGroup,
1307       final long nonce) {
1308     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1309     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1310     builder.setNonceGroup(nonceGroup);
1311     builder.setNonce(nonce);
1312     return builder.build();
1313   }
1314 
1315   /**
1316    * Creates a protocol buffer CreateTableRequest
1317    *
1318    * @param hTableDesc
1319    * @param splitKeys
1320    * @return a CreateTableRequest
1321    */
1322   public static CreateTableRequest buildCreateTableRequest(
1323       final HTableDescriptor hTableDesc,
1324       final byte [][] splitKeys,
1325       final long nonceGroup,
1326       final long nonce) {
1327     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1328     builder.setTableSchema(hTableDesc.convert());
1329     if (splitKeys != null) {
1330       for (byte [] splitKey : splitKeys) {
1331         builder.addSplitKeys(ByteStringer.wrap(splitKey));
1332       }
1333     }
1334     builder.setNonceGroup(nonceGroup);
1335     builder.setNonce(nonce);
1336     return builder.build();
1337   }
1338 
1339 
1340   /**
1341    * Creates a protocol buffer ModifyTableRequest
1342    *
1343    * @param tableName
1344    * @param hTableDesc
1345    * @return a ModifyTableRequest
1346    */
1347   public static ModifyTableRequest buildModifyTableRequest(
1348       final TableName tableName,
1349       final HTableDescriptor hTableDesc,
1350       final long nonceGroup,
1351       final long nonce) {
1352     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1353     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1354     builder.setTableSchema(hTableDesc.convert());
1355     builder.setNonceGroup(nonceGroup);
1356     builder.setNonce(nonce);
1357     return builder.build();
1358   }
1359 
1360   /**
1361    * Creates a protocol buffer GetSchemaAlterStatusRequest
1362    *
1363    * @param tableName
1364    * @return a GetSchemaAlterStatusRequest
1365    */
1366   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1367       final TableName tableName) {
1368     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1369     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1370     return builder.build();
1371   }
1372 
1373   /**
1374    * Creates a protocol buffer GetTableDescriptorsRequest
1375    *
1376    * @param tableNames
1377    * @return a GetTableDescriptorsRequest
1378    */
1379   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1380       final List<TableName> tableNames) {
1381     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1382     if (tableNames != null) {
1383       for (TableName tableName : tableNames) {
1384         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1385       }
1386     }
1387     return builder.build();
1388   }
1389 
1390   /**
1391    * Creates a protocol buffer GetTableDescriptorsRequest
1392    *
1393    * @param pattern The compiled regular expression to match against
1394    * @param includeSysTables False to match only against userspace tables
1395    * @return a GetTableDescriptorsRequest
1396    */
1397   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final Pattern pattern,
1398       boolean includeSysTables) {
1399     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1400     if (pattern != null) builder.setRegex(pattern.toString());
1401     builder.setIncludeSysTables(includeSysTables);
1402     return builder.build();
1403   }
1404 
1405   /**
1406    * Creates a protocol buffer GetTableNamesRequest
1407    *
1408    * @param pattern The compiled regular expression to match against
1409    * @param includeSysTables False to match only against userspace tables
1410    * @return a GetTableNamesRequest
1411    */
1412   public static GetTableNamesRequest buildGetTableNamesRequest(final Pattern pattern,
1413       boolean includeSysTables) {
1414     GetTableNamesRequest.Builder builder = GetTableNamesRequest.newBuilder();
1415     if (pattern != null) builder.setRegex(pattern.toString());
1416     builder.setIncludeSysTables(includeSysTables);
1417     return builder.build();
1418   }
1419 
1420   /**
1421    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1422    *
1423    * @param tableName the table name
1424    * @return a GetTableDescriptorsRequest
1425    */
1426   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1427       final TableName tableName) {
1428     return GetTableDescriptorsRequest.newBuilder()
1429       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1430       .build();
1431   }
1432 
1433   /**
1434    * Creates a protocol buffer IsMasterRunningRequest
1435    *
1436    * @return a IsMasterRunningRequest
1437    */
1438   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1439     return IsMasterRunningRequest.newBuilder().build();
1440   }
1441 
1442   /**
1443    * Creates a protocol buffer BalanceRequest
1444    *
1445    * @return a BalanceRequest
1446    */
1447   public static BalanceRequest buildBalanceRequest(boolean force) {
1448     return BalanceRequest.newBuilder().setForce(force).build();
1449   }
1450 
1451   /**
1452    * Creates a protocol buffer SetBalancerRunningRequest
1453    *
1454    * @param on
1455    * @param synchronous
1456    * @return a SetBalancerRunningRequest
1457    */
1458   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(
1459       boolean on,
1460       boolean synchronous) {
1461     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1462   }
1463 
1464   /**
1465    * Creates a protocol buffer IsBalancerEnabledRequest
1466    *
1467    * @return a IsBalancerEnabledRequest
1468    */
1469   public static IsBalancerEnabledRequest buildIsBalancerEnabledRequest() {
1470     return IsBalancerEnabledRequest.newBuilder().build();
1471   }
1472 
1473   /**
1474    * @see {@link #buildGetClusterStatusRequest}
1475    */
1476   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1477       GetClusterStatusRequest.newBuilder().build();
1478 
1479   /**
1480    * Creates a protocol buffer GetClusterStatusRequest
1481    *
1482    * @return A GetClusterStatusRequest
1483    */
1484   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1485     return GET_CLUSTER_STATUS_REQUEST;
1486   }
1487 
1488   /**
1489    * @see {@link #buildCatalogScanRequest}
1490    */
1491   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1492     RunCatalogScanRequest.newBuilder().build();
1493 
1494   /**
1495    * Creates a request for running a catalog scan
1496    * @return A {@link RunCatalogScanRequest}
1497    */
1498   public static RunCatalogScanRequest buildCatalogScanRequest() {
1499     return CATALOG_SCAN_REQUEST;
1500   }
1501 
1502   /**
1503    * Creates a request for enabling/disabling the catalog janitor
1504    * @return A {@link EnableCatalogJanitorRequest}
1505    */
1506   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1507     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1508   }
1509 
1510   /**
1511    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1512    */
1513   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1514     IsCatalogJanitorEnabledRequest.newBuilder().build();
1515 
1516   /**
1517    * Creates a request for querying the master whether the catalog janitor is enabled
1518    * @return A {@link IsCatalogJanitorEnabledRequest}
1519    */
1520   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1521     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1522   }
1523 
1524   /**
1525    * @see {@link #buildCleanerChoreRequest}
1526    */
1527   private static final RunCleanerChoreRequest CLEANER_CHORE_REQUEST = RunCleanerChoreRequest
1528       .newBuilder().build();
1529 
1530   /**
1531    * Creates a request for running cleaner chore
1532    * @return A {@link RunCleanerChoreRequest}
1533    */
1534   public static RunCleanerChoreRequest buildCleanerChoreRequest() {
1535     return CLEANER_CHORE_REQUEST;
1536   }
1537 
1538   /**
1539    * Creates a request for enabling/disabling the cleaner chore
1540    * @return A {@link SetCleanerChoreRunningRequest}
1541    */
1542   public static SetCleanerChoreRunningRequest buildSetCleanerChoreRunningRequest(boolean on) {
1543     return SetCleanerChoreRunningRequest.newBuilder().setOn(on).build();
1544   }
1545 
1546   /**
1547    * @see {@link #buildIsCleanerChoreEnabledRequest()}
1548    */
1549   private static final IsCleanerChoreEnabledRequest IS_CLEANER_CHORE_ENABLED_REQUEST =
1550     IsCleanerChoreEnabledRequest.newBuilder().build();
1551 
1552   /**
1553    * Creates a request for querying the master whether the cleaner chore is enabled
1554    * @return A {@link IsCleanerChoreEnabledRequest}
1555    */
1556   public static IsCleanerChoreEnabledRequest buildIsCleanerChoreEnabledRequest() {
1557     return IS_CLEANER_CHORE_ENABLED_REQUEST;
1558   }
1559 
1560   /**
1561    * Creates a request for querying the master the last flushed sequence Id for a region
1562    * @param regionName
1563    * @return A {@link GetLastFlushedSequenceIdRequest}
1564    */
1565   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1566       byte[] regionName) {
1567     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1568         ByteStringer.wrap(regionName)).build();
1569   }
1570 
1571   /**
1572    * Create a request to grant user permissions.
1573    *
1574    * @param username the short user name who to grant permissions
1575    * @param actions the permissions to be granted
1576    * @return A {@link AccessControlProtos} GrantRequest
1577    */
1578   public static AccessControlProtos.GrantRequest buildGrantRequest(String username,
1579       boolean mergeExistingPermissions, AccessControlProtos.Permission.Action... actions) {
1580     AccessControlProtos.Permission.Builder ret =
1581         AccessControlProtos.Permission.newBuilder();
1582     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1583         AccessControlProtos.GlobalPermission.newBuilder();
1584     for (AccessControlProtos.Permission.Action a : actions) {
1585       permissionBuilder.addAction(a);
1586     }
1587     ret.setType(AccessControlProtos.Permission.Type.Global)
1588        .setGlobalPermission(permissionBuilder);
1589     return AccessControlProtos.GrantRequest.newBuilder()
1590         .setUserPermission(AccessControlProtos.UserPermission.newBuilder()
1591             .setUser(ByteString.copyFromUtf8(username)).setPermission(ret))
1592         .setMergeExistingPermissions(mergeExistingPermissions).build();
1593   }
1594 
1595   /**
1596    * Create a request to grant user permissions.
1597    *
1598    * @param username the short user name who to grant permissions
1599    * @param tableName optional table name the permissions apply
1600    * @param family optional column family
1601    * @param qualifier optional qualifier
1602    * @param actions the permissions to be granted
1603    * @return A {@link AccessControlProtos} GrantRequest
1604    */
1605   public static AccessControlProtos.GrantRequest buildGrantRequest(
1606       String username, TableName tableName, byte[] family, byte[] qualifier, boolean mergeExistingPermissions,
1607       AccessControlProtos.Permission.Action... actions) {
1608     AccessControlProtos.Permission.Builder ret =
1609         AccessControlProtos.Permission.newBuilder();
1610     AccessControlProtos.TablePermission.Builder permissionBuilder =
1611         AccessControlProtos.TablePermission.newBuilder();
1612     for (AccessControlProtos.Permission.Action a : actions) {
1613       permissionBuilder.addAction(a);
1614     }
1615     if (tableName == null) {
1616       throw new NullPointerException("TableName cannot be null");
1617     }
1618     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1619 
1620     if (family != null) {
1621       permissionBuilder.setFamily(ByteStringer.wrap(family));
1622     }
1623     if (qualifier != null) {
1624       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1625     }
1626     ret.setType(AccessControlProtos.Permission.Type.Table)
1627        .setTablePermission(permissionBuilder);
1628     return AccessControlProtos.GrantRequest.newBuilder()
1629       .setUserPermission(
1630           AccessControlProtos.UserPermission.newBuilder()
1631               .setUser(ByteString.copyFromUtf8(username))
1632               .setPermission(ret)
1633       ).setMergeExistingPermissions(mergeExistingPermissions).build();
1634   }
1635 
1636   /**
1637    * Create a request to grant user permissions.
1638    *
1639    * @param username the short user name who to grant permissions
1640    * @param namespace optional table name the permissions apply
1641    * @param actions the permissions to be granted
1642    * @return A {@link AccessControlProtos} GrantRequest
1643    */
1644   public static AccessControlProtos.GrantRequest buildGrantRequest(String username,
1645       String namespace, boolean mergeExistingPermissions,
1646       AccessControlProtos.Permission.Action... actions) {
1647     AccessControlProtos.Permission.Builder ret =
1648         AccessControlProtos.Permission.newBuilder();
1649     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1650         AccessControlProtos.NamespacePermission.newBuilder();
1651     for (AccessControlProtos.Permission.Action a : actions) {
1652       permissionBuilder.addAction(a);
1653     }
1654     if (namespace != null) {
1655       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1656     }
1657     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1658        .setNamespacePermission(permissionBuilder);
1659     return AccessControlProtos.GrantRequest.newBuilder()
1660         .setUserPermission(AccessControlProtos.UserPermission.newBuilder()
1661             .setUser(ByteString.copyFromUtf8(username)).setPermission(ret))
1662         .setMergeExistingPermissions(mergeExistingPermissions).build();
1663   }
1664 
1665   /**
1666    * Create a request to revoke user permissions.
1667    *
1668    * @param username the short user name whose permissions to be revoked
1669    * @param actions the permissions to be revoked
1670    * @return A {@link AccessControlProtos} RevokeRequest
1671    */
1672   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1673       String username, AccessControlProtos.Permission.Action... actions) {
1674     AccessControlProtos.Permission.Builder ret =
1675         AccessControlProtos.Permission.newBuilder();
1676     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1677         AccessControlProtos.GlobalPermission.newBuilder();
1678     for (AccessControlProtos.Permission.Action a : actions) {
1679       permissionBuilder.addAction(a);
1680     }
1681     ret.setType(AccessControlProtos.Permission.Type.Global)
1682        .setGlobalPermission(permissionBuilder);
1683     return AccessControlProtos.RevokeRequest.newBuilder()
1684       .setUserPermission(
1685           AccessControlProtos.UserPermission.newBuilder()
1686               .setUser(ByteString.copyFromUtf8(username))
1687               .setPermission(ret)
1688       ).build();
1689   }
1690 
1691   /**
1692    * Create a request to revoke user permissions.
1693    *
1694    * @param username the short user name whose permissions to be revoked
1695    * @param tableName optional table name the permissions apply
1696    * @param family optional column family
1697    * @param qualifier optional qualifier
1698    * @param actions the permissions to be revoked
1699    * @return A {@link AccessControlProtos} RevokeRequest
1700    */
1701   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1702       String username, TableName tableName, byte[] family, byte[] qualifier,
1703       AccessControlProtos.Permission.Action... actions) {
1704     AccessControlProtos.Permission.Builder ret =
1705         AccessControlProtos.Permission.newBuilder();
1706     AccessControlProtos.TablePermission.Builder permissionBuilder =
1707         AccessControlProtos.TablePermission.newBuilder();
1708     for (AccessControlProtos.Permission.Action a : actions) {
1709       permissionBuilder.addAction(a);
1710     }
1711     if (tableName != null) {
1712       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1713     }
1714     if (family != null) {
1715       permissionBuilder.setFamily(ByteStringer.wrap(family));
1716     }
1717     if (qualifier != null) {
1718       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1719     }
1720     ret.setType(AccessControlProtos.Permission.Type.Table)
1721        .setTablePermission(permissionBuilder);
1722     return AccessControlProtos.RevokeRequest.newBuilder()
1723       .setUserPermission(
1724           AccessControlProtos.UserPermission.newBuilder()
1725               .setUser(ByteString.copyFromUtf8(username))
1726               .setPermission(ret)
1727       ).build();
1728   }
1729 
1730   /**
1731    * Create a request to revoke user permissions.
1732    *
1733    * @param username the short user name whose permissions to be revoked
1734    * @param namespace optional table name the permissions apply
1735    * @param actions the permissions to be revoked
1736    * @return A {@link AccessControlProtos} RevokeRequest
1737    */
1738   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1739       String username, String namespace,
1740       AccessControlProtos.Permission.Action... actions) {
1741     AccessControlProtos.Permission.Builder ret =
1742         AccessControlProtos.Permission.newBuilder();
1743     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1744         AccessControlProtos.NamespacePermission.newBuilder();
1745     for (AccessControlProtos.Permission.Action a : actions) {
1746       permissionBuilder.addAction(a);
1747     }
1748     if (namespace != null) {
1749       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1750     }
1751     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1752        .setNamespacePermission(permissionBuilder);
1753     return AccessControlProtos.RevokeRequest.newBuilder()
1754       .setUserPermission(
1755           AccessControlProtos.UserPermission.newBuilder()
1756               .setUser(ByteString.copyFromUtf8(username))
1757               .setPermission(ret)
1758       ).build();
1759   }
1760 
1761   /**
1762    * Create a RegionOpenInfo based on given region info and version of offline node
1763    */
1764   private static RegionOpenInfo buildRegionOpenInfo(
1765       final HRegionInfo region, final int versionOfOfflineNode,
1766       final List<ServerName> favoredNodes, Boolean openForReplay) {
1767     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1768     builder.setRegion(HRegionInfo.convert(region));
1769     if (versionOfOfflineNode >= 0) {
1770       builder.setVersionOfOfflineNode(versionOfOfflineNode);
1771     }
1772     if (favoredNodes != null) {
1773       for (ServerName server : favoredNodes) {
1774         builder.addFavoredNodes(ProtobufUtil.toServerName(server));
1775       }
1776     }
1777     if(openForReplay != null) {
1778       builder.setOpenForDistributedLogReplay(openForReplay);
1779     }
1780     return builder.build();
1781   }
1782 
1783   /**
1784    * Creates a protocol buffer NormalizeRequest
1785    *
1786    * @return a NormalizeRequest
1787    */
1788   public static NormalizeRequest buildNormalizeRequest() {
1789     return NormalizeRequest.newBuilder().build();
1790   }
1791 
1792   /**
1793    * Creates a protocol buffer IsNormalizerEnabledRequest
1794    *
1795    * @return a IsNormalizerEnabledRequest
1796    */
1797   public static IsNormalizerEnabledRequest buildIsNormalizerEnabledRequest() {
1798     return IsNormalizerEnabledRequest.newBuilder().build();
1799   }
1800 
1801   /**
1802    * Creates a protocol buffer SetNormalizerRunningRequest
1803    *
1804    * @param on
1805    * @return a SetNormalizerRunningRequest
1806    */
1807   public static SetNormalizerRunningRequest buildSetNormalizerRunningRequest(boolean on) {
1808     return SetNormalizerRunningRequest.newBuilder().setOn(on).build();
1809   }
1810 
1811   /**
1812    * Creates a protocol buffer IsSplitOrMergeEnabledRequest
1813    *
1814    * @param switchType see {@link org.apache.hadoop.hbase.client.Admin.MasterSwitchType}
1815    * @return a IsSplitOrMergeEnabledRequest
1816    */
1817   public static IsSplitOrMergeEnabledRequest buildIsSplitOrMergeEnabledRequest(
1818     Admin.MasterSwitchType switchType) {
1819     IsSplitOrMergeEnabledRequest.Builder builder = IsSplitOrMergeEnabledRequest.newBuilder();
1820     builder.setSwitchType(convert(switchType));
1821     return builder.build();
1822   }
1823 
1824   /**
1825    * Creates a protocol buffer SetSplitOrMergeEnabledRequest
1826    *
1827    * @param enabled switch is enabled or not
1828    * @param synchronous set switch sync?
1829    * @param switchTypes see {@link org.apache.hadoop.hbase.client.Admin.MasterSwitchType}, it is
1830    *                    a list.
1831    * @return a SetSplitOrMergeEnabledRequest
1832    */
1833   public static SetSplitOrMergeEnabledRequest buildSetSplitOrMergeEnabledRequest(boolean enabled,
1834     boolean synchronous, Admin.MasterSwitchType... switchTypes) {
1835     SetSplitOrMergeEnabledRequest.Builder builder = SetSplitOrMergeEnabledRequest.newBuilder();
1836     builder.setEnabled(enabled);
1837     builder.setSynchronous(synchronous);
1838     for (Admin.MasterSwitchType switchType : switchTypes) {
1839       builder.addSwitchTypes(convert(switchType));
1840     }
1841     return builder.build();
1842   }
1843 
1844   public static ClearDeadServersRequest buildClearDeadServersRequest(List<ServerName> deadServers) {
1845     ClearDeadServersRequest.Builder builder = ClearDeadServersRequest.newBuilder();
1846     for(ServerName server: deadServers) {
1847       builder.addServerName(ProtobufUtil.toServerName(server));
1848     }
1849     return builder.build();
1850   }
1851 
1852   private static MasterProtos.MasterSwitchType convert(Admin.MasterSwitchType switchType) {
1853     switch (switchType) {
1854       case SPLIT:
1855         return MasterProtos.MasterSwitchType.SPLIT;
1856       case MERGE:
1857         return MasterProtos.MasterSwitchType.MERGE;
1858       default:
1859         break;
1860     }
1861     throw new UnsupportedOperationException("Unsupport switch type:" + switchType);
1862   }
1863 
1864 
1865   /**
1866    * Creates SetSnapshotCleanupRequest for turning on/off auto snapshot cleanup
1867    *
1868    * @param enabled Set to <code>true</code> to enable,
1869    *   <code>false</code> to disable.
1870    * @param synchronous If <code>true</code>, it waits until current snapshot cleanup is completed,
1871    *   if outstanding.
1872    * @return a SetSnapshotCleanupRequest
1873    */
1874   public static SetSnapshotCleanupRequest buildSetSnapshotCleanupRequest(
1875     final boolean enabled, final boolean synchronous) {
1876     return SetSnapshotCleanupRequest.newBuilder().setEnabled(enabled).setSynchronous(synchronous)
1877       .build();
1878   }
1879 
1880   /**
1881    * Creates IsSnapshotCleanupEnabledRequest to determine if auto snapshot cleanup
1882    * based on TTL expiration is turned on
1883    *
1884    * @return IsSnapshotCleanupEnabledRequest
1885    */
1886   public static IsSnapshotCleanupEnabledRequest buildIsSnapshotCleanupEnabledRequest() {
1887     return IsSnapshotCleanupEnabledRequest.newBuilder().build();
1888   }
1889 
1890   /**
1891    * Build RPC request payload for getLogEntries
1892    *
1893    * @param filterParams map of filter params
1894    * @param limit limit for no of records that server returns
1895    * @param logType type of the log records
1896    * @return request payload HBaseProtos.LogRequest
1897    */
1898   public static HBaseProtos.LogRequest buildSlowLogResponseRequest(
1899       final Map<String, Object> filterParams, final int limit, final String logType) {
1900     SlowLogResponseRequest.Builder builder = SlowLogResponseRequest.newBuilder();
1901     builder.setLimit(limit);
1902     if (logType.equals("SLOW_LOG")) {
1903       builder.setLogType(SlowLogResponseRequest.LogType.SLOW_LOG);
1904     } else if (logType.equals("LARGE_LOG")) {
1905       builder.setLogType(SlowLogResponseRequest.LogType.LARGE_LOG);
1906     }
1907     boolean filterByAnd = false;
1908     if (MapUtils.isNotEmpty(filterParams)) {
1909       if (filterParams.containsKey("clientAddress")) {
1910         final String clientAddress = (String) filterParams.get("clientAddress");
1911         if (StringUtils.isNotEmpty(clientAddress)) {
1912           builder.setClientAddress(clientAddress);
1913         }
1914       }
1915       if (filterParams.containsKey("regionName")) {
1916         final String regionName = (String) filterParams.get("regionName");
1917         if (StringUtils.isNotEmpty(regionName)) {
1918           builder.setRegionName(regionName);
1919         }
1920       }
1921       if (filterParams.containsKey("tableName")) {
1922         final String tableName = (String) filterParams.get("tableName");
1923         if (StringUtils.isNotEmpty(tableName)) {
1924           builder.setTableName(tableName);
1925         }
1926       }
1927       if (filterParams.containsKey("userName")) {
1928         final String userName = (String) filterParams.get("userName");
1929         if (StringUtils.isNotEmpty(userName)) {
1930           builder.setUserName(userName);
1931         }
1932       }
1933       if (filterParams.containsKey("filterByOperator")) {
1934         final String filterByOperator = (String) filterParams.get("filterByOperator");
1935         if (StringUtils.isNotEmpty(filterByOperator)) {
1936           if (filterByOperator.toUpperCase().equals("AND")) {
1937             filterByAnd = true;
1938           }
1939         }
1940       }
1941     }
1942     if (filterByAnd) {
1943       builder.setFilterByOperator(SlowLogResponseRequest.FilterByOperator.AND);
1944     } else {
1945       builder.setFilterByOperator(SlowLogResponseRequest.FilterByOperator.OR);
1946     }
1947     SlowLogResponseRequest slowLogResponseRequest = builder.build();
1948     return HBaseProtos.LogRequest.newBuilder()
1949       .setLogClassName(slowLogResponseRequest.getClass().getName())
1950       .setLogMessage(slowLogResponseRequest.toByteString())
1951       .build();
1952   }
1953 
1954   /**
1955    * Create a protocol buffer {@link ClearSlowLogResponseRequest}
1956    *
1957    * @return a protocol buffer ClearSlowLogResponseRequest
1958    */
1959   public static ClearSlowLogResponseRequest buildClearSlowLogResponseRequest() {
1960     return ClearSlowLogResponseRequest.newBuilder().build();
1961   }
1962 
1963 }