+doc,htp #19896 directives for RequestTimeout and docs
This commit is contained in:
parent
27c004d274
commit
2d7d24dee6
24 changed files with 523 additions and 70 deletions
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
package akka.http.scaladsl.server
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.scaladsl.{ Http, TestUtils }
|
||||
import akka.http.scaladsl.client.RequestBuilding
|
||||
import akka.http.scaladsl.model.{ HttpResponse, HttpRequest }
|
||||
import akka.stream.ActorMaterializer
|
||||
import akka.testkit.AkkaSpec
|
||||
import org.scalatest.concurrent.{ IntegrationPatience, ScalaFutures }
|
||||
import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.Await
|
||||
|
||||
/** INTERNAL API - not (yet?) ready for public consuption */
|
||||
private[akka] trait IntegrationRoutingSpec extends WordSpecLike with Matchers with BeforeAndAfterAll
|
||||
with Directives with RequestBuilding
|
||||
with ScalaFutures with IntegrationPatience {
|
||||
|
||||
implicit val system = ActorSystem(AkkaSpec.getCallerName(getClass))
|
||||
implicit val mat = ActorMaterializer()
|
||||
import system.dispatcher
|
||||
|
||||
override protected def afterAll(): Unit = {
|
||||
Await.ready(system.terminate(), 3.seconds)
|
||||
}
|
||||
|
||||
implicit class DSL(request: HttpRequest) {
|
||||
def ~!>(route: Route) = new Prepped(request, route)
|
||||
}
|
||||
|
||||
final case class Prepped(request: HttpRequest, route: Route)
|
||||
|
||||
implicit class Checking(p: Prepped) {
|
||||
def ~!>(checking: HttpResponse ⇒ Unit) = {
|
||||
val (_, host, port) = TestUtils.temporaryServerHostnameAndPort()
|
||||
val binding = Http().bindAndHandle(p.route, host, port)
|
||||
|
||||
try {
|
||||
val targetUri = p.request.uri.withHost(host).withPort(port).withScheme("http")
|
||||
val response = Http().singleRequest(p.request.withUri(targetUri)).futureValue
|
||||
checking(response)
|
||||
} finally binding.flatMap(_.unbind()).futureValue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,11 +5,13 @@
|
|||
package akka.http.scaladsl.server
|
||||
|
||||
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport
|
||||
import akka.http.scaladsl.model.{ StatusCodes, HttpResponse }
|
||||
import akka.http.scaladsl.server.directives.Credentials
|
||||
import com.typesafe.config.{ ConfigFactory, Config }
|
||||
import akka.actor.ActorSystem
|
||||
import akka.stream.ActorMaterializer
|
||||
import akka.http.scaladsl.Http
|
||||
import scala.concurrent.duration._
|
||||
|
||||
object TestServer extends App {
|
||||
val testConf: Config = ConfigFactory.parseString("""
|
||||
|
|
@ -31,7 +33,11 @@ object TestServer extends App {
|
|||
val bindingFuture = Http().bindAndHandle({
|
||||
get {
|
||||
path("") {
|
||||
complete(index)
|
||||
withRequestTimeout(1.milli, _ ⇒ HttpResponse(StatusCodes.EnhanceYourCalm,
|
||||
entity = "Unable to serve response within time limit, please enchance your calm.")) {
|
||||
Thread.sleep(1000)
|
||||
complete(index)
|
||||
}
|
||||
} ~
|
||||
path("secure") {
|
||||
authenticateBasicPF("My very secure site", auth) { user ⇒
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package akka.http.scaladsl.server.directives
|
||||
|
||||
import akka.http.scaladsl.model.{ HttpResponse, StatusCodes }
|
||||
import akka.http.scaladsl.server.IntegrationRoutingSpec
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Future, Promise }
|
||||
|
||||
class TimeoutDirectivesSpec extends IntegrationRoutingSpec {
|
||||
|
||||
"Request Timeout" should {
|
||||
"be configurable in routing layer" in {
|
||||
|
||||
val route = path("timeout") {
|
||||
withRequestTimeout(3.seconds) {
|
||||
val response: Future[String] = slowFuture() // very slow
|
||||
complete(response)
|
||||
}
|
||||
}
|
||||
|
||||
Get("/timeout") ~!> route ~!> { response ⇒
|
||||
import response._
|
||||
|
||||
status should ===(StatusCodes.ServiceUnavailable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"allow mapping the response" in {
|
||||
val timeoutResponse = HttpResponse(StatusCodes.EnhanceYourCalm,
|
||||
entity = "Unable to serve response within time limit, please enchance your calm.")
|
||||
|
||||
val route =
|
||||
path("timeout") {
|
||||
withRequestTimeout(500.millis) {
|
||||
withRequestTimeoutResponse(request ⇒ timeoutResponse) {
|
||||
val response: Future[String] = slowFuture() // very slow
|
||||
complete(response)
|
||||
}
|
||||
}
|
||||
} ~
|
||||
path("equivalent") {
|
||||
// updates timeout and handler at
|
||||
withRequestTimeout(500.millis, request ⇒ timeoutResponse) {
|
||||
val response: Future[String] = slowFuture() // very slow
|
||||
complete(response)
|
||||
}
|
||||
}
|
||||
|
||||
Get("/timeout") ~!> route ~!> { response ⇒
|
||||
import response._
|
||||
status should ===(StatusCodes.EnhanceYourCalm)
|
||||
}
|
||||
}
|
||||
|
||||
def slowFuture(): Future[String] = Promise[String].future
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue