com.twitter.io.Buf Scala Examples

The following examples show how to use com.twitter.io.Buf. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: XmlTest.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.formats

import com.twitter.io.{Buf, Bufs}
import io.fintrospect.parameters.BodySpec

import scala.xml.{Elem, XML}

class XmlAutoTest extends AutoSpec(Xml.Auto) {
  override def toBuf(l: Letter): Buf = Bufs.utf8Buf(transform()(l).toString())

  override def transform(): (Letter => Elem) = (letter: Letter) => <letter>
    <from>{letter.from.address}</from>
    <to>{letter.to.address}</to>
    <message>{letter.message}</message>
  </letter>

  override def fromBuf(s: Buf): Letter = from(XML.loadString(Bufs.asUtf8String(s)))

  private def from(x: Elem) =  Letter(
    StreetAddress((x \ "to").head.text),
    StreetAddress((x \ "from").head.text),
    (x \ "message").head.text
  )

  override def bodySpec: BodySpec[Letter] = BodySpec.xml().map[Letter](from(_))
}

class XmlResponseBuilderTest extends ResponseBuilderSpec(Xml.ResponseBuilder) {
  override val customError = <message>{message}</message>
  override val customErrorSerialized = Bufs.utf8Buf(s"<message>$message</message>")
  override val customType = <okThing>theMessage</okThing>
  override val customTypeSerialized = Bufs.utf8Buf(customType.toString())
} 
Example 2
Source File: FinatraRequestToRawBody.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.server.finatra

import java.io.ByteArrayInputStream
import java.nio.ByteBuffer
import java.nio.charset.Charset

import com.twitter.finagle.http.Request
import com.twitter.finatra.http.request.RequestUtils
import com.twitter.io.Buf
import com.twitter.util.Future
import org.apache.commons.fileupload.FileItemHeaders
import sttp.model.{Part, Header}
import sttp.tapir.{RawPart, RawBodyType}

import scala.collection.immutable.Seq
import scala.collection.JavaConverters._

class FinatraRequestToRawBody(serverOptions: FinatraServerOptions) {
  def apply[R](bodyType: RawBodyType[R], body: Buf, charset: Option[Charset], request: Request): Future[R] = {
    def asByteArray: Array[Byte] = {
      val array = new Array[Byte](body.length)
      body.write(array, 0)
      array
    }

    def asByteBuffer: ByteBuffer = {
      val buffer = ByteBuffer.allocate(body.length)
      body.write(buffer)
      buffer.flip()
      buffer
    }

    bodyType match {
      case RawBodyType.StringBody(defaultCharset) => Future.value[R](new String(asByteArray, charset.getOrElse(defaultCharset)))
      case RawBodyType.ByteArrayBody              => Future.value[R](asByteArray)
      case RawBodyType.ByteBufferBody             => Future.value[R](asByteBuffer)
      case RawBodyType.InputStreamBody            => Future.value[R](new ByteArrayInputStream(asByteArray))
      case RawBodyType.FileBody                   => serverOptions.createFile(asByteArray)
      case m: RawBodyType.MultipartBody           => multiPartRequestToRawBody(request, m)
    }
  }

  private def parseDispositionParams(headerValue: Option[String]): Map[String, String] =
    headerValue
      .map(
        _.split(";")
          .map(_.trim)
          .tail
          .map(_.split("="))
          .map(array => array(0) -> array(1))
          .toMap
      )
      .getOrElse(Map.empty)

  private def getCharset(contentType: Option[String]): Option[Charset] =
    contentType.flatMap(
      _.split(";")
        .map(_.trim)
        .tail
        .map(_.split("="))
        .map(array => array(0) -> array(1))
        .toMap
        .get("charset")
        .map(Charset.forName)
    )

  private def multiPartRequestToRawBody(request: Request, m: RawBodyType.MultipartBody): Future[Seq[RawPart]] = {
    def fileItemHeaders(headers: FileItemHeaders): Seq[Header] = {
      headers.getHeaderNames.asScala
        .flatMap { name => headers.getHeaders(name).asScala.map(name -> _) }
        .toSeq
        .filter(_._1.toLowerCase != "content-disposition")
        .map { case (k, v) => Header(k, v) }
        .toList
    }

    Future
      .collect(
        RequestUtils
          .multiParams(request)
          .flatMap {
            case (name, multiPartItem) =>
              val dispositionParams: Map[String, String] =
                parseDispositionParams(Option(multiPartItem.headers.getHeader("content-disposition")))
              val charset = getCharset(multiPartItem.contentType)

              for {
                partType <- m.partType(name)
                futureBody = apply(partType, Buf.ByteArray.Owned(multiPartItem.data), charset, request)
              } yield futureBody
                .map(body =>
                  Part(name, body, otherDispositionParams = dispositionParams - "name", headers = fileItemHeaders(multiPartItem.headers))
                    .asInstanceOf[RawPart]
                )
          }
          .toSeq
      )
      .map(_.toList)
  }
} 
Example 3
Source File: SwaggerFinatra.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.swagger.finatra

import java.io.InputStream
import java.util.Properties

import com.twitter.finagle.http.Request
import com.twitter.finatra.http.Controller
import com.twitter.io.{Buf, InputStreamReader, Reader}
import com.twitter.util.Future


class SwaggerFinatra(yaml: String, contextPath: String = "docs", yamlName: String = "docs.yaml") extends Controller {
  private val swaggerVersion: String = {
    val p = new Properties()
    val pomProperties = getClass.getResourceAsStream("/META-INF/maven/org.webjars/swagger-ui/pom.properties")
    try p.load(pomProperties)
    finally pomProperties.close()
    p.getProperty("version")
  }

