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