Package com.alibaba.wasp.protobuf

Source Code of com.alibaba.wasp.protobuf.ProtobufUtil

/**
* 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 com.alibaba.wasp.protobuf;

import com.alibaba.wasp.DataType;
import com.alibaba.wasp.EntityGroupInfo;
import com.alibaba.wasp.FConstants;
import com.alibaba.wasp.MetaException;
import com.alibaba.wasp.ReadModel;
import com.alibaba.wasp.ServerName;
import com.alibaba.wasp.client.ExecuteResult;
import com.alibaba.wasp.client.QueryResult;
import com.alibaba.wasp.client.WriteResult;
import com.alibaba.wasp.fserver.AdminProtocol;
import com.alibaba.wasp.fserver.OperationStatus;
import com.alibaba.wasp.meta.FTable;
import com.alibaba.wasp.meta.Index;
import com.alibaba.wasp.plan.action.Action;
import com.alibaba.wasp.plan.action.ColumnStruct;
import com.alibaba.wasp.plan.action.DeleteAction;
import com.alibaba.wasp.plan.action.GetAction;
import com.alibaba.wasp.plan.action.InsertAction;
import com.alibaba.wasp.plan.action.ScanAction;
import com.alibaba.wasp.plan.action.TransactionAction;
import com.alibaba.wasp.plan.action.UpdateAction;
import com.alibaba.wasp.protobuf.generated.ClientProtos;
import com.alibaba.wasp.protobuf.generated.ClientProtos.ExecuteResultProto;
import com.alibaba.wasp.protobuf.generated.ClientProtos.StringDataTypePair;
import com.alibaba.wasp.protobuf.generated.ComparatorProtos;
import com.alibaba.wasp.protobuf.generated.ComparatorProtos.ByteArrayComparable;
import com.alibaba.wasp.protobuf.generated.FServerAdminProtos;
import com.alibaba.wasp.protobuf.generated.MasterAdminProtos;
import com.alibaba.wasp.protobuf.generated.MasterMonitorProtos;
import com.alibaba.wasp.protobuf.generated.MetaProtos;
import com.alibaba.wasp.protobuf.generated.WaspProtos;
import com.alibaba.wasp.protobuf.generated.WaspProtos.StringStringPair;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.ServiceException;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HConstants.OperationStatusCode;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RowLock;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* Protobufs utility.
*/
public final class ProtobufUtil {

  /**
   * Return the IOException thrown by the remote server wrapped in
   * ServiceException as cause.
   *
   * @param se
   *          ServiceException that wraps IO exception thrown by the server
   * @return Exception wrapped in ServiceException or a new IOException that
   *         wraps the unexpected ServiceException.
   */
  public static IOException getRemoteException(ServiceException se) {
    Throwable e = se.getCause();
    if (e == null) {
      return new IOException(se);
    }
    return e instanceof IOException ? (IOException) e : new IOException(se);
  }

  /**
   * Convert a ServerName to a protocol buffer ServerName
   *
   * @param serverName
   *          the ServerName to convert
   * @return the converted protocol buffer ServerName
   * @see #toServerName( com.alibaba.wasp.protobuf.generated.WaspProtos.ServerName )
   */
  public static WaspProtos.ServerName toServerName(final ServerName serverName) {
    if (serverName == null) {
      return null;
    }
    return serverName.convert();
  }

  /**
   * Convert a protocol buffer ServerName to a ServerName
   *
   * @param proto
   *          the protocol buffer ServerName to convert
   * @return the converted ServerName
   */
  public static ServerName toServerName(final WaspProtos.ServerName proto) {
    return ServerName.convert(proto);
  }