  get(route = s"/$contextPath/?") { _: Request =>
    response.movedPermanently.location(s"/$contextPath/index.html?url=/$contextPath/$yamlName")
  }

  get(route = s"/$contextPath/$yamlName") { _: Request => response.ok(yaml).contentType("application/yaml") }

  get(route = s"/$contextPath/:swaggerResource") { req: Request =>
    val sResource: String = req.getParam("swaggerResource")
    val sIStreamOpt: Option[InputStream] =
      Option(getClass.getResourceAsStream(s"/META-INF/resources/webjars/swagger-ui/$swaggerVersion/$sResource"))

    sIStreamOpt.fold(Future.value(response.notFound))(is =>
      Reader
        .readAllItems(
          InputStreamReader(is)
        )
        .map { bs =>
          val bytes: Array[Byte] = Buf.ByteArray.Shared.extract(bs.fold(Buf.Empty)(_.concat(_)))

          if (sResource.endsWith(".html")) {
            response.ok.html(new String(bytes, "UTF-8"))
          } else if (sResource.endsWith(".css")) {
            response.ok(new String(bytes, "UTF-8")).contentType("text/css")
          } else if (sResource.endsWith(".js")) {
            response.ok(new String(bytes, "UTF-8")).contentType("text/javascript")
          } else {
            response.ok(bytes).contentType("image/png")
          }
        }
    )
  }
} 
Example 4
Source File: ExampleApp.scala    From caliban   with Apache License 2.0 5 votes vote down vote up
package caliban.finch

import caliban.ExampleData.sampleCharacters
import caliban.ExampleService.ExampleService
import caliban.{ ExampleApi, ExampleService, FinchAdapter }
import com.twitter.io.{ Buf, BufReader, Reader }
import com.twitter.util.Await
import io.finch.Endpoint
import zio.clock.Clock
import zio.console.Console
import zio.internal.Platform
import zio.interop.catz._
import zio.{ Runtime, Task }

object ExampleApp extends App with Endpoint.Module[Task] {

  implicit val runtime: Runtime[ExampleService with Console with Clock] =
    Runtime.unsafeFromLayer(ExampleService.make(sampleCharacters) ++ Console.live ++ Clock.live, Platform.default)

  val interpreter = runtime.unsafeRun(ExampleApi.api.interpreter)

  
  import com.twitter.finagle.Http
  import io.finch._
  import io.finch.circe._

  val endpoint = "api" :: "graphql" :: FinchAdapter.makeHttpService(interpreter)

  val graphiqlBuf = {
    val stream = getClass.getResourceAsStream("/graphiql.html")
    BufReader.readAll(Reader.fromStream(stream))
  }

  val grapihql: Endpoint[Task, Buf] = get("graphiql") {
    graphiqlBuf.map(Ok)
  }

  val services = Bootstrap.serve[Application.Json](endpoint).serve[Text.Html](grapihql).toService

  val server = Http.server.serve(":8088", services)

  println(s"Server online at http://localhost:8088/\nPress RETURN to stop...")
  Await.ready(server)

} 
Example 5
Source File: HttpRequest.scala    From cosmos   with Apache License 2.0 5 votes vote down vote up
package com.mesosphere.cosmos.http

import com.mesosphere.http.MediaType
import com.mesosphere.util.UrlSchemeHeader
import com.twitter.finagle.http.Fields
import com.twitter.finagle.http.Method
import com.twitter.finagle.http.Request
import com.twitter.io.Buf
import io.circe.Encoder
import io.circe.syntax._
import io.finch.Input

final case class HttpRequest(
  path: RpcPath,
  headers: Map[String, String],
  method: HttpRequestMethod
)

object HttpRequest {

  def collectHeaders(entries: (String, Option[String])*): Map[String, String] = {
    entries
      .flatMap { case (key, value) => value.map(key -> _) }
      .toMap
  }

  def get(path: RpcPath, accept: MediaType): HttpRequest = {
    get(path, toHeader(accept))
  }

  def get(path: RpcPath, accept: Option[String]): HttpRequest = {
    HttpRequest(path, collectHeaders(Fields.Accept -> accept), Get())
  }

  def post[A](
    path: RpcPath,
    body: A,
    contentType: MediaType,
    accept: MediaType
  )(implicit encoder: Encoder[A]): HttpRequest = {
    post(path, body.asJson.noSpaces, toHeader(contentType), toHeader(accept))
  }

  def post(
    path: RpcPath,
    body: String,
    contentType: Option[String],
    accept: Option[String]
  ): HttpRequest = {
    val headers = collectHeaders(
      Fields.Accept -> accept,
      Fields.ContentType -> contentType
    )
    HttpRequest(path, headers, Post(Buf.Utf8(body)))
  }

  def post(
    path: RpcPath,
    body: Buf,
    contentType: MediaType,
    accept: MediaType,
    host: String,
    urlScheme: String
  ): HttpRequest = {
    val headers = collectHeaders(
      Fields.Accept -> toHeader(accept),
      Fields.ContentType -> toHeader(contentType),
      Fields.Host -> Some(host),
      UrlSchemeHeader -> Some(urlScheme)
    )
    HttpRequest(path, headers, Post(body))
  }

  def toFinagle(cosmosRequest: HttpRequest): Request = {
    val finagleRequest = cosmosRequest.method match {
      case Get(params @ _*) =>
        Request(cosmosRequest.path.path, params: _*)
      case Post(buf) =>
        val req = Request(Method.Post, cosmosRequest.path.path)
        req.content = buf
        req.contentLength = buf.length.toLong
        req
    }

    finagleRequest.headerMap ++= cosmosRequest.headers
    finagleRequest
  }

