View Javadoc

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