Merge pull request #11493 from aron-2809/bbb-core-http-endpoint-wip
WIP: Http endpoint added for health check
This commit is contained in:
commit
d20479d7c4
8
akka-bbb-apps/project/Dependencies.scala
Normal file → Executable file
8
akka-bbb-apps/project/Dependencies.scala
Normal file → Executable 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
|
||||||
}
|
}
|
31
akka-bbb-apps/src/main/scala/org/bigbluebutton/ApiService.scala
Executable file
31
akka-bbb-apps/src/main/scala/org/bigbluebutton/ApiService.scala
Executable 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
45
akka-bbb-apps/src/main/scala/org/bigbluebutton/service/HealthzService.scala
Executable file
45
akka-bbb-apps/src/main/scala/org/bigbluebutton/service/HealthzService.scala
Executable 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")
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user