  def toFinchInput(cosmosRequest: HttpRequest): Input = {
    val finagleRequest = toFinagle(cosmosRequest)

    Input(
      finagleRequest,
      finagleRequest.path.split("/")
    )
  }

  def toHeader(mediaType: MediaType): Option[String] = Some(mediaType.show)

} 
Example 6
Source File: HelloWorld.scala    From finch-101   with Apache License 2.0 5 votes vote down vote up
package i.f.workshop.finagle

import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{ListeningServer, Http, Service}
import com.twitter.io.Buf
import com.twitter.util.{Await, Future}

object HelloWorld extends App {

  val service: Service[Request, Response] = new Service[Request, Response] {
    def apply(req: Request): Future[Response] = {
      val rep: Response = Response()
      rep.content = Buf.Utf8("Hello, World!")

      Future.value(rep)
    }
  }

  val server: ListeningServer = Http.server.serve(":8081", service)
  Await.ready(server)
} 
Example 7
Source File: FinagleImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4gate

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.io.Buf
import com.twitter.util.{Future, Promise, Return, Throw, Try => TTry}
import ee.cone.c4actor.{Executable, Execution}
import ee.cone.c4gate.HttpProtocol.{N_Header, S_HttpResponse}
import ee.cone.c4proto.ToByteString

import scala.concurrent.ExecutionContext
import scala.util.{Failure, Success, Try => STry}

class FinagleService(handler: FHttpHandler)(implicit ec: ExecutionContext)
  extends Service[http.Request, http.Response]
{
  def apply(req: http.Request): Future[http.Response] = {
    val promise = Promise[http.Response]()
    val future: concurrent.Future[S_HttpResponse] = handler.handle(encode(req))
    future.onComplete(res => promise.update(decodeTry(res).map(decode)))
    promise
  }
  def encode(req: http.Request): FHttpRequest = {
    val method = req.method.name
    val path = req.path
    val headerMap = req.headerMap
    val headers = headerMap.keys.toList.sorted
      .flatMap(k=>headerMap.getAll(k).map(v=>N_Header(k,v)))
    val body = ToByteString(Buf.ByteArray.Owned.extract(req.content))
    FHttpRequest(method,path,headers,body)
  }
  def decode(response: S_HttpResponse): http.Response = {
    val finResponse = http.Response(http.Status(Math.toIntExact(response.status)))
    response.headers.foreach(h=>finResponse.headerMap.add(h.key,h.value))
    finResponse.write(Buf.ByteArray.Owned(response.body.toByteArray))
    finResponse
  }
  def decodeTry[T](res: STry[T]): TTry[T] = res match {
    case Success(v) => Return(v)
    case Failure(e) => Throw(e)
  }
}

class FinagleHttpServer(port: Int, handler: FHttpHandler, execution: Execution) extends Executable {
  def run(): Unit = Http.serve(s":$port", new FinagleService(handler)(ExecutionContext.fromExecutor(execution.newExecutorService("finagle-",None))))
} 
Example 8
Source File: Auth0Extend.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.system.externalServices

import akka.http.scaladsl.model._
import com.twitter.io.Buf
import cool.graph.shared.models.Client
import cool.graph.system.authorization.SystemAuth2
import scaldi.{Injectable, Injector}

import scala.concurrent.Future

case class Auth0FunctionData(url: String, auth0Id: String)

trait Auth0Extend {
  def createAuth0Function(client: Client, code: String): Future[Auth0FunctionData]
}

class Auth0ExtendMock extends Auth0Extend {
  var lastCode: Option[String] = None
  var shouldFail: Boolean      = false

  override def createAuth0Function(client: Client, code: String): Future[Auth0FunctionData] = {
    lastCode = Some(code)

    if (shouldFail) {
      sys.error("some error deploying Auth0 Extend function")
    }

    Future.successful(Auth0FunctionData("http://some.url", auth0Id = "some-id"))
  }
}

class Auth0ExtendImplementation(implicit inj: Injector) extends Auth0Extend with Injectable {

  override def createAuth0Function(client: Client, code: String): Future[Auth0FunctionData] = {

    import com.twitter.conversions.time._
    import com.twitter.finagle
    import cool.graph.twitterFutures.TwitterFutureImplicits._
    import spray.json.DefaultJsonProtocol._
    import spray.json._

    import scala.concurrent.ExecutionContext.Implicits.global

    // todo: inject this
    val extendEndpoint = "https://d0b5iw4041.execute-api.eu-west-1.amazonaws.com/prod/create/"
    val clientToken    = SystemAuth2().generatePlatformTokenWithExpiration(clientId = client.id)

    def toDest(s: String) = s"${Uri(s).authority.host}:${Uri(s).effectivePort}"
    val extendService =
      finagle.Http.client.withTls(Uri(extendEndpoint).authority.host.address()).withRequestTimeout(15.seconds).newService(toDest(extendEndpoint))

    val body = Map("code" -> code, "authToken" -> clientToken).toJson.prettyPrint

    val request = com.twitter.finagle.http
      .RequestBuilder()
      .url(extendEndpoint)
      .buildPost(Buf.Utf8(body))
    request.setContentTypeJson()

    for {
      json <- extendService(request)
               .map(res => {
                 res.getContentString().parseJson
               })
               .asScala
    } yield {
      Auth0FunctionData(
        url = json.asJsObject.fields("url").convertTo[String],
        auth0Id = json.asJsObject.fields("fn").convertTo[String]
      )
    }
  }
} 
Example 9
Source File: MustacheTemplates.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.templating

