* #20466 added checks to the TimeoutDirectivesExampleSpec * #20466 added missing Java directive wrapper, added Java test, added some comments to Scala spec * #20466 test minor fixes (typos, comments, unused code) * #20466 replaced placeholders with proper snippets in Java docs * #20466 added proper withRequestTimeout example to JavaTestServer * #20466 comment - clarifies the request-timeout = infinite case * #20466 post-review changes (#20812)
This commit is contained in:
parent
ee77273fac
commit
4b89fcd643
7 changed files with 273 additions and 18 deletions
|
|
@ -5,24 +5,65 @@
|
|||
package docs.http.scaladsl.server.directives
|
||||
|
||||
import akka.http.scaladsl.model.{ HttpResponse, StatusCodes }
|
||||
import akka.http.scaladsl.server.RoutingSpec
|
||||
import akka.http.scaladsl.server.Route
|
||||
import docs.CompileOnlySpec
|
||||
|
||||
import akka.http.scaladsl.{ Http, TestUtils }
|
||||
import akka.http.scaladsl.server.Directives._
|
||||
import akka.stream.ActorMaterializer
|
||||
import akka.http.scaladsl.model.HttpEntity._
|
||||
import akka.http.scaladsl.model._
|
||||
import com.typesafe.config.{ Config, ConfigFactory }
|
||||
import org.scalatest.concurrent.ScalaFutures
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Future, Promise }
|
||||
import akka.testkit.AkkaSpec
|
||||
|
||||
class TimeoutDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec {
|
||||
private[this] object TimeoutDirectivesTestConfig {
|
||||
val testConf: Config = ConfigFactory.parseString("""
|
||||
akka.loggers = ["akka.testkit.TestEventListener"]
|
||||
akka.loglevel = ERROR
|
||||
akka.stdout-loglevel = ERROR
|
||||
windows-connection-abort-workaround-enabled = auto
|
||||
akka.log-dead-letters = OFF
|
||||
akka.http.server.request-timeout = 1000s""")
|
||||
// large timeout - 1000s (please note - setting to infinite will disable Timeout-Access header
|
||||
// and withRequestTimeout will not work)
|
||||
}
|
||||
|
||||
class TimeoutDirectivesExamplesSpec extends AkkaSpec(TimeoutDirectivesTestConfig.testConf)
|
||||
with ScalaFutures with CompileOnlySpec {
|
||||
//#testSetup
|
||||
import system.dispatcher
|
||||
implicit val materializer = ActorMaterializer()
|
||||
|
||||
def slowFuture(): Future[String] = Promise[String].future // move to Future.never in Scala 2.12
|
||||
|
||||
def runRoute(route: Route, routePath: String): HttpResponse = {
|
||||
val (_, hostname, port) = TestUtils.temporaryServerHostnameAndPort()
|
||||
val binding = Http().bindAndHandle(route, hostname, port)
|
||||
|
||||
val response = Http().singleRequest(HttpRequest(uri = s"http://$hostname:$port/$routePath")).futureValue
|
||||
|
||||
binding.flatMap(_.unbind()).futureValue
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
//#
|
||||
|
||||
"Request Timeout" should {
|
||||
"be configurable in routing layer" in compileOnlySpec {
|
||||
"be configurable in routing layer" in {
|
||||
//#withRequestTimeout-plain
|
||||
val route =
|
||||
path("timeout") {
|
||||
withRequestTimeout(3.seconds) {
|
||||
withRequestTimeout(1.seconds) { // modifies the global akka.http.server.request-timeout for this request
|
||||
val response: Future[String] = slowFuture() // very slow
|
||||
complete(response)
|
||||
}
|
||||
}
|
||||
|
||||
// check
|
||||
runRoute(route, "timeout").status should ===(StatusCodes.ServiceUnavailable) // the timeout response
|
||||
//#
|
||||
}
|
||||
"without timeout" in compileOnlySpec {
|
||||
|
|
@ -34,14 +75,16 @@ class TimeoutDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec {
|
|||
complete(response)
|
||||
}
|
||||
}
|
||||
|
||||
// no check as there is no time-out, the future would time out failing the test
|
||||
//#
|
||||
}
|
||||
|
||||
"allow mapping the response while setting the timeout" in compileOnlySpec {
|
||||
"allow mapping the response while setting the timeout" in {
|
||||
//#withRequestTimeout-with-handler
|
||||
val timeoutResponse = HttpResponse(
|
||||
StatusCodes.EnhanceYourCalm,
|
||||
entity = "Unable to serve response within time limit, please enchance your calm.")
|
||||
entity = "Unable to serve response within time limit, please enhance your calm.")
|
||||
|
||||
val route =
|
||||
path("timeout") {
|
||||
|
|
@ -51,28 +94,33 @@ class TimeoutDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec {
|
|||
complete(response)
|
||||
}
|
||||
}
|
||||
|
||||
// check
|
||||
runRoute(route, "timeout").status should ===(StatusCodes.EnhanceYourCalm) // the timeout response
|
||||
//#
|
||||
}
|
||||
|
||||
// make it compile only to avoid flaking in slow builds
|
||||
"allow mapping the response" in compileOnlySpec {
|
||||
//#withRequestTimeoutResponse
|
||||
val timeoutResponse = HttpResponse(
|
||||
StatusCodes.EnhanceYourCalm,
|
||||
entity = "Unable to serve response within time limit, please enchance your calm.")
|
||||
entity = "Unable to serve response within time limit, please enhance your calm.")
|
||||
|
||||
val route =
|
||||
path("timeout") {
|
||||
withRequestTimeout(1.milli) {
|
||||
withRequestTimeout(100.milli) { // racy! for a very short timeout like 1.milli you can still get 503
|
||||
withRequestTimeoutResponse(request => timeoutResponse) {
|
||||
val response: Future[String] = slowFuture() // very slow
|
||||
complete(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check
|
||||
runRoute(route, "timeout").status should ===(StatusCodes.EnhanceYourCalm) // the timeout response
|
||||
//#
|
||||
}
|
||||
}
|
||||
|
||||
def slowFuture(): Future[String] = Promise[String].future
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue