From bf76d6c389167acd57114cac04ad33c355c99e2b Mon Sep 17 00:00:00 2001 From: Michal Sitko Date: Tue, 7 Jun 2016 00:17:23 +0200 Subject: [PATCH] +doc #20699 improve docs for akka-http (#20722) Made imports in docs snippets more complete and a few minor improvements --- .../javadsl/WebSocketClientExampleTest.java | 13 +- .../rst/java/http/common/marshalling.rst | 2 +- .../rst/java/http/common/unmarshalling.rst | 2 +- akka-docs/rst/java/http/routing-dsl/index.rst | 2 +- .../http/scaladsl/HttpClientExampleSpec.scala | 46 +++-- .../http/scaladsl/HttpServerExampleSpec.scala | 82 +++++---- .../http/scaladsl/HttpsExamplesSpec.scala | 7 +- .../http/scaladsl/SprayJsonExampleSpec.scala | 16 +- .../scaladsl/WebSocketClientExampleSpec.scala | 164 +++++++++--------- .../server/WebSocketExampleSpec.scala | 9 +- .../TimeoutDirectivesExamplesSpec.scala | 2 - .../rst/scala/http/common/marshalling.rst | 2 +- .../rst/scala/http/common/unmarshalling.rst | 2 +- akka-docs/rst/scala/http/introduction.rst | 7 +- .../rst/scala/http/routing-dsl/index.rst | 2 +- 15 files changed, 197 insertions(+), 161 deletions(-) diff --git a/akka-docs/rst/java/code/docs/http/javadsl/WebSocketClientExampleTest.java b/akka-docs/rst/java/code/docs/http/javadsl/WebSocketClientExampleTest.java index 1348c65636..0fd90fddc4 100644 --- a/akka-docs/rst/java/code/docs/http/javadsl/WebSocketClientExampleTest.java +++ b/akka-docs/rst/java/code/docs/http/javadsl/WebSocketClientExampleTest.java @@ -14,7 +14,6 @@ import akka.http.javadsl.model.ws.TextMessage; import akka.http.javadsl.model.ws.WebSocketRequest; import akka.http.javadsl.model.ws.WebSocketUpgradeResponse; import akka.japi.Pair; -import akka.japi.function.Procedure; import akka.stream.ActorMaterializer; import akka.stream.Materializer; import akka.stream.javadsl.Flow; @@ -63,9 +62,9 @@ public class WebSocketClientExampleTest { // The first value in the pair is a CompletionStage that // completes when the WebSocket request has connected successfully (or failed) final CompletionStage connected = pair.first().thenApply(upgrade -> { - // just like a regular http request we can get 404 NotFound, - // with a response body, that will be available from upgrade.response - if (upgrade.response().status().equals(StatusCodes.OK)) { + // just like a regular http request we can access response status which is available via upgrade.response.status + // status code 101 (Switching Protocols) indicates that server support WebSockets + if (upgrade.response().status().equals(StatusCodes.SWITCHING_PROTOCOLS)) { return Done.getInstance(); } else { throw new RuntimeException("Connection failed: " + upgrade.response().status()); @@ -220,9 +219,9 @@ public class WebSocketClientExampleTest { CompletionStage connected = upgradeCompletion.thenApply(upgrade-> { - // just like a regular http request we can get 404 NotFound, - // with a response body, that will be available from upgrade.response - if (upgrade.response().status().equals(StatusCodes.OK)) { + // just like a regular http request we can access response status which is available via upgrade.response.status + // status code 101 (Switching Protocols) indicates that server support WebSockets + if (upgrade.response().status().equals(StatusCodes.SWITCHING_PROTOCOLS)) { return Done.getInstance(); } else { throw new RuntimeException(("Connection failed: " + upgrade.response().status())); diff --git a/akka-docs/rst/java/http/common/marshalling.rst b/akka-docs/rst/java/http/common/marshalling.rst index cf098e1b88..b3feb49fed 100644 --- a/akka-docs/rst/java/http/common/marshalling.rst +++ b/akka-docs/rst/java/http/common/marshalling.rst @@ -119,7 +119,7 @@ If, however, your marshaller also needs to set things like the response status c or any headers then a ``ToEntityMarshaller[T]`` won't work. You'll need to fall down to providing a ``ToResponseMarshaller[T]`` or a ``ToRequestMarshaller[T]`` directly. -For writing you own marshallers you won't have to "manually" implement the ``Marshaller`` trait directly. +For writing your own marshallers you won't have to "manually" implement the ``Marshaller`` trait directly. Rather, it should be possible to use one of the convenience construction helpers defined on the ``Marshaller`` companion: diff --git a/akka-docs/rst/java/http/common/unmarshalling.rst b/akka-docs/rst/java/http/common/unmarshalling.rst index 9aaea15c66..37979b5c91 100644 --- a/akka-docs/rst/java/http/common/unmarshalling.rst +++ b/akka-docs/rst/java/http/common/unmarshalling.rst @@ -77,7 +77,7 @@ Custom Unmarshallers Akka HTTP gives you a few convenience tools for constructing unmarshallers for your own types. Usually you won't have to "manually" implement the ``Unmarshaller`` trait directly. -Rather, it should be possible to use one of the convenience construction helpers defined on the ``Marshaller`` +Rather, it should be possible to use one of the convenience construction helpers defined on the ``Unmarshaller`` companion: TODO rewrite sample for Java diff --git a/akka-docs/rst/java/http/routing-dsl/index.rst b/akka-docs/rst/java/http/routing-dsl/index.rst index d5e754af0b..f84f20759f 100644 --- a/akka-docs/rst/java/http/routing-dsl/index.rst +++ b/akka-docs/rst/java/http/routing-dsl/index.rst @@ -32,7 +32,7 @@ Bind failures ^^^^^^^^^^^^^ For example the server might be unable to bind to the given port. For example when the port is already taken by another application, or if the port is privileged (i.e. only usable by ``root``). -In this case the "binding future" will fail immediatly, and we can react to if by listening on the CompletionStage's completion: +In this case the "binding future" will fail immediately, and we can react to if by listening on the CompletionStage's completion: .. includecode:: ../../code/docs/http/javadsl/server/HighLevelServerBindFailureExample.java :include: binding-failure-high-level-example diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/HttpClientExampleSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/HttpClientExampleSpec.scala index 8f13d319cb..85603e37ad 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/HttpClientExampleSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/HttpClientExampleSpec.scala @@ -5,36 +5,48 @@ package docs.http.scaladsl import akka.actor.{ ActorLogging, ActorSystem } -import akka.stream.{ ActorMaterializerSettings } import akka.util.ByteString +import docs.CompileOnlySpec import org.scalatest.{ Matchers, WordSpec } -class HttpClientExampleSpec extends WordSpec with Matchers { +class HttpClientExampleSpec extends WordSpec with Matchers with CompileOnlySpec { - "outgoing-connection-example" in { - pending // compile-time only test + "outgoing-connection-example" in compileOnlySpec { //#outgoing-connection-example + import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.stream.ActorMaterializer import akka.stream.scaladsl._ import scala.concurrent.Future + import scala.util.{ Failure, Success } - implicit val system = ActorSystem() - implicit val materializer = ActorMaterializer() + object WebClient { + def main(args: Array[String]): Unit = { + implicit val system = ActorSystem() + implicit val materializer = ActorMaterializer() + implicit val executionContext = system.dispatcher - val connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]] = - Http().outgoingConnection("akka.io") - val responseFuture: Future[HttpResponse] = - Source.single(HttpRequest(uri = "/")) - .via(connectionFlow) - .runWith(Sink.head) + val connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]] = + Http().outgoingConnection("akka.io") + val responseFuture: Future[HttpResponse] = + Source.single(HttpRequest(uri = "/")) + .via(connectionFlow) + .runWith(Sink.head) + + responseFuture.andThen { + case Success(_) => println("request succeded") + case Failure(_) => println("request failed") + }.andThen { + case _ => system.terminate() + } + } + } //#outgoing-connection-example } - "host-level-example" in { - pending // compile-time only test + "host-level-example" in compileOnlySpec { //#host-level-example import akka.http.scaladsl.Http import akka.http.scaladsl.model._ @@ -55,8 +67,7 @@ class HttpClientExampleSpec extends WordSpec with Matchers { //#host-level-example } - "single-request-example" in { - pending // compile-time only test + "single-request-example" in compileOnlySpec { //#single-request-example import akka.http.scaladsl.Http import akka.http.scaladsl.model._ @@ -72,8 +83,7 @@ class HttpClientExampleSpec extends WordSpec with Matchers { //#single-request-example } - "single-request-in-actor-example" in { - pending // compile-time only test + "single-request-in-actor-example" in compileOnlySpec { //#single-request-in-actor-example import akka.actor.Actor import akka.http.scaladsl.Http diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/HttpServerExampleSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/HttpServerExampleSpec.scala index 9514448a70..6d9e964297 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/HttpServerExampleSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/HttpServerExampleSpec.scala @@ -5,10 +5,6 @@ package docs.http.scaladsl import akka.event.LoggingAdapter -import akka.http.scaladsl.Http.ServerBinding -import akka.http.scaladsl.model._ -import akka.stream.ActorMaterializer -import akka.stream.scaladsl.{ Flow, Sink } import akka.testkit.TestActors import docs.CompileOnlySpec import org.scalatest.{ Matchers, WordSpec } @@ -44,37 +40,50 @@ class HttpServerExampleSpec extends WordSpec with Matchers "binding-failure-high-level-example" in compileOnlySpec { import akka.actor.ActorSystem import akka.http.scaladsl.Http + import akka.http.scaladsl.Http.ServerBinding import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer - implicit val system = ActorSystem() - implicit val materializer = ActorMaterializer() - // needed for the future onFailure in the end - implicit val executionContext = system.dispatcher + import scala.concurrent.Future - val handler = get { - complete("Hello world!") + object WebServer { + def main(args: Array[String]) { + implicit val system = ActorSystem() + implicit val materializer = ActorMaterializer() + // needed for the future onFailure in the end + implicit val executionContext = system.dispatcher + + val handler = get { + complete("Hello world!") + } + + // let's say the OS won't allow us to bind to 80. + val (host, port) = ("localhost", 80) + val bindingFuture: Future[ServerBinding] = + Http().bindAndHandle(handler, host, port) + + bindingFuture.onFailure { + case ex: Exception => + log.error(ex, "Failed to bind to {}:{}!", host, port) + } + } } - - // let's say the OS won't allow us to bind to 80. - val (host, port) = ("localhost", 80) - val bindingFuture: Future[ServerBinding] = - Http().bindAndHandle(handler, host, port) - - bindingFuture.onFailure { - case ex: Exception => - log.error(ex, "Failed to bind to {}:{}!", host, port) - } - } // mock values: - import akka.http.scaladsl.Http - import akka.actor.ActorSystem - val handleConnections: Sink[Http.IncomingConnection, Future[Http.ServerBinding]] = + val handleConnections = { + import akka.stream.scaladsl.Sink Sink.ignore.mapMaterializedValue(_ => Future.failed(new Exception(""))) + } "binding-failure-handling" in compileOnlySpec { + import akka.actor.ActorSystem + import akka.http.scaladsl.Http + import akka.http.scaladsl.Http.ServerBinding + import akka.stream.ActorMaterializer + + import scala.concurrent.Future + implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() // needed for the future onFailure in the end @@ -102,11 +111,8 @@ class HttpServerExampleSpec extends WordSpec with Matchers import akka.actor.ActorSystem import akka.actor.ActorRef import akka.http.scaladsl.Http - import akka.http.scaladsl.model.HttpEntity - import akka.http.scaladsl.model.ContentTypes - import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer - import scala.io.StdIn + import akka.stream.scaladsl.Flow implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() @@ -132,8 +138,9 @@ class HttpServerExampleSpec extends WordSpec with Matchers "connection-stream-failure-handling" in compileOnlySpec { import akka.actor.ActorSystem import akka.http.scaladsl.Http - import akka.http.scaladsl.model.{ ContentTypes, HttpEntity } + import akka.http.scaladsl.model._ import akka.stream.ActorMaterializer + import akka.stream.scaladsl.Flow implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() @@ -203,6 +210,7 @@ class HttpServerExampleSpec extends WordSpec with Matchers } "low-level-server-example" in compileOnlySpec { + import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.model.HttpMethods._ import akka.http.scaladsl.model._ @@ -286,7 +294,9 @@ class HttpServerExampleSpec extends WordSpec with Matchers } "minimal-routing-example" in compileOnlySpec { + import akka.actor.ActorSystem import akka.http.scaladsl.Http + import akka.http.scaladsl.model._ import akka.http.scaladsl.server.Directives._ import akka.stream.ActorMaterializer import scala.io.StdIn @@ -319,13 +329,14 @@ class HttpServerExampleSpec extends WordSpec with Matchers "long-routing-example" in compileOnlySpec { //#long-routing-example - import akka.actor.ActorRef + import akka.actor.{ActorRef, ActorSystem} import akka.http.scaladsl.coding.Deflate import akka.http.scaladsl.marshalling.ToResponseMarshaller import akka.http.scaladsl.model.StatusCodes.MovedPermanently import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller import akka.pattern.ask + import akka.stream.ActorMaterializer import akka.util.Timeout // types used by the API routes @@ -427,6 +438,7 @@ class HttpServerExampleSpec extends WordSpec with Matchers "stream random numbers" in compileOnlySpec { //#stream-random-numbers + import akka.actor.ActorSystem import akka.stream.scaladsl._ import akka.util.ByteString import akka.http.scaladsl.Http @@ -483,15 +495,15 @@ class HttpServerExampleSpec extends WordSpec with Matchers "interact with an actor" in compileOnlySpec { //#actor-interaction import akka.actor.ActorSystem - import akka.actor.Props - import scala.concurrent.duration._ - import akka.util.Timeout - import akka.pattern.ask - import akka.stream.ActorMaterializer import akka.http.scaladsl.Http + import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ + import akka.pattern.ask + import akka.stream.ActorMaterializer + import akka.util.Timeout import spray.json.DefaultJsonProtocol._ + import scala.concurrent.duration._ import scala.io.StdIn object WebServer { diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/HttpsExamplesSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/HttpsExamplesSpec.scala index ff30a2479c..64aeafa5e2 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/HttpsExamplesSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/HttpsExamplesSpec.scala @@ -9,13 +9,12 @@ import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import akka.util.ByteString import com.typesafe.sslconfig.akka.AkkaSSLConfig +import docs.CompileOnlySpec import org.scalatest.{ Matchers, WordSpec } -class HttpsExamplesSpec extends WordSpec with Matchers { - - "disable SNI for connection" in { - pending // compile-time only test +class HttpsExamplesSpec extends WordSpec with Matchers with CompileOnlySpec { + "disable SNI for connection" in compileOnlySpec { val unsafeHost = "example.com" //#disable-sni-connection implicit val system = ActorSystem() diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/SprayJsonExampleSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/SprayJsonExampleSpec.scala index fe5208a5f2..7da0505134 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/SprayJsonExampleSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/SprayJsonExampleSpec.scala @@ -8,8 +8,6 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import akka.http.scaladsl.server.Directives import org.scalatest.{ Matchers, WordSpec } -import scala.concurrent.Future - class SprayJsonExampleSpec extends WordSpec with Matchers { def compileOnlySpec(body: => Unit) = () @@ -53,6 +51,7 @@ class SprayJsonExampleSpec extends WordSpec with Matchers { "second-spray-json-example" in compileOnlySpec { //#second-spray-json-example import akka.actor.ActorSystem + import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import akka.Done import akka.http.scaladsl.server.Route @@ -61,6 +60,10 @@ class SprayJsonExampleSpec extends WordSpec with Matchers { import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import spray.json.DefaultJsonProtocol._ + import scala.io.StdIn + + import scala.concurrent.Future + object WebServer { // domain model @@ -80,6 +83,8 @@ class SprayJsonExampleSpec extends WordSpec with Matchers { // needed to run the route implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() + // needed for the future map/flatmap in the end + implicit val executionContext = system.dispatcher val route: Route = get { @@ -104,6 +109,13 @@ class SprayJsonExampleSpec extends WordSpec with Matchers { } } + val bindingFuture = Http().bindAndHandle(route, "localhost", 8080) + println(s"Server online at http://localhost:8080/\nPress RETURN to stop...") + StdIn.readLine() // let it run until user presses return + bindingFuture + .flatMap(_.unbind()) // trigger unbinding from the port + .onComplete(_ ⇒ system.terminate()) // and shutdown when done + } } //#second-spray-json-example diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/WebSocketClientExampleSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/WebSocketClientExampleSpec.scala index 67baf6628a..fdc88ff200 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/WebSocketClientExampleSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/WebSocketClientExampleSpec.scala @@ -3,17 +3,14 @@ */ package docs.http.scaladsl -import akka.actor.ActorSystem -import akka.http.scaladsl.model.headers.{ Authorization, BasicHttpCredentials } import docs.CompileOnlySpec import org.scalatest.{ Matchers, WordSpec } -import scala.concurrent.Promise - class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnlySpec { "singleWebSocket-request-example" in compileOnlySpec { //#single-WebSocket-request + import akka.actor.ActorSystem import akka.{ Done, NotUsed } import akka.http.scaladsl.Http import akka.stream.ActorMaterializer @@ -23,59 +20,60 @@ class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnly import scala.concurrent.Future - implicit val system = ActorSystem() - implicit val materializer = ActorMaterializer() - import system.dispatcher + object SingleWebSocketRequest { + def main(args: Array[String]) = { + implicit val system = ActorSystem() + implicit val materializer = ActorMaterializer() + import system.dispatcher - // print each incoming strict text message - val printSink: Sink[Message, Future[Done]] = - Sink.foreach { - case message: TextMessage.Strict => - println(message.text) - } + // print each incoming strict text message + val printSink: Sink[Message, Future[Done]] = + Sink.foreach { + case message: TextMessage.Strict => + println(message.text) + } - val helloSource: Source[Message, NotUsed] = - Source.single(TextMessage("hello world!")) + val helloSource: Source[Message, NotUsed] = + Source.single(TextMessage("hello world!")) - // the Future[Done] is the materialized value of Sink.foreach - // and it is completed when the stream completes - val flow: Flow[Message, Message, Future[Done]] = - Flow.fromSinkAndSourceMat(printSink, helloSource)(Keep.left) + // the Future[Done] is the materialized value of Sink.foreach + // and it is completed when the stream completes + val flow: Flow[Message, Message, Future[Done]] = + Flow.fromSinkAndSourceMat(printSink, helloSource)(Keep.left) - // upgradeResponse is a Future[WebSocketUpgradeResponse] that - // completes or fails when the connection succeeds or fails - // and closed is a Future[Done] representing the stream completion from above - val (upgradeResponse, closed) = - Http().singleWebSocketRequest(WebSocketRequest("ws://echo.websocket.org"), flow) + // upgradeResponse is a Future[WebSocketUpgradeResponse] that + // completes or fails when the connection succeeds or fails + // and closed is a Future[Done] representing the stream completion from above + val (upgradeResponse, closed) = + Http().singleWebSocketRequest(WebSocketRequest("ws://echo.websocket.org"), flow) - val connected = upgradeResponse.map { upgrade => - // just like a regular http request we can get 404 NotFound, - // with a response body, that will be available from upgrade.response - if (upgrade.response.status == StatusCodes.OK) { - Done - } else { - throw new RuntimeException(s"Connection failed: ${upgrade.response.status}") + val connected = upgradeResponse.map { upgrade => + // just like a regular http request we can access response status which is available via upgrade.response.status + // status code 101 (Switching Protocols) indicates that server support WebSockets + if (upgrade.response.status == StatusCodes.SwitchingProtocols) { + Done + } else { + throw new RuntimeException(s"Connection failed: ${upgrade.response.status}") + } + } + + // in a real application you would not side effect here + // and handle errors more carefully + connected.onComplete(println) + closed.foreach(_ => println("closed")) } } - - // in a real application you would not side effect here - // and handle errors more carefully - connected.onComplete(println) - closed.foreach(_ => println("closed")) - //#single-WebSocket-request } "half-closed-WebSocket-closing-example" in compileOnlySpec { + import akka.actor.ActorSystem import akka.{ Done, NotUsed } import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import akka.stream.scaladsl._ - import akka.http.scaladsl.model._ import akka.http.scaladsl.model.ws._ - import scala.concurrent.Future - implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() import system.dispatcher @@ -97,14 +95,13 @@ class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnly } "half-closed-WebSocket-working-example" in compileOnlySpec { - import akka.{ Done, NotUsed } + import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import akka.stream.scaladsl._ - import akka.http.scaladsl.model._ import akka.http.scaladsl.model.ws._ - import scala.concurrent.Future + import scala.concurrent.Promise implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() @@ -130,14 +127,14 @@ class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnly } "half-closed-WebSocket-finite-working-example" in compileOnlySpec { + import akka.actor.ActorSystem import akka.{ Done, NotUsed } import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import akka.stream.scaladsl._ - import akka.http.scaladsl.model._ import akka.http.scaladsl.model.ws._ - import scala.concurrent.Future + import scala.concurrent.Promise implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() @@ -163,11 +160,14 @@ class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnly } "authorized-singleWebSocket-request-example" in compileOnlySpec { + import akka.actor.ActorSystem import akka.NotUsed import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import akka.stream.scaladsl._ + import akka.http.scaladsl.model.headers.{ Authorization, BasicHttpCredentials } import akka.http.scaladsl.model.ws._ + implicit val system = ActorSystem() implicit val materializer = ActorMaterializer() import collection.immutable.Seq @@ -187,6 +187,7 @@ class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnly "WebSocketClient-flow-example" in compileOnlySpec { //#WebSocket-client-flow + import akka.actor.ActorSystem import akka.Done import akka.http.scaladsl.Http import akka.stream.ActorMaterializer @@ -196,48 +197,51 @@ class WebSocketClientExampleSpec extends WordSpec with Matchers with CompileOnly import scala.concurrent.Future - implicit val system = ActorSystem() - implicit val materializer = ActorMaterializer() - import system.dispatcher + object WebSocketClientFlow { + def main(args: Array[String]) = { + implicit val system = ActorSystem() + implicit val materializer = ActorMaterializer() + import system.dispatcher - // Future[Done] is the materialized value of Sink.foreach, - // emitted when the stream completes - val incoming: Sink[Message, Future[Done]] = - Sink.foreach[Message] { - case message: TextMessage.Strict => - println(message.text) - } + // Future[Done] is the materialized value of Sink.foreach, + // emitted when the stream completes + val incoming: Sink[Message, Future[Done]] = + Sink.foreach[Message] { + case message: TextMessage.Strict => + println(message.text) + } - // send this as a message over the WebSocket - val outgoing = Source.single(TextMessage("hello world!")) + // send this as a message over the WebSocket + val outgoing = Source.single(TextMessage("hello world!")) - // flow to use (note: not re-usable!) - val webSocketFlow = Http().webSocketClientFlow(WebSocketRequest("ws://echo.websocket.org")) + // flow to use (note: not re-usable!) + val webSocketFlow = Http().webSocketClientFlow(WebSocketRequest("ws://echo.websocket.org")) - // the materialized value is a tuple with - // upgradeResponse is a Future[WebSocketUpgradeResponse] that - // completes or fails when the connection succeeds or fails - // and closed is a Future[Done] with the stream completion from the incoming sink - val (upgradeResponse, closed) = - outgoing - .viaMat(webSocketFlow)(Keep.right) // keep the materialized Future[WebSocketUpgradeResponse] - .toMat(incoming)(Keep.both) // also keep the Future[Done] - .run() + // the materialized value is a tuple with + // upgradeResponse is a Future[WebSocketUpgradeResponse] that + // completes or fails when the connection succeeds or fails + // and closed is a Future[Done] with the stream completion from the incoming sink + val (upgradeResponse, closed) = + outgoing + .viaMat(webSocketFlow)(Keep.right) // keep the materialized Future[WebSocketUpgradeResponse] + .toMat(incoming)(Keep.both) // also keep the Future[Done] + .run() - // just like a regular http request we can get 404 NotFound etc. - // that will be available from upgrade.response - val connected = upgradeResponse.flatMap { upgrade => - if (upgrade.response.status == StatusCodes.OK) { - Future.successful(Done) - } else { - throw new RuntimeException(s"Connection failed: ${upgrade.response.status}") + // just like a regular http request we can access response status which is available via upgrade.response.status + // status code 101 (Switching Protocols) indicates that server support WebSockets + val connected = upgradeResponse.flatMap { upgrade => + if (upgrade.response.status == StatusCodes.SwitchingProtocols) { + Future.successful(Done) + } else { + throw new RuntimeException(s"Connection failed: ${upgrade.response.status}") + } + } + + // in a real application you would not side effect here + connected.onComplete(println) + closed.foreach(_ => println("closed")) } } - - // in a real application you would not side effect here - connected.onComplete(println) - closed.foreach(_ => println("closed")) - //#WebSocket-client-flow } diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/server/WebSocketExampleSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/server/WebSocketExampleSpec.scala index a1c4541ba0..fa552bea27 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/server/WebSocketExampleSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/server/WebSocketExampleSpec.scala @@ -6,11 +6,11 @@ package docs.http.scaladsl.server import akka.http.scaladsl.model.ws.BinaryMessage import akka.stream.scaladsl.Sink +import docs.CompileOnlySpec import org.scalatest.{ Matchers, WordSpec } -class WebSocketExampleSpec extends WordSpec with Matchers { - "core-example" in { - pending // compile-time only test +class WebSocketExampleSpec extends WordSpec with Matchers with CompileOnlySpec { + "core-example" in compileOnlySpec { //#websocket-example-using-core import akka.actor.ActorSystem import akka.stream.ActorMaterializer @@ -64,8 +64,7 @@ class WebSocketExampleSpec extends WordSpec with Matchers { .flatMap(_.unbind()) // trigger unbinding from the port .onComplete(_ => system.terminate()) // and shutdown when done } - "routing-example" in { - pending // compile-time only test + "routing-example" in compileOnlySpec { import akka.actor.ActorSystem import akka.stream.ActorMaterializer import akka.stream.scaladsl.{ Source, Flow } diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/TimeoutDirectivesExamplesSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/TimeoutDirectivesExamplesSpec.scala index f0bda7181a..3ea141bce4 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/TimeoutDirectivesExamplesSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/TimeoutDirectivesExamplesSpec.scala @@ -55,8 +55,6 @@ class TimeoutDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { } "allow mapping the response" in compileOnlySpec { - pending // compile only spec since requires actuall Http server to be run - //#withRequestTimeoutResponse val timeoutResponse = HttpResponse( StatusCodes.EnhanceYourCalm, diff --git a/akka-docs/rst/scala/http/common/marshalling.rst b/akka-docs/rst/scala/http/common/marshalling.rst index 487fe73e3b..c97867d637 100644 --- a/akka-docs/rst/scala/http/common/marshalling.rst +++ b/akka-docs/rst/scala/http/common/marshalling.rst @@ -118,7 +118,7 @@ If, however, your marshaller also needs to set things like the response status c or any headers then a ``ToEntityMarshaller[T]`` won't work. You'll need to fall down to providing a ``ToResponseMarshaller[T]`` or a ``ToRequestMarshaller[T]`` directly. -For writing you own marshallers you won't have to "manually" implement the ``Marshaller`` trait directly. +For writing your own marshallers you won't have to "manually" implement the ``Marshaller`` trait directly. Rather, it should be possible to use one of the convenience construction helpers defined on the ``Marshaller`` companion: diff --git a/akka-docs/rst/scala/http/common/unmarshalling.rst b/akka-docs/rst/scala/http/common/unmarshalling.rst index 9f6426335c..be1e772e84 100644 --- a/akka-docs/rst/scala/http/common/unmarshalling.rst +++ b/akka-docs/rst/scala/http/common/unmarshalling.rst @@ -76,7 +76,7 @@ Custom Unmarshallers Akka HTTP gives you a few convenience tools for constructing unmarshallers for your own types. Usually you won't have to "manually" implement the ``Unmarshaller`` trait directly. -Rather, it should be possible to use one of the convenience construction helpers defined on the ``Marshaller`` +Rather, it should be possible to use one of the convenience construction helpers defined on the ``Unmarshaller`` companion: .. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/unmarshalling/Unmarshaller.scala diff --git a/akka-docs/rst/scala/http/introduction.rst b/akka-docs/rst/scala/http/introduction.rst index 1c46f92c08..453720a88f 100644 --- a/akka-docs/rst/scala/http/introduction.rst +++ b/akka-docs/rst/scala/http/introduction.rst @@ -25,11 +25,14 @@ Akka HTTP was designed specifically as “not-a-framework”, not because we don Using Akka HTTP --------------- -Akka HTTP is provided in separate jar files, to use it make sure to include the following dependencies:: +Akka HTTP is provided in a separate jar file, to use it make sure to include the following dependency:: - "com.typesafe.akka" %% "akka-http-core" % "@version@" @crossString@ "com.typesafe.akka" %% "akka-http-experimental" % "@version@" @crossString@ +Mind that ``akka-http`` comes in two modules: ``akka-http-experimental`` and ``akka-http-core``. Because ``akka-http-experimental`` +depends on ``akka-http-core`` you don't need to bring the latter explicitly. Still you may need to this in case you rely +solely on low-level API. + Routing DSL for HTTP servers ---------------------------- diff --git a/akka-docs/rst/scala/http/routing-dsl/index.rst b/akka-docs/rst/scala/http/routing-dsl/index.rst index 3795d5acbe..10073cd27c 100644 --- a/akka-docs/rst/scala/http/routing-dsl/index.rst +++ b/akka-docs/rst/scala/http/routing-dsl/index.rst @@ -58,7 +58,7 @@ Bind failures ^^^^^^^^^^^^^ For example the server might be unable to bind to the given port. For example when the port is already taken by another application, or if the port is privileged (i.e. only usable by ``root``). -In this case the "binding future" will fail immediatly, and we can react to if by listening on the Future's completion: +In this case the "binding future" will fail immediately, and we can react to if by listening on the Future's completion: .. includecode2:: ../../code/docs/http/scaladsl/HttpServerExampleSpec.scala :snippet: binding-failure-high-level-example