  /**
   * Create a protocol buffer Mutate based on a client Mutation
   *
   * @param mutateType
   * @param mutation
   * @return a mutate
   * @throws java.io.IOException
   */
  public static WaspProtos.Mutate toMutate(final WaspProtos.Mutate.MutateType mutateType,
      final Mutation mutation, final String tableName) throws IOException {
    WaspProtos.Mutate.Builder mutateBuilder = WaspProtos.Mutate.newBuilder();
    mutateBuilder.setTableName(tableName);
    mutateBuilder.setRow(ByteString.copyFrom(mutation.getRow()));
    mutateBuilder.setMutateType(mutateType);
    mutateBuilder.setWriteToWAL(mutation.getWriteToWAL());
    if (mutation.getLockId() >= 0) {
      mutateBuilder.setLockId(mutation.getLockId());
    }
    mutateBuilder.setTimestamp(mutation.getTimeStamp());
    Map<String, byte[]> attributes = mutation.getAttributesMap();
    if (!attributes.isEmpty()) {
      WaspProtos.StringBytesPair.Builder attributeBuilder = WaspProtos.StringBytesPair.newBuilder();
      for (Map.Entry<String, byte[]> attribute : attributes.entrySet()) {
        attributeBuilder.setName(attribute.getKey());
        attributeBuilder.setValue(ByteString.copyFrom(attribute.getValue()));
        mutateBuilder.addAttribute(attributeBuilder.build());
      }
    }
    WaspProtos.Mutate.ColumnValue.Builder columnBuilder = WaspProtos.Mutate.ColumnValue.newBuilder();
    WaspProtos.Mutate.ColumnValue.QualifierValue.Builder valueBuilder = WaspProtos.Mutate.ColumnValue.QualifierValue.newBuilder();
    for (Map.Entry<byte[], List<KeyValue>> family : mutation.getFamilyMap()
        .entrySet()) {
      columnBuilder.setFamily(ByteString.copyFrom(family.getKey()));
      columnBuilder.clearQualifierValue();
      for (KeyValue value : family.getValue()) {
        valueBuilder.setQualifier(ByteString.copyFrom(value.getQualifier()));
        valueBuilder.setValue(ByteString.copyFrom(value.getValue()));
        valueBuilder.setTimestamp(value.getTimestamp());
        if (mutateType == WaspProtos.Mutate.MutateType.DELETE) {
          KeyValue.Type keyValueType = KeyValue.Type
              .codeToType(value.getType());
          valueBuilder.setDeleteType(toDeleteType(keyValueType));
        }
        columnBuilder.addQualifierValue(valueBuilder.build());
      }
      mutateBuilder.addColumnValue(columnBuilder.build());
    }
    return mutateBuilder.build();
  }

  /**
   * Convert a protocol buffer Mutate to a Put
   *
   * @param proto
   *          the protocol buffer Mutate to convert
   * @return the converted client Put
   * @throws org.apache.hadoop.hbase.DoNotRetryIOException
   */
  public static Put toPut(final WaspProtos.Mutate proto, Long timestampTransaction)
      throws DoNotRetryIOException {
    WaspProtos.Mutate.MutateType type = proto.getMutateType();
    assert type == WaspProtos.Mutate.MutateType.PUT : type.name();
    byte[] row = proto.getRow().toByteArray();
    Long timestamp = FConstants.LATEST_TIMESTAMP;
    if (proto.hasTimestamp()) {
      timestamp = proto.getTimestamp();
    }
    if (timestampTransaction != null) {
      timestamp = timestampTransaction;
    }
    RowLock lock = null;
    if (proto.hasLockId()) {
      lock = new RowLock(proto.getLockId());
    }
    Put put = new Put(row, timestamp, lock);
    put.setWriteToWAL(proto.getWriteToWAL());
    for (WaspProtos.StringBytesPair attribute : proto.getAttributeList()) {
      put.setAttribute(attribute.getName(), attribute.getValue().toByteArray());
    }
    for (WaspProtos.Mutate.ColumnValue column : proto.getColumnValueList()) {
      byte[] family = column.getFamily().toByteArray();
      for (WaspProtos.Mutate.ColumnValue.QualifierValue qv : column.getQualifierValueList()) {
        byte[] qualifier = qv.getQualifier().toByteArray();
        if (!qv.hasValue()) {
          throw new DoNotRetryIOException(
              "Missing required field: qualifer value");
        }
        byte[] value = qv.getValue().toByteArray();
        put.add(family, qualifier, value);
      }
    }
    return put;
  }

  /**
   * Convert a delete KeyValue type to protocol buffer DeleteType.
   *
   * @param type
   * @return
   * @throws java.io.IOException
   */
  public static WaspProtos.Mutate.DeleteType toDeleteType(KeyValue.Type type) throws IOException {
    switch (type) {
    case Delete:
      return WaspProtos.Mutate.DeleteType.DELETE_ONE_VERSION;
    case DeleteColumn:
      return WaspProtos.Mutate.DeleteType.DELETE_MULTIPLE_VERSIONS;
    case DeleteFamily:
      return WaspProtos.Mutate.DeleteType.DELETE_FAMILY;
    default:
      throw new IOException("Unknown delete type: " + type);
    }
  }

  public static Delete toDelete(final WaspProtos.Mutate proto) {
    return toDelete(proto, null);
  }

