com.twitter.finagle.Http Scala Examples

The following examples show how to use com.twitter.finagle.Http. 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: CirceSpec.scala    From featherbed   with Apache License 2.0 6 votes vote down vote up
package featherbed.circe

import cats.implicits._
import com.twitter.util.Future
import io.circe._
import io.circe.generic.auto._
import io.circe.parser.parse
import io.circe.syntax._
import org.scalatest.FlatSpec
import shapeless.{Coproduct, Witness}
import shapeless.union.Union

case class Foo(someText: String, someInt: Int)

class CirceSpec extends FlatSpec {

  "post request of a case class" should "derive JSON encoder" in {

    import com.twitter.util.{Future, Await}
    import com.twitter.finagle.{Service, Http}
    import com.twitter.finagle.http.{Request, Response}
    import java.net.InetSocketAddress

    val server = Http.serve(new InetSocketAddress(8766), new Service[Request, Response] {
      def apply(request: Request): Future[Response] = Future {
        val rep = Response()
        rep.contentString = s"${request.contentString}"
        rep.setContentTypeJson()
        rep
      }
    })

    import java.net.URL
    val client = new featherbed.Client(new URL("http://localhost:8766/api/"))

    import io.circe.generic.auto._

    val req = client.post("foo/bar")
      .withContent(Foo("Hello world!", 42), "application/json")
        .accept[Coproduct.`"application/json"`.T]

    val result = Await.result {
       req.send[Foo]()
    }

    Foo("test", 42).asJson.toString

    parse("""{"someText": "test", "someInt": 42}""").toValidated.map(_.as[Foo])

    Await.result(server.close())

  }

  "API example" should "compile" in {
    import shapeless.Coproduct
    import java.net.URL
    import com.twitter.util.Await
    case class Post(userId: Int, id: Int, title: String, body: String)

    case class Comment(postId: Int, id: Int, name: String, email: String, body: String)
    class JSONPlaceholderAPI(baseUrl: URL) {

      private val client = new featherbed.Client(baseUrl)
      type JSON = Coproduct.`"application/json"`.T

      object posts {

        private val listRequest = client.get("posts").accept[JSON]
        private val getRequest = (id: Int) => client.get(s"posts/$id").accept[JSON]

        def list(): Future[Seq[Post]] = listRequest.send[Seq[Post]]()
        def get(id: Int): Future[Post] = getRequest(id).send[Post]()
      }

      object comments {
        private val listRequest = client.get("comments").accept[JSON]
        private val getRequest = (id: Int) => client.get(s"comments/$id").accept[JSON]

        def list(): Future[Seq[Comment]] = listRequest.send[Seq[Comment]]()
        def get(id: Int): Future[Comment] = getRequest(id).send[Comment]()
      }
    }

    val apiClient = new JSONPlaceholderAPI(new URL("http://jsonplaceholder.typicode.com/"))

    Await.result(apiClient.posts.list())
  }

} 
Example 2
Source File: Streaming_Response_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Streaming_Response_Example extends App {

  import argo.jdom.JsonNode
  import com.twitter.concurrent.AsyncStream
  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import com.twitter.util.Duration.fromSeconds
  import com.twitter.util.Future.sleep
  import com.twitter.util.JavaTimer
  import io.fintrospect.formats.Argo.JsonFormat._
  import io.fintrospect.formats.Argo.ResponseBuilder._
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val timer = new JavaTimer()

  def ints(i: Int): AsyncStream[Int] = i +:: AsyncStream.fromFuture(sleep(fromSeconds(1))(timer)).flatMap(_ => ints(i + 1))

  def jsonStream: AsyncStream[JsonNode] = ints(0).map(i => obj("number" -> number(i)))

  val count: Service[Request, Response] = Service.mk[Request, Response] { req => Ok(jsonStream) }

  val route: ServerRoute[Request, Response] = RouteSpec().at(Get) bindTo count

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl --raw http://localhost:9999/ 
Example 3
Source File: Full_Auto_Service_Wrappers_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.json_libraries


case class Profile(name: String, age: Option[Int])

// fintrospect-core
// fintrospect-circe
object Full_Auto_Marshalling_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import com.twitter.util.Future
  import io.circe.generic.auto._
  import io.fintrospect.formats.Circe
  import io.fintrospect.formats.Circe.Auto._
  import io.fintrospect.parameters.Body
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val insultMe: Service[Profile, Profile] = Service.mk[Profile, Profile] {
    inProfile => Future(inProfile.copy(name = inProfile.name + " Smells"))
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(Body.of(Circe.bodySpec[Profile]()))
    .at(Post) bindTo InOut(insultMe)

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -XPOST http://localhost:9999/ --data '{"name":"David", "age": 50}' 
Example 4
Source File: Composite_Request_Parameters_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core


// fintrospect-core
object Composite_Request_Parameters_Example extends App {

  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.parameters.{Binding, Composite, Header, Query}
  import io.fintrospect.util.Extraction
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}



  case class FooBar(foo: String, bar: Int)

  object FooBar extends Composite[FooBar] {
    private val fooQ = add(Header.required.string("foo"))
    private val barQ = add(Query.required.int("bar"))

    override def -->(foobar: FooBar): Iterable[Binding] = (fooQ --> foobar.foo) ++ (barQ --> foobar.bar)

    override def <--?(req: Request): Extraction[FooBar] = {
      for {
        foo <- fooQ <--? req
        bar <- barQ <--? req
      } yield FooBar(foo, bar)
    }
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .taking(FooBar).at(Get) bindTo Service.mk {
    req: Request => Ok("you sent: " + (FooBar <-- req))
  }

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -H"foo: foo" http://localhost:9999?bar=123 
Example 5
Source File: Serving_Multiple_Content_Types_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Serving_Multiple_Content_Types_Example extends App {

  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.ContentTypes.{APPLICATION_JSON, APPLICATION_XML}
  import io.fintrospect.parameters.Path
  import io.fintrospect.util.StrictContentTypeNegotiation
  import io.fintrospect.{RouteModule, RouteSpec}

  def serveJson(name: String) = Service.mk[Request, Response] { req =>
    import io.fintrospect.formats.Argo.JsonFormat._
    import io.fintrospect.formats.Argo.ResponseBuilder._
    Ok(obj("field" -> string(name)))
  }

  def serveXml(name: String) = Service.mk[Request, Response] {
    import io.fintrospect.formats.Xml.ResponseBuilder._
    req =>
      Ok(<root>
        <field>
          {name}
        </field>
      </root>)
  }

  val route = RouteSpec()
    .at(Get) / Path.string("name") bindTo
      StrictContentTypeNegotiation(APPLICATION_XML -> serveXml, APPLICATION_JSON -> serveJson)

  ready(Http.serve(":9999", RouteModule(Root).withRoute(route).toService))
}
//curl -v -H"Accept: application/json" http://localhost:9999/David
//curl -v -H"Accept: application/xml" http://localhost:9999/David 
Example 6
Source File: Simple_XML_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Simple_XML_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.Xml.ResponseBuilder._
  import io.fintrospect.parameters.Body
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  import scala.xml.Elem

  val document: Body[Elem] = Body.xml()

  val analyse: Service[Request, Response] = Service.mk[Request, Response] {
    req => {
      val postedDoc: Elem = document <-- req
      Ok(
        <document>
          <number-of-root-elements>
            {postedDoc.length}
          </number-of-root-elements>
        </document>
      )
    }
  }

  val route: ServerRoute[Request, Response] = RouteSpec().body(document).at(Post) bindTo analyse

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -XPOST http://localhost:9999/ --data '<person name="david" age="100"/>' 
Example 7
Source File: Swagger_Auto_Docs_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Swagger_Auto_Docs_Example extends App {

  import argo.jdom.JsonNode
  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.filter.Cors
  import com.twitter.finagle.http.filter.Cors.HttpFilter
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response, Status}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import com.twitter.util.Future
  import io.fintrospect.ContentTypes.APPLICATION_JSON
  import io.fintrospect.formats.Argo.JsonFormat._
  import io.fintrospect.formats.Argo.ResponseBuilder._
  import io.fintrospect.parameters.{Body, Header, Path, Query}
  import io.fintrospect.renderers.ModuleRenderer
  import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}
  import io.fintrospect.{ApiKey, Module, RouteModule, RouteSpec, ServerRoute}

  def buildResponse(id: Int, sent: JsonNode) = obj("id" -> number(id), "sent" -> sent)

  val exampleBody: JsonNode = array(obj("lastName" -> string("Jane")), obj("name" -> string("Jim")))
  val exampleResponse: JsonNode = buildResponse(222, exampleBody)
  val sentDocument: Body[JsonNode] = Body.json("family description", exampleBody)

  def svc(id: Int): Service[Request, Response] = Service.mk[Request, Response] { req =>
    Ok(buildResponse(id, sentDocument <-- req))
  }

  val securityFilter: Service[String, Boolean] = Service.mk[String, Boolean] { r => Future(r == "secret") }

  val route: ServerRoute[Request, Response] = RouteSpec("a short summary", "a longer description")
    .taking(Query.required.string("firstName", "this is your firstname"))
    .taking(Header.optional.localDate("birthdate", "format yyyy-mm-dd"))
    .producing(APPLICATION_JSON)
    .consuming(APPLICATION_JSON)
    .returning(Status.Ok -> "Valid request accepted", exampleResponse)
    .body(sentDocument)
    .at(Post) / Path.int("id", "custom identifier for this request") bindTo svc

  val docsRenderer: ModuleRenderer = Swagger2dot0Json(
    ApiInfo("My App", "1.0", "This is an extended description of the API's functions")
  )

  val module: Module = RouteModule(Root, docsRenderer)
    .withDescriptionPath(moduleRoot => moduleRoot / "swagger.json")
    .securedBy(ApiKey(Query.required.string("token"), securityFilter))
    .withRoute(route)

  ready(Http.serve(":9999", new HttpFilter(Cors.UnsafePermissivePolicy).andThen(module.toService)))
}

// curl -v http://localhost:9999/swagger.json 
Example 8
Source File: Custom_Response_Format_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core


// fintrospect-core
object Custom_Response_Format_Example extends App {
  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.io.Bufs
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.{AbstractResponseBuilder, ResponseBuilder}
  import io.fintrospect.{ContentType, Module, RouteModule, RouteSpec, ServerRoute}

  object Csv {
    object ResponseBuilder extends AbstractResponseBuilder[List[String]] {
      override def HttpResponse(): ResponseBuilder[List[String]] = new ResponseBuilder(
        (i: List[String]) => Bufs.utf8Buf(i.mkString(",")),
        error => List("ERROR:" + error),
        throwable => List("ERROR:" + throwable.getMessage),
        ContentType("application/csv")
      )
    }
  }

  import Csv.ResponseBuilder._

  val service: Service[Request, Response] = Service.mk { _: Request => Ok(List("this", "is", "comma", "separated", "hello", "world")) }

  val route: ServerRoute[Request, Response] = RouteSpec().at(Get) bindTo service
  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v http://localhost:9999 
Example 9
Source File: Simple_HTML_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core


// fintrospect-core
object Simple_HTML_Example extends App {

  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.Html.ResponseBuilder._
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val serve: Service[Request, Response] = Service.mk[Request, Response] {
    req => {
      Ok(
        <html>
          <head>
            <title>The Title</title>
          </head>
          <body>Some content goes here</body>
        </html>.toString()
      )
    }
  }

  val route: ServerRoute[Request, Response] = RouteSpec().at(Get) bindTo serve

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v http://localhost:9999/' 
Example 10
Source File: Accepting_Multiple_Body_Types_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Accepting_Multiple_Body_Types_Example extends App {

  import argo.jdom.JsonNode
  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.parameters.Body
  import io.fintrospect.util.MultiBodyType
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  import scala.xml.Elem

  val json: Body[JsonNode] = Body.json()

  val echoJson: Service[Request, Response] = Service.mk[Request, Response] { req =>
    import io.fintrospect.formats.Argo.ResponseBuilder._
    Ok(json <-- req)
  }

  val xml: Body[Elem] = Body.xml()

  val echoXml: Service[Request, Response] = Service.mk[Request, Response] { req =>
    import io.fintrospect.formats.Xml.ResponseBuilder._
    Ok(xml <-- req)
  }

  val route: ServerRoute[Request, Response] = RouteSpec("echo posted content in either JSON or XML")
    .at(Post) bindTo MultiBodyType(json -> echoJson, xml -> echoXml)

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -XPOST -H"Content-Type: application/json" http://localhost:9999/ --data '{"name":"David"}'
//curl -v -XPOST -H"Content-Type: application/xml" http://localhost:9999/ --data '<name>David</name>' 
Example 11
Source File: Module_Filters_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Module_Filters_Example extends App {

  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Filter, Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.renderers.ModuleRenderer
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val headers: Service[Request, Response] = Service.mk[Request, Response] { req => Ok(req.uri) }

  val route: ServerRoute[Request, Response] = RouteSpec().at(Get) bindTo headers

  val timingFilter = Filter.mk[Request, Response, Request, Response] {
    (req, next) =>
      val start = System.currentTimeMillis()
      next(req).map {
        resp => {
          val time = System.currentTimeMillis() - start
          resp.headerMap("performance") = s"${resp.contentString} took $time ms"
          resp
        }
      }
  }

  val module: Module = RouteModule(Root, ModuleRenderer.Default, timingFilter).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v http://localhost:9999 
Example 12
Source File: Extracting_Upstream_Responses.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Extracting_Upstream_Responses extends App {

  import argo.jdom.JsonNode
  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.result
  import io.fintrospect.configuration.{Authority, Host, Port}
  import io.fintrospect.filters.RequestFilters.AddHost
  import io.fintrospect.filters.ResponseFilters
  import io.fintrospect.parameters.{Body, BodySpec, Path}
  import io.fintrospect.util.{Extracted, Extraction, ExtractionFailed}
  import io.fintrospect.{RouteClient, RouteSpec}

  case class Pokemon(id: Int, name: String, weight: Int)

  object Pokemon {
    def from(j: JsonNode) = Pokemon(j.getNumberValue("id").toInt,
      j.getStringValue("name"),
      j.getNumberValue("weight").toInt)
  }

  val authority: Authority = Host("pokeapi.co").toAuthority(Port._80)

  val http: Service[Request, Response] = AddHost(authority).andThen(Http.newService(authority.toString))

  val id = Path.int("pokemonId")


  val spec: BodySpec[Pokemon] = BodySpec.json().map(Pokemon.from)

  val nameAndWeight: Body[Pokemon] = Body.of(spec)

  val client: RouteClient[Extraction[Option[Pokemon]]] = RouteSpec().at(Get) / "api" / "v2" / "pokemon" / id / "" bindToClient
    ResponseFilters.ExtractBody(nameAndWeight).andThen(http)

  def reportOnPokemon(pid: Int) =
    println(
      result(client(id --> pid)) match {
        case Extracted(Some(pokemon)) => s"i found a pokemon: $pokemon"
        case Extracted(None) => s"there is no pokemon with id $pid"
        case ExtractionFailed(errors) => s"problem extracting response $errors"
      }
    )

  reportOnPokemon(1)
  reportOnPokemon(11)
  reportOnPokemon(9999)
} 
Example 13
Source File: Simple_JSON_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core


// fintrospect-core
object Simple_JSON_Example extends App {

  import java.time.ZonedDateTime

  import argo.jdom.JsonNode
  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.Argo.JsonFormat._
  import io.fintrospect.formats.Argo.ResponseBuilder._
  import io.fintrospect.parameters.Body
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val json: Body[JsonNode] = Body.json()

  val echo: Service[Request, Response] = Service.mk[Request, Response] { req =>
    val requestJson: JsonNode = json <-- req
    val responseJson: JsonNode = obj(
      "posted" -> requestJson,
      "time" -> string(ZonedDateTime.now().toString)
    )
    Ok(responseJson)
  }

  val route: ServerRoute[Request, Response] = RouteSpec().body(json).at(Post) bindTo echo

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -XPOST http://localhost:9999/ --data '{"name":"David"}' 
Example 14
Source File: Combining_Modules_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.core

// fintrospect-core
object Combining_Modules_Example extends App {

  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val identify: Service[Request, Response] = Service.mk { req: Request => Ok(req.uri) }

  val route: ServerRoute[Request, Response] = RouteSpec().at(Get) bindTo identify
  val childModule: Module = RouteModule(Root / "child").withRoute(route)
  val rootModule: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", childModule.andThen(rootModule).toService))
}

//curl -v http://localhost:9999/child
//curl -v http://localhost:9999 
Example 15
Source File: Semi_Auto_Marshalling_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.json_libraries

case class Person(name: String, age: Option[Int])

// fintrospect-core
// fintrospect-circe
object Semi_Auto_Marshalling_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.circe.generic.auto._
  import io.fintrospect.formats.Circe
  import io.fintrospect.formats.Circe.JsonFormat._
  import io.fintrospect.formats.Circe.ResponseBuilder._
  import io.fintrospect.parameters.Body
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val personBody = Body.of(Circe.bodySpec[Person]())

  val insultMe: Service[Request, Response] = Service.mk[Request, Response] { req =>
    val person: Person = personBody <-- req
    val smellyPerson: Person = person.copy(name = person.name + " Smells")
    Ok(encode(smellyPerson))
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(personBody)
    .at(Post) bindTo insultMe

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -XPOST http://localhost:9999/ --data '{"name":"David", "age": 50}' 
Example 16
Source File: TestHttpServerTest.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package io.fintrospect.testing

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.Status.{Accepted, Conflict}
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import io.fintrospect.RouteSpec
import org.scalatest.{BeforeAndAfterEach, FunSpec, Matchers}


class TestHttpServerTest extends FunSpec with Matchers with BeforeAndAfterEach {
  val originalStatus = Conflict

  private val server = new TestHttpServer(9888, RouteSpec().at(Get) bindTo Service.mk { r: Request => Future(Response(originalStatus)) })

  override def beforeEach() = {
    Await.result(server.start())
  }

  override def afterEach() = {
    Await.result(server.stop())
  }

  it("will serve routes that are passed to it") {
    statusShouldBe(originalStatus)
  }

  it("can override status") {
    server.respondWith(Accepted)
    statusShouldBe(Accepted)
  }

  private def statusShouldBe(expected: Status): Unit = {
    Await.result(Http.newService("localhost:9888", "")(Request())).status shouldBe expected
  }
} 
Example 17
Source File: App.scala    From finagle-metrics   with MIT License 5 votes vote down vote up
import com.codahale.metrics.ConsoleReporter
import com.twitter.finagle.{ Http, Service }
import com.twitter.finagle.metrics.MetricsStatsReceiver
import com.twitter.finagle.http.{ Request, Response, Status }
import com.twitter.io.Charsets
import com.twitter.server.TwitterServer
import com.twitter.util.{ Await, Future }
import java.util.concurrent.TimeUnit

object App extends TwitterServer {

  val service = new Service[Request, Response] {
    def apply(request: Request) = {
      val response = Response(request.version, Status.Ok)
      response.contentString = "hello"
      Future.value(response)
    }
  }

  val reporter = ConsoleReporter
    .forRegistry(MetricsStatsReceiver.metrics)
    .convertRatesTo(TimeUnit.SECONDS)
    .convertDurationsTo(TimeUnit.MILLISECONDS)
    .build

  def main() = {
    val server = Http.serve(":8080", service)
    reporter.start(5, TimeUnit.SECONDS)

    onExit { server.close() }

    Await.ready(server)
  }

} 
Example 18
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 19
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 20
Source File: StackParams.scala    From finch-101   with Apache License 2.0 5 votes vote down vote up
package i.f.workshop.finagle

import com.twitter.finagle.param
import com.twitter.finagle.http.{Response, Request}
import com.twitter.finagle.service.TimeoutFilter
import com.twitter.finagle.transport.Transport
import com.twitter.finagle.{Http, Service}
import com.twitter.util._
import com.twitter.conversions.time._

object StackParams extends App {

  implicit val timer: Timer = new JavaTimer()
  val service: Service[Request, Response] = new Service[Request, Response] {
    def apply(req: Request): Future[Response] =
      Future.sleep(5.seconds).map(_ => Response())
  }

  val monitor: Monitor = new Monitor {
    def handle(exc: Throwable): Boolean = {
      println(exc)

      false
    }
  }

  Await.ready(Http.server
    .configured(TimeoutFilter.Param(1.seconds))
    .configured(Transport.Verbose(true))
    .configured(param.Monitor(monitor))
    .serve(":8081", service)
  )
} 
Example 21
Source File: Greetings.scala    From finch-101   with Apache License 2.0 5 votes vote down vote up
package i.f.workshop.finch

import com.twitter.finagle.Http
import com.twitter.util.Await

import io.finch._
import io.finch.circe._
import io.circe.generic.auto._

object Greetings extends App {

  // GET /hi/:name
  val hi: Endpoint[String] =
    get("hi" / string) { name: String =>
      Ok(s"Hi, $name!")
    }

  // GET /hello/:name?title=Mr.
  val title: RequestReader[String] = paramOption("title").withDefault("")
  val hello: Endpoint[String] =
    get("hello" / string ? title) { (name: String, title: String) =>
      Ok(s"Hello, $title$name!")
    }

  // GET /salute?name=Bob&title=Mr.
  case class Who(name: String, title: String)
  val who: RequestReader[Who] = (param("name") :: title).as[Who]
  val salute: Endpoint[String] =
    get("salute" ? who) { w: Who =>
      Ok(s"Salute, ${w.title}${w.name}!")
    }

  Await.ready(Http.serve(":8081", (hi :+: hello :+: salute).toService))
} 
Example 22
Source File: Frontend.scala    From diffy   with GNU Affero General Public License v3.0 5 votes vote down vote up
package ai.diffy

import java.util.concurrent.atomic.AtomicInteger

import ai.diffy.IsotopeSdkModule.IsotopeClient
import ai.diffy.proxy.Settings
import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.finatra.http.Controller
import javax.inject.Inject

class Frontend @Inject()(settings: Settings, isotopeClient: IsotopeClient) extends Controller {

  case class Dashboard(
    serviceName: String,
    serviceClass: String,
    apiRoot: String,
    excludeNoise: Boolean,
    relativeThreshold: Double,
    absoluteThreshold: Double,
    isotopeReason: String,
    hasIsotope: Boolean = false)

  val reasons = Seq(
    "Do you want to compare side effects like logs and downstream interactions?",
    "Do you want to save and share this comparison?",
    "Do you want to organize all your comparisons across all your services and teams in one place?",
    "Do you want to download sampled traffic?"
  )
  val reasonIndex = new AtomicInteger(0)
  get("/") { req: Request =>
    response.ok.view(
      "dashboard.mustache",
      Dashboard(
        settings.serviceName,
        settings.serviceClass,
        settings.apiRoot,
        req.params.getBooleanOrElse("exclude_noise", false),
        settings.relativeThreshold,
        settings.absoluteThreshold,
        reasons(reasonIndex.getAndIncrement() % reasons.length),
        isotopeClient.isConcrete
      )
    )
  }

  get("/css/:*") { request: Request =>
    response.ok.file(request.path)
  }

  get("/scripts/:*") { request: Request =>
    response.ok.file(request.path)
  }
} 
Example 23
Source File: HttpDifferenceProxy.scala    From diffy   with GNU Affero General Public License v3.0 5 votes vote down vote up
package ai.diffy.proxy

import java.net.SocketAddress

import ai.diffy.analysis.{DifferenceAnalyzer, InMemoryDifferenceCollector, JoinedDifferences}
import ai.diffy.lifter.{HttpLifter, Message}
import com.twitter.finagle.http.{Method, Request, Response}
import com.twitter.finagle.{Filter, Http}
import com.twitter.util.{Future, StorageUnit, Try}

object HttpDifferenceProxy {
  def requestHostHeaderFilter(host: String) =
    Filter.mk[Request, Response, Request, Response] { (req, svc) =>
      req.host(host)
      svc(req)
    }
}

trait HttpDifferenceProxy extends DifferenceProxy {
  import HttpDifferenceProxy._
  val servicePort: SocketAddress
  val lifter = new HttpLifter(settings.excludeHttpHeadersComparison, settings.resourceMatcher)

  override type Req = Request
  override type Rep = Response
  override type Srv = HttpService

  override def serviceFactory(serverset: String, label: String) =
    HttpService(requestHostHeaderFilter(serverset) andThen
      Http.client
        .withMaxResponseSize(settings.maxResponseSize)
        .withMaxHeaderSize(settings.maxHeaderSize)
        .newService(serverset, label))

  override lazy val server =
    Http.serve(
      servicePort,
      proxy
    )

  override def liftRequest(req: Request): Future[Message] =
    lifter.liftRequest(req)

  override def liftResponse(resp: Try[Response]): Future[Message] =
    lifter.liftResponse(resp)
}

object SimpleHttpDifferenceProxy {
  
case class SimpleHttpsDifferenceProxy (
   settings: Settings,
   collector: InMemoryDifferenceCollector,
   joinedDifferences: JoinedDifferences,
   analyzer: DifferenceAnalyzer)
  extends HttpDifferenceProxy
{
  import SimpleHttpDifferenceProxy._

  override val servicePort = settings.servicePort

  override val proxy =
    Filter.identity andThenIf
      (!settings.allowHttpSideEffects, httpSideEffectsFilter) andThen
      super.proxy

  override def serviceFactory(serverset: String, label: String) =
    HttpService(
      Http.client
      .withTls(serverset)
      .newService(serverset+":"+settings.httpsPort, label)
    )
} 
Example 24
Source File: DiffyProject.scala    From diffy   with GNU Affero General Public License v3.0 5 votes vote down vote up
package ai.diffy.util

import ai.diffy.compare.Difference
import ai.diffy.lifter.JsonLifter
import ai.diffy.proxy.Settings
import com.twitter.finagle.Http
import com.twitter.finagle.http.{Method, Request, Response}
import com.twitter.util.Future

object DiffyProject {
  private[this] sealed trait config {
    val client: Request => Future[Response]
  }
  private[this] object production extends config {
    override val client: Request => Future[Response] =
      Http.client
        .withTls("diffyproject.appspot.com")
        .newService("diffyproject.appspot.com:443")
  }
  private[this] object development extends config {
    override val client: Request => Future[Response] =
      Http.client
        .newService("localhost:7000")
  }

  private[this] val cfg: config = production

  def settings(settings: Settings): Unit ={
    s = settings
    val m = Difference.mkMap(s)
    val ed = m("emailDelay")
    uid = m.updated("emailDelay",ed.toString).updated("artifact", "od.2019.8.27.001")
    log("start")
  }

  private[this] var s :Settings = _
  private[this] var uid :Map[String, Any] = Map.empty

  def log(message: String): Unit = {
    val request = Request(Method.Post, "/stats")
    request.setContentTypeJson()
    request.setContentString(JsonLifter.encode(uid.updated("message", message)))
    cfg.client(request)
  }
} 
Example 25
Source File: ThriftFeatureTest.scala    From diffy   with GNU Affero General Public License v3.0 5 votes vote down vote up
package ai.diffy

import java.io.{File, FileOutputStream}
import java.net.ServerSocket
import java.nio.file.Files
import java.util.zip.{ZipEntry, ZipOutputStream}

import ai.diffy.examples.thrift.ExampleServers
import ai.diffy.proxy.DifferenceProxy
import ai.diffy.thriftscala.Adder
import com.google.inject.Stage
import com.twitter.finagle.http.Status
import com.twitter.finagle.util.DefaultTimer
import com.twitter.finagle.{Http, ThriftMux}
import com.twitter.finatra.http.EmbeddedHttpServer
import com.twitter.inject.Test
import com.twitter.util.{Await, Duration, Future, FuturePool}

import scala.io.Source

class ThriftFeatureTest extends Test {

  def getPort(): Int = {
    val s  = new ServerSocket(0)
    val port = s.getLocalPort
    s.close()
    port
  }

  val env@Seq(p,s,c,d) = Seq.fill(4)(getPort())
  val environment = FuturePool.unboundedPool(ExampleServers.main(env.take(3).map(_.toString).toArray))

  val diffy = new MainService
  lazy val differenceProxy = diffy.injector.instance[DifferenceProxy]


  val thriftFile = new File("src/test/thrift/example.thrift")
  val data = Source.fromInputStream(Files.newInputStream(thriftFile.toPath), "UTF-8").mkString
  val thriftJar = Files.createTempFile("thrift", "jar")
  thriftJar.toFile.deleteOnExit()
  val out = new ZipOutputStream(new FileOutputStream(thriftJar.toFile))
  out.putNextEntry(new ZipEntry(thriftFile.getAbsolutePath))
  out.write(data.getBytes)
  out.closeEntry()
  out.close()

  val server = new EmbeddedHttpServer(
    twitterServer = diffy,
    flags = Map(
      "proxy.port" -> s":$d",
      "candidate" -> s"localhost:$c",
      "master.primary" -> s"localhost:$p",
      "master.secondary" -> s"localhost:$s",
      "serviceName" -> "myThriftService",
      "service.protocol" -> "thrift",
      "thrift.jar" -> thriftJar.toAbsolutePath.toString,
      "thrift.serviceClass" -> "Adder",
      "summary.email" -> "test"
    ),
    stage = Stage.PRODUCTION
  )

  val client = ThriftMux.client.build[Adder.MethodPerEndpoint](s"localhost:$d")

  test("verify startup") {
    server.assertHealthy()
  }

  test("verify DifferenceCollector") {
    assert(differenceProxy.collector.fields.isEmpty)
    Await.result(client.add(1, 1).liftToTry)
    var tries = 0
    while(differenceProxy.outstandingRequests.get() > 0 && tries < 10) {
      Await.result(Future.sleep(Duration.fromSeconds(1))(DefaultTimer))
      tries = tries + 1
    }
    assert(!differenceProxy.collector.fields.isEmpty)
  }

  test("verify present differences via API") {
    val response =
      Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/add/stats"))
    assertResult(Status.Ok)(response.status)
    assert(response.getContentString().contains(""""differences":1"""))
  }

  test("verify absent endpoint in API") {
    val response =
      Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/subtract/stats"))
    assertResult(Status.Ok)(response.status)
    assertResult("""{"error":"key not found: subtract"}""")(response.getContentString())
  }

} 
Example 26
Source File: HttpFeatureTest.scala    From diffy   with GNU Affero General Public License v3.0 5 votes vote down vote up
package ai.diffy

import java.net.ServerSocket

import ai.diffy.examples.http.ExampleServers
import ai.diffy.proxy.DifferenceProxy
import com.google.common.collect.ImmutableMap
import com.google.inject.Stage
import com.twitter.finagle.Http
import com.twitter.finagle.http.Status
import com.twitter.finagle.util.DefaultTimer
import com.twitter.finatra.http.EmbeddedHttpServer
import com.twitter.inject.Test
import com.twitter.util.{Await, Duration, Future, FuturePool}

class HttpFeatureTest extends Test {
  def getPort(): Int = {
    val s  = new ServerSocket(0)
    val port = s.getLocalPort
    s.close()
    port
  }

  val env@Seq(p,s,c,d) = Seq.fill(4)(getPort())
  val environment = FuturePool.unboundedPool(ExampleServers.main(env.take(3).map(_.toString).toArray))

  val diffy = new MainService
  lazy val differenceProxy = diffy.injector.instance[DifferenceProxy]

  val server = new EmbeddedHttpServer(
    twitterServer = diffy,
    flags = Map(
      "proxy.port" -> s":$d",
      "candidate" -> s"localhost:$c",
      "master.primary" -> s"localhost:$p",
      "master.secondary" -> s"localhost:$s",
      "serviceName" -> "myHttpService",
      "service.protocol" -> "http",
      "summary.email" ->"test"
    ),
    stage = Stage.PRODUCTION
  )

  test("verify startup") {
    server.assertHealthy()
  }

  test("verify DifferenceCollector") {
    assert(differenceProxy.collector.fields.isEmpty)
    Await.result(Http.fetchUrl(s"http://localhost:$d/json?Twitter").liftToTry)
    var tries = 0
    while(differenceProxy.outstandingRequests.get() > 0 && tries < 10) {
      Await.result(Future.sleep(Duration.fromSeconds(1))(DefaultTimer.twitter))
      tries = tries + 1
    }
    assert(!differenceProxy.collector.fields.isEmpty)
  }

  test("verify present differences via API") {
    val response =
      Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/undefined_endpoint/stats"))
    assertResult(Status.Ok)(response.status)
    assert(response.getContentString().contains(""""differences":1"""))
  }

  test("verify absent endpoint in API") {
    val response =
      Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/json/stats"))
    assertResult(Status.Ok)(response.status)
    assertResult("""{"error":"key not found: json"}""")(response.getContentString())
  }
  Seq(
    "/api/1/overview",
    "/api/1/report",
    "/api/1/endpoints",
    "/api/1/endpoints/json/stats",
    "/api/1/endpoints/json/fields/result.200.values.value.name.PrimitiveDifference/results",
    "/api/1/endpoints/json/fields/result.200.values.value.name.PrimitiveDifference/results/0"
  ) foreach { endpoint =>
    test(s"ping ${endpoint}") {
      val response =
        Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}${endpoint}"))
      assertResult(Status.Ok)(response.status)
    }
  }
} 
Example 27
Source File: App.scala    From finch-template   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.redbubble.finchtemplate

import com.redbubble.finchtemplate.util.config.Config
import com.redbubble.finchtemplate.util.config.Environment.env
import com.redbubble.finchtemplate.util.metrics.newrelic.NewRelicMetrics
import com.redbubble.finchtemplate.util.error.FinchTemplateErrorReporter.errorReporter
import com.redbubble.finchtemplate.util.log.CoreLogger
import com.redbubble.finchtemplate.util.log.CoreLogger._
import com.redbubble.util.async.AsyncOps
import com.redbubble.util.error.ErrorReportingMonitor
import com.redbubble.util.log.Slf4jLogging
import com.twitter.app.{App => TwitterApp}
import com.twitter.finagle.{Http, ListeningServer}
import com.twitter.server._


private[finchtemplate] trait ServiceFeatures extends TwitterApp
    with Hooks
    with Linters
    with Slf4jLogging
    with Stats
    with NewRelicMetrics
    with AdminHttpServer
    with Admin
    with Lifecycle

object ErrorMonitor extends ErrorReportingMonitor(CoreLogger.log, errorReporter)

trait BootableService { self: TwitterApp =>
  private val server = Http.server
      .withLabel(Config.systemId)
      .withStreaming(enabled = true)
      .withAdmissionControl.concurrencyLimit(Config.maxConcurrentRequests, Config.maxWaiters)
      .withRequestTimeout(Config.requestTimeout)
      .withMaxRequestSize(Config.maxRequestSize)
      .withMonitor(ErrorMonitor)
      .configured(Http.Netty4Impl)

  def boot(): ListeningServer = {
    errorReporter.registerForUnhandledExceptions()
    val booted = server.serve(Config.listenAddress, FinchTemplateApi.apiService)
    onExit {
      log.info(s"${Config.systemId} is shutting down...")
      booted.close()
      ()
    }
    booted
  }
}

object App extends BootableService with ServiceFeatures {
  def main(): Unit = {
    val server = boot()
    log.info(s"Booted ${Config.systemId} in ${env.name} mode on ${server.boundAddress}")
    AsyncOps.blockUnit(server)
  }
} 
Example 28
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 29
Source File: Handlebars_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.templating

// fintrospect-core
// fintrospect-handlebars
case class HandlebarsView(name: String, age: Int) extends io.fintrospect.templating.View

object Handlebars_Example extends App {

  import com.twitter.finagle.http.Method.Get
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.Html
  import io.fintrospect.parameters.Path
  import io.fintrospect.templating.{HandlebarsTemplates, RenderView, View}
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  def showAgeIn30(name: String, age: Int): Service[Request, Response] = {
    val svc = Service.mk[Request, View] { req => MustacheView(name, age + 30) }

    new RenderView(Html.ResponseBuilder, HandlebarsTemplates.CachingClasspath(".")).andThen(svc)
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .at(Get) / Path.string("name") / Path.int("age") bindTo showAgeIn30

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v http://localhost:9999/david/100 
Example 30
Source File: Http_03_Client.scala    From airframe   with Apache License 2.0 5 votes vote down vote up
package wvlet.airframe.examples.http

import java.util.concurrent.TimeUnit

import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Duration
import wvlet.airframe.http.finagle.{Finagle, FinagleSyncClient}
import wvlet.airframe.http.{Endpoint, HttpMethod, Router}
import wvlet.log.LogSupport


object Http_03_Client extends App with LogSupport {
  case class User(id: String, name: String)
  trait MyApp extends LogSupport {
    @Endpoint(method = HttpMethod.GET, path = "/user/:id")
    def getUser(id: String): User = {
      User(id, "xxx")
    }
  }

  val router = Router.add[MyApp]

  val serverDesign = Finagle.server
    .withName("myapp")
    .withRouter(router)
    .design

  val clietnDesign =
    Finagle.client
    // Max retry attempts
      .withMaxRetry(3)
      // Use backoff (or jittering)
      .withBackOff(1)
      // Set request timeout
      .withTimeout(Duration(90, TimeUnit.SECONDS))
      // Add Finagle specific configuration
      .withInitializer { client: Http.Client => client.withHttp2 } // optional
      // Create a new http client to access the server.
      .syncClientDesign

  val design = serverDesign + clietnDesign

  design.build[FinagleSyncClient] { client =>
    // FinagleServer will be started here
    // Read the JSON response as an object
    val user = client.get[User]("/user/1")
    debug(user)

    // Read the response as is
    val request = client.send(Request("/user/2"))
    val content = request.contentString
    debug(content)
  }
} 
Example 31
Source File: TodoListApp.scala    From freestyle   with Apache License 2.0 5 votes vote down vote up
package examples.todolist

import cats._
import cats.effect.IO
import cats.implicits._
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, ListeningServer, Service}
import com.twitter.server.TwitterServer
import com.twitter.util.{Await, Future}
import doobie.util.transactor.Transactor
import examples.todolist.http.Api
import examples.todolist.persistence.Persistence
import examples.todolist.services.Services
import freestyle.tagless.config.ConfigM
import freestyle.tagless.config.implicits._
import freestyle.tagless.effects.error.ErrorM
import freestyle.tagless.effects.error.implicits._
import freestyle.tagless.logging.LoggingM
import freestyle.tagless.loggingJVM.log4s.implicits._
import freestyle.tagless.module
import io.circe.generic.auto._
import io.finch.circe._

@module
trait App[F[_]] {
  val persistence: Persistence[F]
  val services: Services[F]
}

object TodoListApp extends TwitterServer {

  import examples.todolist.runtime.implicits._

  def bootstrap[F[_]: Monad](
      implicit app: App[F],
      handler: F ~> Future,
      T: Transactor[F],
      api: Api[F]): F[ListeningServer] = {

    val service: Service[Request, Response] = api.endpoints.toService
    val log: LoggingM[F]                    = app.services.log
    val cfg: ConfigM[F]                     = app.services.config

    for {
      _      <- log.info("Trying to load application.conf")
      config <- cfg.load
      host = config.string("http.host").getOrElse("localhost")
      port = config.int("http.port").getOrElse("8080")
      _ <- log.debug(s"Host: $host")
      _ <- log.debug(s"Port $port")
    } yield
      Await.ready(
        Http.server.withAdmissionControl
          .concurrencyLimit(maxConcurrentRequests = 10, maxWaiters = 10)
          .serve(s"$host:$port", service)
      )
  }

  def main() =
    bootstrap[IO].unsafeRunAsync {
      case Left(error)   => println(s"Error executing server. ${error.getMessage}")
      case Right(server) => server.close()
    }

} 
Example 32
Source File: EmojiService.scala    From finagle-prometheus   with MIT License 5 votes vote down vote up
package com.samstarling.prometheusfinagle.examples

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Method, Request, Response, Status}
import com.twitter.finagle.loadbalancer.LoadBalancerFactory
import com.twitter.finagle.stats.{DefaultStatsReceiver, StatsReceiver}
import com.twitter.util.Future

class EmojiService(statsReceiver: StatsReceiver)
    extends Service[Request, Response] {

  private val client = Http.client
    .withTls("api.github.com")
    .withStatsReceiver(statsReceiver)
    .withHttpStats
    .configured(LoadBalancerFactory.HostStats(statsReceiver.scope("host")))
    .newService("api.github.com:443", "GitHub")

  private val emojiRequest = Request(Method.Get, "/emojis")
  emojiRequest.headerMap.add("User-Agent", "My-Finagle-Example")

  override def apply(request: Request): Future[Response] = {
    client.apply(emojiRequest).map { resp =>
      val r = Response(request.version, Status.Ok)
      r.setContentString(resp.getContentString())
      r
    }
  }
} 
Example 33
Source File: TestServer.scala    From finagle-prometheus   with MIT License 5 votes vote down vote up
package com.samstarling.prometheusfinagle.examples

import java.net.InetSocketAddress

import com.samstarling.prometheusfinagle.PrometheusStatsReceiver
import com.samstarling.prometheusfinagle.metrics.{MetricsService, Telemetry}
import com.twitter.finagle.builder.ServerBuilder
import com.twitter.finagle.http._
import com.twitter.finagle.http.path._
import com.twitter.finagle.http.service.{NotFoundService, RoutingService}
import com.twitter.finagle.loadbalancer.perHostStats
import com.twitter.finagle.{Http, Service}
import io.prometheus.client.CollectorRegistry

object TestServer extends App {

  perHostStats.parse("true")

  val registry = CollectorRegistry.defaultRegistry
  val statsReceiver = new PrometheusStatsReceiver(registry)
  val telemetry = new Telemetry(registry, "namespace")

  val emojiService = new EmojiService(statsReceiver)
  val metricsService = new MetricsService(registry)
  val echoService = new EchoService
  val customTelemetryService = new CustomTelemetryService(telemetry)

  val router: Service[Request, Response] =
    RoutingService.byMethodAndPathObject {
      case (Method.Get, Root / "emoji")   => emojiService
      case (Method.Get, Root / "metrics") => metricsService
      case (Method.Get, Root / "echo")    => echoService
      case (Method.Get, Root / "custom")  => customTelemetryService
      case _                              => new NotFoundService
    }

  ServerBuilder()
    .stack(Http.server)
    .name("testserver")
    .bindTo(new InetSocketAddress(8080))
    .build(router)
} 
Example 34
Source File: TemplatingApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.templating

import java.net.URL

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.Request
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.{Http, Service}
import com.twitter.util.Await
import io.fintrospect.formats.PlainText
import io.fintrospect.renderers.SiteMapModuleRenderer
import io.fintrospect.templating.{MustacheTemplates, RenderView}
import io.fintrospect.{RouteModule, RouteSpec}

object TemplatingApp extends App {

  val devMode = true
  val renderer = if (devMode) MustacheTemplates.HotReload("src/main/resources") else MustacheTemplates.CachingClasspath(".")

  val renderView = new RenderView(PlainText.ResponseBuilder, renderer)

  val module = RouteModule(Root, new SiteMapModuleRenderer(new URL("http://my.cool.app")), renderView)
    .withRoute(RouteSpec().at(Get) / "echo" bindTo Service.mk { rq: Request => MustacheView(rq.uri) })

  println("See the Sitemap description at: http://localhost:8181")

  Await.ready(
    Http.serve(":8181", new HttpFilter(Cors.UnsafePermissivePolicy).andThen(module.toService))
  )
} 
Example 35
Source File: StrictMultiContentTypeRoute.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.strictcontenttypes

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.Request
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.{Http, Service}
import com.twitter.util.Await
import io.fintrospect.ContentTypes.{APPLICATION_JSON, APPLICATION_XML}
import io.fintrospect.filters.RequestFilters
import io.fintrospect.parameters.Path
import io.fintrospect.renderers.simplejson.SimpleJson
import io.fintrospect.util.StrictContentTypeNegotiation
import io.fintrospect.{RouteModule, RouteSpec}



object StrictMultiContentTypeRoute extends App {

  private def serveJson(name: String) = Service.mk { req: Request =>
    import io.fintrospect.formats.Argo.JsonFormat._
    import io.fintrospect.formats.Argo.ResponseBuilder._
    Ok(obj("field" -> string(name)))
  }

  private def serveXml(name: String) = Service.mk {
    import io.fintrospect.formats.Xml.ResponseBuilder._
    req: Request =>
      Ok(<root>
        <field>
          {name}
        </field>
      </root>)
  }

  val route = RouteSpec()
    .producing(APPLICATION_XML, APPLICATION_JSON)
    .at(Get) / "multi" / Path.string("name") bindTo StrictContentTypeNegotiation(APPLICATION_XML -> serveXml, APPLICATION_JSON -> serveJson)

  val jsonOnlyRoute = RouteSpec()
    .producing(APPLICATION_JSON)
    .at(Get) / "json" / Path.string("name") bindTo ((s) => RequestFilters.StrictAccept(APPLICATION_JSON).andThen(serveJson(s)))

  println("See the service description at: http://localhost:8080 . The route at /multi should match wildcard Accept headers set in a browser.")

  Await.ready(
    Http.serve(":8080", new HttpFilter(Cors.UnsafePermissivePolicy)
      .andThen(RouteModule(Root, SimpleJson()).withRoute(route).toService))
  )
} 
Example 36
Source File: MultiBodyTypeRoute.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.strictcontenttypes

import com.twitter.finagle.http.Method.Post
import com.twitter.finagle.http.Request
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.{Http, Service}
import com.twitter.util.Await
import io.fintrospect.parameters.Body
import io.fintrospect.renderers.simplejson.SimpleJson
import io.fintrospect.util.MultiBodyType
import io.fintrospect.{RouteModule, RouteSpec}


object MultiBodyTypeRoute extends App {

  private val json = Body.json("json body")

  private val echoJson = Service.mk { (rq: Request) =>
    import io.fintrospect.formats.Argo.ResponseBuilder._
    Ok(json <-- rq)
  }

  private val xml = Body.xml("xml body")

  private val echoXml = Service.mk { (rq: Request) =>
    import io.fintrospect.formats.Xml.ResponseBuilder._
    Ok(xml <-- rq)
  }

  val route = RouteSpec("echo posted content in either JSON or XML").at(Post) / "echo" bindTo MultiBodyType(json -> echoJson, xml -> echoXml)

  println("See the service description at: http://localhost:8080")

  Await.ready(
    Http.serve(":8080", new HttpFilter(Cors.UnsafePermissivePolicy)
      .andThen(RouteModule(Root, SimpleJson()).withRoute(route).toService))
  )
} 
Example 37
Source File: ContractProxyExample.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.clients

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import com.twitter.util.Await
import io.fintrospect.configuration.{Credentials, Host, Port}
import io.fintrospect.filters.RequestFilters.{AddHost, BasicAuthorization}
import io.fintrospect.parameters.Query
import io.fintrospect.{Contract, ContractEndpoint, ContractProxyModule, RouteSpec}


object ContractProxyExample extends App {

  val proxyModule = ContractProxyModule("brewdog", BrewdogApiHttp(), BrewdogApiContract)

  Await.ready(
    Http.serve(":9000", new HttpFilter(Cors.UnsafePermissivePolicy).andThen(proxyModule.toService))
  )
}

object BrewdogApiHttp {
  private val apiAuthority = Host("punkapi.com").toAuthority(Port(443))

  def apply(): Service[Request, Response] = {
    AddHost(apiAuthority)
      .andThen(BasicAuthorization(Credentials("22244d6b88574064bbbfe284f1631eaf", "")))
      .andThen(Http.client.withTlsWithoutValidation.newService(apiAuthority.toString))
  }
}

object BrewdogApiContract extends Contract {

  object LookupBeers extends ContractEndpoint {
    val brewedBefore = Query.optional.string("brewed_before", "e.g. 01-2010 (format is mm-yyyy)")
    val alcoholContent = Query.optional.int("abv_gt", "Minimum alcohol %")

    override val route =
      RouteSpec("lookup beers")
        .taking(brewedBefore)
        .taking(alcoholContent)
        .at(Get) / "api" / "v1" / "beers"
  }

  object RandomBeer extends ContractEndpoint {
    override val route = RouteSpec("get a random beer recipe")
      .at(Get) / "api" / "v1" / "beers" / "random"
  }

} 
Example 38
Source File: ClientSideAndSharedRouteSpecExample.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.clients

import java.time.LocalDate

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import com.twitter.util.Await
import io.fintrospect.RouteSpec
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.parameters._
import io.fintrospect.testing.TestHttpServer
import io.fintrospect.util.HttpRequestResponseUtil.{headersFrom, statusAndContentFrom}


object ClientSideAndSharedRouteSpecExample extends App {

  val theDate = Path.localDate("date")
  val theWeather = Query.optional.string("weather")
  val theUser = Header.required.string("user")
  val gender = FormField.optional.string("gender")
  val body = Body.form(gender)

  val sharedRouteSpec = RouteSpec()
    .taking(theUser)
    .taking(theWeather)
    .body(body)
    .at(Get) / "firstSection" / theDate

  val fakeServerRoute = sharedRouteSpec bindTo (dateFromPath => Service.mk[Request, Response] {
    request: Request => {
      println("URL was " + request.uri)
      println("Headers were " + headersFrom(request))
      println("Form sent was " + (body <-- request))
      println("Date send was " + dateFromPath.toString)
      Ok(dateFromPath.toString)
    }
  })

  Await.result(new TestHttpServer(10000, fakeServerRoute).start())

  val client = sharedRouteSpec bindToClient Http.newService("localhost:10000")

  val theCall = client(theWeather --> Option("sunny"), body --> Form(gender --> "male"), theDate --> LocalDate.of(2015, 1, 1), theUser --> System.getenv("USER"))

  val response = Await.result(theCall)

  println("Response headers: " + headersFrom(response))
  println("Response: " + statusAndContentFrom(response))
} 
Example 39
Source File: LibraryApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.extended

import com.twitter.finagle.Http
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.util.Await
import io.fintrospect.RouteModule
import io.fintrospect.renderers.simplejson.SimpleJson
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}


object LibraryApp extends App {

  val apiInfo = ApiInfo("Library Example", "1.0", "A simple example of how to construct a Fintrospect module")
  val renderer = Swagger2dot0Json(apiInfo) //  choose your renderer implementation

  val books = new Books()

  // use CORs settings that suit your particular use-case. This one allows any cross-domain traffic at all and is applied
  // to all routes in the module
  val globalCorsFilter = new HttpFilter(Cors.UnsafePermissivePolicy)

  val libraryModule = RouteModule(Root / "library", renderer)
    .withRoute(new BookAdd(books).route)
    .withRoute(new BookCollection(books).route)
    .withRoute(new BookLookup(books).route)
    .withRoute(new BookLengthSearch(books).route)
    .withRoute(new BookTermSearch(books).route)

  val statusModule = RouteModule(Root / "internal", SimpleJson())
    .withRoute(new Ping().route)

  println("See the service description at: http://localhost:8080/library")

  Await.ready(
    Http.serve(":8080", globalCorsFilter.andThen(libraryModule.andThen(statusModule).toService))
  )
} 
Example 40
Source File: InboxApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package examples.circe

import com.twitter.finagle.Http
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.util.Await
import examples.circe.Emails.InMemoryEmails
import io.fintrospect.RouteModule
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}


object InboxApp extends App {

  private val emails = new InMemoryEmails()

  private val inboxModule = RouteModule(Root / "inbox", Swagger2dot0Json(ApiInfo("Inbox Example", "1.0")))
    .withRoute(new AddMessage(emails).route)
    .withRoute(new EmailList(emails).route)
    .withRoute(new FindUserWithEmail(emails).route)
    .withRoute(new UserList(emails).route)

  println("See the service description at: http://localhost:8181/inbox")

  Await.ready(
    Http.serve(":8181", new HttpFilter(Cors.UnsafePermissivePolicy).andThen(inboxModule.toService))
  )
} 
Example 41
Source File: FakeRemoteLibrary.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._6

import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.RouteModule
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.renderers.simplejson.SimpleJson
import presentation.Books


class FakeRemoteLibrary(books: Books) {
  def search(titlePart: String) = Service.mk[Request, Response] {
    request => {
      val results = books.titles().filter(_.toLowerCase.contains(titlePart.toLowerCase))
      Ok(results.mkString(","))
    }
  }

  val service = RouteModule(Root, SimpleJson())
    .withRoute(RemoteBooks.route bindTo search)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":10000", searchService)
} 
Example 42
Source File: SearchApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._6

import com.twitter.finagle.http.Method.{Get, Post}
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.formats.Argo.JsonFormat.array
import io.fintrospect.formats.Argo.ResponseBuilder._
import io.fintrospect.parameters.{Body, BodySpec, Query}
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}
import io.fintrospect.{ResponseSpec, RouteModule, RouteSpec}
import presentation.Book

class SearchRoute(books: RemoteBooks) {
  private val titlePartParam = Query.required.string("titlePart")

  def search() = Service.mk[Request, Response] {
    request => {
      val titlePart = titlePartParam <-- request

      books.search(titlePart)
        .map(results => results.split(",").map(Book(_)).toSeq)
        .map(books => Ok(array(books.map(_.toJson))))
    }
  }

  val route = RouteSpec("search books")
    .taking(titlePartParam)
    .returning(ResponseSpec.json(Status.Ok -> "search results", array(Book("1984").toJson)))
    .at(Get) / "search" bindTo search
}

class BookAvailable(books: RemoteBooks) {
  private val bodySpec = BodySpec.json().map(Book.fromJson, (b: Book) => b.toJson)
  private val body = Body.of(bodySpec, "a book", Book("1984"))

  def availability() = Service.mk[Request, Response] {
    request => {
      val book = body <-- request
      books.search(book.title)
        .map(results => {
          if (results.length > 0) Ok("cool") else NotFound("!")
        })
    }
  }

  val route = RouteSpec("find if the book is owned")
    .body(body)
    .returning(Status.Ok -> "book is available")
    .returning(Status.NotFound -> "book not found")
    .at(Post) / "availability" bindTo availability
}


class SearchApp {
  private val apiInfo = ApiInfo("search some books", "1.0", "an api for searching our book collection")

  val service = RouteModule(Root, Swagger2dot0Json(apiInfo))
    .withRoute(new SearchRoute(new RemoteBooks).route)
    .withRoute(new BookAvailable(new RemoteBooks).route)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":9000", searchService)
} 
Example 43
Source File: FakeRemoteLibrary.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._5

import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.RouteModule
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.renderers.simplejson.SimpleJson
import presentation.Books


class FakeRemoteLibrary(books: Books) {
  def search(titlePart: String) = Service.mk[Request, Response] {
    request => Ok(books.titles().filter(_.toLowerCase.contains(titlePart.toLowerCase)).mkString(","))
  }

  val service = RouteModule(Root, SimpleJson())
    .withRoute(RemoteBooks.route bindTo search)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":10000", searchService)
} 
Example 44
Source File: SearchApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._5

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.formats.Argo.JsonFormat.array
import io.fintrospect.formats.Argo.ResponseBuilder._
import io.fintrospect.parameters.Query
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}
import io.fintrospect.{ResponseSpec, RouteModule, RouteSpec}
import presentation.Book

class SearchRoute(books: RemoteBooks) {
  private val titlePartParam = Query.required.string("titlePart")

  def search() = Service.mk[Request, Response] {
    request => {
      val titlePart = titlePartParam <-- request

      books.search(titlePart)
        .map(results => results.split(",").map(Book(_)).toSeq)
        .map(books => Ok(array(books.map(_.toJson))))
    }
  }

  val route = RouteSpec("search books")
    .taking(titlePartParam)
    .returning(ResponseSpec.json(Status.Ok -> "search results", array(Book("1984").toJson)))
    .at(Get) / "search" bindTo search
}


class SearchApp {
  private val apiInfo = ApiInfo("search some books", "1.0", "an api for searching our book collection")

  val service = RouteModule(Root, Swagger2dot0Json(apiInfo))
    .withRoute(new SearchRoute(new RemoteBooks).route)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":9000", searchService)
} 
Example 45
Source File: FakeRemoteLibrary.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._4

import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.RouteModule
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.renderers.simplejson.SimpleJson
import presentation.Books


class FakeRemoteLibrary(books: Books) {
  def search(titlePart: String) = Service.mk[Request, Response] {
    _ => Ok(books.titles().filter(_.toLowerCase.contains(titlePart.toLowerCase)).mkString(","))
  }

