summaryrefslogtreecommitdiff
path: root/crashbox-server/src/main/scala/io/crashbox/ci/HttpApi.scala
diff options
context:
space:
mode:
Diffstat (limited to 'crashbox-server/src/main/scala/io/crashbox/ci/HttpApi.scala')
-rw-r--r--crashbox-server/src/main/scala/io/crashbox/ci/HttpApi.scala76
1 files changed, 76 insertions, 0 deletions
diff --git a/crashbox-server/src/main/scala/io/crashbox/ci/HttpApi.scala b/crashbox-server/src/main/scala/io/crashbox/ci/HttpApi.scala
new file mode 100644
index 0000000..22feba5
--- /dev/null
+++ b/crashbox-server/src/main/scala/io/crashbox/ci/HttpApi.scala
@@ -0,0 +1,76 @@
+package io.crashbox.ci
+
+import akka.actor.ActorSystem
+import akka.http.scaladsl.Http
+import akka.http.scaladsl.marshalling.Marshaller
+import akka.http.scaladsl.marshalling.ToResponseMarshaller
+import akka.http.scaladsl.model.{
+ ContentType,
+ ContentTypes,
+ HttpEntity,
+ MediaTypes
+}
+import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
+import akka.http.scaladsl.model.HttpResponse
+import akka.http.scaladsl.model.ws.TextMessage
+import akka.http.scaladsl.server.directives.Credentials
+import akka.stream.scaladsl.{Flow, Keep, Sink}
+import akka.stream.{ActorMaterializer, OverflowStrategy}
+import akka.stream.scaladsl.{Source => Src}
+import java.net.URL
+import java.security.MessageDigest
+import java.text.SimpleDateFormat
+import java.util.Date
+import scala.util.{Failure, Success}
+import akka.http.scaladsl.server._
+import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
+import Directives._
+import SprayJsonSupport._
+import spray.json.{DefaultJsonProtocol, JsObject, JsString, JsValue}
+
+trait HttpApi { self: Core with Schedulers with StreamStore =>
+
+ val endpoint = "api"
+
+ case class Request(url: String) {
+ def buildId: String = {
+ val bytes = MessageDigest.getInstance("SHA-256").digest(url.getBytes)
+ bytes.map { byte =>
+ Integer.toString((byte & 0xff) + 0x100, 16)
+ }.mkString
+ }
+ }
+
+ object Protocol extends DefaultJsonProtocol {
+ implicit val request = jsonFormat1(Request)
+ }
+ import Protocol._
+
+ implicit val toResponseMarshaller: ToResponseMarshaller[Src[BuildState, Any]] =
+ Marshaller.opaque { items =>
+ val data = items.map(item => ChunkStreamPart(item.toString + "\n"))
+ HttpResponse(
+ entity = HttpEntity.Chunked(ContentTypes.`text/plain(UTF-8)`, data))
+ }
+
+ def httpApi: Route = pathPrefix(endpoint) {
+ path("submit") {
+ entity(as[Request]) { req =>
+ val source = Src
+ .queue[BuildState](100, OverflowStrategy.fail)
+ .mapMaterializedValue { q =>
+ start(
+ req.buildId,
+ new URL(req.url),
+ () => saveStream(req.buildId),
+ state => q.offer(state)
+ )
+ }
+
+ complete(source)
+ }
+
+ }
+ }
+
+}