  /**
   * Convert a protocol buffer Mutate to a Delete
   *
   * @param proto
   *          the protocol buffer Mutate to convert
   * @return the converted client Delete
   */
  public static Delete toDelete(final WaspProtos.Mutate proto, Long timestampTransaction) {
    WaspProtos.Mutate.MutateType type = proto.getMutateType();
    assert type == WaspProtos.Mutate.MutateType.DELETE : type.name();
    byte[] row = proto.getRow().toByteArray();
    long timestamp = HConstants.LATEST_TIMESTAMP;
    if (proto.hasTimestamp()) {
      timestamp = proto.getTimestamp();
    }
    if (timestampTransaction != null) {
      timestamp = timestampTransaction;
    }
    RowLock lock = null;
    if (proto.hasLockId()) {
      lock = new RowLock(proto.getLockId());
    }
    Delete delete = new Delete(row, timestamp, lock);
    delete.setWriteToWAL(proto.getWriteToWAL());
    for (WaspProtos.StringBytesPair attribute : proto.getAttributeList()) {
      delete.setAttribute(attribute.getName(), attribute.getValue()
          .toByteArray());
    }
    for (WaspProtos.Mutate.ColumnValue column : proto.getColumnValueList()) {
      byte[] family = column.getFamily().toByteArray();
      for (WaspProtos.Mutate.ColumnValue.QualifierValue qv : column.getQualifierValueList()) {
        WaspProtos.Mutate.DeleteType deleteType = qv.getDeleteType();
        byte[] qualifier = null;
        if (qv.hasQualifier()) {
          qualifier = qv.getQualifier().toByteArray();
        }
        long ts = HConstants.LATEST_TIMESTAMP;
        if (qv.hasTimestamp()) {
          ts = qv.getTimestamp();
        }
        if (deleteType == WaspProtos.Mutate.DeleteType.DELETE_ONE_VERSION) {
          delete.deleteColumn(family, qualifier, ts);
        } else if (deleteType == WaspProtos.Mutate.DeleteType.DELETE_MULTIPLE_VERSIONS) {
          delete.deleteColumns(family, qualifier, ts);
        } else {
          delete.deleteFamily(family, ts);
        }
      }
    }
    return delete;
  }

  /**
   * Convert ReadModelProto to ReadModel.
   *
   * @param readModel
   * @return
   */
  public static ReadModel toReadModel(MetaProtos.ReadModelProto readModel) {
    return ReadModel.valueOf(readModel.name());
  }

  /**
   * Convert ReadModel to ReadModelProto.
   *
   * @param readModel
   * @return
   */
  public static MetaProtos.ReadModelProto toReadModelProto(ReadModel readModel) {
    return MetaProtos.ReadModelProto.valueOf(readModel.name());
  }

  /**
   * Convert OperationStatus to WriteResultProto.
   *
   * @return WriteResultProto
   */
  public static ClientProtos.WriteResultProto toWriteResultProto(OperationStatus status) {
    ClientProtos.WriteResultProto.Builder writeResultProtoBuilder = ClientProtos.WriteResultProto
        .newBuilder();
    if (status.getExceptionMsg() != null) {
      writeResultProtoBuilder.setExceptionMsg(status.getExceptionMsg());
    }
    if (status.getExceptionClassname() != null) {
      writeResultProtoBuilder.setExceptionClassName(status
          .getExceptionClassname());
    }
    writeResultProtoBuilder.setCode(ClientProtos.WriteResultProto.StatusCode.valueOf(status
        .getOperationStatusCode().name()));
    return writeResultProtoBuilder.build();
  }

  /**
   * Convert ExecuteResultProto to ExecuteResult.
   *
   * @param protoResults
   * @param metaDatas
   * @return
   */
  public static List<ExecuteResult> toExecuteResult(
      List<ExecuteResultProto> protoResults, List<StringDataTypePair> metaDatas) {

    List<ExecuteResult> results = new ArrayList<ExecuteResult>();
    for (ClientProtos.ExecuteResultProto result : protoResults) {
      if (result.getType() == ClientProtos.ExecuteResultProto.ResultType.QUERY) {
        ClientProtos.QueryResultProto queryResultProto = result.getQueryResult();
        Map<String, Pair<DataType, byte[]>> resultMap = newResultMap(metaDatas);
        for (WaspProtos.StringBytesPair pair : queryResultProto.getResultList()) {
          if (pair.getName().equalsIgnoreCase("rowkey")) {
            continue;
          }
          Pair<DataType, byte[]> dataTypePair = resultMap.get(pair.getName());
          // if dataTypePair is null, the column isn't selected in this case;
          if (dataTypePair == null) {
            continue;
          }
          resultMap.put(pair.getName(), Pair.newPair(dataTypePair.getFirst(),
              pair.getValue().toByteArray()));
        }
        QueryResult queryResult = new QueryResult(resultMap);
        results.add(queryResult);
      } else {
        ClientProtos.WriteResultProto writeResultProto = result.getWriteResult();
        OperationStatus status = new OperationStatus(
            OperationStatusCode.valueOf(writeResultProto.getCode().name()),
            writeResultProto.getExceptionMsg(),
            writeResultProto.getExceptionClassName());
        WriteResult writeResult = new WriteResult(status);
        results.add(writeResult);
      }
    }
    return results;
  }

