diff options
author | Li Haoyi <haoyi.li@databricks.com> | 2019-09-14 19:22:48 +0800 |
---|---|---|
committer | Li Haoyi <haoyi.li@databricks.com> | 2019-09-14 19:22:48 +0800 |
commit | edd1f62ce364f8b559431249e2350c2bb75fccec (patch) | |
tree | 337f0528e9284759800228e46f649cbc01f5edfe | |
parent | 0460ad2eca7fcdec1ff29c289dad4ecc76dde9c6 (diff) | |
download | cask-edd1f62ce364f8b559431249e2350c2bb75fccec.tar.gz cask-edd1f62ce364f8b559431249e2350c2bb75fccec.tar.bz2 cask-edd1f62ce364f8b559431249e2350c2bb75fccec.zip |
Rename `BaseDecorator` -> `Decorator`, `Decorator` -> `RawDecorator`, `BaseEndpoint` -> `Endpoint`, `Endpoint` -> `HttpEndpoint`
-rw-r--r-- | cask/src/cask/decorators/compress.scala | 2 | ||||
-rw-r--r-- | cask/src/cask/endpoints/FormEndpoint.scala | 4 | ||||
-rw-r--r-- | cask/src/cask/endpoints/JsonEndpoint.scala | 6 | ||||
-rw-r--r-- | cask/src/cask/endpoints/StaticEndpoints.scala | 6 | ||||
-rw-r--r-- | cask/src/cask/endpoints/WebEndpoints.scala | 4 | ||||
-rw-r--r-- | cask/src/cask/endpoints/WebSocketEndpoint.scala | 2 | ||||
-rw-r--r-- | cask/src/cask/main/Decorators.scala | 60 | ||||
-rw-r--r-- | cask/src/cask/main/Main.scala | 4 | ||||
-rw-r--r-- | cask/src/cask/main/Routes.scala | 12 | ||||
-rw-r--r-- | cask/src/cask/package.scala | 4 | ||||
-rw-r--r-- | cask/test/src/test/cask/FailureTests.scala | 2 | ||||
-rw-r--r-- | example/decorated/app/src/Decorated.scala | 4 | ||||
-rw-r--r-- | example/decorated2/app/src/Decorated2.scala | 4 | ||||
-rw-r--r-- | example/endpoints/app/src/Endpoints.scala | 2 |
14 files changed, 59 insertions, 57 deletions
diff --git a/cask/src/cask/decorators/compress.scala b/cask/src/cask/decorators/compress.scala index 75e2bed..7a7eefb 100644 --- a/cask/src/cask/decorators/compress.scala +++ b/cask/src/cask/decorators/compress.scala @@ -6,7 +6,7 @@ import cask.internal.Router import cask.model.{Request, Response} import collection.JavaConverters._ -class compress extends cask.Decorator{ +class compress extends cask.RawDecorator{ def wrapFunction(ctx: Request, delegate: Delegate) = { val acceptEncodings = ctx.exchange.getRequestHeaders.get("Accept-Encoding").asScala.flatMap(_.split(", ")) delegate(Map()).map{ v => diff --git a/cask/src/cask/endpoints/FormEndpoint.scala b/cask/src/cask/endpoints/FormEndpoint.scala index 38ce994..6f65786 100644 --- a/cask/src/cask/endpoints/FormEndpoint.scala +++ b/cask/src/cask/endpoints/FormEndpoint.scala @@ -1,7 +1,7 @@ package cask.endpoints import cask.internal.{Router, Util} -import cask.main.Endpoint +import cask.main.HttpEndpoint import cask.model._ import io.undertow.server.handlers.form.FormParserFactory @@ -44,7 +44,7 @@ object FormReader{ } } class postForm(val path: String, override val subpath: Boolean = false) - extends Endpoint[Response.Raw, Seq[FormEntry]] { + extends HttpEndpoint[Response.Raw, Seq[FormEntry]] { val methods = Seq("post") type InputParser[T] = FormReader[T] diff --git a/cask/src/cask/endpoints/JsonEndpoint.scala b/cask/src/cask/endpoints/JsonEndpoint.scala index c4740fd..6d3db82 100644 --- a/cask/src/cask/endpoints/JsonEndpoint.scala +++ b/cask/src/cask/endpoints/JsonEndpoint.scala @@ -3,7 +3,7 @@ package cask.endpoints import java.io.{ByteArrayOutputStream, InputStream, OutputStream, OutputStreamWriter} import cask.internal.{Router, Util} -import cask.main.Endpoint +import cask.main.HttpEndpoint import cask.model.Response.DataCompanion import cask.model.{Request, Response} @@ -40,7 +40,7 @@ object JsonData extends DataCompanion[JsonData]{ } class postJson(val path: String, override val subpath: Boolean = false) - extends Endpoint[Response[JsonData], ujson.Value]{ + extends HttpEndpoint[Response[JsonData], ujson.Value]{ val methods = Seq("post") type InputParser[T] = JsReader[T] override type OuterReturned = Router.Result[Response.Raw] @@ -79,7 +79,7 @@ class postJson(val path: String, override val subpath: Boolean = false) } class getJson(val path: String, override val subpath: Boolean = false) - extends Endpoint[Response[JsonData], Seq[String]]{ + extends HttpEndpoint[Response[JsonData], Seq[String]]{ val methods = Seq("get") type InputParser[T] = QueryParamReader[T] override type OuterReturned = Router.Result[Response.Raw] diff --git a/cask/src/cask/endpoints/StaticEndpoints.scala b/cask/src/cask/endpoints/StaticEndpoints.scala index 2f0568d..0abfcf5 100644 --- a/cask/src/cask/endpoints/StaticEndpoints.scala +++ b/cask/src/cask/endpoints/StaticEndpoints.scala @@ -1,9 +1,9 @@ package cask.endpoints -import cask.main.Endpoint +import cask.main.HttpEndpoint import cask.model.Request -class staticFiles(val path: String) extends Endpoint[String, Seq[String]]{ +class staticFiles(val path: String) extends HttpEndpoint[String, Seq[String]]{ val methods = Seq("get") type InputParser[T] = QueryParamReader[T] override def subpath = true @@ -21,7 +21,7 @@ class staticFiles(val path: String) extends Endpoint[String, Seq[String]]{ } class staticResources(val path: String, resourceRoot: ClassLoader = getClass.getClassLoader) - extends Endpoint[String, Seq[String]]{ + extends HttpEndpoint[String, Seq[String]]{ val methods = Seq("get") type InputParser[T] = QueryParamReader[T] override def subpath = true diff --git a/cask/src/cask/endpoints/WebEndpoints.scala b/cask/src/cask/endpoints/WebEndpoints.scala index ae1e178..8bb3bae 100644 --- a/cask/src/cask/endpoints/WebEndpoints.scala +++ b/cask/src/cask/endpoints/WebEndpoints.scala @@ -1,13 +1,13 @@ package cask.endpoints import cask.internal.Router -import cask.main.Endpoint +import cask.main.HttpEndpoint import cask.model.{Request, Response} import collection.JavaConverters._ -trait WebEndpoint extends Endpoint[Response.Raw, Seq[String]]{ +trait WebEndpoint extends HttpEndpoint[Response.Raw, Seq[String]]{ type InputParser[T] = QueryParamReader[T] def wrapFunction(ctx: Request, delegate: Delegate): Router.Result[Response.Raw] = { diff --git a/cask/src/cask/endpoints/WebSocketEndpoint.scala b/cask/src/cask/endpoints/WebSocketEndpoint.scala index dff2232..842d508 100644 --- a/cask/src/cask/endpoints/WebSocketEndpoint.scala +++ b/cask/src/cask/endpoints/WebSocketEndpoint.scala @@ -14,7 +14,7 @@ object WebsocketResult{ } class websocket(val path: String, override val subpath: Boolean = false) - extends cask.main.BaseEndpoint[WebsocketResult, Seq[String]]{ + extends cask.main.Endpoint[WebsocketResult, Seq[String]]{ val methods = Seq("websocket") type InputParser[T] = QueryParamReader[T] type OuterReturned = Router.Result[WebsocketResult] diff --git a/cask/src/cask/main/Decorators.scala b/cask/src/cask/main/Decorators.scala index dd445a4..573c139 100644 --- a/cask/src/cask/main/Decorators.scala +++ b/cask/src/cask/main/Decorators.scala @@ -4,20 +4,41 @@ import cask.internal.{Conversion, Router} import cask.internal.Router.ArgReader import cask.model.{Request, Response} +/** + * A [[Decorator]] allows you to annotate a function to wrap it, via + * `wrapFunction`. You can use this to perform additional validation before or + * after the function runs, provide an additional parameter list of params, + * open/commit/rollback database transactions before/after the function runs, + * or even retrying the wrapped function if it fails. + * + * Calls to the wrapped function are done on the `delegate` parameter passed + * to `wrapFunction`, which takes a `Map` representing any additional argument + * lists (if any). + */ +trait Decorator[InnerReturned, Input]{ + final type InputTypeAlias = Input + type InputParser[T] <: ArgReader[Input, T, Request] + final type Delegate = Map[String, Input] => Router.Result[InnerReturned] + type OuterReturned <: Router.Result[Any] + def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned + def getParamParser[T](implicit p: InputParser[T]) = p +} /** - * Annotates a Cask endpoint that returns a HTTP [[Response]]; similar to a - * [[Decorator]] but with additional metadata and capabilities. + * A [[RawDecorator]] is a decorator that operates on the raw request and + * response stream, before and after the primary [[Endpoint]] does it's job. */ -trait Endpoint[InnerReturned, Input] extends BaseEndpoint[InnerReturned, Input] { +trait RawDecorator extends Decorator[Response.Raw, Any]{ type OuterReturned = Router.Result[Response.Raw] + type InputParser[T] = NoOpParser[Any, T] } + /** - * An [[Endpoint]] that may return something else than a HTTP response, e.g. + * An [[HttpEndpoint]] that may return something else than a HTTP response, e.g. * a websocket endpoint which may instead return a websocket event handler */ -trait BaseEndpoint[InnerReturned, Input] extends BaseDecorator[InnerReturned, Input]{ +trait Endpoint[InnerReturned, Input] extends Decorator[InnerReturned, Input]{ /** * What is the path that this particular endpoint matches? */ @@ -42,7 +63,7 @@ trait BaseEndpoint[InnerReturned, Input] extends BaseDecorator[InnerReturned, In } /** - * [[Endpoint]]s are unique among decorators in that they alone can bind + * [[HttpEndpoint]]s are unique among decorators in that they alone can bind * path segments to parameters, e.g. binding `/hello/:world` to `(world: Int)`. * In order to do so, we need to box up the path segment strings into an * [[Input]] so they can later be parsed by [[getParamParser]] into an @@ -53,33 +74,14 @@ trait BaseEndpoint[InnerReturned, Input] extends BaseDecorator[InnerReturned, In } /** - * A [[Decorator]] that may deal with values other than HTTP [[Response]]s - */ -trait BaseDecorator[InnerReturned, Input]{ - final type InputTypeAlias = Input - type InputParser[T] <: ArgReader[Input, T, Request] - final type Delegate = Map[String, Input] => Router.Result[InnerReturned] - type OuterReturned <: Router.Result[Any] - def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned - def getParamParser[T](implicit p: InputParser[T]) = p -} - -/** - * A decorator allows you to annotate a function to wrap it, via - * `wrapFunction`. You can use this to perform additional validation before or - * after the function runs, provide an additional parameter list of params, - * open/commit/rollback database transactions before/after the function runs, - * or even retrying the wrapped function if it fails. - * - * Calls to the wrapped function are done on the `delegate` parameter passed - * to `wrapFunction`, which takes a `Map` representing any additional argument - * lists (if any). + * Annotates a Cask endpoint that returns a HTTP [[Response]]; similar to a + * [[RawDecorator]] but with additional metadata and capabilities. */ -trait Decorator extends BaseDecorator[Response.Raw, Any]{ +trait HttpEndpoint[InnerReturned, Input] extends Endpoint[InnerReturned, Input] { type OuterReturned = Router.Result[Response.Raw] - type InputParser[T] = NoOpParser[Any, T] } + class NoOpParser[Input, T] extends ArgReader[Input, T, Request] { def arity = 1 diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala index 1eb2dbc..32e6517 100644 --- a/cask/src/cask/main/Main.scala +++ b/cask/src/cask/main/Main.scala @@ -28,7 +28,7 @@ class Main(servers0: Routes*) extends BaseMain{ def allRoutes = servers0.toSeq } abstract class BaseMain{ - def mainDecorators = Seq.empty[cask.main.Decorator] + def mainDecorators = Seq.empty[cask.main.RawDecorator] def allRoutes: Seq[Routes] def port: Int = 8080 def host: String = "localhost" @@ -88,7 +88,7 @@ abstract class BaseMain{ case None => writeResponse(exchange, handleNotFound()) case Some(((routes, metadata), routeBindings, remaining)) => val ctx = Request(exchange, remaining) - def rec(remaining: List[Decorator], + def rec(remaining: List[RawDecorator], bindings: List[Map[String, Any]]): Router.Result[Any] = try { remaining match { case head :: rest => diff --git a/cask/src/cask/main/Routes.scala b/cask/src/cask/main/Routes.scala index ea9d6fe..f133fdb 100644 --- a/cask/src/cask/main/Routes.scala +++ b/cask/src/cask/main/Routes.scala @@ -7,8 +7,8 @@ import scala.reflect.macros.blackbox.Context import language.experimental.macros object Routes{ - case class EndpointMetadata[T](decorators: Seq[Decorator], - endpoint: BaseEndpoint[_, _], + case class EndpointMetadata[T](decorators: Seq[RawDecorator], + endpoint: Endpoint[_, _], entryPoint: EntryPoint[T, _]) case class RoutesEndpointsMetadata[T](value: EndpointMetadata[T]*) object RoutesEndpointsMetadata{ @@ -19,15 +19,15 @@ object Routes{ val routeParts = for{ m <- c.weakTypeOf[T].members - val annotations = m.annotations.filter(_.tree.tpe <:< c.weakTypeOf[BaseDecorator[_, _]]).reverse + val annotations = m.annotations.filter(_.tree.tpe <:< c.weakTypeOf[Decorator[_, _]]).reverse if annotations.nonEmpty } yield { - if(!(annotations.head.tree.tpe <:< weakTypeOf[BaseEndpoint[_, _]])) c.abort( + if(!(annotations.head.tree.tpe <:< weakTypeOf[Endpoint[_, _]])) c.abort( annotations.head.tree.pos, s"Last annotation applied to a function must be an instance of Endpoint, " + s"not ${annotations.head.tree.tpe}" ) - val allEndpoints = annotations.filter(_.tree.tpe <:< weakTypeOf[BaseEndpoint[_, _]]) + val allEndpoints = annotations.filter(_.tree.tpe <:< weakTypeOf[Endpoint[_, _]]) if(allEndpoints.length > 1) c.abort( annotations.head.tree.pos, s"You can only apply one Endpoint annotation to a function, not " + @@ -70,7 +70,7 @@ object Routes{ trait Routes{ - def decorators = Seq.empty[cask.main.Decorator] + def decorators = Seq.empty[cask.main.RawDecorator] private[this] var metadata0: Routes.RoutesEndpointsMetadata[this.type] = null def caskMetadata = if (metadata0 != null) metadata0 diff --git a/cask/src/cask/package.scala b/cask/src/cask/package.scala index 427f638..d17cfe6 100644 --- a/cask/src/cask/package.scala +++ b/cask/src/cask/package.scala @@ -37,7 +37,7 @@ package object cask { type Routes = main.Routes val Routes = main.Routes type Main = main.Main - type Decorator = main.Decorator - type Endpoint[InnerReturned, Input] = main.Endpoint[InnerReturned, Input] + type RawDecorator = main.RawDecorator + type HttpEndpoint[InnerReturned, Input] = main.HttpEndpoint[InnerReturned, Input] } diff --git a/cask/test/src/test/cask/FailureTests.scala b/cask/test/src/test/cask/FailureTests.scala index ac0f3d8..6b01ec1 100644 --- a/cask/test/src/test/cask/FailureTests.scala +++ b/cask/test/src/test/cask/FailureTests.scala @@ -4,7 +4,7 @@ import cask.model.Request import utest._ object FailureTests extends TestSuite { - class myDecorator extends cask.Decorator { + class myDecorator extends cask.RawDecorator { def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned = { delegate(Map("extra" -> 31337)) } diff --git a/example/decorated/app/src/Decorated.scala b/example/decorated/app/src/Decorated.scala index b3f1149..a88bd2e 100644 --- a/example/decorated/app/src/Decorated.scala +++ b/example/decorated/app/src/Decorated.scala @@ -3,12 +3,12 @@ object Decorated extends cask.MainRoutes{ class User{ override def toString = "[haoyi]" } - class loggedIn extends cask.Decorator { + class loggedIn extends cask.RawDecorator { def wrapFunction(ctx: cask.Request, delegate: Delegate): OuterReturned = { delegate(Map("user" -> new User())) } } - class withExtra extends cask.Decorator { + class withExtra extends cask.RawDecorator { def wrapFunction(ctx: cask.Request, delegate: Delegate): OuterReturned = { delegate(Map("extra" -> 31337)) } diff --git a/example/decorated2/app/src/Decorated2.scala b/example/decorated2/app/src/Decorated2.scala index fa4b1c5..305281a 100644 --- a/example/decorated2/app/src/Decorated2.scala +++ b/example/decorated2/app/src/Decorated2.scala @@ -3,12 +3,12 @@ object Decorated2 extends cask.MainRoutes{ class User{ override def toString = "[haoyi]" } - class loggedIn extends cask.Decorator { + class loggedIn extends cask.RawDecorator { def wrapFunction(ctx: cask.Request, delegate: Delegate): OuterReturned = { delegate(Map("user" -> new User())) } } - class withExtra extends cask.Decorator { + class withExtra extends cask.RawDecorator { def wrapFunction(ctx: cask.Request, delegate: Delegate): OuterReturned = { delegate(Map("extra" -> 31337)) } diff --git a/example/endpoints/app/src/Endpoints.scala b/example/endpoints/app/src/Endpoints.scala index 7417289..9722673 100644 --- a/example/endpoints/app/src/Endpoints.scala +++ b/example/endpoints/app/src/Endpoints.scala @@ -1,7 +1,7 @@ package app class custom(val path: String, val methods: Seq[String]) - extends cask.Endpoint[Int, Seq[String]]{ + extends cask.HttpEndpoint[Int, Seq[String]]{ def wrapFunction(ctx: cask.Request, delegate: Delegate): OuterReturned = { delegate(Map()).map{num => cask.Response("Echo " + num, statusCode = num) |