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 cats.syntax.option._
import com.softwaremill.sttp.{SttpBackend, Uri, sttp} import com.softwaremill.sttp.{SttpBackend, Uri, sttp}
import hackhack.ipfs.{IpfsError, IpfsStore} 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 io.circe.parser.parse
import scodec.bits.ByteVector import scodec.bits.ByteVector
@ -32,12 +33,23 @@ case class Peer(
val RpcUri = Uri(host, rpcPort) val RpcUri = Uri(host, rpcPort)
} }
object Peer {
implicit val encodePeer: Encoder[Peer] = deriveEncoder
implicit val decodePeer: Decoder[Peer] = deriveDecoder
}
case class App(name: String, case class App(name: String,
containerId: String, containerId: String,
peer: Peer, peer: Peer,
binaryHash: ByteVector, binaryHash: ByteVector,
binaryPath: Path) 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]( class AppRegistry[F[_]: Monad: Concurrent: ContextShift: Timer: LiftIO](
ipfsStore: IpfsStore[F], ipfsStore: IpfsStore[F],
runner: Runner[F], runner: Runner[F],
@ -138,6 +150,20 @@ class AppRegistry[F[_]: Monad: Concurrent: ContextShift: Timer: LiftIO](
_ <- EitherT.liftF(deferred.complete(app)) _ <- EitherT.liftF(deferred.complete(app))
} yield status.sync_info.latest_block_height } 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 log(str: String) = EitherT(IO(println(str)).attempt.to[F])
private def getApp(name: String): F[Either[Throwable, App]] = 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 { apps <- Try {
ids.zip(names).zip(envMap).map { ids.zip(names).zip(envMap).map {
case ((id, name), env) => case ((id, name), env) =>
val rpcPort = env("RPCPORT").toShort
val peer = env val peer = env
.get("PEER") .get("PEER")
.map(_.split(Array('@', ':'))) .map(_.split(Array('@', ':')))
.map(a => Peer(a(1), a(2).toShort)) .map(a => Peer(a(1), rpcPort))
.get .get
val binaryHash = ByteVector.fromValidHex(env("BINARY_HASH")) val binaryHash = ByteVector.fromValidHex(env("BINARY_HASH"))
val binaryPath = Paths.get(env("BINARY_PATH")) val binaryPath = Paths.get(env("BINARY_PATH"))

View File

@ -6,6 +6,7 @@ import cats.syntax.applicativeError._
import cats.syntax.flatMap._ import cats.syntax.flatMap._
import fs2.Stream import fs2.Stream
import fs2.concurrent.SignallingRef import fs2.concurrent.SignallingRef
import io.circe.JsonLong
import io.circe.syntax._ import io.circe.syntax._
import org.http4s.HttpRoutes import org.http4s.HttpRoutes
import org.http4s.dsl.Http4sDsl import org.http4s.dsl.Http4sDsl
@ -56,6 +57,24 @@ case class WebsocketServer[F[_]: ConcurrentEffect: Timer: ContextShift](
""".stripMargin) """.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 // TODO: list of registered apps
} }