blob: c4bcbdc00037bf2752412fb67b77a89089edb26e [file] [log] [blame]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.thrift2;
import static org.apache.hadoop.hbase.util.Bytes.getBytes;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.Append;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HRegionLocator;
import org.apache.hadoop.hbase.client.Increment;
import org.apache.hadoop.hbase.client.OperationWithAttributes;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.ParseFilter;
import org.apache.hadoop.hbase.security.visibility.Authorizations;
import org.apache.hadoop.hbase.security.visibility.CellVisibility;
import org.apache.hadoop.hbase.thrift2.generated.TAppend;
import org.apache.hadoop.hbase.thrift2.generated.TColumn;
import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement;
import org.apache.hadoop.hbase.thrift2.generated.TColumnValue;
import org.apache.hadoop.hbase.thrift2.generated.TCompareOp;
import org.apache.hadoop.hbase.thrift2.generated.TDelete;
import org.apache.hadoop.hbase.thrift2.generated.TDeleteType;
import org.apache.hadoop.hbase.thrift2.generated.TDurability;
import org.apache.hadoop.hbase.thrift2.generated.TGet;
import org.apache.hadoop.hbase.thrift2.generated.THRegionInfo;
import org.apache.hadoop.hbase.thrift2.generated.THRegionLocation;
import org.apache.hadoop.hbase.thrift2.generated.TIncrement;
import org.apache.hadoop.hbase.thrift2.generated.TMutation;
import org.apache.hadoop.hbase.thrift2.generated.TPut;
import org.apache.hadoop.hbase.thrift2.generated.TResult;
import org.apache.hadoop.hbase.thrift2.generated.TRowMutations;
import org.apache.hadoop.hbase.thrift2.generated.TScan;
import org.apache.hadoop.hbase.thrift2.generated.TServerName;
import org.apache.hadoop.hbase.thrift2.generated.TTimeRange;
import org.apache.hadoop.hbase.util.Bytes;
@InterfaceAudience.Private
public class ThriftUtilities {
private ThriftUtilities() {
throw new UnsupportedOperationException("Can't initialize class");
}
/**
* Creates a {@link Get} (HBase) from a {@link TGet} (Thrift).
*
* This ignores any timestamps set on {@link TColumn} objects.
*
* @param in the <code>TGet</code> to convert
*
* @return <code>Get</code> object
*
* @throws IOException if an invalid time range or max version parameter is given
*/
public static Get getFromThrift(TGet in) throws IOException {
Get out = new Get(in.getRow());
// Timestamp overwrites time range if both are set
if (in.isSetTimestamp()) {
out.setTimeStamp(in.getTimestamp());
} else if (in.isSetTimeRange()) {
out.setTimeRange(in.getTimeRange().getMinStamp(), in.getTimeRange().getMaxStamp());
}
if (in.isSetMaxVersions()) {
out.setMaxVersions(in.getMaxVersions());
}
if (in.isSetFilterString()) {
ParseFilter parseFilter = new ParseFilter();
out.setFilter(parseFilter.parseFilterString(in.getFilterString()));
}
if (in.isSetAttributes()) {
addAttributes(out,in.getAttributes());
}
if (in.isSetAuthorizations()) {
out.setAuthorizations(new Authorizations(in.getAuthorizations().getLabels()));
}
if (!in.isSetColumns()) {
return out;
}
for (TColumn column : in.getColumns()) {
if (column.isSetQualifier()) {
out.addColumn(column.getFamily(), column.getQualifier());
} else {
out.addFamily(column.getFamily());
}
}
return out;
}
/**
* Converts multiple {@link TGet}s (Thrift) into a list of {@link Get}s (HBase).
*
* @param in list of <code>TGet</code>s to convert
*
* @return list of <code>Get</code> objects
*
* @throws IOException if an invalid time range or max version parameter is given
* @see #getFromThrift(TGet)
*/
public static List<Get> getsFromThrift(List<TGet> in) throws IOException {
List<Get> out = new ArrayList<Get>(in.size());
for (TGet get : in) {
out.add(getFromThrift(get));
}
return out;
}
/**
* Creates a {@link TResult} (Thrift) from a {@link Result} (HBase).
*
* @param in the <code>Result</code> to convert
*
* @return converted result, returns an empty result if the input is <code>null</code>
*/
public static TResult resultFromHBase(Result in) {
Cell[] raw = in.rawCells();
TResult out = new TResult();
byte[] row = in.getRow();
if (row != null) {
out.setRow(in.getRow());
}
List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
for (Cell kv : raw) {
TColumnValue col = new TColumnValue();
col.setFamily(CellUtil.cloneFamily(kv));
col.setQualifier(CellUtil.cloneQualifier(kv));
col.setTimestamp(kv.getTimestamp());
col.setValue(CellUtil.cloneValue(kv));
if (kv.getTagsLength() > 0) {
col.setTags(CellUtil.getTagArray(kv));
}
columnValues.add(col);
}
out.setColumnValues(columnValues);
return out;
}
/**
* Converts multiple {@link Result}s (HBase) into a list of {@link TResult}s (Thrift).
*
* @param in array of <code>Result</code>s to convert
*
* @return list of converted <code>TResult</code>s
*
* @see #resultFromHBase(Result)
*/
public static List<TResult> resultsFromHBase(Result[] in) {
List<TResult> out = new ArrayList<TResult>(in.length);
for (Result result : in) {
out.add(resultFromHBase(result));
}
return out;
}
/**
* Creates a {@link Put} (HBase) from a {@link TPut} (Thrift)
*
* @param in the <code>TPut</code> to convert
*
* @return converted <code>Put</code>
*/
public static Put putFromThrift(TPut in) {
Put out;
if (in.isSetTimestamp()) {
out = new Put(in.getRow(), in.getTimestamp());
} else {
out = new Put(in.getRow());
}
if (in.isSetDurability()) {
out.setDurability(durabilityFromThrift(in.getDurability()));
}
for (TColumnValue columnValue : in.getColumnValues()) {
if (columnValue.isSetTimestamp()) {
out.addImmutable(
columnValue.getFamily(), columnValue.getQualifier(), columnValue.getTimestamp(),
columnValue.getValue());
} else {
out.addImmutable(
columnValue.getFamily(), columnValue.getQualifier(), columnValue.getValue());
}
}
if (in.isSetAttributes()) {
addAttributes(out,in.getAttributes());
}
if (in.getCellVisibility() != null) {
out.setCellVisibility(new CellVisibility(in.getCellVisibility().getExpression()));
}
return out;
}
/**
* Converts multiple {@link TPut}s (Thrift) into a list of {@link Put}s (HBase).
*
* @param in list of <code>TPut</code>s to convert
*
* @return list of converted <code>Put</code>s
*
* @see #putFromThrift(TPut)
*/
public static List<Put> putsFromThrift(List<TPut> in) {
List<Put> out = new ArrayList<Put>(in.size());
for (TPut put : in) {
out.add(putFromThrift(put));
}
return out;
}
/**
* Creates a {@link Delete} (HBase) from a {@link TDelete} (Thrift).
*
* @param in the <code>TDelete</code> to convert
*
* @return converted <code>Delete</code>
*/
public static Delete deleteFromThrift(TDelete in) {
Delete out;
if (in.isSetColumns()) {
out = new Delete(in.getRow());
for (TColumn column : in.getColumns()) {
if (column.isSetQualifier()) {
if (column.isSetTimestamp()) {
if (in.isSetDeleteType() &&
in.getDeleteType().equals(TDeleteType.DELETE_COLUMNS))
out.deleteColumns(column.getFamily(), column.getQualifier(), column.getTimestamp());
else
out.deleteColumn(column.getFamily(), column.getQualifier(), column.getTimestamp());
} else {
if (in.isSetDeleteType() &&
in.getDeleteType().equals(TDeleteType.DELETE_COLUMNS))
out.deleteColumns(column.getFamily(), column.getQualifier());
else
out.deleteColumn(column.getFamily(), column.getQualifier());
}
} else {
if (column.isSetTimestamp()) {
out.deleteFamily(column.getFamily(), column.getTimestamp());
} else {
out.deleteFamily(column.getFamily());
}
}
}
} else {
if (in.isSetTimestamp()) {
out = new Delete(in.getRow(), in.getTimestamp());
} else {
out = new Delete(in.getRow());
}
}
if (in.isSetAttributes()) {
addAttributes(out,in.getAttributes());
}
if (in.isSetDurability()) {
out.setDurability(durabilityFromThrift(in.getDurability()));
}
return out;
}
/**
* Converts multiple {@link TDelete}s (Thrift) into a list of {@link Delete}s (HBase).
*
* @param in list of <code>TDelete</code>s to convert
*
* @return list of converted <code>Delete</code>s
*
* @see #deleteFromThrift(TDelete)
*/
public static List<Delete> deletesFromThrift(List<TDelete> in) {
List<Delete> out = new ArrayList<Delete>(in.size());
for (TDelete delete : in) {
out.add(deleteFromThrift(delete));
}
return out;
}
public static TDelete deleteFromHBase(Delete in) {
TDelete out = new TDelete(ByteBuffer.wrap(in.getRow()));
List<TColumn> columns = new ArrayList<TColumn>();
long rowTimestamp = in.getTimeStamp();
if (rowTimestamp != HConstants.LATEST_TIMESTAMP) {
out.setTimestamp(rowTimestamp);
}
// Map<family, List<KeyValue>>
for (Map.Entry<byte[], List<org.apache.hadoop.hbase.Cell>> familyEntry:
in.getFamilyCellMap().entrySet()) {
TColumn column = new TColumn(ByteBuffer.wrap(familyEntry.getKey()));
for (org.apache.hadoop.hbase.Cell cell: familyEntry.getValue()) {
byte[] family = CellUtil.cloneFamily(cell);
byte[] qualifier = CellUtil.cloneQualifier(cell);
long timestamp = cell.getTimestamp();
if (family != null) {
column.setFamily(family);
}
if (qualifier != null) {
column.setQualifier(qualifier);
}
if (timestamp != HConstants.LATEST_TIMESTAMP) {
column.setTimestamp(timestamp);
}
}
columns.add(column);
}
out.setColumns(columns);
return out;
}
/**
* Creates a {@link RowMutations} (HBase) from a {@link TRowMutations} (Thrift)
*
* @param in the <code>TRowMutations</code> to convert
*
* @return converted <code>RowMutations</code>
*/
public static RowMutations rowMutationsFromThrift(TRowMutations in) throws IOException {
RowMutations out = new RowMutations(in.getRow());
List<TMutation> mutations = in.getMutations();
for (TMutation mutation : mutations) {
if (mutation.isSetPut()) {
out.add(putFromThrift(mutation.getPut()));
}
if (mutation.isSetDeleteSingle()) {
out.add(deleteFromThrift(mutation.getDeleteSingle()));
}
}
return out;
}
public static Scan scanFromThrift(TScan in) throws IOException {
Scan out = new Scan();
if (in.isSetStartRow())
out.setStartRow(in.getStartRow());
if (in.isSetStopRow())
out.setStopRow(in.getStopRow());
if (in.isSetCaching())
out.setCaching(in.getCaching());
if (in.isSetMaxVersions()) {
out.setMaxVersions(in.getMaxVersions());
}
if (in.isSetColumns()) {
for (TColumn column : in.getColumns()) {
if (column.isSetQualifier()) {
out.addColumn(column.getFamily(), column.getQualifier());
} else {
out.addFamily(column.getFamily());
}
}
}
TTimeRange timeRange = in.getTimeRange();
if (timeRange != null &&
timeRange.isSetMinStamp() && timeRange.isSetMaxStamp()) {
out.setTimeRange(timeRange.getMinStamp(), timeRange.getMaxStamp());
}
if (in.isSetBatchSize()) {
out.setBatch(in.getBatchSize());
}
if (in.isSetFilterString()) {
ParseFilter parseFilter = new ParseFilter();
out.setFilter(parseFilter.parseFilterString(in.getFilterString()));
}
if (in.isSetAttributes()) {
addAttributes(out,in.getAttributes());
}
if (in.isSetAuthorizations()) {
out.setAuthorizations(new Authorizations(in.getAuthorizations().getLabels()));
}
if (in.isSetReversed()) {
out.setReversed(in.isReversed());
}
if (in.isSetCacheBlocks()) {
out.setCacheBlocks(in.isCacheBlocks());
}
if (in.isSetColFamTimeRangeMap()) {
Map<ByteBuffer, TTimeRange> colFamTimeRangeMap = in.getColFamTimeRangeMap();
if (MapUtils.isNotEmpty(colFamTimeRangeMap)) {
for (Map.Entry<ByteBuffer, TTimeRange> entry : colFamTimeRangeMap.entrySet()) {
out.setColumnFamilyTimeRange(Bytes.toBytes(entry.getKey()),
entry.getValue().getMinStamp(), entry.getValue().getMaxStamp());
}
}
}
if (in.isSetSmall()) {
out.setSmall(in.isSmall());
}
return out;
}
public static Increment incrementFromThrift(TIncrement in) throws IOException {
Increment out = new Increment(in.getRow());
for (TColumnIncrement column : in.getColumns()) {
out.addColumn(column.getFamily(), column.getQualifier(), column.getAmount());
}
if (in.isSetAttributes()) {
addAttributes(out,in.getAttributes());
}
if (in.isSetDurability()) {
out.setDurability(durabilityFromThrift(in.getDurability()));
}
if(in.getCellVisibility() != null) {
out.setCellVisibility(new CellVisibility(in.getCellVisibility().getExpression()));
}
return out;
}
public static Append appendFromThrift(TAppend append) throws IOException {
Append out = new Append(append.getRow());
for (TColumnValue column : append.getColumns()) {
out.add(column.getFamily(), column.getQualifier(), column.getValue());
}
if (append.isSetAttributes()) {
addAttributes(out, append.getAttributes());
}
if (append.isSetDurability()) {
out.setDurability(durabilityFromThrift(append.getDurability()));
}
if(append.getCellVisibility() != null) {
out.setCellVisibility(new CellVisibility(append.getCellVisibility().getExpression()));
}
return out;
}
public static THRegionLocation regionLocationFromHBase(HRegionLocation hrl) {
HRegionInfo hri = hrl.getRegionInfo();
ServerName serverName = hrl.getServerName();
THRegionInfo thRegionInfo = new THRegionInfo();
THRegionLocation thRegionLocation = new THRegionLocation();
TServerName tServerName = new TServerName();
tServerName.setHostName(serverName.getHostname());
tServerName.setPort(serverName.getPort());
tServerName.setStartCode(serverName.getStartcode());
thRegionInfo.setTableName(hri.getTable().getName());
thRegionInfo.setEndKey(hri.getEndKey());
thRegionInfo.setStartKey(hri.getStartKey());
thRegionInfo.setOffline(hri.isOffline());
thRegionInfo.setSplit(hri.isSplit());
thRegionInfo.setReplicaId(hri.getReplicaId());
thRegionLocation.setRegionInfo(thRegionInfo);
thRegionLocation.setServerName(tServerName);
return thRegionLocation;
}
public static List<THRegionLocation> regionLocationsFromHBase(List<HRegionLocation> locations) {
List<THRegionLocation> tlocations = new ArrayList<THRegionLocation>(locations.size());
for (HRegionLocation hrl:locations) {
tlocations.add(regionLocationFromHBase(hrl));
}
return tlocations;
}
/**
* Adds all the attributes into the Operation object
*/
private static void addAttributes(OperationWithAttributes op,
Map<ByteBuffer, ByteBuffer> attributes) {
if (attributes == null || attributes.size() == 0) {
return;
}
for (Map.Entry<ByteBuffer, ByteBuffer> entry : attributes.entrySet()) {
String name = Bytes.toStringBinary(getBytes(entry.getKey()));
byte[] value = getBytes(entry.getValue());
op.setAttribute(name, value);
}
}
private static Durability durabilityFromThrift(TDurability tDurability) {
switch (tDurability.getValue()) {
case 1: return Durability.SKIP_WAL;
case 2: return Durability.ASYNC_WAL;
case 3: return Durability.SYNC_WAL;
case 4: return Durability.FSYNC_WAL;
default: return null;
}
}
public static CompareOp compareOpFromThrift(TCompareOp tCompareOp) {
switch (tCompareOp.getValue()) {
case 0: return CompareOp.LESS;
case 1: return CompareOp.LESS_OR_EQUAL;
case 2: return CompareOp.EQUAL;
case 3: return CompareOp.NOT_EQUAL;
case 4: return CompareOp.GREATER_OR_EQUAL;
case 5: return CompareOp.GREATER;
case 6: return CompareOp.NO_OP;
default: return null;
}
}
}