001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.thrift2;
019
020import static org.apache.hadoop.hbase.util.Bytes.getBytes;
021
022import java.io.IOException;
023import java.nio.ByteBuffer;
024import java.util.ArrayList;
025import java.util.Collections;
026import java.util.HashSet;
027import java.util.List;
028import java.util.Map;
029import java.util.NavigableSet;
030import java.util.Set;
031import java.util.stream.Collectors;
032import org.apache.hadoop.hbase.Cell;
033import org.apache.hadoop.hbase.CellBuilderFactory;
034import org.apache.hadoop.hbase.CellBuilderType;
035import org.apache.hadoop.hbase.CellUtil;
036import org.apache.hadoop.hbase.CompareOperator;
037import org.apache.hadoop.hbase.ExtendedCellBuilder;
038import org.apache.hadoop.hbase.ExtendedCellBuilderFactory;
039import org.apache.hadoop.hbase.HConstants;
040import org.apache.hadoop.hbase.HRegionLocation;
041import org.apache.hadoop.hbase.KeepDeletedCells;
042import org.apache.hadoop.hbase.NamespaceDescriptor;
043import org.apache.hadoop.hbase.PrivateCellUtil;
044import org.apache.hadoop.hbase.ServerName;
045import org.apache.hadoop.hbase.TableName;
046import org.apache.hadoop.hbase.client.Append;
047import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
048import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
049import org.apache.hadoop.hbase.client.Consistency;
050import org.apache.hadoop.hbase.client.Delete;
051import org.apache.hadoop.hbase.client.Durability;
052import org.apache.hadoop.hbase.client.Get;
053import org.apache.hadoop.hbase.client.Increment;
054import org.apache.hadoop.hbase.client.LogQueryFilter;
055import org.apache.hadoop.hbase.client.Mutation;
056import org.apache.hadoop.hbase.client.OnlineLogRecord;
057import org.apache.hadoop.hbase.client.OperationWithAttributes;
058import org.apache.hadoop.hbase.client.Put;
059import org.apache.hadoop.hbase.client.RegionInfo;
060import org.apache.hadoop.hbase.client.Result;
061import org.apache.hadoop.hbase.client.RowMutations;
062import org.apache.hadoop.hbase.client.Scan;
063import org.apache.hadoop.hbase.client.Scan.ReadType;
064import org.apache.hadoop.hbase.client.TableDescriptor;
065import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
066import org.apache.hadoop.hbase.exceptions.DeserializationException;
067import org.apache.hadoop.hbase.filter.Filter;
068import org.apache.hadoop.hbase.filter.ParseFilter;
069import org.apache.hadoop.hbase.io.TimeRange;
070import org.apache.hadoop.hbase.io.compress.Compression;
071import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
072import org.apache.hadoop.hbase.regionserver.BloomType;
073import org.apache.hadoop.hbase.security.access.Permission;
074import org.apache.hadoop.hbase.security.visibility.Authorizations;
075import org.apache.hadoop.hbase.security.visibility.CellVisibility;
076import org.apache.hadoop.hbase.thrift2.generated.TAppend;
077import org.apache.hadoop.hbase.thrift2.generated.TAuthorization;
078import org.apache.hadoop.hbase.thrift2.generated.TBloomFilterType;
079import org.apache.hadoop.hbase.thrift2.generated.TCellVisibility;
080import org.apache.hadoop.hbase.thrift2.generated.TColumn;
081import org.apache.hadoop.hbase.thrift2.generated.TColumnFamilyDescriptor;
082import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement;
083import org.apache.hadoop.hbase.thrift2.generated.TColumnValue;
084import org.apache.hadoop.hbase.thrift2.generated.TCompareOperator;
085import org.apache.hadoop.hbase.thrift2.generated.TCompressionAlgorithm;
086import org.apache.hadoop.hbase.thrift2.generated.TConsistency;
087import org.apache.hadoop.hbase.thrift2.generated.TDataBlockEncoding;
088import org.apache.hadoop.hbase.thrift2.generated.TDelete;
089import org.apache.hadoop.hbase.thrift2.generated.TDeleteType;
090import org.apache.hadoop.hbase.thrift2.generated.TDurability;
091import org.apache.hadoop.hbase.thrift2.generated.TFilterByOperator;
092import org.apache.hadoop.hbase.thrift2.generated.TGet;
093import org.apache.hadoop.hbase.thrift2.generated.THRegionInfo;
094import org.apache.hadoop.hbase.thrift2.generated.THRegionLocation;
095import org.apache.hadoop.hbase.thrift2.generated.TIncrement;
096import org.apache.hadoop.hbase.thrift2.generated.TKeepDeletedCells;
097import org.apache.hadoop.hbase.thrift2.generated.TLogQueryFilter;
098import org.apache.hadoop.hbase.thrift2.generated.TLogType;
099import org.apache.hadoop.hbase.thrift2.generated.TMutation;
100import org.apache.hadoop.hbase.thrift2.generated.TNamespaceDescriptor;
101import org.apache.hadoop.hbase.thrift2.generated.TOnlineLogRecord;
102import org.apache.hadoop.hbase.thrift2.generated.TPut;
103import org.apache.hadoop.hbase.thrift2.generated.TReadType;
104import org.apache.hadoop.hbase.thrift2.generated.TResult;
105import org.apache.hadoop.hbase.thrift2.generated.TRowMutations;
106import org.apache.hadoop.hbase.thrift2.generated.TScan;
107import org.apache.hadoop.hbase.thrift2.generated.TServerName;
108import org.apache.hadoop.hbase.thrift2.generated.TTableDescriptor;
109import org.apache.hadoop.hbase.thrift2.generated.TTableName;
110import org.apache.hadoop.hbase.thrift2.generated.TTimeRange;
111import org.apache.hadoop.hbase.util.Bytes;
112import org.apache.yetus.audience.InterfaceAudience;
113
114import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils;
115import org.apache.hbase.thirdparty.org.apache.commons.collections4.MapUtils;
116
117import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
118import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos;
119
120@InterfaceAudience.Private
121public final class ThriftUtilities {
122
123  private final static Cell[] EMPTY_CELL_ARRAY = new Cell[] {};
124  private final static Result EMPTY_RESULT = Result.create(EMPTY_CELL_ARRAY);
125  private final static Result EMPTY_RESULT_STALE = Result.create(EMPTY_CELL_ARRAY, null, true);
126
127  private ThriftUtilities() {
128    throw new UnsupportedOperationException("Can't initialize class");
129  }
130
131  /**
132   * Creates a {@link Get} (HBase) from a {@link TGet} (Thrift). This ignores any timestamps set on
133   * {@link TColumn} objects.
134   * @param in the <code>TGet</code> to convert
135   * @return <code>Get</code> object
136   * @throws IOException if an invalid time range or max version parameter is given
137   */
138  public static Get getFromThrift(TGet in) throws IOException {
139    Get out = new Get(in.getRow());
140
141    // Timestamp overwrites time range if both are set
142    if (in.isSetTimestamp()) {
143      out.setTimestamp(in.getTimestamp());
144    } else if (in.isSetTimeRange()) {
145      out.setTimeRange(in.getTimeRange().getMinStamp(), in.getTimeRange().getMaxStamp());
146    }
147
148    if (in.isSetMaxVersions()) {
149      out.readVersions(in.getMaxVersions());
150    }
151
152    if (in.isSetFilterString()) {
153      ParseFilter parseFilter = new ParseFilter();
154      out.setFilter(parseFilter.parseFilterString(in.getFilterString()));
155    }
156
157    if (in.isSetAttributes()) {
158      addAttributes(out, in.getAttributes());
159    }
160
161    if (in.isSetAuthorizations()) {
162      out.setAuthorizations(new Authorizations(in.getAuthorizations().getLabels()));
163    }
164
165    if (in.isSetConsistency()) {
166      out.setConsistency(consistencyFromThrift(in.getConsistency()));
167    }
168
169    if (in.isSetTargetReplicaId()) {
170      out.setReplicaId(in.getTargetReplicaId());
171    }
172
173    if (in.isSetCacheBlocks()) {
174      out.setCacheBlocks(in.isCacheBlocks());
175    }
176    if (in.isSetStoreLimit()) {
177      out.setMaxResultsPerColumnFamily(in.getStoreLimit());
178    }
179    if (in.isSetStoreOffset()) {
180      out.setRowOffsetPerColumnFamily(in.getStoreOffset());
181    }
182    if (in.isSetExistence_only()) {
183      out.setCheckExistenceOnly(in.isExistence_only());
184    }
185
186    if (in.isSetColumns()) {
187      for (TColumn column : in.getColumns()) {
188        if (column.isSetQualifier()) {
189          out.addColumn(column.getFamily(), column.getQualifier());
190        } else {
191          out.addFamily(column.getFamily());
192        }
193      }
194    }
195
196    if (in.isSetFilterBytes()) {
197      out.setFilter(filterFromThrift(in.getFilterBytes()));
198    }
199    return out;
200  }
201
202  /**
203   * Converts multiple {@link TGet}s (Thrift) into a list of {@link Get}s (HBase).
204   * @param in list of <code>TGet</code>s to convert
205   * @return list of <code>Get</code> objects
206   * @throws IOException if an invalid time range or max version parameter is given
207   * @see #getFromThrift(TGet)
208   */
209  public static List<Get> getsFromThrift(List<TGet> in) throws IOException {
210    List<Get> out = new ArrayList<>(in.size());
211    for (TGet get : in) {
212      out.add(getFromThrift(get));
213    }
214    return out;
215  }
216
217  /**
218   * Creates a {@link TResult} (Thrift) from a {@link Result} (HBase).
219   * @param in the <code>Result</code> to convert
220   * @return converted result, returns an empty result if the input is <code>null</code>
221   */
222  public static TResult resultFromHBase(Result in) {
223    Cell[] raw = in.rawCells();
224    TResult out = new TResult();
225    byte[] row = in.getRow();
226    if (row != null) {
227      out.setRow(in.getRow());
228    }
229    List<TColumnValue> columnValues = new ArrayList<>(raw.length);
230    for (Cell kv : raw) {
231      TColumnValue col = new TColumnValue();
232      col.setFamily(CellUtil.cloneFamily(kv));
233      col.setQualifier(CellUtil.cloneQualifier(kv));
234      col.setTimestamp(kv.getTimestamp());
235      col.setValue(CellUtil.cloneValue(kv));
236      col.setType(kv.getType().getCode());
237      if (kv.getTagsLength() > 0) {
238        col.setTags(PrivateCellUtil.cloneTags(kv));
239      }
240      columnValues.add(col);
241    }
242    out.setColumnValues(columnValues);
243
244    out.setStale(in.isStale());
245
246    out.setPartial(in.mayHaveMoreCellsInRow());
247    return out;
248  }
249
250  /**
251   * Converts multiple {@link Result}s (HBase) into a list of {@link TResult}s (Thrift).
252   * @param in array of <code>Result</code>s to convert
253   * @return list of converted <code>TResult</code>s
254   * @see #resultFromHBase(Result)
255   */
256  public static List<TResult> resultsFromHBase(Result[] in) {
257    List<TResult> out = new ArrayList<>(in.length);
258    for (Result result : in) {
259      out.add(resultFromHBase(result));
260    }
261    return out;
262  }
263
264  /**
265   * Creates a {@link Put} (HBase) from a {@link TPut} (Thrift)
266   * @param in the <code>TPut</code> to convert
267   * @return converted <code>Put</code>
268   */
269  public static Put putFromThrift(TPut in) {
270    Put out;
271
272    if (in.isSetTimestamp()) {
273      out = new Put(in.getRow(), in.getTimestamp());
274    } else {
275      out = new Put(in.getRow());
276    }
277
278    if (in.isSetDurability()) {
279      out.setDurability(durabilityFromThrift(in.getDurability()));
280    }
281
282    for (TColumnValue columnValue : in.getColumnValues()) {
283      try {
284        if (columnValue.isSetTimestamp()) {
285          out.add(CellBuilderFactory.create(CellBuilderType.DEEP_COPY).setRow(out.getRow())
286            .setFamily(columnValue.getFamily()).setQualifier(columnValue.getQualifier())
287            .setTimestamp(columnValue.getTimestamp()).setType(Cell.Type.Put)
288            .setValue(columnValue.getValue()).build());
289        } else {
290          out.add(CellBuilderFactory.create(CellBuilderType.DEEP_COPY).setRow(out.getRow())
291            .setFamily(columnValue.getFamily()).setQualifier(columnValue.getQualifier())
292            .setTimestamp(out.getTimestamp()).setType(Cell.Type.Put)
293            .setValue(columnValue.getValue()).build());
294        }
295      } catch (IOException e) {
296        throw new IllegalArgumentException((e));
297      }
298    }
299
300    if (in.isSetAttributes()) {
301      addAttributes(out, in.getAttributes());
302    }
303
304    if (in.getCellVisibility() != null) {
305      out.setCellVisibility(new CellVisibility(in.getCellVisibility().getExpression()));
306    }
307
308    return out;
309  }
310
311  /**
312   * Converts multiple {@link TPut}s (Thrift) into a list of {@link Put}s (HBase).
313   * @param in list of <code>TPut</code>s to convert
314   * @return list of converted <code>Put</code>s
315   * @see #putFromThrift(TPut)
316   */
317  public static List<Put> putsFromThrift(List<TPut> in) {
318    List<Put> out = new ArrayList<>(in.size());
319    for (TPut put : in) {
320      out.add(putFromThrift(put));
321    }
322    return out;
323  }
324
325  /**
326   * Creates a {@link Delete} (HBase) from a {@link TDelete} (Thrift).
327   * @param in the <code>TDelete</code> to convert
328   * @return converted <code>Delete</code>
329   */
330  public static Delete deleteFromThrift(TDelete in) {
331    Delete out;
332
333    if (in.isSetColumns()) {
334      out = new Delete(in.getRow());
335      for (TColumn column : in.getColumns()) {
336        if (in.isSetDeleteType()) {
337          switch (in.getDeleteType()) {
338            case DELETE_COLUMN:
339              if (column.isSetTimestamp()) {
340                out.addColumn(column.getFamily(), column.getQualifier(), column.getTimestamp());
341              } else {
342                out.addColumn(column.getFamily(), column.getQualifier());
343              }
344              break;
345            case DELETE_COLUMNS:
346              if (column.isSetTimestamp()) {
347                out.addColumns(column.getFamily(), column.getQualifier(), column.getTimestamp());
348              } else {
349                out.addColumns(column.getFamily(), column.getQualifier());
350              }
351              break;
352            case DELETE_FAMILY:
353              if (column.isSetTimestamp()) {
354                out.addFamily(column.getFamily(), column.getTimestamp());
355              } else {
356                out.addFamily(column.getFamily());
357              }
358              break;
359            case DELETE_FAMILY_VERSION:
360              if (column.isSetTimestamp()) {
361                out.addFamilyVersion(column.getFamily(), column.getTimestamp());
362              } else {
363                throw new IllegalArgumentException(
364                  "Timestamp is required for TDelete with DeleteFamilyVersion type");
365              }
366              break;
367            default:
368              throw new IllegalArgumentException("DeleteType is required for TDelete");
369          }
370        } else {
371          throw new IllegalArgumentException("DeleteType is required for TDelete");
372        }
373      }
374    } else {
375      if (in.isSetTimestamp()) {
376        out = new Delete(in.getRow(), in.getTimestamp());
377      } else {
378        out = new Delete(in.getRow());
379      }
380    }
381
382    if (in.isSetAttributes()) {
383      addAttributes(out, in.getAttributes());
384    }
385
386    if (in.isSetDurability()) {
387      out.setDurability(durabilityFromThrift(in.getDurability()));
388    }
389
390    return out;
391  }
392
393  /**
394   * Converts multiple {@link TDelete}s (Thrift) into a list of {@link Delete}s (HBase).
395   * @param in list of <code>TDelete</code>s to convert
396   * @return list of converted <code>Delete</code>s
397   * @see #deleteFromThrift(TDelete)
398   */
399
400  public static List<Delete> deletesFromThrift(List<TDelete> in) {
401    List<Delete> out = new ArrayList<>(in.size());
402    for (TDelete delete : in) {
403      out.add(deleteFromThrift(delete));
404    }
405    return out;
406  }
407
408  public static TDeleteType deleteTypeFromHBase(Cell.Type type) {
409    switch (type) {
410      case Delete:
411        return TDeleteType.DELETE_COLUMN;
412      case DeleteColumn:
413        return TDeleteType.DELETE_COLUMNS;
414      case DeleteFamily:
415        return TDeleteType.DELETE_FAMILY;
416      case DeleteFamilyVersion:
417        return TDeleteType.DELETE_FAMILY_VERSION;
418      default:
419        throw new IllegalArgumentException("Unknow delete type " + type);
420    }
421  }
422
423  public static TDelete deleteFromHBase(Delete in) {
424    TDelete out = new TDelete(ByteBuffer.wrap(in.getRow()));
425
426    List<TColumn> columns = new ArrayList<>(in.getFamilyCellMap().entrySet().size());
427    long rowTimestamp = in.getTimestamp();
428    if (rowTimestamp != HConstants.LATEST_TIMESTAMP) {
429      out.setTimestamp(rowTimestamp);
430    }
431
432    for (Map.Entry<String, byte[]> attribute : in.getAttributesMap().entrySet()) {
433      out.putToAttributes(ByteBuffer.wrap(Bytes.toBytes(attribute.getKey())),
434        ByteBuffer.wrap(attribute.getValue()));
435    }
436    if (in.getDurability() != Durability.USE_DEFAULT) {
437      out.setDurability(durabilityFromHBase(in.getDurability()));
438    }
439    // Delete the whole row
440    if (in.getFamilyCellMap().size() == 0) {
441      return out;
442    }
443    TDeleteType type = null;
444    for (Map.Entry<byte[], List<Cell>> familyEntry : in.getFamilyCellMap().entrySet()) {
445      byte[] family = familyEntry.getKey();
446      TColumn column = new TColumn(ByteBuffer.wrap(familyEntry.getKey()));
447      for (Cell cell : familyEntry.getValue()) {
448        TDeleteType cellDeleteType = deleteTypeFromHBase(cell.getType());
449        if (type == null) {
450          type = cellDeleteType;
451        } else if (type != cellDeleteType) {
452          throw new RuntimeException("Only the same delete type is supported, but two delete type "
453            + "is founded, one is " + type + " the other one is " + cellDeleteType);
454        }
455        byte[] qualifier = CellUtil.cloneQualifier(cell);
456        long timestamp = cell.getTimestamp();
457        column.setFamily(family);
458        if (qualifier != null) {
459          column.setQualifier(qualifier);
460        }
461        if (timestamp != HConstants.LATEST_TIMESTAMP) {
462          column.setTimestamp(timestamp);
463        }
464      }
465      columns.add(column);
466    }
467    out.setColumns(columns);
468    out.setDeleteType(type);
469
470    return out;
471  }
472
473  /**
474   * Creates a {@link RowMutations} (HBase) from a {@link TRowMutations} (Thrift)
475   * @param in the <code>TRowMutations</code> to convert
476   * @return converted <code>RowMutations</code>
477   */
478  public static RowMutations rowMutationsFromThrift(TRowMutations in) throws IOException {
479    List<TMutation> mutations = in.getMutations();
480    RowMutations out = new RowMutations(in.getRow(), mutations.size());
481    for (TMutation mutation : mutations) {
482      if (mutation.isSetPut()) {
483        out.add(putFromThrift(mutation.getPut()));
484      }
485      if (mutation.isSetDeleteSingle()) {
486        out.add(deleteFromThrift(mutation.getDeleteSingle()));
487      }
488    }
489    return out;
490  }
491
492  public static Scan scanFromThrift(TScan in) throws IOException {
493    Scan out = new Scan();
494
495    if (in.isSetStartRow()) {
496      out.withStartRow(in.getStartRow());
497    }
498    if (in.isSetStopRow()) {
499      out.withStopRow(in.getStopRow());
500    }
501    if (in.isSetCaching()) {
502      out.setCaching(in.getCaching());
503    }
504    if (in.isSetMaxVersions()) {
505      out.readVersions(in.getMaxVersions());
506    }
507
508    if (in.isSetColumns()) {
509      for (TColumn column : in.getColumns()) {
510        if (column.isSetQualifier()) {
511          out.addColumn(column.getFamily(), column.getQualifier());
512        } else {
513          out.addFamily(column.getFamily());
514        }
515      }
516    }
517
518    TTimeRange timeRange = in.getTimeRange();
519    if (timeRange != null && timeRange.isSetMinStamp() && timeRange.isSetMaxStamp()) {
520      out.setTimeRange(timeRange.getMinStamp(), timeRange.getMaxStamp());
521    }
522
523    if (in.isSetBatchSize()) {
524      out.setBatch(in.getBatchSize());
525    }
526
527    if (in.isSetFilterString()) {
528      ParseFilter parseFilter = new ParseFilter();
529      out.setFilter(parseFilter.parseFilterString(in.getFilterString()));
530    }
531
532    if (in.isSetAttributes()) {
533      addAttributes(out, in.getAttributes());
534    }
535
536    if (in.isSetAuthorizations()) {
537      out.setAuthorizations(new Authorizations(in.getAuthorizations().getLabels()));
538    }
539
540    if (in.isSetReversed()) {
541      out.setReversed(in.isReversed());
542    }
543
544    if (in.isSetCacheBlocks()) {
545      out.setCacheBlocks(in.isCacheBlocks());
546    }
547
548    if (in.isSetColFamTimeRangeMap()) {
549      Map<ByteBuffer, TTimeRange> colFamTimeRangeMap = in.getColFamTimeRangeMap();
550      if (MapUtils.isNotEmpty(colFamTimeRangeMap)) {
551        for (Map.Entry<ByteBuffer, TTimeRange> entry : colFamTimeRangeMap.entrySet()) {
552          out.setColumnFamilyTimeRange(Bytes.toBytes(entry.getKey()),
553            entry.getValue().getMinStamp(), entry.getValue().getMaxStamp());
554        }
555      }
556    }
557
558    if (in.isSetReadType()) {
559      out.setReadType(readTypeFromThrift(in.getReadType()));
560    }
561
562    if (in.isSetLimit()) {
563      out.setLimit(in.getLimit());
564    }
565
566    if (in.isSetConsistency()) {
567      out.setConsistency(consistencyFromThrift(in.getConsistency()));
568    }
569
570    if (in.isSetTargetReplicaId()) {
571      out.setReplicaId(in.getTargetReplicaId());
572    }
573
574    if (in.isSetFilterBytes()) {
575      out.setFilter(filterFromThrift(in.getFilterBytes()));
576    }
577
578    return out;
579  }
580
581  public static byte[] filterFromHBase(Filter filter) throws IOException {
582    FilterProtos.Filter filterPB = ProtobufUtil.toFilter(filter);
583    return filterPB.toByteArray();
584  }
585
586  public static Filter filterFromThrift(byte[] filterBytes) throws IOException {
587    FilterProtos.Filter filterPB = FilterProtos.Filter.parseFrom(filterBytes);
588    return ProtobufUtil.toFilter(filterPB);
589  }
590
591  public static TScan scanFromHBase(Scan in) throws IOException {
592    TScan out = new TScan();
593    out.setStartRow(in.getStartRow());
594    out.setStopRow(in.getStopRow());
595    out.setCaching(in.getCaching());
596    out.setMaxVersions(in.getMaxVersions());
597    for (Map.Entry<byte[], NavigableSet<byte[]>> family : in.getFamilyMap().entrySet()) {
598
599      if (family.getValue() != null && !family.getValue().isEmpty()) {
600        for (byte[] qualifier : family.getValue()) {
601          TColumn column = new TColumn();
602          column.setFamily(family.getKey());
603          column.setQualifier(qualifier);
604          out.addToColumns(column);
605        }
606      } else {
607        TColumn column = new TColumn();
608        column.setFamily(family.getKey());
609        out.addToColumns(column);
610      }
611    }
612    TTimeRange tTimeRange = new TTimeRange();
613    tTimeRange.setMinStamp(in.getTimeRange().getMin()).setMaxStamp(in.getTimeRange().getMax());
614    out.setTimeRange(tTimeRange);
615    out.setBatchSize(in.getBatch());
616
617    for (Map.Entry<String, byte[]> attribute : in.getAttributesMap().entrySet()) {
618      out.putToAttributes(ByteBuffer.wrap(Bytes.toBytes(attribute.getKey())),
619        ByteBuffer.wrap(attribute.getValue()));
620    }
621
622    try {
623      Authorizations authorizations = in.getAuthorizations();
624      if (authorizations != null) {
625        TAuthorization tAuthorization = new TAuthorization();
626        tAuthorization.setLabels(authorizations.getLabels());
627        out.setAuthorizations(tAuthorization);
628      }
629    } catch (DeserializationException e) {
630      throw new RuntimeException(e);
631    }
632
633    out.setReversed(in.isReversed());
634    out.setCacheBlocks(in.getCacheBlocks());
635    out.setReadType(readTypeFromHBase(in.getReadType()));
636    out.setLimit(in.getLimit());
637    out.setConsistency(consistencyFromHBase(in.getConsistency()));
638    out.setTargetReplicaId(in.getReplicaId());
639    for (Map.Entry<byte[], TimeRange> entry : in.getColumnFamilyTimeRange().entrySet()) {
640      if (entry.getValue() != null) {
641        TTimeRange timeRange = new TTimeRange();
642        timeRange.setMinStamp(entry.getValue().getMin()).setMaxStamp(entry.getValue().getMax());
643        out.putToColFamTimeRangeMap(ByteBuffer.wrap(entry.getKey()), timeRange);
644      }
645    }
646    if (in.getFilter() != null) {
647      try {
648        out.setFilterBytes(filterFromHBase(in.getFilter()));
649      } catch (IOException ioE) {
650        throw new RuntimeException(ioE);
651      }
652    }
653    return out;
654  }
655
656  public static Increment incrementFromThrift(TIncrement in) throws IOException {
657    Increment out = new Increment(in.getRow());
658    for (TColumnIncrement column : in.getColumns()) {
659      out.addColumn(column.getFamily(), column.getQualifier(), column.getAmount());
660    }
661
662    if (in.isSetAttributes()) {
663      addAttributes(out, in.getAttributes());
664    }
665
666    if (in.isSetDurability()) {
667      out.setDurability(durabilityFromThrift(in.getDurability()));
668    }
669
670    if (in.getCellVisibility() != null) {
671      out.setCellVisibility(new CellVisibility(in.getCellVisibility().getExpression()));
672    }
673
674    if (in.isSetReturnResults()) {
675      out.setReturnResults(in.isReturnResults());
676    }
677
678    return out;
679  }
680
681  public static Append appendFromThrift(TAppend append) throws IOException {
682    Append out = new Append(append.getRow());
683    for (TColumnValue column : append.getColumns()) {
684      out.addColumn(column.getFamily(), column.getQualifier(), column.getValue());
685    }
686
687    if (append.isSetAttributes()) {
688      addAttributes(out, append.getAttributes());
689    }
690
691    if (append.isSetDurability()) {
692      out.setDurability(durabilityFromThrift(append.getDurability()));
693    }
694
695    if (append.getCellVisibility() != null) {
696      out.setCellVisibility(new CellVisibility(append.getCellVisibility().getExpression()));
697    }
698
699    if (append.isSetReturnResults()) {
700      out.setReturnResults(append.isReturnResults());
701    }
702
703    return out;
704  }
705
706  public static THRegionLocation regionLocationFromHBase(HRegionLocation hrl) {
707    RegionInfo hri = hrl.getRegion();
708    ServerName serverName = hrl.getServerName();
709
710    THRegionInfo thRegionInfo = new THRegionInfo();
711    THRegionLocation thRegionLocation = new THRegionLocation();
712    TServerName tServerName = new TServerName();
713
714    tServerName.setHostName(serverName.getHostname());
715    tServerName.setPort(serverName.getPort());
716    tServerName.setStartCode(serverName.getStartcode());
717
718    thRegionInfo.setTableName(hri.getTable().getName());
719    thRegionInfo.setEndKey(hri.getEndKey());
720    thRegionInfo.setStartKey(hri.getStartKey());
721    thRegionInfo.setOffline(hri.isOffline());
722    thRegionInfo.setSplit(hri.isSplit());
723    thRegionInfo.setReplicaId(hri.getReplicaId());
724
725    thRegionLocation.setRegionInfo(thRegionInfo);
726    thRegionLocation.setServerName(tServerName);
727
728    return thRegionLocation;
729  }
730
731  public static List<THRegionLocation> regionLocationsFromHBase(List<HRegionLocation> locations) {
732    List<THRegionLocation> tlocations = new ArrayList<>(locations.size());
733    for (HRegionLocation hrl : locations) {
734      tlocations.add(regionLocationFromHBase(hrl));
735    }
736    return tlocations;
737  }
738
739  /**
740   * Adds all the attributes into the Operation object
741   */
742  private static void addAttributes(OperationWithAttributes op,
743    Map<ByteBuffer, ByteBuffer> attributes) {
744    if (attributes == null || attributes.isEmpty()) {
745      return;
746    }
747    for (Map.Entry<ByteBuffer, ByteBuffer> entry : attributes.entrySet()) {
748      String name = Bytes.toStringBinary(getBytes(entry.getKey()));
749      byte[] value = getBytes(entry.getValue());
750      op.setAttribute(name, value);
751    }
752  }
753
754  private static Durability durabilityFromThrift(TDurability tDurability) {
755    switch (tDurability.getValue()) {
756      case 0:
757        return Durability.USE_DEFAULT;
758      case 1:
759        return Durability.SKIP_WAL;
760      case 2:
761        return Durability.ASYNC_WAL;
762      case 3:
763        return Durability.SYNC_WAL;
764      case 4:
765        return Durability.FSYNC_WAL;
766      default:
767        return Durability.USE_DEFAULT;
768    }
769  }
770
771  public static CompareOperator compareOpFromThrift(TCompareOperator tCompareOp) {
772    switch (tCompareOp.getValue()) {
773      case 0:
774        return CompareOperator.LESS;
775      case 1:
776        return CompareOperator.LESS_OR_EQUAL;
777      case 2:
778        return CompareOperator.EQUAL;
779      case 3:
780        return CompareOperator.NOT_EQUAL;
781      case 4:
782        return CompareOperator.GREATER_OR_EQUAL;
783      case 5:
784        return CompareOperator.GREATER;
785      case 6:
786        return CompareOperator.NO_OP;
787      default:
788        return null;
789    }
790  }
791
792  private static ReadType readTypeFromThrift(TReadType tReadType) {
793    switch (tReadType.getValue()) {
794      case 1:
795        return ReadType.DEFAULT;
796      case 2:
797        return ReadType.STREAM;
798      case 3:
799        return ReadType.PREAD;
800      default:
801        return null;
802    }
803  }
804
805  private static TReadType readTypeFromHBase(ReadType readType) {
806    switch (readType) {
807      case DEFAULT:
808        return TReadType.DEFAULT;
809      case STREAM:
810        return TReadType.STREAM;
811      case PREAD:
812        return TReadType.PREAD;
813      default:
814        return TReadType.DEFAULT;
815    }
816  }
817
818  private static Consistency consistencyFromThrift(TConsistency tConsistency) {
819    switch (tConsistency.getValue()) {
820      case 1:
821        return Consistency.STRONG;
822      case 2:
823        return Consistency.TIMELINE;
824      default:
825        return Consistency.STRONG;
826    }
827  }
828
829  public static TableName tableNameFromThrift(TTableName tableName) {
830    return TableName.valueOf(tableName.getNs(), tableName.getQualifier());
831  }
832
833  public static TableName[] tableNamesArrayFromThrift(List<TTableName> tableNames) {
834    TableName[] out = new TableName[tableNames.size()];
835    int index = 0;
836    for (TTableName tableName : tableNames) {
837      out[index++] = tableNameFromThrift(tableName);
838    }
839    return out;
840  }
841
842  public static List<TableName> tableNamesFromThrift(List<TTableName> tableNames) {
843    List<TableName> out = new ArrayList<>(tableNames.size());
844    for (TTableName tableName : tableNames) {
845      out.add(tableNameFromThrift(tableName));
846    }
847    return out;
848  }
849
850  public static TTableName tableNameFromHBase(TableName table) {
851    TTableName tableName = new TTableName();
852    tableName.setNs(table.getNamespace());
853    tableName.setQualifier(table.getQualifier());
854    return tableName;
855  }
856
857  public static List<TTableName> tableNamesFromHBase(List<TableName> in) {
858    List<TTableName> out = new ArrayList<>(in.size());
859    for (TableName tableName : in) {
860      out.add(tableNameFromHBase(tableName));
861    }
862    return out;
863  }
864
865  public static List<TTableName> tableNamesFromHBase(TableName[] in) {
866    List<TTableName> out = new ArrayList<>(in.length);
867    for (TableName tableName : in) {
868      out.add(tableNameFromHBase(tableName));
869    }
870    return out;
871  }
872
873  public static byte[][] splitKeyFromThrift(List<ByteBuffer> in) {
874    if (in == null || in.size() == 0) {
875      return null;
876    }
877    byte[][] out = new byte[in.size()][];
878    int index = 0;
879    for (ByteBuffer key : in) {
880      out[index++] = key.array();
881    }
882    return out;
883  }
884
885  public static BloomType bloomFilterFromThrift(TBloomFilterType in) {
886    switch (in.getValue()) {
887      case 0:
888        return BloomType.NONE;
889      case 1:
890        return BloomType.ROW;
891      case 2:
892        return BloomType.ROWCOL;
893      case 3:
894        return BloomType.ROWPREFIX_FIXED_LENGTH;
895      default:
896        return BloomType.ROW;
897    }
898  }
899
900  public static Compression.Algorithm compressionAlgorithmFromThrift(TCompressionAlgorithm in) {
901    switch (in.getValue()) {
902      case 0:
903        return Compression.Algorithm.LZO;
904      case 1:
905        return Compression.Algorithm.GZ;
906      case 2:
907        return Compression.Algorithm.NONE;
908      case 3:
909        return Compression.Algorithm.SNAPPY;
910      case 4:
911        return Compression.Algorithm.LZ4;
912      case 5:
913        return Compression.Algorithm.BZIP2;
914      case 6:
915        return Compression.Algorithm.ZSTD;
916      default:
917        return Compression.Algorithm.NONE;
918    }
919  }
920
921  public static DataBlockEncoding dataBlockEncodingFromThrift(TDataBlockEncoding in) {
922    switch (in.getValue()) {
923      case 0:
924        return DataBlockEncoding.NONE;
925      case 2:
926        return DataBlockEncoding.PREFIX;
927      case 3:
928        return DataBlockEncoding.DIFF;
929      case 4:
930        return DataBlockEncoding.FAST_DIFF;
931      case 7:
932        return DataBlockEncoding.ROW_INDEX_V1;
933      default:
934        return DataBlockEncoding.NONE;
935    }
936  }
937
938  public static KeepDeletedCells keepDeletedCellsFromThrift(TKeepDeletedCells in) {
939    switch (in.getValue()) {
940      case 0:
941        return KeepDeletedCells.FALSE;
942      case 1:
943        return KeepDeletedCells.TRUE;
944      case 2:
945        return KeepDeletedCells.TTL;
946      default:
947        return KeepDeletedCells.FALSE;
948    }
949  }
950
951  public static ColumnFamilyDescriptor
952    columnFamilyDescriptorFromThrift(TColumnFamilyDescriptor in) {
953    ColumnFamilyDescriptorBuilder builder = ColumnFamilyDescriptorBuilder.newBuilder(in.getName());
954
955    if (in.isSetAttributes()) {
956      for (Map.Entry<ByteBuffer, ByteBuffer> attribute : in.getAttributes().entrySet()) {
957        builder.setValue(attribute.getKey().array(), attribute.getValue().array());
958      }
959    }
960    if (in.isSetConfiguration()) {
961      for (Map.Entry<String, String> conf : in.getConfiguration().entrySet()) {
962        builder.setConfiguration(conf.getKey(), conf.getValue());
963      }
964    }
965    if (in.isSetBlockSize()) {
966      builder.setBlocksize(in.getBlockSize());
967    }
968    if (in.isSetBloomnFilterType()) {
969      builder.setBloomFilterType(bloomFilterFromThrift(in.getBloomnFilterType()));
970    }
971    if (in.isSetCompressionType()) {
972      builder.setCompressionType(compressionAlgorithmFromThrift(in.getCompressionType()));
973    }
974    if (in.isSetDfsReplication()) {
975      builder.setDFSReplication(in.getDfsReplication());
976    }
977    if (in.isSetDataBlockEncoding()) {
978      builder.setDataBlockEncoding(dataBlockEncodingFromThrift(in.getDataBlockEncoding()));
979    }
980    if (in.isSetKeepDeletedCells()) {
981      builder.setKeepDeletedCells(keepDeletedCellsFromThrift(in.getKeepDeletedCells()));
982    }
983    if (in.isSetMaxVersions()) {
984      builder.setMaxVersions(in.getMaxVersions());
985    }
986    if (in.isSetMinVersions()) {
987      builder.setMinVersions(in.getMinVersions());
988    }
989    if (in.isSetScope()) {
990      builder.setScope(in.getScope());
991    }
992    if (in.isSetTimeToLive()) {
993      builder.setTimeToLive(in.getTimeToLive());
994    }
995    if (in.isSetBlockCacheEnabled()) {
996      builder.setBlockCacheEnabled(in.isBlockCacheEnabled());
997    }
998    if (in.isSetCacheBloomsOnWrite()) {
999      builder.setCacheBloomsOnWrite(in.isCacheBloomsOnWrite());
1000    }
1001    if (in.isSetCacheDataOnWrite()) {
1002      builder.setCacheDataOnWrite(in.isCacheDataOnWrite());
1003    }
1004    if (in.isSetCacheIndexesOnWrite()) {
1005      builder.setCacheIndexesOnWrite(in.isCacheIndexesOnWrite());
1006    }
1007    if (in.isSetCompressTags()) {
1008      builder.setCompressTags(in.isCompressTags());
1009    }
1010    if (in.isSetEvictBlocksOnClose()) {
1011      builder.setEvictBlocksOnClose(in.isEvictBlocksOnClose());
1012    }
1013    if (in.isSetInMemory()) {
1014      builder.setInMemory(in.isInMemory());
1015    }
1016
1017    return builder.build();
1018  }
1019
1020  public static NamespaceDescriptor namespaceDescriptorFromThrift(TNamespaceDescriptor in) {
1021    NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(in.getName());
1022    if (in.isSetConfiguration()) {
1023      for (Map.Entry<String, String> conf : in.getConfiguration().entrySet()) {
1024        builder.addConfiguration(conf.getKey(), conf.getValue());
1025      }
1026    }
1027    return builder.build();
1028  }
1029
1030  public static TNamespaceDescriptor namespaceDescriptorFromHBase(NamespaceDescriptor in) {
1031    TNamespaceDescriptor out = new TNamespaceDescriptor();
1032    out.setName(in.getName());
1033    for (Map.Entry<String, String> conf : in.getConfiguration().entrySet()) {
1034      out.putToConfiguration(conf.getKey(), conf.getValue());
1035    }
1036    return out;
1037  }
1038
1039  public static List<TNamespaceDescriptor> namespaceDescriptorsFromHBase(NamespaceDescriptor[] in) {
1040    List<TNamespaceDescriptor> out = new ArrayList<>(in.length);
1041    for (NamespaceDescriptor descriptor : in) {
1042      out.add(namespaceDescriptorFromHBase(descriptor));
1043    }
1044    return out;
1045  }
1046
1047  public static TableDescriptor tableDescriptorFromThrift(TTableDescriptor in) {
1048    TableDescriptorBuilder builder =
1049      TableDescriptorBuilder.newBuilder(tableNameFromThrift(in.getTableName()));
1050    for (TColumnFamilyDescriptor column : in.getColumns()) {
1051      builder.setColumnFamily(columnFamilyDescriptorFromThrift(column));
1052    }
1053    if (in.isSetAttributes()) {
1054      for (Map.Entry<ByteBuffer, ByteBuffer> attribute : in.getAttributes().entrySet()) {
1055        builder.setValue(attribute.getKey().array(), attribute.getValue().array());
1056      }
1057    }
1058    if (in.isSetDurability()) {
1059      builder.setDurability(durabilityFromThrift(in.getDurability()));
1060    }
1061    return builder.build();
1062  }
1063
1064  public static List<TableDescriptor> tableDescriptorsFromThrift(List<TTableDescriptor> in) {
1065    List<TableDescriptor> out = new ArrayList<>();
1066    for (TTableDescriptor tableDescriptor : in) {
1067      out.add(tableDescriptorFromThrift(tableDescriptor));
1068    }
1069    return out;
1070  }
1071
1072  private static TDurability durabilityFromHBase(Durability durability) {
1073    switch (durability) {
1074      case USE_DEFAULT:
1075        return TDurability.USE_DEFAULT;
1076      case SKIP_WAL:
1077        return TDurability.SKIP_WAL;
1078      case ASYNC_WAL:
1079        return TDurability.ASYNC_WAL;
1080      case SYNC_WAL:
1081        return TDurability.SYNC_WAL;
1082      case FSYNC_WAL:
1083        return TDurability.FSYNC_WAL;
1084      default:
1085        return null;
1086    }
1087  }
1088
1089  public static TTableDescriptor tableDescriptorFromHBase(TableDescriptor in) {
1090    TTableDescriptor out = new TTableDescriptor();
1091    out.setTableName(tableNameFromHBase(in.getTableName()));
1092    Map<Bytes, Bytes> attributes = in.getValues();
1093    for (Map.Entry<Bytes, Bytes> attribute : attributes.entrySet()) {
1094      out.putToAttributes(ByteBuffer.wrap(attribute.getKey().get()),
1095        ByteBuffer.wrap(attribute.getValue().get()));
1096    }
1097    for (ColumnFamilyDescriptor column : in.getColumnFamilies()) {
1098      out.addToColumns(columnFamilyDescriptorFromHBase(column));
1099    }
1100    out.setDurability(durabilityFromHBase(in.getDurability()));
1101    return out;
1102  }
1103
1104  public static List<TTableDescriptor> tableDescriptorsFromHBase(List<TableDescriptor> in) {
1105    List<TTableDescriptor> out = new ArrayList<>(in.size());
1106    for (TableDescriptor descriptor : in) {
1107      out.add(tableDescriptorFromHBase(descriptor));
1108    }
1109    return out;
1110  }
1111
1112  public static List<TTableDescriptor> tableDescriptorsFromHBase(TableDescriptor[] in) {
1113    List<TTableDescriptor> out = new ArrayList<>(in.length);
1114    for (TableDescriptor descriptor : in) {
1115      out.add(tableDescriptorFromHBase(descriptor));
1116    }
1117    return out;
1118  }
1119
1120  public static TBloomFilterType bloomFilterFromHBase(BloomType in) {
1121    switch (in) {
1122      case NONE:
1123        return TBloomFilterType.NONE;
1124      case ROW:
1125        return TBloomFilterType.ROW;
1126      case ROWCOL:
1127        return TBloomFilterType.ROWCOL;
1128      case ROWPREFIX_FIXED_LENGTH:
1129        return TBloomFilterType.ROWPREFIX_FIXED_LENGTH;
1130      default:
1131        return TBloomFilterType.ROW;
1132    }
1133  }
1134
1135  public static TCompressionAlgorithm compressionAlgorithmFromHBase(Compression.Algorithm in) {
1136    switch (in) {
1137      case LZO:
1138        return TCompressionAlgorithm.LZO;
1139      case GZ:
1140        return TCompressionAlgorithm.GZ;
1141      case NONE:
1142        return TCompressionAlgorithm.NONE;
1143      case SNAPPY:
1144        return TCompressionAlgorithm.SNAPPY;
1145      case LZ4:
1146        return TCompressionAlgorithm.LZ4;
1147      case BZIP2:
1148        return TCompressionAlgorithm.BZIP2;
1149      case ZSTD:
1150        return TCompressionAlgorithm.ZSTD;
1151      default:
1152        return TCompressionAlgorithm.NONE;
1153    }
1154  }
1155
1156  public static TDataBlockEncoding dataBlockEncodingFromHBase(DataBlockEncoding in) {
1157    switch (in) {
1158      case NONE:
1159        return TDataBlockEncoding.NONE;
1160      case PREFIX:
1161        return TDataBlockEncoding.PREFIX;
1162      case DIFF:
1163        return TDataBlockEncoding.DIFF;
1164      case FAST_DIFF:
1165        return TDataBlockEncoding.FAST_DIFF;
1166      case ROW_INDEX_V1:
1167        return TDataBlockEncoding.ROW_INDEX_V1;
1168      default:
1169        return TDataBlockEncoding.NONE;
1170    }
1171  }
1172
1173  public static TKeepDeletedCells keepDeletedCellsFromHBase(KeepDeletedCells in) {
1174    switch (in) {
1175      case FALSE:
1176        return TKeepDeletedCells.FALSE;
1177      case TRUE:
1178        return TKeepDeletedCells.TRUE;
1179      case TTL:
1180        return TKeepDeletedCells.TTL;
1181      default:
1182        return TKeepDeletedCells.FALSE;
1183    }
1184  }
1185
1186  public static TColumnFamilyDescriptor columnFamilyDescriptorFromHBase(ColumnFamilyDescriptor in) {
1187    TColumnFamilyDescriptor out = new TColumnFamilyDescriptor();
1188    out.setName(in.getName());
1189    for (Map.Entry<Bytes, Bytes> attribute : in.getValues().entrySet()) {
1190      out.putToAttributes(ByteBuffer.wrap(attribute.getKey().get()),
1191        ByteBuffer.wrap(attribute.getValue().get()));
1192    }
1193    for (Map.Entry<String, String> conf : in.getConfiguration().entrySet()) {
1194      out.putToConfiguration(conf.getKey(), conf.getValue());
1195    }
1196    out.setBlockSize(in.getBlocksize());
1197    out.setBloomnFilterType(bloomFilterFromHBase(in.getBloomFilterType()));
1198    out.setCompressionType(compressionAlgorithmFromHBase(in.getCompressionType()));
1199    out.setDfsReplication(in.getDFSReplication());
1200    out.setDataBlockEncoding(dataBlockEncodingFromHBase(in.getDataBlockEncoding()));
1201    out.setKeepDeletedCells(keepDeletedCellsFromHBase(in.getKeepDeletedCells()));
1202    out.setMaxVersions(in.getMaxVersions());
1203    out.setMinVersions(in.getMinVersions());
1204    out.setScope(in.getScope());
1205    out.setTimeToLive(in.getTimeToLive());
1206    out.setBlockCacheEnabled(in.isBlockCacheEnabled());
1207    out.setCacheBloomsOnWrite(in.isCacheBloomsOnWrite());
1208    out.setCacheDataOnWrite(in.isCacheDataOnWrite());
1209    out.setCacheIndexesOnWrite(in.isCacheIndexesOnWrite());
1210    out.setCompressTags(in.isCompressTags());
1211    out.setEvictBlocksOnClose(in.isEvictBlocksOnClose());
1212    out.setInMemory(in.isInMemory());
1213    return out;
1214  }
1215
1216  private static TConsistency consistencyFromHBase(Consistency consistency) {
1217    switch (consistency) {
1218      case STRONG:
1219        return TConsistency.STRONG;
1220      case TIMELINE:
1221        return TConsistency.TIMELINE;
1222      default:
1223        return TConsistency.STRONG;
1224    }
1225  }
1226
1227  public static TGet getFromHBase(Get in) {
1228    TGet out = new TGet();
1229    out.setRow(in.getRow());
1230
1231    TTimeRange tTimeRange = new TTimeRange();
1232    tTimeRange.setMaxStamp(in.getTimeRange().getMax()).setMinStamp(in.getTimeRange().getMin());
1233    out.setTimeRange(tTimeRange);
1234    out.setMaxVersions(in.getMaxVersions());
1235
1236    for (Map.Entry<String, byte[]> attribute : in.getAttributesMap().entrySet()) {
1237      out.putToAttributes(ByteBuffer.wrap(Bytes.toBytes(attribute.getKey())),
1238        ByteBuffer.wrap(attribute.getValue()));
1239    }
1240    try {
1241      Authorizations authorizations = in.getAuthorizations();
1242      if (authorizations != null) {
1243        TAuthorization tAuthorization = new TAuthorization();
1244        tAuthorization.setLabels(authorizations.getLabels());
1245        out.setAuthorizations(tAuthorization);
1246      }
1247    } catch (DeserializationException e) {
1248      throw new RuntimeException(e);
1249    }
1250    out.setConsistency(consistencyFromHBase(in.getConsistency()));
1251    out.setTargetReplicaId(in.getReplicaId());
1252    out.setCacheBlocks(in.getCacheBlocks());
1253    out.setStoreLimit(in.getMaxResultsPerColumnFamily());
1254    out.setStoreOffset(in.getRowOffsetPerColumnFamily());
1255    out.setExistence_only(in.isCheckExistenceOnly());
1256    for (Map.Entry<byte[], NavigableSet<byte[]>> family : in.getFamilyMap().entrySet()) {
1257
1258      if (family.getValue() != null && !family.getValue().isEmpty()) {
1259        for (byte[] qualifier : family.getValue()) {
1260          TColumn column = new TColumn();
1261          column.setFamily(family.getKey());
1262          column.setQualifier(qualifier);
1263          out.addToColumns(column);
1264        }
1265      } else {
1266        TColumn column = new TColumn();
1267        column.setFamily(family.getKey());
1268        out.addToColumns(column);
1269      }
1270    }
1271    if (in.getFilter() != null) {
1272      try {
1273        out.setFilterBytes(filterFromHBase(in.getFilter()));
1274      } catch (IOException ioE) {
1275        throw new RuntimeException(ioE);
1276      }
1277    }
1278    return out;
1279  }
1280
1281  public static Cell toCell(ExtendedCellBuilder cellBuilder, byte[] row, TColumnValue columnValue) {
1282    return cellBuilder.clear().setRow(row).setFamily(columnValue.getFamily())
1283      .setQualifier(columnValue.getQualifier()).setTimestamp(columnValue.getTimestamp())
1284      .setType(columnValue.getType()).setValue(columnValue.getValue())
1285      .setTags(columnValue.getTags()).build();
1286  }
1287
1288  public static Result resultFromThrift(TResult in) {
1289    if (in == null) {
1290      return null;
1291    }
1292    if (!in.isSetColumnValues() || in.getColumnValues().isEmpty()) {
1293      return in.isStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT;
1294    }
1295    List<Cell> cells = new ArrayList<>(in.getColumnValues().size());
1296    ExtendedCellBuilder builder = ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY);
1297    for (TColumnValue columnValue : in.getColumnValues()) {
1298      cells.add(toCell(builder, in.getRow(), columnValue));
1299    }
1300    return Result.create(cells, null, in.isStale(), in.isPartial());
1301  }
1302
1303  public static TPut putFromHBase(Put in) {
1304    TPut out = new TPut();
1305    out.setRow(in.getRow());
1306    if (in.getTimestamp() != HConstants.LATEST_TIMESTAMP) {
1307      out.setTimestamp(in.getTimestamp());
1308    }
1309    if (in.getDurability() != Durability.USE_DEFAULT) {
1310      out.setDurability(durabilityFromHBase(in.getDurability()));
1311    }
1312    for (Map.Entry<byte[], List<Cell>> entry : in.getFamilyCellMap().entrySet()) {
1313      byte[] family = entry.getKey();
1314      for (Cell cell : entry.getValue()) {
1315        TColumnValue columnValue = new TColumnValue();
1316        columnValue.setFamily(family).setQualifier(CellUtil.cloneQualifier(cell))
1317          .setType(cell.getType().getCode()).setTimestamp(cell.getTimestamp())
1318          .setValue(CellUtil.cloneValue(cell));
1319        if (cell.getTagsLength() != 0) {
1320          columnValue.setTags(PrivateCellUtil.cloneTags(cell));
1321        }
1322        out.addToColumnValues(columnValue);
1323      }
1324    }
1325    for (Map.Entry<String, byte[]> attribute : in.getAttributesMap().entrySet()) {
1326      out.putToAttributes(ByteBuffer.wrap(Bytes.toBytes(attribute.getKey())),
1327        ByteBuffer.wrap(attribute.getValue()));
1328    }
1329    try {
1330      CellVisibility cellVisibility = in.getCellVisibility();
1331      if (cellVisibility != null) {
1332        TCellVisibility tCellVisibility = new TCellVisibility();
1333        tCellVisibility.setExpression(cellVisibility.getExpression());
1334        out.setCellVisibility(tCellVisibility);
1335      }
1336    } catch (DeserializationException e) {
1337      throw new RuntimeException(e);
1338    }
1339    return out;
1340  }
1341
1342  public static List<TPut> putsFromHBase(List<Put> in) {
1343    List<TPut> out = new ArrayList<>(in.size());
1344    for (Put put : in) {
1345      out.add(putFromHBase(put));
1346    }
1347    return out;
1348  }
1349
1350  public static NamespaceDescriptor[]
1351    namespaceDescriptorsFromThrift(List<TNamespaceDescriptor> in) {
1352    NamespaceDescriptor[] out = new NamespaceDescriptor[in.size()];
1353    int index = 0;
1354    for (TNamespaceDescriptor descriptor : in) {
1355      out[index++] = namespaceDescriptorFromThrift(descriptor);
1356    }
1357    return out;
1358  }
1359
1360  public static List<TDelete> deletesFromHBase(List<Delete> in) {
1361    List<TDelete> out = new ArrayList<>(in.size());
1362    for (Delete delete : in) {
1363      out.add(deleteFromHBase(delete));
1364    }
1365    return out;
1366  }
1367
1368  public static TAppend appendFromHBase(Append in) throws IOException {
1369    TAppend out = new TAppend();
1370    out.setRow(in.getRow());
1371
1372    if (in.getDurability() != Durability.USE_DEFAULT) {
1373      out.setDurability(durabilityFromHBase(in.getDurability()));
1374    }
1375    for (Map.Entry<byte[], List<Cell>> entry : in.getFamilyCellMap().entrySet()) {
1376      byte[] family = entry.getKey();
1377      for (Cell cell : entry.getValue()) {
1378        TColumnValue columnValue = new TColumnValue();
1379        columnValue.setFamily(family).setQualifier(CellUtil.cloneQualifier(cell))
1380          .setType(cell.getType().getCode()).setTimestamp(cell.getTimestamp())
1381          .setValue(CellUtil.cloneValue(cell));
1382        if (cell.getTagsLength() != 0) {
1383          columnValue.setTags(PrivateCellUtil.cloneTags(cell));
1384        }
1385        out.addToColumns(columnValue);
1386      }
1387    }
1388    for (Map.Entry<String, byte[]> attribute : in.getAttributesMap().entrySet()) {
1389      out.putToAttributes(ByteBuffer.wrap(Bytes.toBytes(attribute.getKey())),
1390        ByteBuffer.wrap(attribute.getValue()));
1391    }
1392    try {
1393      CellVisibility cellVisibility = in.getCellVisibility();
1394      if (cellVisibility != null) {
1395        TCellVisibility tCellVisibility = new TCellVisibility();
1396        tCellVisibility.setExpression(cellVisibility.getExpression());
1397        out.setCellVisibility(tCellVisibility);
1398      }
1399    } catch (DeserializationException e) {
1400      throw new RuntimeException(e);
1401    }
1402    out.setReturnResults(in.isReturnResults());
1403    return out;
1404  }
1405
1406  public static TIncrement incrementFromHBase(Increment in) throws IOException {
1407    TIncrement out = new TIncrement();
1408    out.setRow(in.getRow());
1409
1410    if (in.getDurability() != Durability.USE_DEFAULT) {
1411      out.setDurability(durabilityFromHBase(in.getDurability()));
1412    }
1413    for (Map.Entry<byte[], List<Cell>> entry : in.getFamilyCellMap().entrySet()) {
1414      byte[] family = entry.getKey();
1415      for (Cell cell : entry.getValue()) {
1416        TColumnIncrement columnValue = new TColumnIncrement();
1417        columnValue.setFamily(family).setQualifier(CellUtil.cloneQualifier(cell));
1418        columnValue.setAmount(
1419          Bytes.toLong(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
1420        out.addToColumns(columnValue);
1421      }
1422    }
1423    for (Map.Entry<String, byte[]> attribute : in.getAttributesMap().entrySet()) {
1424      out.putToAttributes(ByteBuffer.wrap(Bytes.toBytes(attribute.getKey())),
1425        ByteBuffer.wrap(attribute.getValue()));
1426    }
1427    try {
1428      CellVisibility cellVisibility = in.getCellVisibility();
1429      if (cellVisibility != null) {
1430        TCellVisibility tCellVisibility = new TCellVisibility();
1431        tCellVisibility.setExpression(cellVisibility.getExpression());
1432        out.setCellVisibility(tCellVisibility);
1433      }
1434    } catch (DeserializationException e) {
1435      throw new RuntimeException(e);
1436    }
1437    out.setReturnResults(in.isReturnResults());
1438    return out;
1439  }
1440
1441  public static TRowMutations rowMutationsFromHBase(RowMutations in) {
1442    TRowMutations tRowMutations = new TRowMutations();
1443    tRowMutations.setRow(in.getRow());
1444    for (Mutation mutation : in.getMutations()) {
1445      TMutation tMutation = new TMutation();
1446      if (mutation instanceof Put) {
1447        tMutation.setPut(ThriftUtilities.putFromHBase((Put) mutation));
1448      } else if (mutation instanceof Delete) {
1449        tMutation.setDeleteSingle(ThriftUtilities.deleteFromHBase((Delete) mutation));
1450      } else {
1451        throw new IllegalArgumentException(
1452          "Only Put and Delete is supported in mutateRow, but muation=" + mutation);
1453      }
1454      tRowMutations.addToMutations(tMutation);
1455    }
1456    return tRowMutations;
1457  }
1458
1459  public static TCompareOperator compareOpFromHBase(CompareOperator compareOp) {
1460    switch (compareOp) {
1461      case LESS:
1462        return TCompareOperator.LESS;
1463      case LESS_OR_EQUAL:
1464        return TCompareOperator.LESS_OR_EQUAL;
1465      case EQUAL:
1466        return TCompareOperator.EQUAL;
1467      case NOT_EQUAL:
1468        return TCompareOperator.NOT_EQUAL;
1469      case GREATER_OR_EQUAL:
1470        return TCompareOperator.GREATER_OR_EQUAL;
1471      case GREATER:
1472        return TCompareOperator.GREATER;
1473      case NO_OP:
1474        return TCompareOperator.NO_OP;
1475      default:
1476        return null;
1477    }
1478  }
1479
1480  public static List<ByteBuffer> splitKeyFromHBase(byte[][] in) {
1481    if (in == null || in.length == 0) {
1482      return null;
1483    }
1484    List<ByteBuffer> out = new ArrayList<>(in.length);
1485    for (byte[] key : in) {
1486      out.add(ByteBuffer.wrap(key));
1487    }
1488    return out;
1489  }
1490
1491  public static Result[] resultsFromThrift(List<TResult> in) {
1492    Result[] out = new Result[in.size()];
1493    int index = 0;
1494    for (TResult tResult : in) {
1495      out[index++] = resultFromThrift(tResult);
1496    }
1497    return out;
1498  }
1499
1500  public static List<TGet> getsFromHBase(List<Get> in) {
1501    List<TGet> out = new ArrayList<>(in.size());
1502    for (Get get : in) {
1503      out.add(getFromHBase(get));
1504    }
1505    return out;
1506  }
1507
1508  public static Set<TServerName> getServerNamesFromHBase(Set<ServerName> serverNames) {
1509    if (CollectionUtils.isEmpty(serverNames)) {
1510      return Collections.emptySet();
1511    }
1512    return serverNames.stream().map(serverName -> {
1513      TServerName tServerName = new TServerName();
1514      tServerName.setHostName(serverName.getHostname());
1515      tServerName.setPort(serverName.getPort());
1516      tServerName.setStartCode(serverName.getStartcode());
1517      return tServerName;
1518    }).collect(Collectors.toSet());
1519  }
1520
1521  public static Set<ServerName> getServerNamesFromThrift(Set<TServerName> tServerNames) {
1522    if (CollectionUtils.isEmpty(tServerNames)) {
1523      return Collections.emptySet();
1524    }
1525    return tServerNames.stream().map(tServerName -> ServerName.valueOf(tServerName.getHostName(),
1526      tServerName.getPort(), tServerName.getStartCode())).collect(Collectors.toSet());
1527  }
1528
1529  public static TLogQueryFilter getSlowLogQueryFromHBase(LogQueryFilter logQueryFilter) {
1530    TLogQueryFilter tLogQueryFilter = new TLogQueryFilter();
1531    tLogQueryFilter.setRegionName(logQueryFilter.getRegionName());
1532    tLogQueryFilter.setClientAddress(logQueryFilter.getClientAddress());
1533    tLogQueryFilter.setTableName(logQueryFilter.getTableName());
1534    tLogQueryFilter.setUserName(logQueryFilter.getUserName());
1535    tLogQueryFilter.setLimit(logQueryFilter.getLimit());
1536    TLogType tLogType = gettLogTypeFromHBase(logQueryFilter);
1537    tLogQueryFilter.setLogType(tLogType);
1538    TFilterByOperator tFilterByOperator = getTFilterByFromHBase(logQueryFilter);
1539    tLogQueryFilter.setFilterByOperator(tFilterByOperator);
1540    return tLogQueryFilter;
1541  }
1542
1543  private static TLogType gettLogTypeFromHBase(final LogQueryFilter logQueryFilter) {
1544    TLogType tLogType;
1545    switch (logQueryFilter.getType()) {
1546      case SLOW_LOG: {
1547        tLogType = TLogType.SLOW_LOG;
1548        break;
1549      }
1550      case LARGE_LOG: {
1551        tLogType = TLogType.LARGE_LOG;
1552        break;
1553      }
1554      default: {
1555        tLogType = TLogType.SLOW_LOG;
1556      }
1557    }
1558    return tLogType;
1559  }
1560
1561  private static TFilterByOperator getTFilterByFromHBase(final LogQueryFilter logQueryFilter) {
1562    TFilterByOperator tFilterByOperator;
1563    switch (logQueryFilter.getFilterByOperator()) {
1564      case AND: {
1565        tFilterByOperator = TFilterByOperator.AND;
1566        break;
1567      }
1568      case OR: {
1569        tFilterByOperator = TFilterByOperator.OR;
1570        break;
1571      }
1572      default: {
1573        tFilterByOperator = TFilterByOperator.OR;
1574      }
1575    }
1576    return tFilterByOperator;
1577  }
1578
1579  public static LogQueryFilter getSlowLogQueryFromThrift(TLogQueryFilter tLogQueryFilter) {
1580    LogQueryFilter logQueryFilter = new LogQueryFilter();
1581    logQueryFilter.setRegionName(tLogQueryFilter.getRegionName());
1582    logQueryFilter.setClientAddress(tLogQueryFilter.getClientAddress());
1583    logQueryFilter.setTableName(tLogQueryFilter.getTableName());
1584    logQueryFilter.setUserName(tLogQueryFilter.getUserName());
1585    logQueryFilter.setLimit(tLogQueryFilter.getLimit());
1586    LogQueryFilter.Type type = getLogTypeFromThrift(tLogQueryFilter);
1587    logQueryFilter.setType(type);
1588    LogQueryFilter.FilterByOperator filterByOperator = getFilterByFromThrift(tLogQueryFilter);
1589    logQueryFilter.setFilterByOperator(filterByOperator);
1590    return logQueryFilter;
1591  }
1592
1593  private static LogQueryFilter.Type
1594    getLogTypeFromThrift(final TLogQueryFilter tSlowLogQueryFilter) {
1595    LogQueryFilter.Type type;
1596    switch (tSlowLogQueryFilter.getLogType()) {
1597      case SLOW_LOG: {
1598        type = LogQueryFilter.Type.SLOW_LOG;
1599        break;
1600      }
1601      case LARGE_LOG: {
1602        type = LogQueryFilter.Type.LARGE_LOG;
1603        break;
1604      }
1605      default: {
1606        type = LogQueryFilter.Type.SLOW_LOG;
1607      }
1608    }
1609    return type;
1610  }
1611
1612  private static LogQueryFilter.FilterByOperator
1613    getFilterByFromThrift(final TLogQueryFilter tLogQueryFilter) {
1614    LogQueryFilter.FilterByOperator filterByOperator;
1615    switch (tLogQueryFilter.getFilterByOperator()) {
1616      case AND: {
1617        filterByOperator = LogQueryFilter.FilterByOperator.AND;
1618        break;
1619      }
1620      case OR: {
1621        filterByOperator = LogQueryFilter.FilterByOperator.OR;
1622        break;
1623      }
1624      default: {
1625        filterByOperator = LogQueryFilter.FilterByOperator.OR;
1626      }
1627    }
1628    return filterByOperator;
1629  }
1630
1631  public static List<TOnlineLogRecord>
1632    getSlowLogRecordsFromHBase(List<OnlineLogRecord> onlineLogRecords) {
1633    if (CollectionUtils.isEmpty(onlineLogRecords)) {
1634      return Collections.emptyList();
1635    }
1636    return onlineLogRecords.stream().map(slowLogRecord -> {
1637      TOnlineLogRecord tOnlineLogRecord = new TOnlineLogRecord();
1638      tOnlineLogRecord.setCallDetails(slowLogRecord.getCallDetails());
1639      tOnlineLogRecord.setClientAddress(slowLogRecord.getClientAddress());
1640      tOnlineLogRecord.setMethodName(slowLogRecord.getMethodName());
1641      tOnlineLogRecord.setMultiGetsCount(slowLogRecord.getMultiGetsCount());
1642      tOnlineLogRecord.setMultiMutationsCount(slowLogRecord.getMultiMutationsCount());
1643      tOnlineLogRecord.setMultiServiceCalls(slowLogRecord.getMultiServiceCalls());
1644      tOnlineLogRecord.setParam(slowLogRecord.getParam());
1645      tOnlineLogRecord.setProcessingTime(slowLogRecord.getProcessingTime());
1646      tOnlineLogRecord.setQueueTime(slowLogRecord.getQueueTime());
1647      tOnlineLogRecord.setRegionName(slowLogRecord.getRegionName());
1648      tOnlineLogRecord.setResponseSize(slowLogRecord.getResponseSize());
1649      tOnlineLogRecord.setBlockBytesScanned(slowLogRecord.getBlockBytesScanned());
1650      tOnlineLogRecord.setFsReadTime(slowLogRecord.getFsReadTime());
1651      tOnlineLogRecord.setServerClass(slowLogRecord.getServerClass());
1652      tOnlineLogRecord.setStartTime(slowLogRecord.getStartTime());
1653      tOnlineLogRecord.setUserName(slowLogRecord.getUserName());
1654      return tOnlineLogRecord;
1655    }).collect(Collectors.toList());
1656  }
1657
1658  public static List<OnlineLogRecord>
1659    getSlowLogRecordsFromThrift(List<TOnlineLogRecord> tOnlineLogRecords) {
1660    if (CollectionUtils.isEmpty(tOnlineLogRecords)) {
1661      return Collections.emptyList();
1662    }
1663    return tOnlineLogRecords.stream()
1664      .map(tSlowLogRecord -> new OnlineLogRecord.OnlineLogRecordBuilder()
1665        .setCallDetails(tSlowLogRecord.getCallDetails())
1666        .setClientAddress(tSlowLogRecord.getClientAddress())
1667        .setMethodName(tSlowLogRecord.getMethodName())
1668        .setMultiGetsCount(tSlowLogRecord.getMultiGetsCount())
1669        .setMultiMutationsCount(tSlowLogRecord.getMultiMutationsCount())
1670        .setMultiServiceCalls(tSlowLogRecord.getMultiServiceCalls())
1671        .setParam(tSlowLogRecord.getParam()).setProcessingTime(tSlowLogRecord.getProcessingTime())
1672        .setQueueTime(tSlowLogRecord.getQueueTime()).setRegionName(tSlowLogRecord.getRegionName())
1673        .setResponseSize(tSlowLogRecord.getResponseSize())
1674        .setBlockBytesScanned(tSlowLogRecord.getBlockBytesScanned())
1675        .setServerClass(tSlowLogRecord.getServerClass()).setStartTime(tSlowLogRecord.getStartTime())
1676        .setUserName(tSlowLogRecord.getUserName()).build())
1677      .collect(Collectors.toList());
1678  }
1679
1680  public static Permission.Action[] permissionActionsFromString(String permission_actions) {
1681    Set<Permission.Action> actions = new HashSet<>();
1682    for (char c : permission_actions.toCharArray()) {
1683      switch (c) {
1684        case 'R':
1685          actions.add(Permission.Action.READ);
1686          break;
1687        case 'W':
1688          actions.add(Permission.Action.WRITE);
1689          break;
1690        case 'C':
1691          actions.add(Permission.Action.CREATE);
1692          break;
1693        case 'X':
1694          actions.add(Permission.Action.EXEC);
1695          break;
1696        case 'A':
1697          actions.add(Permission.Action.ADMIN);
1698          break;
1699        default:
1700          break;
1701      }
1702    }
1703    return actions.toArray(new Permission.Action[0]);
1704  }
1705
1706}