import java.io.{ByteArrayOutputStream, File, OutputStreamWriter}
import java.nio.charset.StandardCharsets

import com.github.mustachejava.resolver.{DefaultResolver, FileSystemResolver}
import com.github.mustachejava.{DefaultMustacheFactory, Mustache}
import com.twitter.io.Buf

object MustacheTemplates extends Templates {

  private def render(view: View, mustache: Mustache): Buf = {
    val outputStream = new ByteArrayOutputStream(4096)
    val writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)
    try {
      mustache.execute(writer, view)
    } finally {
      writer.close()
    }

    Buf.ByteArray.Owned(outputStream.toByteArray)
  }

  def CachingClasspath(baseClasspathPackage: String = "."): TemplateRenderer = new TemplateRenderer {

    private val factory = new DefaultMustacheFactory(new DefaultResolver(baseClasspathPackage)) {
      setObjectHandler(new ScalaObjectHandler)
    }

    def toBuf(view: View): Buf = render(view, factory.compile(view.template + ".mustache"))
  }

  def Caching(baseTemplateDir: String): TemplateRenderer = new TemplateRenderer {

    private val factory = new DefaultMustacheFactory(new FileSystemResolver(new File(baseTemplateDir))) {
      setObjectHandler(new ScalaObjectHandler)
    }

    def toBuf(view: View): Buf = render(view, factory.compile(view.template + ".mustache"))
  }

  def HotReload(baseTemplateDir: String = "."): TemplateRenderer = new TemplateRenderer {

    class WipeableMustacheFactory extends DefaultMustacheFactory(new FileSystemResolver(new File(baseTemplateDir))) {
      setObjectHandler(new ScalaObjectHandler)
    }

    def toBuf(view: View): Buf = render(view, new WipeableMustacheFactory().compile(view.template + ".mustache"))
  }
} 
Example 10
Source File: TemplatesSpec.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.templating

import com.twitter.io.Buf
import org.scalatest.{FunSpec, Matchers}

abstract class TemplatesSpec[T](renderers: Templates, subProjectName: String) extends FunSpec with Matchers {

  describe(subProjectName + " templating") {

    describe("caching classpath") {
      val renderer = renderers.CachingClasspath()
      it("renders a template from a case class on the classpath") {
        renderOnClasspath(renderer)
      }

      it("renders a template from a case class with overridden template") {
        renderAtRoot(renderer)
      }
    }

    describe("caching file-based") {
      val renderer = renderers.Caching(subProjectName + "/src/test/resources")
      it("renders a template from a case class on the classpath") {
        renderOnClasspath(renderer)
      }

      it("renders a template from a case class with overridden template") {
        renderAtRoot(renderer)
      }
    }

    describe("hot reload") {
      val renderer = renderers.HotReload(subProjectName + "/src/test/resources")
      it("renders a template from a case class on the classpath") {
        renderOnClasspath(renderer)
      }

      it("renders a template from a case class with overridden template") {
        renderAtRoot(renderer)
      }
    }
  }

  private val items = Seq(
    Item("item1", "£1", Seq(Feature("pretty"))),
    Item("item2", "£3", Seq(Feature("nasty")))
  )

  private def renderOnClasspath(renderer: TemplateRenderer): Unit = {
    Buf.Utf8.unapply(renderer.toBuf(OnClasspath(items))).get shouldBe "Name:item1Price:£1Feature:prettyName:item2Price:£3Feature:nasty"
  }

  private def renderAtRoot(renderer: TemplateRenderer): Unit = {
    Buf.Utf8.unapply(renderer.toBuf(AtRoot(items))).get shouldBe "AtRootName:item1Price:£1Feature:prettyAtRootName:item2Price:£3Feature:nasty"
  }
} 
Example 11
Source File: ResponseBuilderSpec.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.formats

import com.twitter.finagle.http.Status
import com.twitter.io.{Buf, Bufs}
import org.scalatest.{FunSpec, Matchers}

abstract class ResponseBuilderSpec[T](bldr: AbstractResponseBuilder[T]) extends FunSpec with Matchers {

  val message = "some text goes here"

  val customType: T
  val customTypeSerialized: Buf

  val customError: T
  val customErrorSerialized: Buf

  describe("Rendering") {
    it("builds non error with custom type") {
      val rsp = bldr.Ok(customType)
      (rsp.status, Bufs.asByteArrayBuf(rsp.content)) shouldBe(Status.Ok, Bufs.asByteArrayBuf(customTypeSerialized))
    }

    it("builds error with message - String") {
      val rsp = bldr.NotFound(customError)
      (rsp.status, Bufs.asByteArrayBuf(rsp.content)) shouldBe(Status.NotFound, Bufs.asByteArrayBuf(customErrorSerialized))
    }
  }

} 
Example 12
Source File: package.scala    From featherbed   with Apache License 2.0 5 votes vote down vote up
package featherbed

import java.nio.CharBuffer
import java.nio.charset.{Charset, CodingErrorAction}
import scala.util.Try

import cats.data.{Validated, ValidatedNel}
import com.twitter.finagle.http.Response
import com.twitter.io.Buf
import shapeless.Witness
import sun.nio.cs.ThreadLocalCoders

