+htc #18027 add the missing javadsl.clientLayer and serverLayer
This commit is contained in:
parent
e14773c3d9
commit
8ef7c64886
7 changed files with 110 additions and 10 deletions
|
|
@ -62,7 +62,19 @@ as a more general purpose streaming infrastructure feature.
|
|||
However, akka-stream should soon provide such a feature.
|
||||
|
||||
|
||||
.. _http-client-layer-java:
|
||||
|
||||
Stand-Alone HTTP Layer Usage
|
||||
----------------------------
|
||||
|
||||
// TODO
|
||||
Due to its Reactive-Streams-based nature the Akka HTTP layer is fully detachable from the underlying TCP
|
||||
interface. While in most applications this "feature" will not be crucial it can be useful in certain cases to be able
|
||||
to "run" the HTTP layer (and, potentially, higher-layers) against data that do not come from the network but rather
|
||||
some other source. Potential scenarios where this might be useful include tests, debugging or low-level event-sourcing
|
||||
(e.g by replaying network traffic).
|
||||
|
||||
On the client-side the stand-alone HTTP layer forms a ``BidiFlow<HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, BoxedUnit>``,
|
||||
that is a stage that "upgrades" a potentially encrypted raw connection to the HTTP level.
|
||||
|
||||
You create an instance of the layer by calling one of the two overloads of the ``Http.get(system).clientLayer`` method,
|
||||
which also allows for varying degrees of configuration.
|
||||
|
|
@ -154,7 +154,15 @@ If defined encryption is enabled on all accepted connections. Otherwise it is di
|
|||
Stand-Alone HTTP Layer Usage
|
||||
----------------------------
|
||||
|
||||
It is currently only possible to use the HTTP server layer with Scala in a stand-alone fashion.
|
||||
See :ref:`http-server-layer-scala` and `#18027`_ for the plan to add Java support.
|
||||
Due to its Reactive-Streams-based nature the Akka HTTP layer is fully detachable from the underlying TCP
|
||||
interface. While in most applications this "feature" will not be crucial it can be useful in certain cases to be able
|
||||
to "run" the HTTP layer (and, potentially, higher-layers) against data that do not come from the network but rather
|
||||
some other source. Potential scenarios where this might be useful include tests, debugging or low-level event-sourcing
|
||||
(e.g by replaying network traffic).
|
||||
|
||||
.. _`#18027`: https://github.com/akka/akka/issues/18027
|
||||
On the server-side the stand-alone HTTP layer forms a ``BidiFlow<HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, BoxedUnit>``,
|
||||
that is a stage that "upgrades" a potentially encrypted raw connection to the HTTP level.
|
||||
|
||||
You create an instance of the layer by calling one of the two overloads of the ``Http.get(system).serverLayer`` method,
|
||||
which also allows for varying degrees of configuration. Note, that the returned instance is not reusable and can only
|
||||
be materialized once.
|
||||
|
|
@ -67,7 +67,7 @@ However, akka-stream should soon provide such a feature.
|
|||
Stand-Alone HTTP Layer Usage
|
||||
----------------------------
|
||||
|
||||
Due to its Reactive-Stream-based nature the Akka HTTP layer is fully detachable from the underlying TCP
|
||||
Due to its Reactive-Streams-based nature the Akka HTTP layer is fully detachable from the underlying TCP
|
||||
interface. While in most applications this "feature" will not be crucial it can be useful in certain cases to be able
|
||||
to "run" the HTTP layer (and, potentially, higher-layers) against data that do not come from the network but rather
|
||||
some other source. Potential scenarios where this might be useful include tests, debugging or low-level event-sourcing
|
||||
|
|
|
|||
|
|
@ -155,13 +155,13 @@ If defined encryption is enabled on all accepted connections. Otherwise it is di
|
|||
Stand-Alone HTTP Layer Usage
|
||||
----------------------------
|
||||
|
||||
Due to its Reactive-Stream-based nature the Akka HTTP layer is fully detachable from the underlying TCP
|
||||
Due to its Reactive-Streams-based nature the Akka HTTP layer is fully detachable from the underlying TCP
|
||||
interface. While in most applications this "feature" will not be crucial it can be useful in certain cases to be able
|
||||
to "run" the HTTP layer (and, potentially, higher-layers) against data that do not come from the network but rather
|
||||
some other source. Potential scenarios where this might be useful include tests, debugging or low-level event-sourcing
|
||||
(e.g by replaying network traffic).
|
||||
|
||||
On the server-side the stand-alone HTTP layer forms a ``BidiStage`` that is defined like this:
|
||||
On the server-side the stand-alone HTTP layer forms a ``BidiFlow`` that is defined like this:
|
||||
|
||||
.. includecode2:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala
|
||||
:snippet: server-layer
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ private[http] object JavaMapping {
|
|||
}
|
||||
}
|
||||
|
||||
/** This trivial mapping isn't enabled by default to prevent it from conflicting with the `Inherited ones `*/
|
||||
/** This trivial mapping isn't enabled by default to prevent it from conflicting with the `Inherited` ones `*/
|
||||
def identity[T]: JavaMapping[T, T] =
|
||||
new JavaMapping[T, T] {
|
||||
def toJava(scalaObject: T): J = scalaObject
|
||||
|
|
@ -117,6 +117,14 @@ private[http] object JavaMapping {
|
|||
scaladsl.Flow[JIn].map(inMapping.toScala(_)).viaMat(scalaObject)(scaladsl.Keep.right).map(outMapping.toJava(_))
|
||||
}
|
||||
}
|
||||
|
||||
def scalaToJavaAdapterFlow[J, S](implicit mapping: JavaMapping[J, S]): scaladsl.Flow[S, J, Unit] =
|
||||
scaladsl.Flow[S].map(mapping.toJava(_))
|
||||
def javaToScalaAdapterFlow[J, S](implicit mapping: JavaMapping[J, S]): scaladsl.Flow[J, S, Unit] =
|
||||
scaladsl.Flow[J].map(mapping.toScala(_))
|
||||
def adapterBidiFlow[JIn, SIn, SOut, JOut](implicit inMapping: JavaMapping[JIn, SIn], outMapping: JavaMapping[JOut, SOut]): scaladsl.BidiFlow[JIn, SIn, SOut, JOut, Unit] =
|
||||
scaladsl.BidiFlow.wrap(javaToScalaAdapterFlow(inMapping), scalaToJavaAdapterFlow(outMapping))(scaladsl.Keep.none)
|
||||
|
||||
implicit def pairMapping[J1, J2, S1, S2](implicit _1Mapping: JavaMapping[J1, S1], _2Mapping: JavaMapping[J2, S2]): JavaMapping[Pair[J1, J2], (S1, S2)] =
|
||||
new JavaMapping[Pair[J1, J2], (S1, S2)] {
|
||||
def toJava(scalaObject: (S1, S2)): J = Pair(_1Mapping.toJava(scalaObject._1), _2Mapping.toJava(scalaObject._2))
|
||||
|
|
@ -165,6 +173,8 @@ private[http] object JavaMapping {
|
|||
implicit object RemoteAddress extends Inherited[jm.RemoteAddress, sm.RemoteAddress]
|
||||
implicit object TransferEncoding extends Inherited[jm.TransferEncoding, sm.TransferEncoding]
|
||||
|
||||
implicit object HostHeader extends Inherited[jm.headers.Host, sm.headers.Host]
|
||||
|
||||
implicit object ByteRange extends Inherited[jm.headers.ByteRange, sm.headers.ByteRange]
|
||||
implicit object CacheDirective extends Inherited[jm.headers.CacheDirective, sm.headers.CacheDirective]
|
||||
implicit object ContentDispositionType extends Inherited[jm.headers.ContentDispositionType, sm.headers.ContentDispositionType]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package akka.http.javadsl
|
|||
import java.lang.{ Iterable ⇒ JIterable }
|
||||
import java.net.InetSocketAddress
|
||||
import akka.http.impl.util.JavaMapping
|
||||
import akka.stream.io.{ SslTlsInbound, SslTlsOutbound }
|
||||
|
||||
import scala.language.implicitConversions
|
||||
import scala.concurrent.Future
|
||||
|
|
@ -17,7 +18,8 @@ import akka.actor.{ ExtendedActorSystem, ActorSystem, ExtensionIdProvider, Exten
|
|||
import akka.event.LoggingAdapter
|
||||
import akka.io.Inet
|
||||
import akka.stream.Materializer
|
||||
import akka.stream.javadsl.{ Flow, Source }
|
||||
import akka.stream.javadsl.{ BidiFlow, Flow, Source }
|
||||
|
||||
import akka.http.impl.util.JavaMapping.Implicits._
|
||||
import akka.http.scaladsl.{ model ⇒ sm }
|
||||
import akka.http.javadsl.model._
|
||||
|
|
@ -37,6 +39,42 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
private implicit def convertHttpsContext(hctx: Option[HttpsContext]) =
|
||||
hctx.map(_.asInstanceOf[akka.http.scaladsl.HttpsContext])
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the configured default [[ServerSettings]]. The returned [[BidiFlow]] isn't
|
||||
* reusable and can only be materialized once.
|
||||
*/
|
||||
def serverLayer(materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, Unit] =
|
||||
adaptServerLayer(delegate.serverLayer()(materializer))
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* can only be materialized once.
|
||||
*/
|
||||
def serverLayer(settings: ServerSettings,
|
||||
materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, Unit] =
|
||||
adaptServerLayer(delegate.serverLayer(settings)(materializer))
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* can only be materialized once. The `remoteAddress`, if provided, will be added as a header to each [[HttpRequest]]
|
||||
* this layer produces if the `akka.http.server.remote-address-header` configuration option is enabled.
|
||||
*/
|
||||
def serverLayer(settings: ServerSettings,
|
||||
remoteAddress: Option[InetSocketAddress],
|
||||
materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, Unit] =
|
||||
adaptServerLayer(delegate.serverLayer(settings, remoteAddress.asScala)(materializer))
|
||||
|
||||
/**
|
||||
* Constructs a server layer stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* can only be materialized once. The remoteAddress, if provided, will be added as a header to each [[HttpRequest]]
|
||||
* this layer produces if the `akka.http.server.remote-address-header` configuration option is enabled.
|
||||
*/
|
||||
def serverLayer(settings: ServerSettings,
|
||||
remoteAddress: Option[InetSocketAddress],
|
||||
log: LoggingAdapter,
|
||||
materializer: Materializer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, Unit] =
|
||||
adaptServerLayer(delegate.serverLayer(settings, remoteAddress.asScala, log)(materializer))
|
||||
|
||||
/**
|
||||
* Creates a [[Source]] of [[IncomingConnection]] instances which represents a prospective HTTP server binding
|
||||
* on the given `endpoint`.
|
||||
|
|
@ -167,6 +205,27 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
interface, port, settings, httpsContext, parallelism, log)(materializer)
|
||||
.map(new ServerBinding(_))(ec)
|
||||
|
||||
/**
|
||||
* Constructs a client layer stage using the configured default [[ClientConnectionSettings]].
|
||||
*/
|
||||
def clientLayer(hostHeader: headers.Host): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, Unit] =
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader)))
|
||||
|
||||
/**
|
||||
* Constructs a client layer stage using the given [[ClientConnectionSettings]].
|
||||
*/
|
||||
def clientLayer(hostHeader: headers.Host,
|
||||
settings: ClientConnectionSettings): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, Unit] =
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader), settings))
|
||||
|
||||
/**
|
||||
* Constructs a client layer stage using the given [[ClientConnectionSettings]].
|
||||
*/
|
||||
def clientLayer(hostHeader: headers.Host,
|
||||
settings: ClientConnectionSettings,
|
||||
log: LoggingAdapter): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, Unit] =
|
||||
adaptClientLayer(delegate.clientLayer(JavaMapping.toScala(hostHeader), settings, log))
|
||||
|
||||
/**
|
||||
* Creates a [[Flow]] representing a prospective HTTP client connection to the given endpoint.
|
||||
* Every materialization of the produced flow will attempt to establish a new outgoing connection.
|
||||
|
|
@ -468,4 +527,14 @@ class Http(system: ExtendedActorSystem) extends akka.actor.Extension {
|
|||
implicit val _ = JavaMapping.identity[T]
|
||||
JavaMapping.toJava(scalaFlow)(JavaMapping.flowMapping[Pair[HttpRequest, T], (scaladsl.model.HttpRequest, T), Pair[Try[HttpResponse], T], (Try[scaladsl.model.HttpResponse], T), Mat])
|
||||
}
|
||||
|
||||
private def adaptServerLayer(serverLayer: scaladsl.Http.ServerLayer): BidiFlow[HttpResponse, SslTlsOutbound, SslTlsInbound, HttpRequest, Unit] =
|
||||
new BidiFlow(
|
||||
JavaMapping.adapterBidiFlow[HttpResponse, sm.HttpResponse, sm.HttpRequest, HttpRequest]
|
||||
.atop(serverLayer))
|
||||
|
||||
private def adaptClientLayer(clientLayer: scaladsl.Http.ClientLayer): BidiFlow[HttpRequest, SslTlsOutbound, SslTlsInbound, HttpResponse, Unit] =
|
||||
new BidiFlow(
|
||||
JavaMapping.adapterBidiFlow[HttpRequest, sm.HttpRequest, sm.HttpResponse, HttpResponse]
|
||||
.atop(clientLayer))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,8 @@ class HttpExt(config: Config)(implicit system: ActorSystem) extends akka.actor.E
|
|||
|
||||
/**
|
||||
* Constructs a [[ServerLayer]] stage using the given [[ServerSettings]]. The returned [[BidiFlow]] isn't reusable and
|
||||
* can only be materialized once.
|
||||
* can only be materialized once. The `remoteAddress`, if provided, will be added as a header to each [[HttpRequest]]
|
||||
* this layer produces if the `akka.http.server.remote-address-header` configuration option is enabled.
|
||||
*/
|
||||
def serverLayer(settings: ServerSettings,
|
||||
remoteAddress: Option[InetSocketAddress] = None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue