This commit is contained in:
folex 2019-06-16 08:14:43 +02:00
parent d5caf69dfd
commit 1055669d75
3 changed files with 48 additions and 2 deletions

View File

@ -18,7 +18,8 @@ import cats.syntax.either._
import cats.syntax.option._
import com.softwaremill.sttp.{SttpBackend, Uri, sttp}
import hackhack.ipfs.{IpfsError, IpfsStore}
import io.circe.Json
import io.circe.{Decoder, Encoder, Json, ObjectEncoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.parser.parse
import scodec.bits.ByteVector
@ -32,12 +33,23 @@ case class Peer(
val RpcUri = Uri(host, rpcPort)
}
object Peer {
implicit val encodePeer: Encoder[Peer] = deriveEncoder
implicit val decodePeer: Decoder[Peer] = deriveDecoder
}
case class App(name: String,
containerId: String,
peer: Peer,
binaryHash: ByteVector,
binaryPath: Path)
object App {
private implicit val encbc: Encoder[ByteVector] = Encoder.encodeString.contramap(_.toHex)
private implicit val encPath: Encoder[Path] = Encoder.encodeString.contramap(_.toString)
implicit val encodeApp: ObjectEncoder[App] = deriveEncoder
}
class AppRegistry[F[_]: Monad: Concurrent: ContextShift: Timer: LiftIO](
ipfsStore: IpfsStore[F],
runner: Runner[F],
@ -138,6 +150,20 @@ class AppRegistry[F[_]: Monad: Concurrent: ContextShift: Timer: LiftIO](
_ <- EitherT.liftF(deferred.complete(app))
} yield status.sync_info.latest_block_height
def getAllApps: EitherT[F, Throwable, List[(App, Long)]] = {
for {
appList <- EitherT.right(
apps.get.flatMap(map =>
Traverse[List].sequence(map.values.map(_.get).toList))
)
statuses <- Traverse[List].sequence(appList.map(app =>
status(app.name, app.peer)))
} yield
appList.zip(statuses).map {
case (app, status) => (app, status.sync_info.latest_block_height)
}
}
private def log(str: String) = EitherT(IO(println(str)).attempt.to[F])
private def getApp(name: String): F[Either[Throwable, App]] =

View File

@ -117,10 +117,11 @@ case class Runner[F[_]: Monad: LiftIO: ContextShift: Defer: Concurrent](
apps <- Try {
ids.zip(names).zip(envMap).map {
case ((id, name), env) =>
val rpcPort = env("RPCPORT").toShort
val peer = env
.get("PEER")
.map(_.split(Array('@', ':')))
.map(a => Peer(a(1), a(2).toShort))
.map(a => Peer(a(1), rpcPort))
.get
val binaryHash = ByteVector.fromValidHex(env("BINARY_HASH"))
val binaryPath = Paths.get(env("BINARY_PATH"))

View File

@ -6,6 +6,7 @@ import cats.syntax.applicativeError._
import cats.syntax.flatMap._
import fs2.Stream
import fs2.concurrent.SignallingRef
import io.circe.JsonLong
import io.circe.syntax._
import org.http4s.HttpRoutes
import org.http4s.dsl.Http4sDsl
@ -56,6 +57,24 @@ case class WebsocketServer[F[_]: ConcurrentEffect: Timer: ContextShift](
""".stripMargin)
}
case GET -> Root / "apps" =>
(for {
apps <- appRegistry.getAllApps
json = apps
.map {
case (app, height) =>
app.asJsonObject
.add("consensusHeight", height.asJson)
.toMap
.asJson
}
.asJson
.spaces2
} yield json).value.flatMap {
case Left(e) => InternalServerError(s"Error on /apps: $e")
case Right(json) => Ok(json)
}
// TODO: list of registered apps
}