  private static Map<String, Pair<DataType, byte[]>> newResultMap(
      List<StringDataTypePair> metaDatas) {
    Map<String, Pair<DataType, byte[]>> resultMap;
    resultMap = new LinkedHashMap<String, Pair<DataType, byte[]>>();
    for (ClientProtos.StringDataTypePair metaData : metaDatas) {
      resultMap.put(metaData.getName(), Pair.newPair(
          DataType.convertDataTypeProtosToDataType(metaData.getDataType()),
          new byte[]{}));
    }
    return resultMap;
  }

  /**
   * Convert DeleteActionProto to DeleteAction.
   *
   * @param deleteActionProto
   * @return
   */
  public static DeleteAction toDeleteAction(MetaProtos.DeleteActionProto deleteActionProto) {
    return DeleteAction.convert(deleteActionProto);
  }

  /**
   * Convert UpdateActionProto to UpdateAction.
   *
   * @param updateActionProto
   * @return
   */
  public static UpdateAction toUpdateAction(MetaProtos.UpdateActionProto updateActionProto) {
    return UpdateAction.convert(updateActionProto);
  }

   /**
   * Convert TransactionActionProto to TransactionAction.
   *
   * @param transactionActionProto
   * @return
   */
  public static TransactionAction toTransactionAction(MetaProtos.TransactionActionProto transactionActionProto) {
    return TransactionAction.convert(transactionActionProto);
  }

  /**
   * Convert ColumnStructProto to ColumnAction.
   *
   * @param col
   * @return
   */
  public static ColumnStruct toColumnAction(MetaProtos.ColumnStructProto col) {
    return ColumnStruct.convert(col);
  }

  /**
   * Convert ColumnStructProto to ColumnAction.
   *
   * @param col
   * @return
   */
  public static MetaProtos.ColumnStructProto toColumnStructProto(ColumnStruct col) {
    return ColumnStruct.convert(col);
  }

  /**
   * Convert InsertActionProto to InsertAction.
   *
   * @param insertActionProto
   * @return
   */
  public static InsertAction toInsertAction(MetaProtos.InsertActionProto insertActionProto) {
    return InsertAction.convert(insertActionProto);
  }

  /**
   * Convert GetActionProto to GetAction.
   *
   * @param getAction
   * @return
   */
  public static GetAction toGetAction(MetaProtos.GetActionProto getAction) {
    return GetAction.convert(getAction);
  }

  /**
   * Convert GetAction to GetActionProto.
   *
   * @param getAction
   * @return
   */
  public static MetaProtos.GetActionProto toGetActionProto(GetAction getAction) {
    return GetAction.convert(getAction);
  }

  /**
   * Convert protobuf value to message object.This method will be used by
   * message queue.
   *
   * @param value
   * @return
   * @throws com.google.protobuf.InvalidProtocolBufferException
   */
  public static Action convertWriteAction(byte[] value)
      throws InvalidProtocolBufferException {
    MetaProtos.MessageProto.Builder builder = MetaProtos.MessageProto.newBuilder();
    builder = builder.mergeFrom(value);
    MetaProtos.MessageProto proto = builder.build();
    return convertWriteAction(proto);
  }

  /**
   * Convert protobuf object MessageProto to write Action.
   *
   * @param proto
   * @return
   * @throws com.google.protobuf.InvalidProtocolBufferException
   */
  public static Action convertWriteAction(MetaProtos.MessageProto proto)
      throws InvalidProtocolBufferException {
    if (proto.getType() == MetaProtos.MessageProto.ActionType.UPDATE) {
      return UpdateAction.convert(proto.getUpdate());
    } else if (proto.getType() == MetaProtos.MessageProto.ActionType.DELETE) {
      return DeleteAction.convert(proto.getDelete());
    } else if (proto.getType() == MetaProtos.MessageProto.ActionType.INSERT) {
      return InsertAction.convert(proto.getInsert());
    }
    throw new InvalidProtocolBufferException(String.valueOf(proto.getType()));
  }

  /**
   * convert Action to MessageProto.
   *
   * @param action
   * @return
   * @throws com.google.protobuf.InvalidProtocolBufferException
   */
  public static MetaProtos.MessageProto convertWriteAction(Action action)
      throws InvalidProtocolBufferException {
    if (action instanceof DeleteAction) {
      return ProtobufUtil.convertDeleteAction((DeleteAction) action);
    } else if (action instanceof UpdateAction) {
      return ProtobufUtil.convertUpdateAction((UpdateAction) action);
    } else if (action instanceof InsertAction) {
      return ProtobufUtil.convertInsertAction((InsertAction) action);
    }
    throw new InvalidProtocolBufferException(action.toString());
  }