  val service = RouteModule(Root, SimpleJson())
    .withRoute(RemoteBooks.route bindTo search)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":10000", searchService)
} 
Example 46
Source File: SearchApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._4

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.parameters.Query
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}
import io.fintrospect.{RouteModule, RouteSpec}

class SearchRoute(books: RemoteBooks) {
  private val titlePartParam = Query.required.string("titlePart")

  def search() = Service.mk[Request, Response] {
    request => {
      val titlePart = titlePartParam <-- request

      books.search(titlePart)
        .map(results => Ok(results))
    }
  }

  val route = RouteSpec("search books")
    .taking(titlePartParam)
    .at(Get) / "search" bindTo search
}


class SearchApp {
  private val apiInfo = ApiInfo("search some books", "1.0", "an api for searching our book collection")

  val service = RouteModule(Root, Swagger2dot0Json(apiInfo))
    .withRoute(new SearchRoute(new RemoteBooks).route)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":9000", searchService)
} 
Example 47
Source File: SearchApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._3

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.parameters.Query
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}
import io.fintrospect.{RouteModule, RouteSpec}
import presentation.Books

class SearchRoute(books: Books) {
  private val titlePartParam = Query.required.string("titlePart")

  def search() = Service.mk[Request, Response] {
    request => {
      val titlePart = titlePartParam <-- request
      val results = books.titles().filter(_.toLowerCase.contains(titlePart.toLowerCase))
      Ok(results.toString())
    }
  }

