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