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