  val route = RouteSpec("search books")
    .taking(titlePartParam)
    .at(Get) / "search" bindTo search
}


class SearchApp(books: Books) {
  private val apiInfo = ApiInfo("search some books", "1.0", "an api for searching our book collection")

  val service = RouteModule(Root, Swagger2dot0Json(apiInfo))
    .withRoute(new SearchRoute(books).route)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":9000", searchService)
}


object Environment extends App {
  new SearchApp(new Books)
  Thread.currentThread().join()
}

 
Example 48
Source File: SearchApp.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package presentation._2

import com.twitter.finagle.http.Method.Get
import com.twitter.finagle.http.filter.Cors
import com.twitter.finagle.http.filter.Cors.HttpFilter
import com.twitter.finagle.http.path.Root
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.{Http, Service}
import io.fintrospect.formats.PlainText.ResponseBuilder._
import io.fintrospect.renderers.swagger2dot0.{ApiInfo, Swagger2dot0Json}
import io.fintrospect.{RouteModule, RouteSpec}
import presentation.Books

class SearchApp(books: Books) {
  def search() = Service.mk[Request, Response] { _ => Ok(books.titles().toString()) }

  private val apiInfo = ApiInfo("search some books", "1.0", "an api for searching our book collection")

  val service = RouteModule(Root, Swagger2dot0Json(apiInfo))
    .withRoute(RouteSpec("search books").at(Get) / "search" bindTo search)
    .toService

  val searchService = new HttpFilter(Cors.UnsafePermissivePolicy).andThen(service)
  Http.serve(":9000", searchService)
}


object Environment extends App {
  new SearchApp(new Books)
  Thread.currentThread().join()
}

 
Example 49
Source File: MultiPart_Web_Form_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.forms


// fintrospect-core
object MultiPart_Web_Form_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import com.twitter.util.Future
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.parameters.{Body, Form, FormField, MultiPartFile}
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}



  val usernameField = FormField.required.string("user")
  val fileField = FormField.required.file("data")
  val form: Body[Form] = Body.multiPartWebForm(usernameField -> "everyone has a name!", fileField -> "file is required!")

  val svc: Service[Request, Response] = Service.mk[Request, Response] {
    req => {
      val postedForm: Form = form <-- req
      if (postedForm.isValid) successMessage(postedForm) else failureMessage(postedForm)
    }
  }

  def failureMessage(postedForm: Form): Future[Response] = {
    val errorString = postedForm.errors.map(e => e.param.name + ": " + e.reason).mkString("\n")
    BadRequest("errors were: " + errorString)
  }

  def successMessage(postedForm: Form): Future[Response] = {
    val name: String = usernameField <-- postedForm
    val data: MultiPartFile = fileField <-- postedForm
    Ok(s"$name posted ${data.filename} which is ${data.length}" + " bytes")
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(form)
    .at(Post) bindTo svc

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
} 
Example 50
Source File: Web_Form_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.forms