  /**
   * convert Action to MessageProto.
   *
   * @param action
   * @return
   */
  public static MetaProtos.MessageProto convertInsertAction(InsertAction action) {
    MetaProtos.MessageProto.Builder builder = MetaProtos.MessageProto.newBuilder();
    MetaProtos.InsertActionProto proto = InsertAction.convert(action);
    builder.setType(MetaProtos.MessageProto.ActionType.INSERT);
    builder.setInsert(proto);
    return builder.build();
  }

  /**
   * convert Action to MessageProto.
   *
   * @param action
   * @return
   */
  public static MetaProtos.MessageProto convertTransactionAction(TransactionAction action) {
    MetaProtos.MessageProto.Builder builder = MetaProtos.MessageProto.newBuilder();
    MetaProtos.TransactionActionProto proto = TransactionAction.convert(action);
    builder.setType(MetaProtos.MessageProto.ActionType.TRANSACTION);
    builder.setTransaction(proto);
    return builder.build();
  }

  /**
   * convert Action to MessageProto.
   *
   * @param action
   * @return
   */
  public static MetaProtos.MessageProto convertUpdateAction(UpdateAction action) {
    MetaProtos.MessageProto.Builder builder = MetaProtos.MessageProto.newBuilder();
    MetaProtos.UpdateActionProto proto = UpdateAction.convert(action);
    builder.setType(MetaProtos.MessageProto.ActionType.UPDATE);
    builder.setUpdate(proto);
    return builder.build();
  }

  /**
   * Convert Action to MessageProto.
   *
   * @param action
   * @return
   */
  public static MetaProtos.MessageProto convertDeleteAction(DeleteAction action) {
    MetaProtos.MessageProto.Builder builder = MetaProtos.MessageProto.newBuilder();
    MetaProtos.DeleteActionProto proto = DeleteAction.convert(action);
    builder.setType(MetaProtos.MessageProto.ActionType.DELETE);
    builder.setDelete(proto);
    return builder.build();
  }

  /**
   * Convert ScanActionProto to ScanAction.
   *
   * @param scanActionProto
   * @return
   */
  public static ScanAction convertScanAction(MetaProtos.ScanActionProto scanActionProto) {
    return ScanAction.convert(scanActionProto);
  }

  /**
   * Convert ScanAction to ScanActionProto.
   *
   * @param scanAction
   * @return
   */
  public static MetaProtos.ScanActionProto convertScanAction(ScanAction scanAction) {
    return ScanAction.convert(scanAction);
  }

  /**
   * Convert result to QueryResultProto.
   *
   * @param result
   * @return
   */
  public static ClientProtos.QueryResultProto toQeuryResultProto(
      org.apache.hadoop.hbase.client.Result result) {
    ClientProtos.QueryResultProto.Builder builder = ClientProtos.QueryResultProto.newBuilder();
    KeyValue[] raw = result.raw();
    for (KeyValue kv : raw) {
      builder.addResult(toStringBytesPair(kv));
    }
    return builder.build();
  }

  /**
   * Combine result1 and result2,then convert it to QueryResultProto.
   *
   * @param result1
   * @param result2
   * @return
   */
  public static ClientProtos.QueryResultProto toQeuryResultProto(
      org.apache.hadoop.hbase.client.Result result1,
      org.apache.hadoop.hbase.client.Result result2) {
    ClientProtos.QueryResultProto.Builder builder = ClientProtos.QueryResultProto.newBuilder();
    KeyValue[] raw = result1.raw();
    for (KeyValue kv : raw) {
      builder.addResult(toStringBytesPair(kv));
    }
    if(result1.raw().length == 0) {
      raw = result2.raw();
      for (KeyValue kv : raw) {
        builder.addResult(toStringBytesPair(kv));
      }
    }
    return builder.build();
  }

  /**
   * Convert result to NameDataTypeBytesPair.
   *
   * @param kv
   * @return
   */
  public static WaspProtos.StringBytesPair toStringBytesPair(KeyValue kv) {
    WaspProtos.StringBytesPair.Builder builder = WaspProtos.StringBytesPair.newBuilder();
    String column = Bytes.toString(kv.getQualifier());
    builder.setName(column);
    builder.setValue(ByteString.copyFrom(kv.getValue()));
    return builder.build();
  }

  /**
   * Convert UpdateActionProto to UpdateAction.
   *
   * @param updateActionProto
   * @return
   */
  public static UpdateAction convertUpdateAction(
      MetaProtos.UpdateActionProto updateActionProto) {
    return UpdateAction.convert(updateActionProto);
  }

  /**
   * Convert InsertActionProto to InsertAction.
   *
   * @param insertActionProto
   * @return
   */
  public static InsertAction convertInsertAction(
      MetaProtos.InsertActionProto insertActionProto) {
    return InsertAction.convert(insertActionProto);
  }

  /**
   * Convert DeleteActionProto to DeleteAction.
   *
   * @param deleteActionProto
   * @return
   */
  public static DeleteAction convertDeleteAction(
      MetaProtos.DeleteActionProto deleteActionProto) {
    return DeleteAction.convert(deleteActionProto);
  }

  /**
   * Get HTableDescriptor[] from GetTableDescriptorsResponse protobuf
   *
   * @param proto
   *          the GetTableDescriptorsResponse
   * @return HTableDescriptor[]
   */
  public static FTable[] getHTableDescriptorArray(
      MasterMonitorProtos.GetTableDescriptorsResponse proto) {
    if (proto == null)
      return null;

    FTable[] ret = new FTable[proto.getTableSchemaCount()];
    for (int i = 0; i < proto.getTableSchemaCount(); ++i) {
      ret[i] = convertITableSchema(proto.getTableSchema(i));
    }
    return ret;
  }

  public static FTable convertITableSchema(MasterMonitorProtos.ITableSchema proto) {
    FTable table = FTable.convert(proto.getTableSchema());
    LinkedHashMap<String, Index> indexs = new LinkedHashMap<String, Index>();
    for (MetaProtos.IndexSchema indexSchema : proto.getIndexSchemaList()) {
      Index index = Index.convert(indexSchema);
      indexs.put(index.getIndexName(), index);
    }
    table.setIndex(indexs);
    return table;
  }

  public static MasterMonitorProtos.ITableSchema convertITableSchema(FTable table)
      throws MetaException {
    MasterMonitorProtos.ITableSchema.Builder iBuilder = MasterMonitorProtos.ITableSchema.newBuilder();
    iBuilder.setTableSchema(table.convert());
    for (Index index : table.getIndex().values()) {
      iBuilder.addIndexSchema(index.convert());
    }
    return iBuilder.build();
  }

  /**
   * get the split keys in form "byte [][]" from a CreateTableRequest proto
   *
   * @param proto
   *          the CreateTableRequest
   * @return the split keys
   */
  public static byte[][] getSplitKeysArray(final MasterAdminProtos.CreateTableRequest proto) {
    byte[][] splitKeys = new byte[proto.getSplitKeysCount()][];
    for (int i = 0; i < proto.getSplitKeysCount(); ++i) {
      splitKeys[i] = proto.getSplitKeys(i).toByteArray();
    }
    return splitKeys;
  }

  /**
   * Convert a ByteArrayComparable to a protocol buffer Comparator
   *
   * @param comparator
   *          the ByteArrayComparable to convert
   * @return the converted protocol buffer Comparator
   */
  public static ComparatorProtos.Comparator toComparator(
      ComparatorProtos.ByteArrayComparable comparator) {
    ComparatorProtos.Comparator.Builder builder = ComparatorProtos.Comparator
        .newBuilder();
    builder.setName(comparator.getClass().getName());
    builder.setSerializedComparator(ByteString.copyFrom(comparator
        .toByteArray()));
    return builder.build();
  }

  /**
   * Convert a protocol buffer Comparator to a ByteArrayComparable
   *
   * @param proto
   *          the protocol buffer Comparator to convert
   * @return the converted ByteArrayComparable
   */
  @SuppressWarnings("unchecked")
  public static ComparatorProtos.ByteArrayComparable toComparator(
      ComparatorProtos.Comparator proto) throws IOException {
    String type = proto.getName();
    String funcName = "parseFrom";
    byte[] value = proto.getSerializedComparator().toByteArray();
    try {
      Class<? extends ByteArrayComparable> c = (Class<? extends ByteArrayComparable>) (Class
          .forName(type));
      Method parseFrom = c.getMethod(funcName, byte[].class);
      if (parseFrom == null) {
        throw new IOException("Unable to locate function: " + funcName
            + " in type: " + type);
      }
      return (ComparatorProtos.ByteArrayComparable) parseFrom.invoke(null, value);
    } catch (Exception e) {
      throw new IOException(e);
    }
  }

  /**
   * Convert a stringified protocol buffer exception Parameter to a Java
   * Exception
   *
   * @param parameter
   *          the protocol buffer Parameter to convert
   * @return the converted Exception
   * @throws java.io.IOException
   *           if failed to deserialize the parameter
   */
  @SuppressWarnings("unchecked")
  public static Throwable toException(final WaspProtos.StringBytesPair parameter)
      throws IOException {
    if (parameter == null || !parameter.hasValue())
      return null;
    String desc = parameter.getValue().toStringUtf8();
    String type = parameter.getName();
    try {
      Class<? extends Throwable> c = (Class<? extends Throwable>) Class
          .forName(type);
      Constructor<? extends Throwable> cn = c
          .getDeclaredConstructor(String.class);
      return cn.newInstance(desc);
    } catch (Exception e) {
      throw new IOException(e);
    }
  }

