View Javadoc

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