package object content {
  type ContentType = String

  trait Decoder[ContentType] {
    type Out
    val contentType: String //widened version of ContentType
    def apply(buf: Response): ValidatedNel[Throwable, Out]
  }

  object Decoder extends LowPriorityDecoders {
    type Aux[CT, A1] = Decoder[CT] { type Out = A1 }

    def of[T <: ContentType, A1](t: T)(fn: Response => ValidatedNel[Throwable, A1]): Decoder.Aux[t.type, A1] =
      new Decoder[t.type] {
        type Out = A1
        val contentType = t
        def apply(response: Response) = fn(response)
      }

    def decodeString(response: Response): ValidatedNel[Throwable, String] = {
      Validated.fromTry(Try {
        response.charset.map(Charset.forName).getOrElse(Charset.defaultCharset)
      }).andThen { charset: Charset =>
        val decoder = ThreadLocalCoders.decoderFor(charset)
        Validated.fromTry(
          Try(
            decoder
              .onMalformedInput(CodingErrorAction.REPORT)
              .onUnmappableCharacter(CodingErrorAction.REPORT)
              .decode(Buf.ByteBuffer.Owned.extract(response.content).asReadOnlyBuffer()))).map[String](_.toString)
      }.toValidatedNel
    }
  }

  private[featherbed] trait LowPriorityDecoders {
    implicit val plainTextDecoder: Decoder.Aux[Witness.`"text/plain"`.T, String] = Decoder.of("text/plain") {
      response => Decoder.decodeString(response)
    }

    implicit val anyResponseDecoder: Decoder.Aux[Witness.`"**") {
      response => Validated.Valid(response)
    }
  }

  trait Encoder[A, ForContentType] {
    def apply(value: A, charset: Charset): ValidatedNel[Throwable, Buf]
  }

  object Encoder extends LowPriorityEncoders {
    def of[A, T <: ContentType](t: T)(fn: (A, Charset) => ValidatedNel[Throwable, Buf]): Encoder[A, t.type] =
      new Encoder[A, t.type] {
        def apply(value: A, charset: Charset) = fn(value, charset)
      }

    def encodeString(value: String, charset: Charset): ValidatedNel[Throwable, Buf] = {
      val encoder = ThreadLocalCoders.encoderFor(charset)
      Validated.fromTry(Try(encoder
        .onMalformedInput(CodingErrorAction.REPORT)
        .onUnmappableCharacter(CodingErrorAction.REPORT)
        .encode(CharBuffer.wrap(value)))).toValidatedNel.map[Buf](Buf.ByteBuffer.Owned(_))
    }
  }

  private[featherbed] trait LowPriorityEncoders {
    implicit val plainTextEncoder: Encoder[String, Witness.`"text/plain"`.T] = Encoder.of("text/plain") {
      case (value, charset) => Encoder.encodeString(value, charset)
    }
  }
} 
Example 13
Source File: MultipartFileTest.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.parameters

import java.io.File
import java.nio.charset.StandardCharsets.UTF_8

import com.google.common.io.Files
import com.twitter.io.{Buf, Bufs}
import org.scalatest.{FunSpec, Matchers}

class MultipartFileTest extends FunSpec with Matchers {

  describe("OnDiskMultiPartFile") {
    it("converts toFileElement") {
      val tempFile = File.createTempFile("temp", "file")
      Files.write("hello bob", tempFile, UTF_8)
      tempFile.deleteOnExit()
      Bufs.asUtf8String(OnDiskMultiPartFile("file", tempFile, None).toFileElement("hello").content) shouldBe "hello bob"
    }
  }

  describe("InMemoryMultiPartFile") {
    it("converts toFileElement") {
      Bufs.asUtf8String(InMemoryMultiPartFile("file", Buf.Utf8("hello bob"), None).toFileElement("hello").content) shouldBe "hello bob"
    }
  }

} 
Example 14
Source File: BodySpec.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.parameters

import com.twitter.io.Buf
import com.twitter.io.Buf.ByteArray.Shared.extract
import io.fintrospect.ContentType
import io.fintrospect.ContentTypes.{APPLICATION_JSON, APPLICATION_XML, TEXT_PLAIN}
import io.fintrospect.formats.{Argo, JsonLibrary}

import scala.xml.{Elem, XML}


  def map[O](in: T => O) = BodySpec[O](contentType, paramType, s => in(deserialize(s)))
}

object BodySpec {
  def string(contentType: ContentType = TEXT_PLAIN, validation: StringValidations.Rule = StringValidations.EmptyIsInvalid): BodySpec[String] =
    BodySpec[String](contentType, StringParamType, b => validation(new String(extract(b))))

  def json[T](jsonLib: JsonLibrary[T, _] = Argo): BodySpec[T] =
    BodySpec[T](APPLICATION_JSON, ObjectParamType, b => jsonLib.JsonFormat.parse(new String(extract(b))), t => Buf.Utf8(jsonLib.JsonFormat.compact(t)))

  def xml(): BodySpec[Elem] = string(APPLICATION_XML).map(XML.loadString, _.toString())

  def binary(contentType: ContentType): BodySpec[Buf] = BodySpec(contentType, FileParamType,
    b => {
      require(b.length > 0)
      b
    },
    b => {
      require(b.length > 0)
      b
    }
  )
} 
Example 15
Source File: CirceTest.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.formats

import com.twitter.finagle.Service
import com.twitter.finagle.http.{Request, Status}
import com.twitter.io.{Buf, Bufs}
import com.twitter.util.Future
import io.circe.generic.auto._
import io.fintrospect.formats.Circe.Auto._
import io.fintrospect.formats.Circe.JsonFormat._
import io.fintrospect.formats.Circe._
import io.fintrospect.formats.JsonFormat.InvalidJsonForDecoding
import io.fintrospect.parameters.{Body, BodySpec, Query}



class CirceJsonResponseBuilderTest extends JsonResponseBuilderSpec(Circe)

class CirceAutoTest extends AutoSpec(Circe.Auto) {

  describe("API") {
    it("can find implicits") {
      Circe.Auto.InOut[Letter, Letter](Service.mk { in: Letter => Future(in) })
    }
  }


  override def toBuf(l: Letter) = Bufs.utf8Buf(encode(l).noSpaces)

  override def fromBuf(s: Buf): Letter = decode[Letter](parse(Bufs.asUtf8String(s)))

  override def bodySpec: BodySpec[Letter] = Circe.bodySpec[Letter]()

  override def transform() = Circe.Auto.tToJson[Letter]
}

class CirceJsonFormatTest extends JsonFormatSpec(Circe) {

  import io.circe.generic.auto._

  describe("Circe.JsonFormat") {
    val aLetter = Letter(StreetAddress("my house"), StreetAddress("your house"), "hi there")

    it("roundtrips to JSON and back") {
      val encoded = encode(aLetter)
      decode[Letter](encoded) shouldBe aLetter
    }

    it("patchbody modifies original object with a non-null value") {
      val original = LetterOpt(StreetAddress("my house"), StreetAddress("your house"), None)
      val modifier = encode(obj("message" -> string("hi there")))
      val modifyLetter = patcher[LetterOpt](modifier)
      modifyLetter(original) shouldBe LetterOpt(StreetAddress("my house"), StreetAddress("your house"), Option("hi there"))
    }

    // wait for circe 0.6.X, where this bug will be fixed - https://github.com/travisbrown/circe/issues/304
    ignore("patcher modifies original object with a null value") {
      val original = LetterOpt(StreetAddress("my house"), StreetAddress("your house"), Option("hi there"))
      val modifier = encode(obj())
      val modifyLetter = patcher[LetterOpt](modifier)
      modifyLetter(original) shouldBe LetterOpt(StreetAddress("my house"), StreetAddress("your house"), None)
    }

    it("invalid extracted JSON throws up") {
      intercept[InvalidJsonForDecoding](decode[Letter](Circe.JsonFormat.obj()))
    }

    it("body spec decodes content") {
      (Body.of(bodySpec[Letter]()) <-- Circe.ResponseBuilder.Ok(encode(aLetter)).build()) shouldBe aLetter
    }

    it("patch body can be used to modify an existing case class object") {
      val letterWithNoMessage = LetterOpt(StreetAddress("my house"), StreetAddress("your house"), None)
      val modifiedMessage = encode(obj("message" -> string("hi there")))
      val modifiedLetterWithMessage = LetterOpt(StreetAddress("my house"), StreetAddress("your house"), Some("hi there"))

      val patch = patchBody[LetterOpt]("path to body", modifiedLetterWithMessage) <-- Circe.ResponseBuilder.Ok(modifiedMessage).build()

      patch(letterWithNoMessage) shouldBe modifiedLetterWithMessage
    }

    it("response spec has correct code") {
      Circe.responseSpec[Letter](Status.Ok -> "ok", aLetter).status shouldBe Status.Ok
    }

    it("param spec decodes content") {
      val param = Query.required(parameterSpec[Letter](), "name")
      (param <-- Request("?name=" + encode(aLetter))) shouldBe aLetter
    }
  }
  override val expectedJson: String = """{"string":"hello","object":{"field1":"aString"},"int":10,"long":2,"double":1.2,"decimal":1.2,"bigInt":12344,"bool":true,"null":null,"array":["world",true]}"""
} 
Example 16
Source File: PlayTest.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.formats

import com.twitter.finagle.Service
import com.twitter.finagle.http.Request
import com.twitter.io.{Buf, Bufs}
import com.twitter.util.Future
import io.fintrospect.formats.JsonFormat.InvalidJsonForDecoding
import io.fintrospect.formats.Play.Auto._
import io.fintrospect.formats.Play.JsonFormat._
import io.fintrospect.formats.Play._
import io.fintrospect.parameters.{Body, BodySpec, Query}
import play.api.libs.json._



object helpers {
  implicit val SAWrites = new Writes[StreetAddress] {
    override def writes(in: StreetAddress) = JsObject(Seq("address" -> JsString(in.address)))
  }
  implicit val SAReads = new Reads[StreetAddress] {
    override def reads(in: JsValue) = JsSuccess(StreetAddress(
      (in \ "address").as[String]
    ))
  }

  implicit val Writes = Json.writes[Letter]
  implicit val Reads = Json.reads[Letter]
}


class PlayAutoTest extends AutoSpec(Play.Auto) {

  import helpers._

  describe("API") {
    it("can find implicits") {
      Play.Auto.InOut[Letter, Letter](Service.mk { in: Letter => Future(in) })
    }
  }

  override def toBuf(l: Letter) = Bufs.utf8Buf(compact(Play.JsonFormat.encode(l)(Writes)))

  override def fromBuf(s: Buf): Letter = decode[Letter](parse(Bufs.asUtf8String(s)))(Reads)

  override def bodySpec: BodySpec[Letter] = Play.bodySpec[Letter]()(helpers.Reads, helpers.Writes)

  override def transform() = Play.Auto.tToJsValue[Letter](Writes)
}

class PlayJsonResponseBuilderTest extends JsonResponseBuilderSpec(Play)

class PlayJsonFormatTest extends JsonFormatSpec(Play) {

  describe("Play.JsonFormat") {
    val aLetter = Letter(StreetAddress("my house"), StreetAddress("your house"), "hi there")

    it("roundtrips to JSON and back") {
      val encoded = Play.JsonFormat.encode(aLetter)(helpers.Writes)
      Play.JsonFormat.decode[Letter](encoded)(helpers.Reads) shouldBe aLetter
    }

    it("invalid extracted JSON throws up") {
      intercept[InvalidJsonForDecoding](Play.JsonFormat.decode[Letter](Play.JsonFormat.obj())(helpers.Reads))
    }

    it("body spec decodes content") {
      (Body.of(bodySpec[Letter]()(helpers.Reads, helpers.Writes)) <-- Play.ResponseBuilder.Ok(encode(aLetter)(helpers.Writes)).build()) shouldBe aLetter
    }

    it("param spec decodes content") {
      val param = Query.required(parameterSpec[Letter]()(helpers.Reads, helpers.Writes), "name")
      (param <-- Request("?name=" + encode(aLetter)(helpers.Writes))) shouldBe aLetter
    }
  }

} 
Example 17
Source File: MsgPackFormatTest.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.formats

import com.twitter.io.Buf
import io.fintrospect.formats.MsgPack.Format._
import org.scalatest.{FunSpec, Matchers}
import org.velvia.InvalidMsgPackDataException

class MsgPackFormatTest extends FunSpec with Matchers {

  describe("roundtrips") {
    val aLetter = Letter(StreetAddress("my house"), StreetAddress("your house"), "hi there")

      it("roundtrips to JSON and back") {
        decode[Letter](encode(aLetter)) shouldBe aLetter
      }

      it("invalid extracted Msg throws up") {
        intercept[InvalidMsgPackDataException](decode[Letter](Buf.Empty))
      }
  }
} 
Example 18
Source File: HandlebarsTemplates.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.templating

import java.io.File
import java.util.concurrent.ConcurrentHashMap

import com.gilt.handlebars.scala.Handlebars
import com.gilt.handlebars.scala.binding.dynamic._
import com.twitter.io.Buf
import com.twitter.io.Buf.ByteArray.Owned

import scala.collection.JavaConverters._
import scala.io.Source

object HandlebarsTemplates extends Templates {

  def CachingClasspath(baseClasspathPackage: String = "."): TemplateRenderer =
    new TemplateRenderer {

      private val classToTemplate = new ConcurrentHashMap[Class[_], Handlebars[Any]]().asScala

      private def loadView[T <: View](view: T): Handlebars[Any] =
        classToTemplate.getOrElseUpdate(view.getClass,
          Option(getClass.getResourceAsStream("/" + view.template + ".hbs"))
            .map(t => Handlebars[Any](Source.fromInputStream(t).mkString))
            .getOrElse(throw new ViewNotFound(view))
        )

      override def toBuf(view: View): Buf = Owned(loadView(view)(view).getBytes)
    }

  def Caching(baseTemplateDir: String): TemplateRenderer = {
    val baseDir = new File(baseTemplateDir)

    new TemplateRenderer {
      private val classToTemplate = new ConcurrentHashMap[Class[_], Handlebars[Any]]().asScala

      private def loadView[T <: View](view: T): Handlebars[Any] =
        classToTemplate.getOrElseUpdate(view.getClass, {
          val file = new File(baseDir, view.template + ".hbs")
          if (!file.exists()) throw new ViewNotFound(view)
          Handlebars[Any](Source.fromFile(file).mkString)
        })

      override def toBuf(view: View): Buf = Owned(loadView(view)(view).getBytes)
    }
  }

  def HotReload(baseTemplateDir: String = "."): TemplateRenderer = new TemplateRenderer {
    override def toBuf(view: View): Buf = {
      val handlebars = Handlebars[Any](new File(baseTemplateDir, view.template + ".hbs"))
      Owned(handlebars(view).getBytes)
    }
  }
} 
Example 19
Source File: ScodecSerial.scala    From finagle-serial   with Apache License 2.0 5 votes vote down vote up
package io.github.finagle.serial.scodec

import _root_.scodec.{Codec, Err}
import _root_.scodec.bits.BitVector
import _root_.scodec.codecs._
import com.twitter.io.Buf
import com.twitter.util.{Return, Throw, Try}
import io.github.finagle.serial.{ApplicationError, CodecError, Serial}

trait ScodecSerial extends Serial {
  type C[A] = Codec[A]
  type Bytes = BitVector

  
  lazy val applicationErrorCodec: Codec[Throwable] = ApplicationErrorCodec.basic.underlying

  private[this] def reqMessageCodec[A](c: Codec[A]): Codec[Either[CodecError, A]] =
    either(bool, codecErrorCodec, c)

  def encodeReq[A](a: A)(c: Codec[A]): Try[BitVector] = {
    val codec = reqMessageCodec(c)

    codec.encode(Right(a)).fold(
      e => codec.encode(Left(CodecError(e.message))).fold(
        e => Throw(CodecError(e.message)),
        bits => Return(bits)
      ),
      bits => Return(bits)
    )
  }

  def decodeReq[A](bytes: BitVector)(c: Codec[A]): Try[A] =
    reqMessageCodec(c).decode(bytes).fold(
      e => Throw(CodecError(e.message)),
      o => o.value.fold(Throw(_), Return(_))
    )

  def encodeRep[A](t: Try[A])(c: Codec[A]): Try[BitVector] = {
    val message: RepMessage[A] = t match {
      case Return(a) => ContentRepMessage(a)
      case Throw(e @ CodecError(_)) => CodecErrorRepMessage(e)
      case Throw(e) => ApplicationErrorRepMessage(e)
    }

    val codec = RepMessage.codec(
      c,
      codecErrorCodec,
      applicationErrorCodec,
      unhandledApplicationErrorCodec
    )

    codec.encode(message).fold(
      {
        case Err.MatchingDiscriminatorNotFound(t: Throwable, _) =>
          codec.encode(UnhandledApplicationErrorRepMessage(ApplicationError(t.toString))).fold(
            e => Throw(CodecError(e.message)),
            bits => Return(bits)
          )
        case e => codec.encode(CodecErrorRepMessage(CodecError(e.message))).fold(
          e => Throw(CodecError(e.message)),
          bits => Return(bits)
        )
      },
      bits => Return(bits)
    )
  }

  def decodeRep[A](bytes: BitVector)(c: Codec[A]): Try[A] =
    RepMessage.codec(
      c,
      codecErrorCodec,
      applicationErrorCodec,
      unhandledApplicationErrorCodec
    ).decode(bytes).fold(
      e => Throw(CodecError(e.message)),
      o => o.value.toTry
    )

  def toBuf(bytes: BitVector): Buf = Buf.ByteArray.Owned(bytes.toByteArray)
  def fromBuf(buf: Buf): BitVector = BitVector(Buf.ByteArray.Owned.extract(buf))
}

object ScodecSerial extends ScodecSerial 
Example 20
Source File: UserContext.scala    From the-finagle-docs   with MIT License 5 votes vote down vote up
package net.gutefrage.context

import com.twitter.finagle.context.Contexts
import com.twitter.finagle.util.ByteArrays
import com.twitter.io.Buf
import com.twitter.util.{Return, Throw, Try}

case class UserContext(userId: Long)


  def current: Option[UserContext] = Contexts.broadcast.get(UserContext)

  override def marshal(userContext: UserContext): Buf = {
    val bytes = new Array[Byte](bodyLengthBytes)
    ByteArrays.put64be(bytes, 0, userContext.userId)
    Buf.ByteArray.Owned(bytes)
  }

  override def tryUnmarshal(body: Buf): Try[UserContext] = {
    if (body.length != bodyLengthBytes) {
      return Throw(new IllegalArgumentException(s"Invalid body. Length ${body.length} but required 16"))
    }

    val bytes = Buf.ByteArray.Owned.extract(body)
    val userId = ByteArrays.get64be(bytes, 0)

    Return(UserContext(userId))
  }
} 
Example 21
Source File: HttpRecord.scala    From airframe   with Apache License 2.0 5 votes vote down vote up
package wvlet.airframe.http.recorder
import java.sql.{Connection, ResultSet}
import java.time.Instant

import com.twitter.finagle.http.{Response, Status, Version}
import com.twitter.io.Buf
import wvlet.airframe.codec._
import wvlet.airframe.control.Control.withResource
import wvlet.airframe.http.recorder.HttpRecord.headerCodec
import wvlet.log.LogSupport


case class HttpRecord(
    session: String,
    requestHash: Int,
    method: String,
    destHost: String,
    path: String,
    requestHeader: Seq[(String, String)],
    requestBody: String,
    responseCode: Int,
    responseHeader: Seq[(String, String)],
    responseBody: String,
    createdAt: Instant
) {
  def summary: String = {
    s"${method}(${responseCode}) ${destHost}${path}: ${responseBody.substring(0, 30.min(responseBody.size))} ..."
  }

  def toResponse: Response = {
    val r = Response(Version.Http11, Status.fromCode(responseCode))

    responseHeader.foreach { x => r.headerMap.set(x._1, x._2) }

    // Decode binary contents with Base64
    val contentBytes = HttpRecordStore.decodeFromBase64(responseBody)
    r.content = Buf.ByteArray.Owned(contentBytes)
    r.contentLength = contentBytes.length
    r
  }

  def insertInto(tableName: String, conn: Connection): Unit = {
    withResource(conn.prepareStatement(s"""|insert into "${tableName}" values(
          |?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
          |)
      """.stripMargin)) { prep =>
      // TODO Implement this logic in JDBCResultSetCodec
      prep.setString(1, session)
      prep.setInt(2, requestHash)
      prep.setString(3, method)
      prep.setString(4, destHost)
      prep.setString(5, path)
      prep.setString(6, JSONCodec.toJson(headerCodec.toMsgPack(requestHeader)))
      prep.setString(7, requestBody)
      prep.setInt(8, responseCode)
      prep.setString(9, JSONCodec.toJson(headerCodec.toMsgPack(responseHeader)))
      prep.setString(10, responseBody)
      prep.setString(11, createdAt.toString)

      prep.execute()
    }
  }
}

object HttpRecord extends LogSupport {
  private[recorder] val headerCodec                               = MessageCodec.of[Seq[(String, String)]]
  private[recorder] val recordCodec                               = MessageCodec.of[HttpRecord]
  private[recorder] def createTableSQL(tableName: String): String =
    // TODO: Add a method to generate this SQL statement in airframe-codec
    s"""create table if not exists "${tableName}" (
       |  session string,
       |  requestHash string,
       |  method string,
       |  destHost string,
       |  path string,
       |  requestHeader string,
       |  requestBody string,
       |  responseCode int,
       |  responseHeader string,
       |  responseBody string,
       |  createdAt string
       |)
     """.stripMargin

  private[recorder] def read(rs: ResultSet): Seq[HttpRecord] = {
    val resultSetCodec = JDBCCodec(rs)
    resultSetCodec
      .mapMsgPackMapRows(msgpack => recordCodec.unpackBytes(msgpack))
      .filter(_.isDefined)
      .map(_.get)
      .toSeq
  }
}