  /**
   * A helper to retrieve entityGroup info given a entityGroup name using admin
   * protocol.
   *
   * @param admin
   * @param entityGroupName
   * @return the retrieved entityGroup info
   * @throws java.io.IOException
   */
  public static EntityGroupInfo getEntityGroupInfo(final AdminProtocol admin,
      final byte[] entityGroupName) throws IOException {
    try {
      FServerAdminProtos.GetEntityGroupInfoRequest request = RequestConverter
          .buildGetEntityGroupInfoRequest(entityGroupName);
      FServerAdminProtos.GetEntityGroupInfoResponse response = admin.getEntityGroupInfo(null,
          request);
      return EntityGroupInfo.convert(response.getEntityGroupInfo());
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
  }

  /**
   * A helper to close a entityGroup given a entityGroup name using admin
   * protocol.
   *
   * @param admin
   * @param egi
   * @param transitionInZK
   * @throws java.io.IOException
   */
  public static void closeEntityGroup(final AdminProtocol admin,
      final EntityGroupInfo egi, final boolean transitionInZK)
      throws IOException {
    FServerAdminProtos.CloseEntityGroupRequest closeEntityGroupRequest = RequestConverter
        .buildCloseEntityGroupRequest(egi, transitionInZK);
    try {
      admin.closeEntityGroup(null, closeEntityGroupRequest);
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
  }

  /**
   * A helper to close a entityGroup given a entityGroup name using admin
   * protocol.
   *
   * @param admin
   * @param egi
   * @param versionOfClosingNode
   * @return true if the entityGroup is closed
   * @throws java.io.IOException
   */
  public static boolean closeEntityGroup(final AdminProtocol admin,
      final EntityGroupInfo egi, final int versionOfClosingNode,
      final boolean transitionInZK) throws IOException {
    FServerAdminProtos.CloseEntityGroupRequest closeEntityGroupRequest = RequestConverter
        .buildCloseEntityGroupRequest(egi, versionOfClosingNode, transitionInZK);
    try {
      FServerAdminProtos.CloseEntityGroupResponse response = admin.closeEntityGroup(null,
          closeEntityGroupRequest);
      return ResponseConverter.isClosed(response);
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
  }

  /**
   * A helper to close a entityGroup given a entityGroup name using admin
   * protocol.
   *
   * @param admin
   * @param egi
   * @param versionOfClosingNode
   * @return true if the entityGroup is closed
   * @throws java.io.IOException
   */
  public static boolean closeEntityGroup(final AdminProtocol admin,
      final EntityGroupInfo egi, final int versionOfClosingNode)
      throws IOException {
    FServerAdminProtos.CloseEntityGroupRequest closeEntityGroupRequest = RequestConverter
        .buildCloseEntityGroupRequest(egi, versionOfClosingNode);
    try {
      FServerAdminProtos.CloseEntityGroupResponse response = admin.closeEntityGroup(null,
          closeEntityGroupRequest);
      return ResponseConverter.isClosed(response);
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
  }

  /**
   * A helper to open a entityGroup using admin protocol.
   *
   * @param admin
   * @param entityGroup
   * @throws java.io.IOException
   */
  public static void openEntityGroup(final AdminProtocol admin,
      final EntityGroupInfo entityGroup) throws IOException {
    FServerAdminProtos.OpenEntityGroupRequest request = RequestConverter
        .buildOpenEntityGroupRequest(entityGroup, -1);
    try {
      admin.openEntityGroup(null, request);
    } catch (ServiceException se) {
      throw ProtobufUtil.getRemoteException(se);
    }
  }

  /**
   * A helper to open a list of entityGroups using admin protocol.
   *
   * @param admin
   * @param entityGroups
   * @return OpenEntityGroupResponse
   * @throws java.io.IOException
   */
  public static FServerAdminProtos.OpenEntityGroupResponse openEntityGroup(
      final AdminProtocol admin, final List<EntityGroupInfo> entityGroups)
      throws IOException {
    FServerAdminProtos.OpenEntityGroupRequest request = RequestConverter
        .buildOpenEntityGroupRequest(entityGroups);
    try {
      return admin.openEntityGroup(null, request);
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
  }

  /**
   * A helper to get the all the online entityGroups on a fserver using admin
   * protocol.
   *
   * @param admin
   * @return a list of online entityGroup info
   * @throws java.io.IOException
   */
  public static List<EntityGroupInfo> getOnlineEntityGroups(
      final AdminProtocol admin) throws IOException {
    FServerAdminProtos.GetOnlineEntityGroupsRequest request = RequestConverter
        .buildGetOnlineEntityGroupsRequest();
    FServerAdminProtos.GetOnlineEntityGroupsResponse response = null;
    try {
      response = admin.getOnlineEntityGroups(null, request);
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
    return getEntityGroupInfos(response);
  }

  /**
   * Get the list of entityGroup info from a GetOnlineEntityGroupsResponse
   *
   * @param proto
   *          the GetOnlineEntityGroupsResponse
   * @return the list of entityGroup info or null if <code>proto</code> is null
   */
  static List<EntityGroupInfo> getEntityGroupInfos(
      final FServerAdminProtos.GetOnlineEntityGroupsResponse proto) {
    if (proto == null)
      return null;
    List<EntityGroupInfo> entityGroupInfos = new ArrayList<EntityGroupInfo>();
    for (WaspProtos.EntityGroupInfoProtos entityGroupInfo : proto
        .getEntityGroupInfosList()) {
      entityGroupInfos.add(EntityGroupInfo.convert(entityGroupInfo));
    }
    return entityGroupInfos;
  }

  /**
   * A helper to get the info of a fserver using admin protocol.
   *
   * @param admin
   * @return the server name
   * @throws java.io.IOException
   */
  public static FServerAdminProtos.ServerInfo getServerInfo(final AdminProtocol admin)
      throws IOException {
    FServerAdminProtos.GetServerInfoRequest request = RequestConverter.buildGetServerInfoRequest();
    try {
      FServerAdminProtos.GetServerInfoResponse response = admin.getServerInfo(null, request);
      return response.getServerInfo();
    } catch (ServiceException se) {
      throw getRemoteException(se);
    }
  }

  /**
   * A helper to split a entityGroup using admin protocol.
   *
   * @param admin
   * @param egi
   * @param splitPoint
   * @throws java.io.IOException
   */
  public static void split(final AdminProtocol admin,
      final EntityGroupInfo egi, byte[] splitPoint) throws IOException {
    FServerAdminProtos.SplitEntityGroupRequest request = RequestConverter
        .buildSplitEntityGroupRequest(egi.getEntityGroupName(), splitPoint);
    try {
      admin.splitEntityGroup(null, request);
    } catch (ServiceException se) {
      throw ProtobufUtil.getRemoteException(se);
    }
  }

  // End helpers for Admin

  /*
   * Get the total (read + write) requests from a EntityGroupLoad pb
   *
   * @param rl - EntityGroupLoad pb
   *
   * @return total (read + write) requests
   */
  public static long getTotalRequestsCount(WaspProtos.EntityGroupLoadProtos rl) {
    if (rl == null) {
      return 0;
    }

    return rl.getReadRequestsCount() + rl.getWriteRequestsCount();
  }

  /**
   * @param m
   *          Message to get delimited pb serialization of (with pb magic
   *          prefix)
   */
  public static byte[] toDelimitedByteArray(final Message m) throws IOException {
    // Allocate arbitrary big size so we avoid resizing.
    ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
    m.writeDelimitedTo(baos);
    baos.close();
    return baos.toByteArray();
  }

  /**
   * Unwraps an exception from a protobuf service into the underlying (expected)
   * IOException. This method will <strong>always</strong> throw an exception.
   *
   * @param se
   *          the {@code ServiceException} instance to convert into an
   *          {@code IOException}
   */
  public static void toIOException(ServiceException se) throws IOException {
    if (se == null) {
      throw new NullPointerException("Null service exception passed!");
    }

    Throwable cause = se.getCause();
    if (cause != null && cause instanceof IOException) {
      throw (IOException) cause;
    }
    throw new IOException(se);
  }

  public static List<StringStringPair> toStringStringPairList(
      Map<String, String> parameter) {
    List<StringStringPair> pairs = new ArrayList<StringStringPair>();
    for (Map.Entry<String, String> entry : parameter.entrySet()) {
      WaspProtos.StringStringPair.Builder builder = WaspProtos.StringStringPair.newBuilder();
      builder.setName(entry.getKey());
      builder.setName(entry.getValue());
      pairs.add(builder.build());
    }
    return pairs;
  }

  public static Map<String, String> toMap(List<StringStringPair> pairs) {
    Map<String, String> parameters = new HashMap<String, String>();
    for (WaspProtos.StringStringPair pair : pairs) {
      parameters.put(pair.getName(), pair.getValue());
    }
    return parameters;
  }

  public static WaspProtos.StringStringPair toStringStringPair(String key, String value) {
    WaspProtos.StringStringPair.Builder builder = WaspProtos.StringStringPair.newBuilder();
    builder.setName(key);
    builder.setValue(value);
    return builder.build();
  }

  public static MetaProtos.GetActionProto convertGetAction(GetAction action) {
    return GetAction.convert(action);
  }


}
TOP

Related Classes of com.alibaba.wasp.protobuf.ProtobufUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.