2018-03-13 23:45:55 +09:00
|
|
|
/*
|
2019-01-02 18:55:26 +08:00
|
|
|
* Copyright (C) 2018-2019 Lightbend Inc. <https://www.lightbend.com>
|
2018-03-13 23:45:55 +09:00
|
|
|
*/
|
|
|
|
|
|
2014-12-08 17:29:40 +01:00
|
|
|
package docs.stream.cookbook
|
|
|
|
|
|
|
|
|
|
import scala.concurrent.Await
|
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
|
|
|
|
|
class RecipeDigest extends RecipeSpec {
|
|
|
|
|
|
|
|
|
|
"Recipe for calculating digest" must {
|
|
|
|
|
|
|
|
|
|
"work" in {
|
|
|
|
|
|
|
|
|
|
//#calculating-digest
|
2018-03-03 08:22:46 +01:00
|
|
|
import java.security.MessageDigest
|
|
|
|
|
|
|
|
|
|
import akka.NotUsed
|
2019-03-11 10:38:24 +01:00
|
|
|
import akka.stream.{ Attributes, FlowShape, Inlet, Outlet }
|
2018-03-03 08:22:46 +01:00
|
|
|
import akka.stream.scaladsl.{ Sink, Source }
|
|
|
|
|
import akka.util.ByteString
|
|
|
|
|
|
2014-12-08 17:29:40 +01:00
|
|
|
import akka.stream.stage._
|
2018-03-03 08:22:46 +01:00
|
|
|
|
|
|
|
|
val data: Source[ByteString, NotUsed] = Source.single(ByteString("abc"))
|
|
|
|
|
|
2016-02-11 16:39:25 +01:00
|
|
|
class DigestCalculator(algorithm: String) extends GraphStage[FlowShape[ByteString, ByteString]] {
|
|
|
|
|
val in = Inlet[ByteString]("DigestCalculator.in")
|
|
|
|
|
val out = Outlet[ByteString]("DigestCalculator.out")
|
2018-03-03 08:22:46 +01:00
|
|
|
override val shape = FlowShape(in, out)
|
2016-02-11 16:39:25 +01:00
|
|
|
|
|
|
|
|
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) {
|
2018-03-03 08:22:46 +01:00
|
|
|
private val digest = MessageDigest.getInstance(algorithm)
|
2016-02-11 16:39:25 +01:00
|
|
|
|
|
|
|
|
setHandler(out, new OutHandler {
|
2018-03-03 08:22:46 +01:00
|
|
|
override def onPull(): Unit = pull(in)
|
2016-02-11 16:39:25 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
setHandler(in, new InHandler {
|
2018-03-03 08:22:46 +01:00
|
|
|
override def onPush(): Unit = {
|
2016-02-11 16:39:25 +01:00
|
|
|
val chunk = grab(in)
|
|
|
|
|
digest.update(chunk.toArray)
|
|
|
|
|
pull(in)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override def onUpstreamFinish(): Unit = {
|
|
|
|
|
emit(out, ByteString(digest.digest()))
|
|
|
|
|
completeStage()
|
|
|
|
|
}
|
|
|
|
|
})
|
2014-12-08 17:29:40 +01:00
|
|
|
}
|
|
|
|
|
}
|
2018-03-03 08:22:46 +01:00
|
|
|
|
2016-02-11 16:39:25 +01:00
|
|
|
val digest: Source[ByteString, NotUsed] = data.via(new DigestCalculator("SHA-256"))
|
2014-12-08 17:29:40 +01:00
|
|
|
//#calculating-digest
|
|
|
|
|
|
2015-03-05 12:21:17 +01:00
|
|
|
Await.result(digest.runWith(Sink.head), 3.seconds) should be(
|
2019-03-11 10:38:24 +01:00
|
|
|
ByteString(0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0,
|
|
|
|
|
0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad))
|
2014-12-08 17:29:40 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|