// fintrospect-core
object Web_Form_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import com.twitter.util.Future
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.parameters.{Body, Form, FormField}
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val nameField = FormField.required.string("name")
  val ageField = FormField.optional.int("age")
  val form: Body[Form] = Body.webForm(nameField -> "everyone has a name!", ageField -> "age is an int!")

  val svc: Service[Request, Response] = Service.mk[Request, Response] {
    req => {
      val postedForm: Form = form <-- req
      if (postedForm.isValid) successMessage(postedForm) else failureMessage(postedForm)
    }
  }

  def failureMessage(postedForm: Form): Future[Response] = {
    val errorString = postedForm.errors.map(e => e.param.name + ": " + e.reason).mkString("\n")
    BadRequest("errors were: " + errorString)
  }

  def successMessage(postedForm: Form): Future[Response] = {
    val name: String = nameField <-- postedForm
    val age: Option[Int] = ageField <-- postedForm
    Ok(s"$name is ${age.map(_.toString).getOrElse("too old to admit it")}")
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(form)
    .at(Post) bindTo svc

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -H"Content-Type: application/x-www-form-urlencoded" -XPOST http://localhost:9999/ --data '&age=asd'
//curl -v -H"Content-Type: application/x-www-form-urlencoded" -XPOST http://localhost:9999/ --data 'name=david&age=12' 
Example 51
Source File: Simple_Form_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.forms


// fintrospect-core
object Simple_Form_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.parameters.{Body, Form, FormField}
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  val nameField = FormField.required.string("name")
  val ageField = FormField.optional.int("age")
  val form: Body[Form] = Body.form(nameField, ageField)

  val svc: Service[Request, Response] = Service.mk[Request, Response] {
    req => {
      val formInstance: Form = form <-- req
      val name: String = nameField <-- formInstance
      val age: Option[Int] = ageField <-- formInstance
      Ok(s"$name is ${age.map(_.toString).getOrElse("too old to admit it")}")
    }
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(form)
    .at(Post) bindTo svc

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -H"Content-Type: application/x-www-form-urlencoded" -XPOST http://localhost:9999/ --data '&age=asd'
//curl -v -H"Content-Type: application/x-www-form-urlencoded" -XPOST http://localhost:9999/ --data 'name=david&age=12' 
Example 52
Source File: MultiPart_Form_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.forms


// fintrospect-core
object MultiPart_Form_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import io.fintrospect.formats.PlainText.ResponseBuilder._
  import io.fintrospect.parameters.{Body, Form, FormField, MultiPartFile}
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}



  val usernameField = FormField.required.string("user")
  val fileField = FormField.required.file("data")
  val form: Body[Form] = Body.multiPartForm(usernameField, fileField)

  val svc: Service[Request, Response] = Service.mk[Request, Response] {
    req => {
      val postedForm: Form = form <-- req
      val name: String = usernameField <-- postedForm
      val data: MultiPartFile = fileField <-- postedForm
      Ok(s"$name posted ${data.filename} which is ${data.length}" + " bytes")
    }
  }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(form)
    .at(Post) bindTo svc

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
} 
Example 53
Source File: MsgPack_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.msgpack

object MsgPack_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.Request
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.result
  import com.twitter.util.Future
  import io.fintrospect.formats.MsgPack.Auto._
  import io.fintrospect.formats.MsgPack.Format.{decode, encode}
  import io.fintrospect.{RouteModule, RouteSpec}

  case class StreetAddress(address: String)

  case class Letter(to: StreetAddress, from: StreetAddress, message: String)

  val replyToLetter = RouteSpec()
    .at(Post) / "reply" bindTo InOut[StreetAddress, Letter](
    Service.mk { in: StreetAddress =>
      Future(Letter(StreetAddress("2 Bob St"), in, "hi fools!"))
    })

  val module = RouteModule(Root).withRoute(replyToLetter)

  Http.serve(":8181", module.toService)


  val request = Request(Post, "reply")
  request.content = encode(StreetAddress("1 hello street"))
  val response = result(Http.newService("localhost:8181")(request))
  println("Response was:" + decode[Letter](response.content))

} 
Example 54
Source File: Patching_Endpoint_Example.scala    From fintrospect   with Apache License 2.0 5 votes vote down vote up
package cookbook.json_libraries


case class Employee(name: String, age: Option[Int])

// fintrospect-core
// fintrospect-circe
object Patching_Endpoint_Example extends App {

  import com.twitter.finagle.http.Method.Post
  import com.twitter.finagle.http.path.Root
  import com.twitter.finagle.http.{Request, Response}
  import com.twitter.finagle.{Http, Service}
  import com.twitter.util.Await.ready
  import com.twitter.util.Future
  import io.circe.generic.auto._
  import io.fintrospect.formats.Circe
  import io.fintrospect.formats.Circe.JsonFormat._
  import io.fintrospect.formats.Circe.ResponseBuilder._
  import io.fintrospect.parameters.Path
  import io.fintrospect.{Module, RouteModule, RouteSpec, ServerRoute}

  import scala.collection.mutable

  val employees = mutable.Map[Int, Employee](1 -> Employee("David", None))

  val patchBody = Circe.patchBody[Employee]()

  def updateAge(id: Int): Service[Request, Response] =
    Service.mk[Request, Response] {
      req =>
        val patcher = patchBody <-- req
        Future(employees.get(id) match {
          case Some(employee) =>
            employees(id) = patcher(employee)
            Ok(encode(employees.get(id)))
          case _ => NotFound(s"with id $id")
        })
    }

  val route: ServerRoute[Request, Response] = RouteSpec()
    .body(patchBody)
    .at(Post) / Path.int("id") bindTo updateAge

  val module: Module = RouteModule(Root).withRoute(route)

  ready(Http.serve(":9999", module.toService))
}

//curl -v -XPOST http://localhost:9999/1 --data '{"age": 50}' 
Example 55
Source File: package.scala    From featherbed   with Apache License 2.0 4 votes vote down vote up
package featherbed

import java.net.URL

import com.twitter.finagle.{Filter, Http}
import com.twitter.finagle.http.{Request, Response}
import org.scalamock.matchers.Matcher
import org.scalamock.scalatest.MockFactory

package object fixture {
  private[fixture] class MockClient (
    baseUrl: URL,
    filter: Filter[Request, Response, Request, Response]
  ) extends Client(baseUrl) {
    override def clientTransform(c: Http.Client) = c.filtered(filter)
  }

  trait ClientTest { self: MockFactory =>
    class TransportRequestMatcher(f: Request => Unit) extends Matcher[Any] {
      override def canEqual(x: Any) = x match {
        case x: Request => true
        case _ => false
      }
      override def safeEquals(that: Any): Boolean = that match {
        case x: Request => f(x); true
        case _ => false
      }
    }

    def request(f: Request => Unit): TransportRequestMatcher = new TransportRequestMatcher(f)

    def mockClient(url: String, filter: Filter[Request, Response, Request, Response]): Client =
      new MockClient(new URL(url), filter)
  }
}