This repository has been archived by the owner on Apr 23, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 113
/
PostActionBuilder.scala
105 lines (85 loc) · 3.79 KB
/
PostActionBuilder.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package v1.post
import javax.inject.Inject
import net.logstash.logback.marker.LogstashMarker
import play.api.{Logger, MarkerContext}
import play.api.http.{FileMimeTypes, HttpVerbs}
import play.api.i18n.{Langs, MessagesApi}
import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}
/**
* A wrapped request for post resources.
*
* This is commonly used to hold request-specific information like
* security credentials, and useful shortcut methods.
*/
trait PostRequestHeader extends MessagesRequestHeader with PreferredMessagesProvider
class PostRequest[A](request: Request[A], val messagesApi: MessagesApi) extends WrappedRequest(request) with PostRequestHeader
/**
* Provides an implicit marker that will show the request in all logger statements.
*/
trait RequestMarkerContext {
import net.logstash.logback.marker.Markers
private def marker(tuple: (String, Any)) = Markers.append(tuple._1, tuple._2)
private implicit class RichLogstashMarker(marker1: LogstashMarker) {
def &&(marker2: LogstashMarker): LogstashMarker = marker1.and(marker2)
}
implicit def requestHeaderToMarkerContext(implicit request: RequestHeader): MarkerContext = {
MarkerContext {
marker("id" -> request.id) && marker("host" -> request.host) && marker("remoteAddress" -> request.remoteAddress)
}
}
}
/**
* The action builder for the Post resource.
*
* This is the place to put logging, metrics, to augment
* the request with contextual data, and manipulate the
* result.
*/
class PostActionBuilder @Inject()(messagesApi: MessagesApi, playBodyParsers: PlayBodyParsers)
(implicit val executionContext: ExecutionContext)
extends ActionBuilder[PostRequest, AnyContent]
with RequestMarkerContext
with HttpVerbs {
val parser: BodyParser[AnyContent] = playBodyParsers.anyContent
type PostRequestBlock[A] = PostRequest[A] => Future[Result]
private val logger = Logger(this.getClass)
override def invokeBlock[A](request: Request[A],
block: PostRequestBlock[A]): Future[Result] = {
// Convert to marker context and use request in block
implicit val markerContext: MarkerContext = requestHeaderToMarkerContext(request)
logger.trace(s"invokeBlock: ")
val future = block(new PostRequest(request, messagesApi))
future.map { result =>
request.method match {
case GET | HEAD =>
result.withHeaders("Cache-Control" -> s"max-age: 100")
case other =>
result
}
}
}
}
/**
* Packages up the component dependencies for the post controller.
*
* This is a good way to minimize the surface area exposed to the controller, so the
* controller only has to have one thing injected.
*/
case class PostControllerComponents @Inject()(postActionBuilder: PostActionBuilder,
postResourceHandler: PostResourceHandler,
actionBuilder: DefaultActionBuilder,
parsers: PlayBodyParsers,
messagesApi: MessagesApi,
langs: Langs,
fileMimeTypes: FileMimeTypes,
executionContext: scala.concurrent.ExecutionContext)
extends ControllerComponents
/**
* Exposes actions and handler to the PostController by wiring the injected state into the base class.
*/
class PostBaseController @Inject()(pcc: PostControllerComponents) extends BaseController with RequestMarkerContext {
override protected def controllerComponents: ControllerComponents = pcc
def PostAction: PostActionBuilder = pcc.postActionBuilder
def postResourceHandler: PostResourceHandler = pcc.postResourceHandler
}