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