=str #21753 simplify TLSActor configuration by allowing to specify SSLEngine directly (#21822)

Do all (Akka)SSLConfig magic in one place directly in the TLS API.

Also, introduce new low-level entrypoint in TLS that allows to specify
an SSLEngine constructor directly without relying on SSLContext. This
allows users to use third-party SSLEngine implementations like netty's
OpenSslEngine together with akka-stream.
This commit is contained in:
Johannes Rudolph 2016-11-17 16:07:24 +01:00 committed by Konrad Malawski
parent 97bada7deb
commit b4cfc3717f
4 changed files with 151 additions and 110 deletions

View file

@ -1,27 +1,28 @@
package akka.stream.impl.io
import javax.net.ssl.SSLContext
import javax.net.ssl.{ SSLContext, SSLEngine, SSLSession }
import akka.actor.ActorSystem
import akka.stream._
import akka.stream.impl.StreamLayout.{ CompositeModule, AtomicModule }
import akka.stream.impl.StreamLayout.{ AtomicModule, CompositeModule }
import akka.stream.TLSProtocol._
import akka.util.ByteString
import com.typesafe.sslconfig.akka.AkkaSSLConfig
import scala.util.Try
/**
* INTERNAL API.
*/
final case class TlsModule(plainIn: Inlet[SslTlsOutbound], plainOut: Outlet[SslTlsInbound],
cipherIn: Inlet[ByteString], cipherOut: Outlet[ByteString],
shape: Shape, attributes: Attributes,
sslContext: SSLContext,
sslConfig: Option[AkkaSSLConfig],
firstSession: NegotiateNewSession,
role: TLSRole, closing: TLSClosing, hostInfo: Option[(String, Int)]) extends AtomicModule {
private[stream] final case class TlsModule(plainIn: Inlet[SslTlsOutbound], plainOut: Outlet[SslTlsInbound],
cipherIn: Inlet[ByteString], cipherOut: Outlet[ByteString],
shape: Shape, attributes: Attributes,
createSSLEngine: ActorSystem SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
verifySession: (ActorSystem, SSLSession) Try[Unit], // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
closing: TLSClosing) extends AtomicModule {
override def withAttributes(att: Attributes): TlsModule = copy(attributes = att)
override def carbonCopy: TlsModule =
TlsModule(attributes, sslContext, sslConfig, firstSession, role, closing, hostInfo)
override def carbonCopy: TlsModule = TlsModule(attributes, createSSLEngine, verifySession, closing)
override def replaceShape(s: Shape) =
if (s != shape) {
@ -29,20 +30,24 @@ final case class TlsModule(plainIn: Inlet[SslTlsOutbound], plainOut: Outlet[SslT
CompositeModule(this, s)
} else this
override def toString: String = f"TlsModule($firstSession, $role, $closing, $hostInfo) [${System.identityHashCode(this)}%08x]"
override def toString: String = f"TlsModule($closing) [${System.identityHashCode(this)}%08x]"
}
/**
* INTERNAL API.
*/
object TlsModule {
def apply(attributes: Attributes, sslContext: SSLContext, sslConfig: Option[AkkaSSLConfig], firstSession: NegotiateNewSession, role: TLSRole, closing: TLSClosing, hostInfo: Option[(String, Int)]): TlsModule = {
val name = attributes.nameOrDefault(s"StreamTls($role)")
private[stream] object TlsModule {
def apply(
attributes: Attributes,
createSSLEngine: ActorSystem SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
verifySession: (ActorSystem, SSLSession) Try[Unit], // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
closing: TLSClosing): TlsModule = {
val name = attributes.nameOrDefault(s"StreamTls()")
val cipherIn = Inlet[ByteString](s"$name.cipherIn")
val cipherOut = Outlet[ByteString](s"$name.cipherOut")
val plainIn = Inlet[SslTlsOutbound](s"$name.transportIn")
val plainOut = Outlet[SslTlsInbound](s"$name.transportOut")
val shape = new BidiShape(plainIn, cipherOut, cipherIn, plainOut)
TlsModule(plainIn, plainOut, cipherIn, cipherOut, shape, attributes, sslContext, sslConfig, firstSession, role, closing, hostInfo)
TlsModule(plainIn, plainOut, cipherIn, cipherOut, shape, attributes, createSSLEngine, verifySession, closing)
}
}