Package com.adgear.anoa.source.thrift

Source Code of com.adgear.anoa.source.thrift.ThriftCompactSource

package com.adgear.anoa.source.thrift;

import com.adgear.anoa.provider.base.ProviderBase;
import com.adgear.anoa.source.Source;

import org.apache.thrift.TBase;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.transport.TIOStreamTransport;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;

/**
* Iterates over a stream of Thrift compact binary serializations.
*
* @param <T> Type of the Thrift record to be provided by the Codec.
*/
public class ThriftCompactSource<T extends TBase<?, ?>>
    extends ProviderBase<T, ThriftCompactSource.Counter>
    implements Source<T> {

  final protected Class<T> thriftClass;
  final protected Constructor<T> constructor;
  final private BufferedInputStream in;
  final private TIOStreamTransport tioStreamTransport;
  final private TCompactProtocol tCompactProtocol;
  private T nextRecord = null;

  public ThriftCompactSource(BufferedInputStream in, Class<T> thriftClass) {
    super(Counter.class);
    this.in = in;
    if (!TBase.class.isAssignableFrom(thriftClass)) {
      throw new IllegalArgumentException("Supplied class does not derive from TBase.");
    }
    try {
      this.constructor = thriftClass.getConstructor();
      constructor.newInstance();
    } catch (Exception e) {
      throw new IllegalArgumentException(e);
    }
    this.thriftClass = thriftClass;
    tioStreamTransport = new TIOStreamTransport(in);
    tCompactProtocol = new TCompactProtocol(tioStreamTransport);
  }

  public ThriftCompactSource(InputStream in, Class<T> thriftClass) {
    this(new BufferedInputStream(in), thriftClass);
  }

  @Override
  public void close() throws IOException {
    tioStreamTransport.close();
  }

  private void update() throws IOException {
    if (nextRecord == null) {
      final int val;
      try {
        in.mark(1);
        val = in.read();
        in.reset();
      } catch (IOException e) {
        increment(Counter.STREAM_READ_FAIL);
        logger.error(e.getMessage());
        throw e;
      }
      if (val == -1) {
        return;
      }
      final T record;
      try {
        record = constructor.newInstance();
      } catch (Exception e) {
        increment(Counter.THRIFT_REFLECT_FAIL);
        logger.error(e.getMessage());
        throw new IOException(e);
      }
      try {
        record.read(tCompactProtocol);
      } catch (TException e) {
        increment(Counter.THRIFT_DESERIALIZE_FAIL);
        logger.warn(e.getMessage());
        throw new IOException(e);
      }
      nextRecord = record;
    }
  }

  @Override
  protected T getNext() throws IOException {
    update();
    T next = nextRecord;
    nextRecord = null;
    return next;
  }

  @Override
  public boolean hasNext() {
    try {
      update();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return (nextRecord != null);
  }

  static public enum Counter {
    /**
     * Counts the number of times an attempt to read from the stream failed.
     */
    STREAM_READ_FAIL,

    /**
     * Java reflection error counter.
     */
    THRIFT_REFLECT_FAIL,

    /**
     * Counts the number of records which could not be deserialized.
     */
    THRIFT_DESERIALIZE_FAIL
  }
}
TOP

Related Classes of com.adgear.anoa.source.thrift.ThriftCompactSource

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.