View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.protobuf;
19  
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.regex.Pattern;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.CellScannable;
26  import org.apache.hadoop.hbase.DoNotRetryIOException;
27  import org.apache.hadoop.hbase.HColumnDescriptor;
28  import org.apache.hadoop.hbase.HConstants;
29  import org.apache.hadoop.hbase.HRegionInfo;
30  import org.apache.hadoop.hbase.HTableDescriptor;
31  import org.apache.hadoop.hbase.ServerName;
32  import org.apache.hadoop.hbase.TableName;
33  import org.apache.hadoop.hbase.client.Action;
34  import org.apache.hadoop.hbase.client.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.WarmupRegionRequest;
50  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
51  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest;
63  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.UpdateFavoredNodesRequest.RegionUpdateInfo;
64  import org.apache.hadoop.hbase.protobuf.generated.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.IsBalancerEnabledRequest;
95  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
96  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
97  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyColumnRequest;
98  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.ModifyTableRequest;
99  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest;
100 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
101 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
102 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
103 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.TruncateTableRequest;
104 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.UnassignRegionRequest;
105 import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest;
106 import org.apache.hadoop.hbase.util.ByteStringer;
107 import org.apache.hadoop.hbase.util.Bytes;
108 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
109 import org.apache.hadoop.hbase.util.Pair;
110 import org.apache.hadoop.hbase.util.Triple;
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,
483       final Scan scan, final int numberOfRows,
484         final boolean closeScanner) throws IOException {
485     ScanRequest.Builder builder = ScanRequest.newBuilder();
486     RegionSpecifier region = buildRegionSpecifier(
487       RegionSpecifierType.REGION_NAME, regionName);
488     builder.setNumberOfRows(numberOfRows);
489     builder.setCloseScanner(closeScanner);
490     builder.setRegion(region);
491     builder.setScan(ProtobufUtil.toScan(scan));
492     builder.setClientHandlesPartials(true);
493     builder.setClientHandlesHeartbeats(true);
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,
506       final int numberOfRows, final boolean closeScanner) {
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     return builder.build();
514   }
515 
516   /**
517    * Create a protocol buffer ScanRequest for a scanner id
518    *
519    * @param scannerId
520    * @param numberOfRows
521    * @param closeScanner
522    * @param nextCallSeq
523    * @return a scan request
524    */
525   public static ScanRequest buildScanRequest(final long scannerId, final int numberOfRows,
526       final boolean closeScanner, final long nextCallSeq, final boolean renew) {
527     ScanRequest.Builder builder = ScanRequest.newBuilder();
528     builder.setNumberOfRows(numberOfRows);
529     builder.setCloseScanner(closeScanner);
530     builder.setScannerId(scannerId);
531     builder.setNextCallSeq(nextCallSeq);
532     builder.setClientHandlesPartials(true);
533     builder.setClientHandlesHeartbeats(true);
534     builder.setRenew(renew);
535     return builder.build();
536   }
537 
538   /**
539    * Create a protocol buffer bulk load request
540    *
541    * @param familyPaths
542    * @param regionName
543    * @param assignSeqNum
544    * @return a bulk load request
545    */
546   public static BulkLoadHFileRequest buildBulkLoadHFileRequest(
547       final List<Pair<byte[], String>> familyPaths,
548       final byte[] regionName, boolean assignSeqNum) {
549     BulkLoadHFileRequest.Builder builder = BulkLoadHFileRequest.newBuilder();
550     RegionSpecifier region = buildRegionSpecifier(
551       RegionSpecifierType.REGION_NAME, regionName);
552     builder.setRegion(region);
553     FamilyPath.Builder familyPathBuilder = FamilyPath.newBuilder();
554     for (Pair<byte[], String> familyPath: familyPaths) {
555       familyPathBuilder.setFamily(ByteStringer.wrap(familyPath.getFirst()));
556       familyPathBuilder.setPath(familyPath.getSecond());
557       builder.addFamilyPath(familyPathBuilder.build());
558     }
559     builder.setAssignSeqNum(assignSeqNum);
560     return builder.build();
561   }
562 
563   /**
564    * Create a protocol buffer multi request for a list of actions.
565    * Propagates Actions original index.
566    *
567    * @param regionName
568    * @param actions
569    * @return a multi request
570    * @throws IOException
571    */
572   public static <R> RegionAction.Builder buildRegionAction(final byte[] regionName,
573       final List<Action<R>> actions, final RegionAction.Builder regionActionBuilder,
574       final ClientProtos.Action.Builder actionBuilder,
575       final MutationProto.Builder mutationBuilder) throws IOException {
576     for (Action<R> action: actions) {
577       Row row = action.getAction();
578       actionBuilder.clear();
579       actionBuilder.setIndex(action.getOriginalIndex());
580       mutationBuilder.clear();
581       if (row instanceof Get) {
582         Get g = (Get)row;
583         regionActionBuilder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
584       } else if (row instanceof Put) {
585         regionActionBuilder.addAction(actionBuilder.
586           setMutation(ProtobufUtil.toMutation(MutationType.PUT, (Put)row, mutationBuilder)));
587       } else if (row instanceof Delete) {
588         regionActionBuilder.addAction(actionBuilder.
589           setMutation(ProtobufUtil.toMutation(MutationType.DELETE, (Delete)row, mutationBuilder)));
590       } else if (row instanceof Append) {
591         regionActionBuilder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutation(
592             MutationType.APPEND, (Append)row, mutationBuilder, action.getNonce())));
593       } else if (row instanceof Increment) {
594         regionActionBuilder.addAction(actionBuilder.setMutation(
595             ProtobufUtil.toMutation((Increment)row, mutationBuilder, action.getNonce())));
596       } else if (row instanceof RegionCoprocessorServiceExec) {
597         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
598         regionActionBuilder.addAction(actionBuilder.setServiceCall(
599             ClientProtos.CoprocessorServiceCall.newBuilder()
600               .setRow(ByteStringer.wrap(exec.getRow()))
601               .setServiceName(exec.getMethod().getService().getFullName())
602               .setMethodName(exec.getMethod().getName())
603               .setRequest(exec.getRequest().toByteString())));
604       } else if (row instanceof RowMutations) {
605         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
606       } else {
607         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
608       }
609     }
610     return regionActionBuilder;
611   }
612 
613   /**
614    * Create a protocol buffer multirequest with NO data for a list of actions (data is carried
615    * otherwise than via protobuf).  This means it just notes attributes, whether to write the
616    * WAL, etc., and the presence in protobuf serves as place holder for the data which is
617    * coming along otherwise.  Note that Get is different.  It does not contain 'data' and is always
618    * carried by protobuf.  We return references to the data by adding them to the passed in
619    * <code>data</code> param.
620    *
621    * <p>Propagates Actions original index.
622    *
623    * @param regionName
624    * @param actions
625    * @param cells Place to stuff references to actual data.
626    * @return a multi request that does not carry any data.
627    * @throws IOException
628    */
629   public static <R> RegionAction.Builder buildNoDataRegionAction(final byte[] regionName,
630       final List<Action<R>> actions, final List<CellScannable> cells,
631       final RegionAction.Builder regionActionBuilder,
632       final ClientProtos.Action.Builder actionBuilder,
633       final MutationProto.Builder mutationBuilder) throws IOException {
634     RegionAction.Builder builder = getRegionActionBuilderWithRegion(
635       RegionAction.newBuilder(), regionName);
636     for (Action<R> action: actions) {
637       Row row = action.getAction();
638       actionBuilder.clear();
639       actionBuilder.setIndex(action.getOriginalIndex());
640       mutationBuilder.clear();
641       if (row instanceof Get) {
642         Get g = (Get)row;
643         builder.addAction(actionBuilder.setGet(ProtobufUtil.toGet(g)));
644       } else if (row instanceof Put) {
645         Put p = (Put)row;
646         cells.add(p);
647         builder.addAction(actionBuilder.
648           setMutation(ProtobufUtil.toMutationNoData(MutationType.PUT, p, mutationBuilder)));
649       } else if (row instanceof Delete) {
650         Delete d = (Delete)row;
651         int size = d.size();
652         // Note that a legitimate Delete may have a size of zero; i.e. a Delete that has nothing
653         // in it but the row to delete.  In this case, the current implementation does not make
654         // a KeyValue to represent a delete-of-all-the-row until we serialize... For such cases
655         // where the size returned is zero, we will send the Delete fully pb'd rather than have
656         // metadata only in the pb and then send the kv along the side in cells.
657         if (size > 0) {
658           cells.add(d);
659           builder.addAction(actionBuilder.
660             setMutation(ProtobufUtil.toMutationNoData(MutationType.DELETE, d, mutationBuilder)));
661         } else {
662           builder.addAction(actionBuilder.
663             setMutation(ProtobufUtil.toMutation(MutationType.DELETE, d, mutationBuilder)));
664         }
665       } else if (row instanceof Append) {
666         Append a = (Append)row;
667         cells.add(a);
668         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
669           MutationType.APPEND, a, mutationBuilder, action.getNonce())));
670       } else if (row instanceof Increment) {
671         Increment i = (Increment)row;
672         cells.add(i);
673         builder.addAction(actionBuilder.setMutation(ProtobufUtil.toMutationNoData(
674           MutationType.INCREMENT, i, mutationBuilder, action.getNonce())));
675       } else if (row instanceof RegionCoprocessorServiceExec) {
676         RegionCoprocessorServiceExec exec = (RegionCoprocessorServiceExec) row;
677         builder.addAction(actionBuilder.setServiceCall(ClientProtos.CoprocessorServiceCall
678             .newBuilder().setRow(ByteStringer.wrap(exec.getRow()))
679             .setServiceName(exec.getMethod().getService().getFullName())
680             .setMethodName(exec.getMethod().getName())
681             .setRequest(exec.getRequest().toByteString())));
682       } else if (row instanceof RowMutations) {
683         throw new UnsupportedOperationException("No RowMutations in multi calls; use mutateRow");
684       } else {
685         throw new DoNotRetryIOException("Multi doesn't support " + row.getClass().getName());
686       }
687     }
688     return builder;
689   }
690 
691 // End utilities for Client
692 //Start utilities for Admin
693 
694   /**
695    * Create a protocol buffer GetRegionInfoRequest for a given region name
696    *
697    * @param regionName the name of the region to get info
698    * @return a protocol buffer GetRegionInfoRequest
699    */
700   public static GetRegionInfoRequest
701       buildGetRegionInfoRequest(final byte[] regionName) {
702     return buildGetRegionInfoRequest(regionName, false);
703   }
704 
705   /**
706    * Create a protocol buffer GetRegionInfoRequest for a given region name
707    *
708    * @param regionName the name of the region to get info
709    * @param includeCompactionState indicate if the compaction state is requested
710    * @return a protocol buffer GetRegionInfoRequest
711    */
712   public static GetRegionInfoRequest
713       buildGetRegionInfoRequest(final byte[] regionName,
714         final boolean includeCompactionState) {
715     GetRegionInfoRequest.Builder builder = GetRegionInfoRequest.newBuilder();
716     RegionSpecifier region = buildRegionSpecifier(
717       RegionSpecifierType.REGION_NAME, regionName);
718     builder.setRegion(region);
719     if (includeCompactionState) {
720       builder.setCompactionState(includeCompactionState);
721     }
722     return builder.build();
723   }
724 
725  /**
726   * Create a protocol buffer GetStoreFileRequest for a given region name
727   *
728   * @param regionName the name of the region to get info
729   * @param family the family to get store file list
730   * @return a protocol buffer GetStoreFileRequest
731   */
732  public static GetStoreFileRequest
733      buildGetStoreFileRequest(final byte[] regionName, final byte[] family) {
734    GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder();
735    RegionSpecifier region = buildRegionSpecifier(
736      RegionSpecifierType.REGION_NAME, regionName);
737    builder.setRegion(region);
738    builder.addFamily(ByteStringer.wrap(family));
739    return builder.build();
740  }
741 
742  /**
743   * Create a protocol buffer GetOnlineRegionRequest
744   *
745   * @return a protocol buffer GetOnlineRegionRequest
746   */
747  public static GetOnlineRegionRequest buildGetOnlineRegionRequest() {
748    return GetOnlineRegionRequest.newBuilder().build();
749  }
750 
751  /**
752   * Create a protocol buffer FlushRegionRequest for a given region name
753   *
754   * @param regionName the name of the region to get info
755   * @return a protocol buffer FlushRegionRequest
756   */
757  public static FlushRegionRequest
758      buildFlushRegionRequest(final byte[] regionName) {
759    return buildFlushRegionRequest(regionName, false);
760  }
761 
762  /**
763   * Create a protocol buffer FlushRegionRequest for a given region name
764   *
765   * @param regionName the name of the region to get info
766   * @return a protocol buffer FlushRegionRequest
767   */
768  public static FlushRegionRequest
769      buildFlushRegionRequest(final byte[] regionName, boolean writeFlushWALMarker) {
770    FlushRegionRequest.Builder builder = FlushRegionRequest.newBuilder();
771    RegionSpecifier region = buildRegionSpecifier(
772      RegionSpecifierType.REGION_NAME, regionName);
773    builder.setRegion(region);
774    builder.setWriteFlushWalMarker(writeFlushWALMarker);
775    return builder.build();
776  }
777 
778  /**
779   * Create a protocol buffer OpenRegionRequest to open a list of regions
780   *
781   * @param server the serverName for the RPC
782   * @param regionOpenInfos info of a list of regions to open
783   * @param openForReplay
784   * @return a protocol buffer OpenRegionRequest
785   */
786  public static OpenRegionRequest
787      buildOpenRegionRequest(ServerName server, final List<Triple<HRegionInfo, Integer,
788          List<ServerName>>> regionOpenInfos, Boolean openForReplay) {
789    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
790    for (Triple<HRegionInfo, Integer, List<ServerName>> regionOpenInfo: regionOpenInfos) {
791      Integer second = regionOpenInfo.getSecond();
792      int versionOfOfflineNode = second == null ? -1 : second.intValue();
793      builder.addOpenInfo(buildRegionOpenInfo(regionOpenInfo.getFirst(), versionOfOfflineNode,
794        regionOpenInfo.getThird(), openForReplay));
795    }
796    if (server != null) {
797      builder.setServerStartCode(server.getStartcode());
798    }
799    // send the master's wall clock time as well, so that the RS can refer to it
800    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
801    return builder.build();
802  }
803 
804  /**
805   * Create a protocol buffer OpenRegionRequest for a given region
806   *
807   * @param server the serverName for the RPC
808   * @param region the region to open
809   * @param versionOfOfflineNode that needs to be present in the offline node
810   * @param favoredNodes
811   * @param openForReplay
812   * @return a protocol buffer OpenRegionRequest
813   */
814  public static OpenRegionRequest buildOpenRegionRequest(ServerName server,
815      final HRegionInfo region, final int versionOfOfflineNode, List<ServerName> favoredNodes,
816      Boolean openForReplay) {
817    OpenRegionRequest.Builder builder = OpenRegionRequest.newBuilder();
818    builder.addOpenInfo(buildRegionOpenInfo(region, versionOfOfflineNode, favoredNodes,
819      openForReplay));
820    if (server != null) {
821      builder.setServerStartCode(server.getStartcode());
822    }
823    builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
824    return builder.build();
825  }
826 
827  /**
828   * Create a protocol buffer UpdateFavoredNodesRequest to update a list of favorednode mappings
829   * @param updateRegionInfos
830   * @return a protocol buffer UpdateFavoredNodesRequest
831   */
832  public static UpdateFavoredNodesRequest buildUpdateFavoredNodesRequest(
833      final List<Pair<HRegionInfo, List<ServerName>>> updateRegionInfos) {
834    UpdateFavoredNodesRequest.Builder ubuilder = UpdateFavoredNodesRequest.newBuilder();
835    for (Pair<HRegionInfo, List<ServerName>> pair : updateRegionInfos) {
836      RegionUpdateInfo.Builder builder = RegionUpdateInfo.newBuilder();
837      builder.setRegion(HRegionInfo.convert(pair.getFirst()));
838      for (ServerName server : pair.getSecond()) {
839        builder.addFavoredNodes(ProtobufUtil.toServerName(server));
840      }
841      ubuilder.addUpdateInfo(builder.build());
842    }
843    return ubuilder.build();
844  }
845 
846  /**
847   * Create a CloseRegionRequest for a given region name
848   *
849   * @param regionName the name of the region to close
850   * @param transitionInZK indicator if to transition in ZK
851   * @return a CloseRegionRequest
852   */
853  public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
854      final byte[] regionName, final boolean transitionInZK) {
855    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
856    RegionSpecifier region = buildRegionSpecifier(
857      RegionSpecifierType.REGION_NAME, regionName);
858    builder.setRegion(region);
859    builder.setTransitionInZK(transitionInZK);
860    if (server != null) {
861      builder.setServerStartCode(server.getStartcode());
862    }
863    return builder.build();
864  }
865 
866   public static CloseRegionRequest buildCloseRegionRequest(ServerName server,
867     final byte[] regionName, final int versionOfClosingNode,
868     ServerName destinationServer, final boolean transitionInZK) {
869     CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
870     RegionSpecifier region = buildRegionSpecifier(
871       RegionSpecifierType.REGION_NAME, regionName);
872     builder.setRegion(region);
873     builder.setVersionOfClosingNode(versionOfClosingNode);
874     builder.setTransitionInZK(transitionInZK);
875     if (destinationServer != null){
876       builder.setDestinationServer(ProtobufUtil.toServerName( destinationServer) );
877     }
878     if (server != null) {
879       builder.setServerStartCode(server.getStartcode());
880     }
881     return builder.build();
882   }
883 
884   /**
885    *  Create a WarmupRegionRequest for a given region name
886    *
887    *  @param regionInfo Region we are warming up
888    */
889   public static WarmupRegionRequest buildWarmupRegionRequest(final HRegionInfo regionInfo) {
890     WarmupRegionRequest.Builder builder = WarmupRegionRequest.newBuilder();
891     builder.setRegionInfo(HRegionInfo.convert(regionInfo));
892     return builder.build();
893   }
894  /**
895   * Create a CloseRegionRequest for a given encoded region name
896   *
897   * @param encodedRegionName the name of the region to close
898   * @param transitionInZK indicator if to transition in ZK
899   * @return a CloseRegionRequest
900   */
901  public static CloseRegionRequest
902      buildCloseRegionRequest(ServerName server, final String encodedRegionName,
903        final boolean transitionInZK) {
904    CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder();
905    RegionSpecifier region = buildRegionSpecifier(
906      RegionSpecifierType.ENCODED_REGION_NAME,
907      Bytes.toBytes(encodedRegionName));
908    builder.setRegion(region);
909    builder.setTransitionInZK(transitionInZK);
910    if (server != null) {
911      builder.setServerStartCode(server.getStartcode());
912    }
913    return builder.build();
914  }
915 
916  /**
917   * Create a SplitRegionRequest for a given region name
918   *
919   * @param regionName the name of the region to split
920   * @param splitPoint the split point
921   * @return a SplitRegionRequest
922   */
923  public static SplitRegionRequest buildSplitRegionRequest(
924      final byte[] regionName, final byte[] splitPoint) {
925    SplitRegionRequest.Builder builder = SplitRegionRequest.newBuilder();
926    RegionSpecifier region = buildRegionSpecifier(
927      RegionSpecifierType.REGION_NAME, regionName);
928    builder.setRegion(region);
929    if (splitPoint != null) {
930      builder.setSplitPoint(ByteStringer.wrap(splitPoint));
931    }
932    return builder.build();
933  }
934 
935   /**
936    * Create a MergeRegionsRequest for the given regions
937    * @param regionA name of region a
938    * @param regionB name of region b
939    * @param forcible true if it is a compulsory merge
940    * @return a MergeRegionsRequest
941    */
942   public static MergeRegionsRequest buildMergeRegionsRequest(
943       final byte[] regionA, final byte[] regionB, final boolean forcible) {
944     MergeRegionsRequest.Builder builder = MergeRegionsRequest.newBuilder();
945     RegionSpecifier regionASpecifier = buildRegionSpecifier(
946         RegionSpecifierType.REGION_NAME, regionA);
947     RegionSpecifier regionBSpecifier = buildRegionSpecifier(
948         RegionSpecifierType.REGION_NAME, regionB);
949     builder.setRegionA(regionASpecifier);
950     builder.setRegionB(regionBSpecifier);
951     builder.setForcible(forcible);
952     // send the master's wall clock time as well, so that the RS can refer to it
953     builder.setMasterSystemTime(EnvironmentEdgeManager.currentTime());
954     return builder.build();
955   }
956 
957  /**
958   * Create a  CompactRegionRequest for a given region name
959   *
960   * @param regionName the name of the region to get info
961   * @param major indicator if it is a major compaction
962   * @return a CompactRegionRequest
963   */
964  public static CompactRegionRequest buildCompactRegionRequest(
965      final byte[] regionName, final boolean major, final byte [] family) {
966    CompactRegionRequest.Builder builder = CompactRegionRequest.newBuilder();
967    RegionSpecifier region = buildRegionSpecifier(
968      RegionSpecifierType.REGION_NAME, regionName);
969    builder.setRegion(region);
970    builder.setMajor(major);
971    if (family != null) {
972      builder.setFamily(ByteStringer.wrap(family));
973    }
974    return builder.build();
975  }
976 
977  /**
978   * @see {@link #buildRollWALWriterRequest()
979   */
980  private static RollWALWriterRequest ROLL_WAL_WRITER_REQUEST =
981      RollWALWriterRequest.newBuilder().build();
982 
983   /**
984   * Create a new RollWALWriterRequest
985   *
986   * @return a ReplicateWALEntryRequest
987   */
988  public static RollWALWriterRequest buildRollWALWriterRequest() {
989    return ROLL_WAL_WRITER_REQUEST;
990  }
991 
992  /**
993   * @see {@link #buildGetServerInfoRequest()}
994   */
995  private static GetServerInfoRequest GET_SERVER_INFO_REQUEST =
996    GetServerInfoRequest.newBuilder().build();
997 
998  /**
999   * Create a new GetServerInfoRequest
1000   *
1001   * @return a GetServerInfoRequest
1002   */
1003  public static GetServerInfoRequest buildGetServerInfoRequest() {
1004    return GET_SERVER_INFO_REQUEST;
1005  }
1006 
1007  /**
1008   * Create a new StopServerRequest
1009   *
1010   * @param reason the reason to stop the server
1011   * @return a StopServerRequest
1012   */
1013  public static StopServerRequest buildStopServerRequest(final String reason) {
1014    StopServerRequest.Builder builder = StopServerRequest.newBuilder();
1015    builder.setReason(reason);
1016    return builder.build();
1017  }
1018 
1019 //End utilities for Admin
1020 
1021   /**
1022    * Convert a byte array to a protocol buffer RegionSpecifier
1023    *
1024    * @param type the region specifier type
1025    * @param value the region specifier byte array value
1026    * @return a protocol buffer RegionSpecifier
1027    */
1028   public static RegionSpecifier buildRegionSpecifier(
1029       final RegionSpecifierType type, final byte[] value) {
1030     RegionSpecifier.Builder regionBuilder = RegionSpecifier.newBuilder();
1031     regionBuilder.setValue(ByteStringer.wrap(value));
1032     regionBuilder.setType(type);
1033     return regionBuilder.build();
1034   }
1035 
1036   /**
1037    * Create a protocol buffer Condition
1038    *
1039    * @param row
1040    * @param family
1041    * @param qualifier
1042    * @param comparator
1043    * @param compareType
1044    * @return a Condition
1045    * @throws IOException
1046    */
1047   private static Condition buildCondition(final byte[] row,
1048       final byte[] family, final byte [] qualifier,
1049       final ByteArrayComparable comparator,
1050       final CompareType compareType) throws IOException {
1051     Condition.Builder builder = Condition.newBuilder();
1052     builder.setRow(ByteStringer.wrap(row));
1053     builder.setFamily(ByteStringer.wrap(family));
1054     builder.setQualifier(ByteStringer.wrap(qualifier));
1055     builder.setComparator(ProtobufUtil.toComparator(comparator));
1056     builder.setCompareType(compareType);
1057     return builder.build();
1058   }
1059 
1060   /**
1061    * Create a protocol buffer AddColumnRequest
1062    *
1063    * @param tableName
1064    * @param column
1065    * @return an AddColumnRequest
1066    */
1067   public static AddColumnRequest buildAddColumnRequest(
1068       final TableName tableName,
1069       final HColumnDescriptor column,
1070       final long nonceGroup,
1071       final long nonce) {
1072     AddColumnRequest.Builder builder = AddColumnRequest.newBuilder();
1073     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1074     builder.setColumnFamilies(column.convert());
1075     builder.setNonceGroup(nonceGroup);
1076     builder.setNonce(nonce);
1077     return builder.build();
1078   }
1079 
1080   /**
1081    * Create a protocol buffer DeleteColumnRequest
1082    *
1083    * @param tableName
1084    * @param columnName
1085    * @return a DeleteColumnRequest
1086    */
1087   public static DeleteColumnRequest buildDeleteColumnRequest(
1088       final TableName tableName,
1089       final byte [] columnName,
1090       final long nonceGroup,
1091       final long nonce) {
1092     DeleteColumnRequest.Builder builder = DeleteColumnRequest.newBuilder();
1093     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1094     builder.setColumnName(ByteStringer.wrap(columnName));
1095     builder.setNonceGroup(nonceGroup);
1096     builder.setNonce(nonce);
1097     return builder.build();
1098   }
1099 
1100   /**
1101    * Create a protocol buffer ModifyColumnRequest
1102    *
1103    * @param tableName
1104    * @param column
1105    * @return an ModifyColumnRequest
1106    */
1107   public static ModifyColumnRequest buildModifyColumnRequest(
1108       final TableName tableName,
1109       final HColumnDescriptor column,
1110       final long nonceGroup,
1111       final long nonce) {
1112     ModifyColumnRequest.Builder builder = ModifyColumnRequest.newBuilder();
1113     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1114     builder.setColumnFamilies(column.convert());
1115     builder.setNonceGroup(nonceGroup);
1116     builder.setNonce(nonce);
1117     return builder.build();
1118   }
1119 
1120   /**
1121    * Create a protocol buffer MoveRegionRequest
1122    *
1123    * @param encodedRegionName
1124    * @param destServerName
1125    * @return A MoveRegionRequest
1126    * @throws DeserializationException
1127    */
1128   public static MoveRegionRequest buildMoveRegionRequest(
1129       final byte [] encodedRegionName, final byte [] destServerName) throws
1130       DeserializationException {
1131     MoveRegionRequest.Builder builder = MoveRegionRequest.newBuilder();
1132     builder.setRegion(
1133       buildRegionSpecifier(RegionSpecifierType.ENCODED_REGION_NAME,encodedRegionName));
1134     if (destServerName != null) {
1135       builder.setDestServerName(
1136         ProtobufUtil.toServerName(ServerName.valueOf(Bytes.toString(destServerName))));
1137     }
1138     return builder.build();
1139   }
1140 
1141   public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest(
1142       final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
1143       final boolean forcible) throws DeserializationException {
1144     DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder();
1145     builder.setRegionA(buildRegionSpecifier(
1146         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA));
1147     builder.setRegionB(buildRegionSpecifier(
1148         RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB));
1149     builder.setForcible(forcible);
1150     return builder.build();
1151   }
1152 
1153   /**
1154    * Create a protocol buffer AssignRegionRequest
1155    *
1156    * @param regionName
1157    * @return an AssignRegionRequest
1158    */
1159   public static AssignRegionRequest buildAssignRegionRequest(final byte [] regionName) {
1160     AssignRegionRequest.Builder builder = AssignRegionRequest.newBuilder();
1161     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1162     return builder.build();
1163   }
1164 
1165   /**
1166    * Creates a protocol buffer UnassignRegionRequest
1167    *
1168    * @param regionName
1169    * @param force
1170    * @return an UnassignRegionRequest
1171    */
1172   public static UnassignRegionRequest buildUnassignRegionRequest(
1173       final byte [] regionName, final boolean force) {
1174     UnassignRegionRequest.Builder builder = UnassignRegionRequest.newBuilder();
1175     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1176     builder.setForce(force);
1177     return builder.build();
1178   }
1179 
1180   /**
1181    * Creates a protocol buffer OfflineRegionRequest
1182    *
1183    * @param regionName
1184    * @return an OfflineRegionRequest
1185    */
1186   public static OfflineRegionRequest buildOfflineRegionRequest(final byte [] regionName) {
1187     OfflineRegionRequest.Builder builder = OfflineRegionRequest.newBuilder();
1188     builder.setRegion(buildRegionSpecifier(RegionSpecifierType.REGION_NAME,regionName));
1189     return builder.build();
1190   }
1191 
1192   /**
1193    * Creates a protocol buffer DeleteTableRequest
1194    *
1195    * @param tableName
1196    * @return a DeleteTableRequest
1197    */
1198   public static DeleteTableRequest buildDeleteTableRequest(
1199       final TableName tableName,
1200       final long nonceGroup,
1201       final long nonce) {
1202     DeleteTableRequest.Builder builder = DeleteTableRequest.newBuilder();
1203     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1204     builder.setNonceGroup(nonceGroup);
1205     builder.setNonce(nonce);
1206     return builder.build();
1207   }
1208 
1209   /**
1210    * Creates a protocol buffer TruncateTableRequest
1211    *
1212    * @param tableName name of table to truncate
1213    * @param preserveSplits True if the splits should be preserved
1214    * @return a TruncateTableRequest
1215    */
1216   public static TruncateTableRequest buildTruncateTableRequest(
1217       final TableName tableName,
1218       final boolean preserveSplits,
1219       final long nonceGroup,
1220       final long nonce) {
1221     TruncateTableRequest.Builder builder = TruncateTableRequest.newBuilder();
1222     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1223     builder.setPreserveSplits(preserveSplits);
1224     builder.setNonceGroup(nonceGroup);
1225     builder.setNonce(nonce);
1226     return builder.build();
1227   }
1228 
1229   /**
1230    * Creates a protocol buffer EnableTableRequest
1231    *
1232    * @param tableName
1233    * @return an EnableTableRequest
1234    */
1235   public static EnableTableRequest buildEnableTableRequest(
1236       final TableName tableName,
1237       final long nonceGroup,
1238       final long nonce) {
1239     EnableTableRequest.Builder builder = EnableTableRequest.newBuilder();
1240     builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1241     builder.setNonceGroup(nonceGroup);
1242     builder.setNonce(nonce);
1243     return builder.build();
1244   }
1245 
1246   /**
1247    * Creates a protocol buffer DisableTableRequest
1248    *
1249    * @param tableName
1250    * @return a DisableTableRequest
1251    */
1252   public static DisableTableRequest buildDisableTableRequest(
1253       final TableName tableName,
1254       final long nonceGroup,
1255       final long nonce) {
1256     DisableTableRequest.Builder builder = DisableTableRequest.newBuilder();
1257     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1258     builder.setNonceGroup(nonceGroup);
1259     builder.setNonce(nonce);
1260     return builder.build();
1261   }
1262 
1263   /**
1264    * Creates a protocol buffer CreateTableRequest
1265    *
1266    * @param hTableDesc
1267    * @param splitKeys
1268    * @return a CreateTableRequest
1269    */
1270   public static CreateTableRequest buildCreateTableRequest(
1271       final HTableDescriptor hTableDesc,
1272       final byte [][] splitKeys,
1273       final long nonceGroup,
1274       final long nonce) {
1275     CreateTableRequest.Builder builder = CreateTableRequest.newBuilder();
1276     builder.setTableSchema(hTableDesc.convert());
1277     if (splitKeys != null) {
1278       for (byte [] splitKey : splitKeys) {
1279         builder.addSplitKeys(ByteStringer.wrap(splitKey));
1280       }
1281     }
1282     builder.setNonceGroup(nonceGroup);
1283     builder.setNonce(nonce);
1284     return builder.build();
1285   }
1286 
1287 
1288   /**
1289    * Creates a protocol buffer ModifyTableRequest
1290    *
1291    * @param tableName
1292    * @param hTableDesc
1293    * @return a ModifyTableRequest
1294    */
1295   public static ModifyTableRequest buildModifyTableRequest(
1296       final TableName tableName,
1297       final HTableDescriptor hTableDesc,
1298       final long nonceGroup,
1299       final long nonce) {
1300     ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
1301     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1302     builder.setTableSchema(hTableDesc.convert());
1303     builder.setNonceGroup(nonceGroup);
1304     builder.setNonce(nonce);
1305     return builder.build();
1306   }
1307 
1308   /**
1309    * Creates a protocol buffer GetSchemaAlterStatusRequest
1310    *
1311    * @param tableName
1312    * @return a GetSchemaAlterStatusRequest
1313    */
1314   public static GetSchemaAlterStatusRequest buildGetSchemaAlterStatusRequest(
1315       final TableName tableName) {
1316     GetSchemaAlterStatusRequest.Builder builder = GetSchemaAlterStatusRequest.newBuilder();
1317     builder.setTableName(ProtobufUtil.toProtoTableName((tableName)));
1318     return builder.build();
1319   }
1320 
1321   /**
1322    * Creates a protocol buffer GetTableDescriptorsRequest
1323    *
1324    * @param tableNames
1325    * @return a GetTableDescriptorsRequest
1326    */
1327   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1328       final List<TableName> tableNames) {
1329     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1330     if (tableNames != null) {
1331       for (TableName tableName : tableNames) {
1332         builder.addTableNames(ProtobufUtil.toProtoTableName(tableName));
1333       }
1334     }
1335     return builder.build();
1336   }
1337 
1338   /**
1339    * Creates a protocol buffer GetTableDescriptorsRequest
1340    *
1341    * @param pattern The compiled regular expression to match against
1342    * @param includeSysTables False to match only against userspace tables
1343    * @return a GetTableDescriptorsRequest
1344    */
1345   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final Pattern pattern,
1346       boolean includeSysTables) {
1347     GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder();
1348     if (pattern != null) builder.setRegex(pattern.toString());
1349     builder.setIncludeSysTables(includeSysTables);
1350     return builder.build();
1351   }
1352 
1353   /**
1354    * Creates a protocol buffer GetTableNamesRequest
1355    *
1356    * @param pattern The compiled regular expression to match against
1357    * @param includeSysTables False to match only against userspace tables
1358    * @return a GetTableNamesRequest
1359    */
1360   public static GetTableNamesRequest buildGetTableNamesRequest(final Pattern pattern,
1361       boolean includeSysTables) {
1362     GetTableNamesRequest.Builder builder = GetTableNamesRequest.newBuilder();
1363     if (pattern != null) builder.setRegex(pattern.toString());
1364     builder.setIncludeSysTables(includeSysTables);
1365     return builder.build();
1366   }
1367 
1368   /**
1369    * Creates a protocol buffer GetTableDescriptorsRequest for a single table
1370    *
1371    * @param tableName the table name
1372    * @return a GetTableDescriptorsRequest
1373    */
1374   public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(
1375       final TableName tableName) {
1376     return GetTableDescriptorsRequest.newBuilder()
1377       .addTableNames(ProtobufUtil.toProtoTableName(tableName))
1378       .build();
1379   }
1380 
1381   /**
1382    * Creates a protocol buffer IsMasterRunningRequest
1383    *
1384    * @return a IsMasterRunningRequest
1385    */
1386   public static IsMasterRunningRequest buildIsMasterRunningRequest() {
1387     return IsMasterRunningRequest.newBuilder().build();
1388   }
1389 
1390   /**
1391    * Creates a protocol buffer BalanceRequest
1392    *
1393    * @return a BalanceRequest
1394    */
1395   public static BalanceRequest buildBalanceRequest() {
1396     return BalanceRequest.newBuilder().build();
1397   }
1398 
1399   /**
1400    * Creates a protocol buffer SetBalancerRunningRequest
1401    *
1402    * @param on
1403    * @param synchronous
1404    * @return a SetBalancerRunningRequest
1405    */
1406   public static SetBalancerRunningRequest buildSetBalancerRunningRequest(
1407       boolean on,
1408       boolean synchronous) {
1409     return SetBalancerRunningRequest.newBuilder().setOn(on).setSynchronous(synchronous).build();
1410   }
1411 
1412   /**
1413    * Creates a protocol buffer IsBalancerEnabledRequest
1414    *
1415    * @return a IsBalancerEnabledRequest
1416    */
1417   public static IsBalancerEnabledRequest buildIsBalancerEnabledRequest() {
1418     return IsBalancerEnabledRequest.newBuilder().build();
1419   }
1420 
1421   /**
1422    * @see {@link #buildGetClusterStatusRequest}
1423    */
1424   private static final GetClusterStatusRequest GET_CLUSTER_STATUS_REQUEST =
1425       GetClusterStatusRequest.newBuilder().build();
1426 
1427   /**
1428    * Creates a protocol buffer GetClusterStatusRequest
1429    *
1430    * @return A GetClusterStatusRequest
1431    */
1432   public static GetClusterStatusRequest buildGetClusterStatusRequest() {
1433     return GET_CLUSTER_STATUS_REQUEST;
1434   }
1435 
1436   /**
1437    * @see {@link #buildCatalogScanRequest}
1438    */
1439   private static final RunCatalogScanRequest CATALOG_SCAN_REQUEST =
1440     RunCatalogScanRequest.newBuilder().build();
1441 
1442   /**
1443    * Creates a request for running a catalog scan
1444    * @return A {@link RunCatalogScanRequest}
1445    */
1446   public static RunCatalogScanRequest buildCatalogScanRequest() {
1447     return CATALOG_SCAN_REQUEST;
1448   }
1449 
1450   /**
1451    * Creates a request for enabling/disabling the catalog janitor
1452    * @return A {@link EnableCatalogJanitorRequest}
1453    */
1454   public static EnableCatalogJanitorRequest buildEnableCatalogJanitorRequest(boolean enable) {
1455     return EnableCatalogJanitorRequest.newBuilder().setEnable(enable).build();
1456   }
1457 
1458   /**
1459    * @see {@link #buildIsCatalogJanitorEnabledRequest()}
1460    */
1461   private static final IsCatalogJanitorEnabledRequest IS_CATALOG_JANITOR_ENABLED_REQUEST =
1462     IsCatalogJanitorEnabledRequest.newBuilder().build();
1463 
1464   /**
1465    * Creates a request for querying the master whether the catalog janitor is enabled
1466    * @return A {@link IsCatalogJanitorEnabledRequest}
1467    */
1468   public static IsCatalogJanitorEnabledRequest buildIsCatalogJanitorEnabledRequest() {
1469     return IS_CATALOG_JANITOR_ENABLED_REQUEST;
1470   }
1471 
1472   /**
1473    * Creates a request for querying the master the last flushed sequence Id for a region
1474    * @param regionName
1475    * @return A {@link GetLastFlushedSequenceIdRequest}
1476    */
1477   public static GetLastFlushedSequenceIdRequest buildGetLastFlushedSequenceIdRequest(
1478       byte[] regionName) {
1479     return GetLastFlushedSequenceIdRequest.newBuilder().setRegionName(
1480         ByteStringer.wrap(regionName)).build();
1481   }
1482 
1483   /**
1484    * Create a request to grant user permissions.
1485    *
1486    * @param username the short user name who to grant permissions
1487    * @param actions the permissions to be granted
1488    * @return A {@link AccessControlProtos} GrantRequest
1489    */
1490   public static AccessControlProtos.GrantRequest buildGrantRequest(
1491       String username, AccessControlProtos.Permission.Action... actions) {
1492     AccessControlProtos.Permission.Builder ret =
1493         AccessControlProtos.Permission.newBuilder();
1494     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1495         AccessControlProtos.GlobalPermission.newBuilder();
1496     for (AccessControlProtos.Permission.Action a : actions) {
1497       permissionBuilder.addAction(a);
1498     }
1499     ret.setType(AccessControlProtos.Permission.Type.Global)
1500        .setGlobalPermission(permissionBuilder);
1501     return AccessControlProtos.GrantRequest.newBuilder()
1502       .setUserPermission(
1503           AccessControlProtos.UserPermission.newBuilder()
1504               .setUser(ByteString.copyFromUtf8(username))
1505               .setPermission(ret)
1506       ).build();
1507   }
1508 
1509   /**
1510    * Create a request to grant user permissions.
1511    *
1512    * @param username the short user name who to grant permissions
1513    * @param tableName optional table name the permissions apply
1514    * @param family optional column family
1515    * @param qualifier optional qualifier
1516    * @param actions the permissions to be granted
1517    * @return A {@link AccessControlProtos} GrantRequest
1518    */
1519   public static AccessControlProtos.GrantRequest buildGrantRequest(
1520       String username, TableName tableName, byte[] family, byte[] qualifier,
1521       AccessControlProtos.Permission.Action... actions) {
1522     AccessControlProtos.Permission.Builder ret =
1523         AccessControlProtos.Permission.newBuilder();
1524     AccessControlProtos.TablePermission.Builder permissionBuilder =
1525         AccessControlProtos.TablePermission.newBuilder();
1526     for (AccessControlProtos.Permission.Action a : actions) {
1527       permissionBuilder.addAction(a);
1528     }
1529     if (tableName == null) {
1530       throw new NullPointerException("TableName cannot be null");
1531     }
1532     permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1533 
1534     if (family != null) {
1535       permissionBuilder.setFamily(ByteStringer.wrap(family));
1536     }
1537     if (qualifier != null) {
1538       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1539     }
1540     ret.setType(AccessControlProtos.Permission.Type.Table)
1541        .setTablePermission(permissionBuilder);
1542     return AccessControlProtos.GrantRequest.newBuilder()
1543       .setUserPermission(
1544           AccessControlProtos.UserPermission.newBuilder()
1545               .setUser(ByteString.copyFromUtf8(username))
1546               .setPermission(ret)
1547       ).build();
1548   }
1549 
1550   /**
1551    * Create a request to grant user permissions.
1552    *
1553    * @param username the short user name who to grant permissions
1554    * @param namespace optional table name the permissions apply
1555    * @param actions the permissions to be granted
1556    * @return A {@link AccessControlProtos} GrantRequest
1557    */
1558   public static AccessControlProtos.GrantRequest buildGrantRequest(
1559       String username, String namespace,
1560       AccessControlProtos.Permission.Action... actions) {
1561     AccessControlProtos.Permission.Builder ret =
1562         AccessControlProtos.Permission.newBuilder();
1563     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1564         AccessControlProtos.NamespacePermission.newBuilder();
1565     for (AccessControlProtos.Permission.Action a : actions) {
1566       permissionBuilder.addAction(a);
1567     }
1568     if (namespace != null) {
1569       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1570     }
1571     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1572        .setNamespacePermission(permissionBuilder);
1573     return AccessControlProtos.GrantRequest.newBuilder()
1574       .setUserPermission(
1575           AccessControlProtos.UserPermission.newBuilder()
1576               .setUser(ByteString.copyFromUtf8(username))
1577               .setPermission(ret)
1578       ).build();
1579   }
1580 
1581   /**
1582    * Create a request to revoke user permissions.
1583    *
1584    * @param username the short user name whose permissions to be revoked
1585    * @param actions the permissions to be revoked
1586    * @return A {@link AccessControlProtos} RevokeRequest
1587    */
1588   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1589       String username, AccessControlProtos.Permission.Action... actions) {
1590     AccessControlProtos.Permission.Builder ret =
1591         AccessControlProtos.Permission.newBuilder();
1592     AccessControlProtos.GlobalPermission.Builder permissionBuilder =
1593         AccessControlProtos.GlobalPermission.newBuilder();
1594     for (AccessControlProtos.Permission.Action a : actions) {
1595       permissionBuilder.addAction(a);
1596     }
1597     ret.setType(AccessControlProtos.Permission.Type.Global)
1598        .setGlobalPermission(permissionBuilder);
1599     return AccessControlProtos.RevokeRequest.newBuilder()
1600       .setUserPermission(
1601           AccessControlProtos.UserPermission.newBuilder()
1602               .setUser(ByteString.copyFromUtf8(username))
1603               .setPermission(ret)
1604       ).build();
1605   }
1606 
1607   /**
1608    * Create a request to revoke user permissions.
1609    *
1610    * @param username the short user name whose permissions to be revoked
1611    * @param tableName optional table name the permissions apply
1612    * @param family optional column family
1613    * @param qualifier optional qualifier
1614    * @param actions the permissions to be revoked
1615    * @return A {@link AccessControlProtos} RevokeRequest
1616    */
1617   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1618       String username, TableName tableName, byte[] family, byte[] qualifier,
1619       AccessControlProtos.Permission.Action... actions) {
1620     AccessControlProtos.Permission.Builder ret =
1621         AccessControlProtos.Permission.newBuilder();
1622     AccessControlProtos.TablePermission.Builder permissionBuilder =
1623         AccessControlProtos.TablePermission.newBuilder();
1624     for (AccessControlProtos.Permission.Action a : actions) {
1625       permissionBuilder.addAction(a);
1626     }
1627     if (tableName != null) {
1628       permissionBuilder.setTableName(ProtobufUtil.toProtoTableName(tableName));
1629     }
1630     if (family != null) {
1631       permissionBuilder.setFamily(ByteStringer.wrap(family));
1632     }
1633     if (qualifier != null) {
1634       permissionBuilder.setQualifier(ByteStringer.wrap(qualifier));
1635     }
1636     ret.setType(AccessControlProtos.Permission.Type.Table)
1637        .setTablePermission(permissionBuilder);
1638     return AccessControlProtos.RevokeRequest.newBuilder()
1639       .setUserPermission(
1640           AccessControlProtos.UserPermission.newBuilder()
1641               .setUser(ByteString.copyFromUtf8(username))
1642               .setPermission(ret)
1643       ).build();
1644   }
1645 
1646   /**
1647    * Create a request to revoke user permissions.
1648    *
1649    * @param username the short user name whose permissions to be revoked
1650    * @param namespace optional table name the permissions apply
1651    * @param actions the permissions to be revoked
1652    * @return A {@link AccessControlProtos} RevokeRequest
1653    */
1654   public static AccessControlProtos.RevokeRequest buildRevokeRequest(
1655       String username, String namespace,
1656       AccessControlProtos.Permission.Action... actions) {
1657     AccessControlProtos.Permission.Builder ret =
1658         AccessControlProtos.Permission.newBuilder();
1659     AccessControlProtos.NamespacePermission.Builder permissionBuilder =
1660         AccessControlProtos.NamespacePermission.newBuilder();
1661     for (AccessControlProtos.Permission.Action a : actions) {
1662       permissionBuilder.addAction(a);
1663     }
1664     if (namespace != null) {
1665       permissionBuilder.setNamespaceName(ByteString.copyFromUtf8(namespace));
1666     }
1667     ret.setType(AccessControlProtos.Permission.Type.Namespace)
1668        .setNamespacePermission(permissionBuilder);
1669     return AccessControlProtos.RevokeRequest.newBuilder()
1670       .setUserPermission(
1671           AccessControlProtos.UserPermission.newBuilder()
1672               .setUser(ByteString.copyFromUtf8(username))
1673               .setPermission(ret)
1674       ).build();
1675   }
1676 
1677   /**
1678    * Create a RegionOpenInfo based on given region info and version of offline node
1679    */
1680   private static RegionOpenInfo buildRegionOpenInfo(
1681       final HRegionInfo region, final int versionOfOfflineNode,
1682       final List<ServerName> favoredNodes, Boolean openForReplay) {
1683     RegionOpenInfo.Builder builder = RegionOpenInfo.newBuilder();
1684     builder.setRegion(HRegionInfo.convert(region));
1685     if (versionOfOfflineNode >= 0) {
1686       builder.setVersionOfOfflineNode(versionOfOfflineNode);
1687     }
1688     if (favoredNodes != null) {
1689       for (ServerName server : favoredNodes) {
1690         builder.addFavoredNodes(ProtobufUtil.toServerName(server));
1691       }
1692     }
1693     if(openForReplay != null) {
1694       builder.setOpenForDistributedLogReplay(openForReplay);
1695     }
1696     return builder.build();
1697   }
1698 }