From a00e3942d95fd0a0e29e14b47fa0997c8e6b3799 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Mon, 15 Apr 2019 19:26:45 +0000 Subject: [PATCH] finagle-core, twitter-server: Add `c.t.finagle.DtabFlags` Problem There is currently no defined way for users of the `c.t.finagle.Dtab` API to append to the `Dtab.base` delegation table with a supplemental value that is passed at runtime. Solution Add the `c.t.finagle.DtabFlags` trait which defines a `c.t.app.Flag`, "dtab.add" that can provide a supplemental delegation table (`Dtab`) to append to the current server `Dtab.base`. The trait exposes a `addDtabs()` function which applies the parsed Flag value and appends it to the current `Dtab.base`. Result Users are able to augment the base delegation table (`Dtab.base`) of the server with a value passed at runtime via the command line. JIRA Issues: CSL-7766 Differential Revision: https://phabricator.twitter.biz/D297596 --- CHANGELOG.rst | 8 +++++ .../main/scala/com/twitter/server/Admin.scala | 4 +-- .../com/twitter/server/FlagResolver.scala | 5 +-- .../com/twitter/server/TwitterServer.scala | 2 ++ .../twitter/server/handler/DtabHandler.scala | 36 +++++++++++++++---- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 925ceeb0..9d627847 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,14 @@ Changes * Remove deprecated uses of `c.t.server.ShadowAdminServer`. ``PHAB_ID=D269149`` +* Mix in the `c.t.finagle.DtabFlags` to allow servers to append to the "base" `c.t.finagle.Dtab` + delegation table. Users can now call `c.t.finagle.DtabFlags#addDtabs()` when they want to append + the parsed Flag value to the `Dtab.base` delegation table. Users should note to only call this + method _after_ Flag parsing has occurred (which is after **init** and before **premain**). + + We also update the `c.t.server.handler.DtabHandler` to always return a proper JSON response of + the currently configured `c.t.finagle.Dtab.base`. ``PHAB_ID=D297596`` + 19.3.0 ------ diff --git a/server/src/main/scala/com/twitter/server/Admin.scala b/server/src/main/scala/com/twitter/server/Admin.scala index 3a2ce979..d60f44a7 100644 --- a/server/src/main/scala/com/twitter/server/Admin.scala +++ b/server/src/main/scala/com/twitter/server/Admin.scala @@ -138,7 +138,7 @@ trait Admin { self: App with AdminHttpServer with Stats => ), Route( path = "/admin/dtab", - handler = new TextBlockView().andThen(new DtabHandler), + handler = new DtabHandler, alias = "Dtab", group = Some(Grouping.ProcessInfo), includeInIndex = true @@ -195,7 +195,7 @@ trait Admin { self: App with AdminHttpServer with Stats => ), Route( path = LoadBalancersHandler.RoutePath, - handler = new LoadBalancersHandler(), + handler = new LoadBalancersHandler, alias = "Load Balancers", group = Some(Grouping.ProcessInfo), includeInIndex = true diff --git a/server/src/main/scala/com/twitter/server/FlagResolver.scala b/server/src/main/scala/com/twitter/server/FlagResolver.scala index 6d5f61e5..cc066249 100644 --- a/server/src/main/scala/com/twitter/server/FlagResolver.scala +++ b/server/src/main/scala/com/twitter/server/FlagResolver.scala @@ -4,8 +4,9 @@ import com.twitter.app.GlobalFlag import com.twitter.finagle.{Addr, Resolver, Name} import com.twitter.util.Var -// TODO: deprecate in favor of Wily dtabs. - +@deprecated( + "Users should prefer using Dtabs which are overridable by setting the `dtab.add` flag", + "2019-04-03") object resolverMap extends GlobalFlag[Map[String, String]]( Map.empty, diff --git a/server/src/main/scala/com/twitter/server/TwitterServer.scala b/server/src/main/scala/com/twitter/server/TwitterServer.scala index 1c5e11ce..8d284d63 100644 --- a/server/src/main/scala/com/twitter/server/TwitterServer.scala +++ b/server/src/main/scala/com/twitter/server/TwitterServer.scala @@ -1,6 +1,7 @@ package com.twitter.server import com.twitter.app.App +import com.twitter.finagle.DtabFlags import com.twitter.finagle.util.DefaultTimer import com.twitter.util.Timer import com.twitter.util.logging.Logging @@ -36,6 +37,7 @@ trait TwitterServer with Slf4jBridge with Logging with Linters + with DtabFlags with Hooks with AdminHttpServer with Admin diff --git a/server/src/main/scala/com/twitter/server/handler/DtabHandler.scala b/server/src/main/scala/com/twitter/server/handler/DtabHandler.scala index 5ff1c144..f62bd9be 100644 --- a/server/src/main/scala/com/twitter/server/handler/DtabHandler.scala +++ b/server/src/main/scala/com/twitter/server/handler/DtabHandler.scala @@ -1,18 +1,40 @@ package com.twitter.server.handler +import com.twitter.finagle.http.{MediaType, Request, Response} import com.twitter.finagle.{Dtab, Service} -import com.twitter.finagle.http.{Request, Response} -import com.twitter.server.util.HttpUtils.newOk +import com.twitter.io.Buf +import com.twitter.server.util.{HttpUtils, JsonConverter} import com.twitter.util.Future /** - * Dumps a simple string representation of the current Dtab. + * Dumps a simple JSON string representation of the current [[com.twitter.finagle.Dtab.base]]. * * From the Dtab docs: A Dtab--short for delegation table--comprises a sequence - * of delegation rules. Together, these describe how to bind a - * path to an Addr. + * of delegation rules. Together, these describe how to bind a path to an Addr. + * + * {{{ + * { + * "dtab": [ + * "/srv => /srv#/production", + * "/srv => /srv#/prod", + * "/s => /srv/local", + * "/$/inet => /$/nil", + * "/zk => /$/nil" + * ] + * } + * }}} + * + * @see [[com.twitter.finagle.Dtab]] */ -class DtabHandler extends Service[Request, Response] { +final class DtabHandler extends Service[Request, Response] { def apply(req: Request): Future[Response] = - newOk(Dtab.base.toString) + HttpUtils.newResponse(contentType = MediaType.Json, content = Buf.Utf8(jsonResponse)) + + private[this] def jsonResponse: String = { + JsonConverter.writeToString(Map("dtab" -> formattedDtabEntries)) + } + + private[this] def formattedDtabEntries: Seq[String] = { + for (dentry <- Dtab.base) yield { s"${dentry.prefix.show} => ${dentry.dst.show}" } + } }