Skip to content

Instantly share code, notes, and snippets.

@grimrose
Last active March 9, 2019 00:48
Show Gist options
  • Save grimrose/ad1d0d1deb1726e9660351e25dea44ed to your computer and use it in GitHub Desktop.
Save grimrose/ad1d0d1deb1726e9660351e25dea44ed to your computer and use it in GitHub Desktop.
airframe-http-finagle(19.2.0) + zipkin-finagle-http(2.0.11) or finagle-opencensus-tracing(19.2.0) sample
import com.twitter.finagle.Http
import com.twitter.finagle.http.{ Request, Response }
import com.twitter.finagle.tracing.Tracer
import wvlet.airframe._
import wvlet.airframe.http.{ Endpoint, HttpMethod }
import wvlet.airframe.http.finagle.FinagleServer.FinagleService
import wvlet.airframe.http.finagle._
import wvlet.airframe.http.{ ControllerProvider, ResponseHandler, Router }
import wvlet.log.LogFormatter.SourceCodeLogFormatter
import wvlet.log.Logger
import zipkin2.finagle.http.HttpZipkinTracer
object Server {
def main(args: Array[String]): Unit = {
Logger.scheduleLogLevelScan
Logger.setDefaultFormatter(SourceCodeLogFormatter)
val router = Router.of[MessageApi]
val port = 9001
val tracer = new HttpZipkinTracer()
val repository = new MessageRepository {
override def find(id: MessageId): Option[PostedMessage] = {
Some(PostedMessage(id, Message("hello, airframe-http-finagle")))
}
}
finagleDefaultDesign
.bind[Router]
.toInstance(router)
.bind[FinagleServerConfig]
.toInstance(FinagleServerConfig(port))
.bind[ZipkinTracingContext]
.toInstance(ZipkinTracingContext(tracer, "airframe-http-finagle"))
.bind[FinagleServer]
.toProvider { factory: ZipkinFinagleServerFactory /* OpenCensusTracingFinagleServerFactory */ =>
factory.newFinagleServer(port, router)
}
.bind[MessageRepository]
.toInstance(repository)
.withProductionMode
.withSession { session =>
val server = session.build[FinagleServer]
server.waitServerTermination
}
}
}
case class ZipkinTracingContext(tracer: Tracer, label: String)
class ZipkinFinagleServer(finagleConfig: FinagleServerConfig,
finagleService: FinagleService,
context: ZipkinTracingContext)
extends FinagleServer(finagleConfig, finagleService) {
override def start: Unit = {
info(s"Starting a server at http://localhost:${finagleConfig.port}")
server = Some(
Http
.Server()
.withTracer(context.tracer)
.withLabel(context.label)
.serve(s":${finagleConfig.port}", finagleService)
)
}
}
class ZipkinFinagleServerFactory extends FinagleServerFactory {
private val controllerProvider = bind[ControllerProvider]
private val responseHandler = bind[ResponseHandler[Request, Response]]
private val finagleConfig = bind[FinagleServerConfig]
private val tracingContext = bind[ZipkinTracingContext]
override def newFinagleServer(port: Int, router: Router): FinagleServer = {
val finagleRouter = new FinagleRouter(router, controllerProvider, responseHandler)
new ZipkinFinagleServer(finagleConfig = finagleConfig, finagleService = newService(finagleRouter), tracingContext)
}
}
@Endpoint(path = "/messages")
trait MessageApi {
import MessageApi._
private val repository = bind[MessageRepository]
@Endpoint(method = HttpMethod.GET, path = "/:id")
def getMessage(id: String): Option[ResponseMessage] = {
repository.find(MessageId(id.toLong)).map(message => ResponseMessage(message.id.value, message.value.value))
}
}
object MessageApi {
case class ResponseMessage(id: Long, value: String)
}
case class MessageId(value: Long) extends AnyVal
case class Message(value: String) extends AnyVal
case class PostedMessage(id: MessageId, value: Message)
trait MessageRepository { def find(id: MessageId): Option[PostedMessage] }
// for OpenCensus
class OpenCensusTracingFinagleServer(finagleConfig: FinagleServerConfig, finagleService: FinagleService)
extends FinagleServer(finagleConfig, finagleService) {
import com.twitter.finagle.tracing.opencensus.StackServerOps._
override def start: Unit = {
info(s"Starting a server at http://localhost:${finagleConfig.port}")
server = Some(
Http
.Server()
.withOpenCensusTracing
.serve(s":${finagleConfig.port}", finagleService)
)
}
}
class OpenCensusTracingFinagleServerFactory extends FinagleServerFactory {
private val controllerProvider = bind[ControllerProvider]
private val responseHandler = bind[ResponseHandler[Request, Response]]
override def newFinagleServer(port: Int, router: Router): FinagleServer = {
val finagleRouter = new FinagleRouter(router, controllerProvider, responseHandler)
new OpenCensusTracingFinagleServer(
finagleConfig = FinagleServerConfig(port = port),
finagleService = newService(finagleRouter)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment