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