2015-05-11 23:05:18 +02:00
|
|
|
/*
|
2016-02-23 12:58:39 +01:00
|
|
|
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
|
2015-05-11 23:05:18 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package docs.http.scaladsl
|
|
|
|
|
|
2016-07-08 14:47:29 +02:00
|
|
|
import akka.Done
|
2015-09-30 12:07:03 +02:00
|
|
|
import akka.actor.{ ActorLogging, ActorSystem }
|
2016-07-08 14:47:29 +02:00
|
|
|
import akka.http.scaladsl.model.HttpEntity.Strict
|
|
|
|
|
import akka.http.scaladsl.model.HttpMessage.DiscardedEntity
|
|
|
|
|
import akka.stream.{ IOResult, Materializer }
|
|
|
|
|
import akka.stream.scaladsl.{ Framing, Sink }
|
2015-09-30 12:07:03 +02:00
|
|
|
import akka.util.ByteString
|
2016-06-07 00:17:23 +02:00
|
|
|
import docs.CompileOnlySpec
|
2015-05-11 23:05:18 +02:00
|
|
|
import org.scalatest.{ Matchers, WordSpec }
|
|
|
|
|
|
2016-07-08 14:47:29 +02:00
|
|
|
import scala.concurrent.{ ExecutionContextExecutor, Future }
|
|
|
|
|
|
2016-06-07 00:17:23 +02:00
|
|
|
class HttpClientExampleSpec extends WordSpec with Matchers with CompileOnlySpec {
|
2015-05-11 23:05:18 +02:00
|
|
|
|
2016-07-08 14:47:29 +02:00
|
|
|
"manual-entity-consume-example-1" in compileOnlySpec {
|
|
|
|
|
//#manual-entity-consume-example-1
|
|
|
|
|
import java.io.File
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.stream.scaladsl.Framing
|
|
|
|
|
import akka.stream.scaladsl.FileIO
|
|
|
|
|
import akka.http.scaladsl.model._
|
|
|
|
|
|
|
|
|
|
implicit val system = ActorSystem()
|
|
|
|
|
implicit val dispatcher = system.dispatcher
|
|
|
|
|
implicit val materializer = ActorMaterializer()
|
|
|
|
|
|
|
|
|
|
val response: HttpResponse = ???
|
|
|
|
|
|
|
|
|
|
response.entity.dataBytes
|
|
|
|
|
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 256))
|
|
|
|
|
.map(transformEachLine)
|
|
|
|
|
.runWith(FileIO.toPath(new File("/tmp/example.out").toPath))
|
|
|
|
|
|
|
|
|
|
def transformEachLine(line: ByteString): ByteString = ???
|
|
|
|
|
|
|
|
|
|
//#manual-entity-consume-example-1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"manual-entity-consume-example-2" in compileOnlySpec {
|
|
|
|
|
//#manual-entity-consume-example-2
|
|
|
|
|
import java.io.File
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.http.scaladsl.model._
|
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
|
|
|
|
|
implicit val system = ActorSystem()
|
|
|
|
|
implicit val dispatcher = system.dispatcher
|
|
|
|
|
implicit val materializer = ActorMaterializer()
|
|
|
|
|
|
|
|
|
|
case class ExamplePerson(name: String)
|
|
|
|
|
def parse(line: ByteString): ExamplePerson = ???
|
|
|
|
|
|
|
|
|
|
val response: HttpResponse = ???
|
|
|
|
|
|
|
|
|
|
// toStrict to enforce all data be loaded into memory from the connection
|
|
|
|
|
val strictEntity: Future[HttpEntity.Strict] = response.entity.toStrict(3.seconds)
|
|
|
|
|
|
|
|
|
|
// while API remains the same to consume dataBytes, now they're in memory already:
|
|
|
|
|
val transformedData: Future[ExamplePerson] =
|
|
|
|
|
strictEntity flatMap { e =>
|
|
|
|
|
e.dataBytes
|
|
|
|
|
.runFold(ByteString.empty) { case (acc, b) => acc ++ b }
|
|
|
|
|
.map(parse)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#manual-entity-consume-example-2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"manual-entity-discard-example-1" in compileOnlySpec {
|
|
|
|
|
//#manual-entity-discard-example-1
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.http.scaladsl.model._
|
|
|
|
|
|
|
|
|
|
implicit val system = ActorSystem()
|
|
|
|
|
implicit val dispatcher = system.dispatcher
|
|
|
|
|
implicit val materializer = ActorMaterializer()
|
|
|
|
|
|
|
|
|
|
val response1: HttpResponse = ??? // obtained from an HTTP call (see examples below)
|
|
|
|
|
|
|
|
|
|
val discarded: DiscardedEntity = response1.discardEntityBytes()
|
|
|
|
|
discarded.future.onComplete { case done => println("Entity discarded completely!") }
|
|
|
|
|
|
|
|
|
|
//#manual-entity-discard-example-1
|
|
|
|
|
}
|
|
|
|
|
"manual-entity-discard-example-2" in compileOnlySpec {
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.http.scaladsl.model._
|
|
|
|
|
|
|
|
|
|
implicit val system = ActorSystem()
|
|
|
|
|
implicit val dispatcher = system.dispatcher
|
|
|
|
|
implicit val materializer = ActorMaterializer()
|
|
|
|
|
|
|
|
|
|
//#manual-entity-discard-example-2
|
|
|
|
|
val response1: HttpResponse = ??? // obtained from an HTTP call (see examples below)
|
|
|
|
|
|
|
|
|
|
val discardingComplete: Future[Done] = response1.entity.dataBytes.runWith(Sink.ignore)
|
|
|
|
|
discardingComplete.onComplete { case done => println("Entity discarded completely!") }
|
|
|
|
|
//#manual-entity-discard-example-2
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-07 00:17:23 +02:00
|
|
|
"outgoing-connection-example" in compileOnlySpec {
|
2015-05-11 23:05:18 +02:00
|
|
|
//#outgoing-connection-example
|
2016-06-07 00:17:23 +02:00
|
|
|
import akka.actor.ActorSystem
|
2015-09-30 12:07:03 +02:00
|
|
|
import akka.http.scaladsl.Http
|
|
|
|
|
import akka.http.scaladsl.model._
|
2015-06-23 18:28:53 +02:00
|
|
|
import akka.stream.ActorMaterializer
|
2015-05-11 23:05:18 +02:00
|
|
|
import akka.stream.scaladsl._
|
2015-09-30 12:07:03 +02:00
|
|
|
|
|
|
|
|
import scala.concurrent.Future
|
2016-06-07 00:17:23 +02:00
|
|
|
import scala.util.{ Failure, Success }
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
responseFuture.andThen {
|
|
|
|
|
case Success(_) => println("request succeded")
|
|
|
|
|
case Failure(_) => println("request failed")
|
|
|
|
|
}.andThen {
|
|
|
|
|
case _ => system.terminate()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-05-11 23:05:18 +02:00
|
|
|
//#outgoing-connection-example
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-07 00:17:23 +02:00
|
|
|
"host-level-example" in compileOnlySpec {
|
2015-05-11 23:05:18 +02:00
|
|
|
//#host-level-example
|
2015-09-30 12:07:03 +02:00
|
|
|
import akka.http.scaladsl.Http
|
|
|
|
|
import akka.http.scaladsl.model._
|
2015-06-23 18:28:53 +02:00
|
|
|
import akka.stream.ActorMaterializer
|
2015-05-11 23:05:18 +02:00
|
|
|
import akka.stream.scaladsl._
|
2015-09-30 12:07:03 +02:00
|
|
|
|
|
|
|
|
import scala.concurrent.Future
|
|
|
|
|
import scala.util.Try
|
2015-05-11 23:05:18 +02:00
|
|
|
|
|
|
|
|
implicit val system = ActorSystem()
|
2015-06-23 18:28:53 +02:00
|
|
|
implicit val materializer = ActorMaterializer()
|
2015-05-11 23:05:18 +02:00
|
|
|
// construct a pool client flow with context type `Int`
|
2015-06-18 16:30:03 +02:00
|
|
|
val poolClientFlow = Http().cachedHostConnectionPool[Int]("akka.io")
|
2015-05-11 23:05:18 +02:00
|
|
|
val responseFuture: Future[(Try[HttpResponse], Int)] =
|
|
|
|
|
Source.single(HttpRequest(uri = "/") -> 42)
|
|
|
|
|
.via(poolClientFlow)
|
|
|
|
|
.runWith(Sink.head)
|
|
|
|
|
//#host-level-example
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-07 00:17:23 +02:00
|
|
|
"single-request-example" in compileOnlySpec {
|
2015-05-11 23:05:18 +02:00
|
|
|
//#single-request-example
|
|
|
|
|
import akka.http.scaladsl.Http
|
2015-09-30 12:07:03 +02:00
|
|
|
import akka.http.scaladsl.model._
|
|
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
|
|
|
|
|
import scala.concurrent.Future
|
2016-07-08 14:47:29 +02:00
|
|
|
import scala.util.{ Failure, Success }
|
2015-05-11 23:05:18 +02:00
|
|
|
|
|
|
|
|
implicit val system = ActorSystem()
|
2015-06-23 18:28:53 +02:00
|
|
|
implicit val materializer = ActorMaterializer()
|
2015-05-11 23:05:18 +02:00
|
|
|
|
|
|
|
|
val responseFuture: Future[HttpResponse] =
|
|
|
|
|
Http().singleRequest(HttpRequest(uri = "http://akka.io"))
|
|
|
|
|
//#single-request-example
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-07 00:17:23 +02:00
|
|
|
"single-request-in-actor-example" in compileOnlySpec {
|
2015-09-30 12:07:03 +02:00
|
|
|
//#single-request-in-actor-example
|
|
|
|
|
import akka.actor.Actor
|
|
|
|
|
import akka.http.scaladsl.Http
|
|
|
|
|
import akka.http.scaladsl.model._
|
2016-01-13 13:32:42 +01:00
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.stream.ActorMaterializerSettings
|
2015-09-30 12:07:03 +02:00
|
|
|
|
|
|
|
|
class Myself extends Actor
|
|
|
|
|
with ActorLogging {
|
|
|
|
|
|
|
|
|
|
import akka.pattern.pipe
|
|
|
|
|
import context.dispatcher
|
|
|
|
|
|
2016-01-13 13:32:42 +01:00
|
|
|
final implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system))
|
|
|
|
|
|
2015-09-30 12:07:03 +02:00
|
|
|
val http = Http(context.system)
|
|
|
|
|
|
|
|
|
|
override def preStart() = {
|
|
|
|
|
http.singleRequest(HttpRequest(uri = "http://akka.io"))
|
|
|
|
|
.pipeTo(self)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def receive = {
|
|
|
|
|
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
|
|
|
|
|
log.info("Got response, body: " + entity.dataBytes.runFold(ByteString(""))(_ ++ _))
|
|
|
|
|
case HttpResponse(code, _, _, _) =>
|
|
|
|
|
log.info("Request failed, response code: " + code)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//#single-request-in-actor-example
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 23:05:18 +02:00
|
|
|
}
|