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