Merge pull request #11493 from aron-2809/bbb-core-http-endpoint-wip

WIP: Http endpoint added for health check
This commit is contained in:
Anton Georgiev 2021-02-26 12:44:04 -05:00 committed by GitHub
commit d20479d7c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 103 additions and 3 deletions

8
akka-bbb-apps/project/Dependencies.scala Normal file → Executable file
View File

@ -14,6 +14,7 @@ object Dependencies {
// Libraries // Libraries
val akkaVersion = "2.5.19" val akkaVersion = "2.5.19"
val akkaHttpVersion = "10.1.4"
val gson = "2.8.5" val gson = "2.8.5"
val jackson = "2.9.7" val jackson = "2.9.7"
val logback = "1.2.3" val logback = "1.2.3"
@ -47,6 +48,10 @@ object Dependencies {
val commonsCodec = "commons-codec" % "commons-codec" % Versions.codec val commonsCodec = "commons-codec" % "commons-codec" % Versions.codec
val sprayJson = "io.spray" % "spray-json_2.12" % Versions.spray val sprayJson = "io.spray" % "spray-json_2.12" % Versions.spray
val akkaStream = "com.typesafe.akka" %% "akka-stream" % Versions.akkaVersion
val akkaHttp = "com.typesafe.akka" %% "akka-http" % Versions.akkaHttpVersion
val akkaHttpSprayJson = "com.typesafe.akka" %% "akka-http-spray-json" % Versions.akkaHttpVersion
val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang
val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons excludeAll ( val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons excludeAll (
@ -73,6 +78,7 @@ object Dependencies {
Compile.scalaCompiler, Compile.scalaCompiler,
Compile.akkaActor, Compile.akkaActor,
Compile.akkaSl4fj, Compile.akkaSl4fj,
Compile.akkaStream,
Compile.googleGson, Compile.googleGson,
Compile.jacksonModule, Compile.jacksonModule,
Compile.quicklens, Compile.quicklens,
@ -80,5 +86,7 @@ object Dependencies {
Compile.commonsCodec, Compile.commonsCodec,
Compile.sprayJson, Compile.sprayJson,
Compile.apacheLang, Compile.apacheLang,
Compile.akkaHttp,
Compile.akkaHttpSprayJson,
Compile.bbbCommons) ++ testing Compile.bbbCommons) ++ testing
} }

View File

@ -0,0 +1,31 @@
package org.bigbluebutton
import akka.http.scaladsl.model._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.Directives._
import org.bigbluebutton.service.HealthzService
import spray.json.DefaultJsonProtocol
case class HealthResponse(isHealthy: Boolean)
trait JsonSupportProtocol extends SprayJsonSupport with DefaultJsonProtocol {
implicit val healthServiceJsonFormat = jsonFormat1(HealthResponse)
}
class ApiService(healthz: HealthzService) extends JsonSupportProtocol {
def routes =
path("healthz") {
get {
val future = healthz.getHealthz()
onSuccess(future) {
case response =>
if (response.isHealthy) {
complete(StatusCodes.OK, HealthResponse(response.isHealthy))
} else {
complete(StatusCodes.ServiceUnavailable, HealthResponse(response.isHealthy))
}
}
}
}
}

View File

@ -1,5 +1,9 @@
package org.bigbluebutton package org.bigbluebutton
import akka.actor.ActorSystem
import akka.event.Logging
import akka.http.scaladsl.Http
import akka.stream.ActorMaterializer
import org.bigbluebutton.common2.redis.{ MessageSender, RedisConfig, RedisPublisher } import org.bigbluebutton.common2.redis.{ MessageSender, RedisConfig, RedisPublisher }
import org.bigbluebutton.core._ import org.bigbluebutton.core._
import org.bigbluebutton.core.bus._ import org.bigbluebutton.core.bus._
@ -8,13 +12,13 @@ import org.bigbluebutton.core2.AnalyticsActor
import org.bigbluebutton.core2.FromAkkaAppsMsgSenderActor import org.bigbluebutton.core2.FromAkkaAppsMsgSenderActor
import org.bigbluebutton.endpoint.redis.AppsRedisSubscriberActor import org.bigbluebutton.endpoint.redis.AppsRedisSubscriberActor
import org.bigbluebutton.endpoint.redis.RedisRecorderActor import org.bigbluebutton.endpoint.redis.RedisRecorderActor
import akka.actor.ActorSystem
import akka.event.Logging
import org.bigbluebutton.common2.bus.IncomingJsonMessageBus import org.bigbluebutton.common2.bus.IncomingJsonMessageBus
import org.bigbluebutton.service.HealthzService
object Boot extends App with SystemConfiguration { object Boot extends App with SystemConfiguration {
implicit val system = ActorSystem("bigbluebutton-apps-system") implicit val system = ActorSystem("bigbluebutton-apps-system")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executor = system.dispatcher implicit val executor = system.dispatcher
val logger = Logging(system, getClass) val logger = Logging(system, getClass)
@ -75,4 +79,10 @@ object Boot extends App with SystemConfiguration {
), ),
"redis-subscriber" "redis-subscriber"
) )
val healthz = HealthzService(system)
val apiService = new ApiService(healthz)
val bindingFuture = Http().bindAndHandle(apiService.routes, httpHost, httpPort)
} }

View File

@ -75,4 +75,8 @@ trait SystemConfiguration {
lazy val toAkkaTranscodeJsonChannel = Try(config.getString("eventBus.toAkkaTranscodeJsonChannel")).getOrElse("to-akka-transcode-json-channel") lazy val toAkkaTranscodeJsonChannel = Try(config.getString("eventBus.toAkkaTranscodeJsonChannel")).getOrElse("to-akka-transcode-json-channel")
lazy val fromAkkaTranscodeJsonChannel = Try(config.getString("eventBus.fromAkkaTranscodeJsonChannel")).getOrElse("from-akka-transcode-json-channel") lazy val fromAkkaTranscodeJsonChannel = Try(config.getString("eventBus.fromAkkaTranscodeJsonChannel")).getOrElse("from-akka-transcode-json-channel")
// Grab the "interface" parameter from the http config
val httpHost = config.getString("http.interface")
// Grab the "port" parameter from the http config
val httpPort = config.getInt("http.port")
} }

View File

@ -0,0 +1,45 @@
package org.bigbluebutton.service
import akka.actor.{ Actor, ActorLogging, ActorSystem, Props }
import akka.util.Timeout
import scala.concurrent.Future
import scala.concurrent.duration.DurationInt
import akka.pattern.{ AskTimeoutException, ask }
sealed trait HealthMessage
case object GetHealthMessage extends HealthMessage
case class GetHealthResponseMessage(isHealthy: Boolean) extends HealthMessage
object HealthzService {
def apply(system: ActorSystem) = new HealthzService(system)
}
class HealthzService(system: ActorSystem) {
implicit def executionContext = system.dispatcher
implicit val timeout: Timeout = 2 seconds
val actorRef = system.actorOf(HealthzActor.props())
def getHealthz(): Future[GetHealthResponseMessage] = {
val future = actorRef.ask(GetHealthMessage).mapTo[GetHealthResponseMessage]
future.recover {
case e: AskTimeoutException => {
GetHealthResponseMessage(isHealthy = false)
}
}
}
}
object HealthzActor {
def props(): Props = Props(classOf[HealthzActor])
}
class HealthzActor extends Actor with ActorLogging {
override def receive: Receive = {
case GetHealthMessage => sender ! GetHealthResponseMessage(isHealthy = true)
case _ => println("unexpected message, exception could be raised")
}
}

View File

@ -61,7 +61,9 @@ eventBus {
http { http {
interface = "127.0.0.1" interface = "127.0.0.1"
port = 9999 interface = ${?INTERFACE}
port = 8901
port = ${?PORT}
} }
services { services {