All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.thrift.legacy.ThriftClientCodec.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.finagle.thrift

import org.apache.thrift.TApplicationException
import org.apache.thrift.protocol.{TMessageType, TProtocolFactory}

import org.jboss.netty.buffer.{ChannelBuffer, ChannelBuffers}
import org.jboss.netty.channel._
import org.jboss.netty.handler.codec.replay.{ReplayingDecoder, VoidEnum}

/**
 * Translate ThriftCalls to their wire representation
 */
private[thrift] class ThriftClientEncoder(protocolFactory: TProtocolFactory)
    extends SimpleChannelDownstreamHandler
{
  protected var seqid = 0

  override def writeRequested(ctx: ChannelHandlerContext, e: MessageEvent) =
    e.getMessage match {
      case call: ThriftCall[_, _] =>
        val buffer = ChannelBuffers.dynamicBuffer()
        val transport = new ChannelBufferToTransport(buffer)
        val protocol = protocolFactory.getProtocol(transport)
        seqid += 1
        call.seqid = seqid
        call.writeRequest(seqid, protocol)
        Channels.write(ctx, Channels.succeededFuture(e.getChannel()),
                       buffer, e.getRemoteAddress)
      case _: Throwable =>
        Channels.fireExceptionCaught(ctx, new IllegalArgumentException)
        null
    }
}

/**
 * Translate wire representation to ThriftReply
 */
private[thrift] class ThriftClientDecoder(protocolFactory: TProtocolFactory)
    extends ReplayingDecoder[VoidEnum]
{
  def decodeThriftReply(ctx: ChannelHandlerContext,
                        channel: Channel,
                        buffer: ChannelBuffer): Object = {
    val transport = new ChannelBufferToTransport(buffer)
    val protocol = protocolFactory.getProtocol(transport)
    val message = protocol.readMessageBegin()

    message.`type` match {
      case TMessageType.EXCEPTION =>
        // Create an event for any TApplicationExceptions.  Though these are
        // usually protocol-level errors, so there's not much the client can do.
        val exception = TApplicationException.read(protocol)
        protocol.readMessageEnd()
        Channels.fireExceptionCaught(ctx, exception)
        null
      case TMessageType.REPLY =>
        val call = ThriftTypes(message.name).newInstance()
        val result = call.readResponse(protocol).asInstanceOf[AnyRef]
        call.reply(result)
      case _ =>
        Channels.fireExceptionCaught(ctx, new TApplicationException(
          TApplicationException.INVALID_MESSAGE_TYPE))
        null
    }
  }

  override def decode(ctx: ChannelHandlerContext,
                      channel: Channel,
                      buffer: ChannelBuffer,
                      state: VoidEnum) =
    // TProtocol assumes a read of zero bytes is an error, so treat empty buffers
    // as no-ops. This only happens with the ReplayingDecoder.
    if (buffer.readable)
      decodeThriftReply(ctx, channel, buffer)
    else
      null
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy