Redis refactoring : remove duplicate classes, factorisation and build configuration update.

This commit is contained in:
Ghazi Triki 2018-11-09 20:08:20 +01:00
parent 6b1fa41777
commit fc4028d6de
60 changed files with 360 additions and 542 deletions

View File

@ -75,3 +75,5 @@ daemonGroup in Linux := group
mappings in(Universal, packageBin) += file("src/main/resources/application.conf") -> "conf/application.conf" mappings in(Universal, packageBin) += file("src/main/resources/application.conf") -> "conf/application.conf"
mappings in(Universal, packageBin) += file("src/main/resources/logback.xml") -> "conf/logback.xml" mappings in(Universal, packageBin) += file("src/main/resources/logback.xml") -> "conf/logback.xml"
debianPackageDependencies in Debian ++= Seq("java8-runtime-headless", "bash")

View File

@ -1,12 +1,18 @@
package org.bigbluebutton package org.bigbluebutton
import akka.event.Logging import org.bigbluebutton.common2.redis.RedisPublisher
import akka.actor.ActorSystem
import org.bigbluebutton.endpoint.redis.{ AppsRedisSubscriberActor, KeepAliveRedisPublisher, RedisPublisher, RedisRecorderActor }
import org.bigbluebutton.core._ import org.bigbluebutton.core._
import org.bigbluebutton.core.bus._ import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.pubsub.senders.ReceivedJsonMsgHandlerActor import org.bigbluebutton.core.pubsub.senders.ReceivedJsonMsgHandlerActor
import org.bigbluebutton.core2.{ AnalyticsActor, FromAkkaAppsMsgSenderActor } import org.bigbluebutton.core2.AnalyticsActor
import org.bigbluebutton.core2.FromAkkaAppsMsgSenderActor
import org.bigbluebutton.endpoint.redis.AppsRedisSubscriberActor
import org.bigbluebutton.endpoint.redis.RedisRecorderActor
import akka.actor.ActorSystem
import akka.event.Logging
import org.bigbluebutton.common2.redis.MessageSender
import org.bigbluebutton.common2.bus.IncomingJsonMessageBus
object Boot extends App with SystemConfiguration { object Boot extends App with SystemConfiguration {
@ -22,7 +28,7 @@ object Boot extends App with SystemConfiguration {
val outGW = new OutMessageGatewayImp(outBus2) val outGW = new OutMessageGatewayImp(outBus2)
val redisPublisher = new RedisPublisher(system) val redisPublisher = new RedisPublisher(system, "BbbAppsAkkaPub")
val msgSender = new MessageSender(redisPublisher) val msgSender = new MessageSender(redisPublisher)
val redisRecorderActor = system.actorOf(RedisRecorderActor.props(system), "redisRecorderActor") val redisRecorderActor = system.actorOf(RedisRecorderActor.props(system), "redisRecorderActor")
@ -47,7 +53,4 @@ object Boot extends App with SystemConfiguration {
incomingJsonMessageBus.subscribe(redisMessageHandlerActor, toAkkaAppsJsonChannel) incomingJsonMessageBus.subscribe(redisMessageHandlerActor, toAkkaAppsJsonChannel)
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(incomingJsonMessageBus), "redis-subscriber") val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(incomingJsonMessageBus), "redis-subscriber")
val keepAliveRedisPublisher = new KeepAliveRedisPublisher(system, redisPublisher)
} }

View File

@ -1,15 +1,10 @@
package org.bigbluebutton package org.bigbluebutton
import com.typesafe.config.ConfigFactory
import scala.util.Try import scala.util.Try
trait SystemConfiguration { import org.bigbluebutton.common2.redis.RedisConfiguration
val config = ConfigFactory.load() trait SystemConfiguration extends RedisConfiguration {
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
lazy val bbbWebHost = Try(config.getString("services.bbbWebHost")).getOrElse("localhost") lazy val bbbWebHost = Try(config.getString("services.bbbWebHost")).getOrElse("localhost")
lazy val bbbWebPort = Try(config.getInt("services.bbbWebPort")).getOrElse(8888) lazy val bbbWebPort = Try(config.getInt("services.bbbWebPort")).getOrElse(8888)
@ -31,8 +26,6 @@ trait SystemConfiguration {
lazy val outBbbMsgMsgChannel = Try(config.getString("eventBus.outBbbMsgMsgChannel")).getOrElse("OutBbbMsgChannel") lazy val outBbbMsgMsgChannel = Try(config.getString("eventBus.outBbbMsgMsgChannel")).getOrElse("OutBbbMsgChannel")
lazy val recordServiceMessageChannel = Try(config.getString("eventBus.recordServiceMessageChannel")).getOrElse("RecordServiceMessageChannel") lazy val recordServiceMessageChannel = Try(config.getString("eventBus.recordServiceMessageChannel")).getOrElse("RecordServiceMessageChannel")
lazy val toAkkaAppsRedisChannel = Try(config.getString("redis.toAkkaAppsRedisChannel")).getOrElse("to-akka-apps-redis-channel")
lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel")
lazy val toHTML5RedisChannel = Try(config.getString("redis.toHTML5RedisChannel")).getOrElse("to-html5-redis-channel") lazy val toHTML5RedisChannel = Try(config.getString("redis.toHTML5RedisChannel")).getOrElse("to-html5-redis-channel")
lazy val fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-channel") lazy val fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-channel")
lazy val toAkkaAppsChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-channel") lazy val toAkkaAppsChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-channel")
@ -41,21 +34,9 @@ trait SystemConfiguration {
lazy val toAkkaAppsJsonChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-json-channel") lazy val toAkkaAppsJsonChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-json-channel")
lazy val fromAkkaAppsJsonChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-json-channel") lazy val fromAkkaAppsJsonChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-json-channel")
lazy val toVoiceConfRedisChannel = Try(config.getString("redis.toVoiceConfRedisChannel")).getOrElse("to-voice-conf-redis-channel")
lazy val fromVoiceConfRedisChannel = Try(config.getString("redis.fromVoiceConfRedisChannel")).getOrElse("from-voice-conf-redis-channel")
lazy val fromAkkaAppsWbRedisChannel = Try(config.getString("redis.fromAkkaAppsWbRedisChannel")).getOrElse("from-akka-apps-wb-redis-channel")
lazy val fromAkkaAppsChatRedisChannel = Try(config.getString("redis.fromAkkaAppsChatRedisChannel")).getOrElse("from-akka-apps-chat-redis-channel")
lazy val fromAkkaAppsPresRedisChannel = Try(config.getString("redis.fromAkkaAppsPresRedisChannel")).getOrElse("from-akka-apps-pres-redis-channel")
lazy val maxNumberOfNotes = Try(config.getInt("sharedNotes.maxNumberOfNotes")).getOrElse(3) lazy val maxNumberOfNotes = Try(config.getInt("sharedNotes.maxNumberOfNotes")).getOrElse(3)
lazy val maxNumberOfUndos = Try(config.getInt("sharedNotes.maxNumberOfUndos")).getOrElse(30) lazy val maxNumberOfUndos = Try(config.getInt("sharedNotes.maxNumberOfUndos")).getOrElse(30)
lazy val httpInterface = Try(config.getString("http.interface")).getOrElse("")
lazy val httpPort = Try(config.getInt("http.port")).getOrElse(9090)
lazy val telizeHost = Try(config.getString("services.telizeHost")).getOrElse("")
lazy val telizePort = Try(config.getInt("services.telizePort")).getOrElse(80)
lazy val applyPermissionCheck = Try(config.getBoolean("apps.checkPermissions")).getOrElse(false) lazy val applyPermissionCheck = Try(config.getBoolean("apps.checkPermissions")).getOrElse(false)
lazy val voiceConfRecordPath = Try(config.getString("voiceConf.recordPath")).getOrElse("/var/freeswitch/meetings") lazy val voiceConfRecordPath = Try(config.getString("voiceConf.recordPath")).getOrElse("/var/freeswitch/meetings")

View File

@ -1,10 +0,0 @@
package org.bigbluebutton.core
import org.bigbluebutton.endpoint.redis.RedisPublisher
class MessageSender(publisher: RedisPublisher) {
def send(channel: String, data: String) {
publisher.publish(channel, data)
}
}

View File

@ -6,7 +6,9 @@ import com.fasterxml.jackson.databind.JsonNode
import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.bus._ import org.bigbluebutton.core.bus._
import org.bigbluebutton.core2.ReceivedMessageRouter import org.bigbluebutton.core2.ReceivedMessageRouter
import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._
import org.bigbluebutton.common2.bus.ReceivedJsonMessage
import org.bigbluebutton.common2.bus.IncomingJsonMessageBus
object ReceivedJsonMsgHandlerActor { object ReceivedJsonMsgHandlerActor {
def props(eventBus: BbbMsgRouterEventBus, incomingJsonMessageBus: IncomingJsonMessageBus): Props = def props(eventBus: BbbMsgRouterEventBus, incomingJsonMessageBus: IncomingJsonMessageBus): Props =

View File

@ -3,8 +3,8 @@ package org.bigbluebutton.core2
import akka.actor.{ Actor, ActorLogging, Props } import akka.actor.{ Actor, ActorLogging, Props }
import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.util.JsonUtil import org.bigbluebutton.common2.util.JsonUtil
import org.bigbluebutton.core.MessageSender import org.bigbluebutton.common2.redis.MessageSender
object FromAkkaAppsMsgSenderActor { object FromAkkaAppsMsgSenderActor {
def props(msgSender: MessageSender): Props = Props(classOf[FromAkkaAppsMsgSenderActor], msgSender) def props(msgSender: MessageSender): Props = Props(classOf[FromAkkaAppsMsgSenderActor], msgSender)

View File

@ -1,22 +1,27 @@
package org.bigbluebutton.endpoint.redis package org.bigbluebutton.endpoint.redis
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import java.io.{ PrintWriter, StringWriter }
import java.net.InetSocketAddress import java.net.InetSocketAddress
import redis.actors.RedisSubscriberActor
import redis.api.pubsub.{ Message, PMessage }
import scala.concurrent.duration._
import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.core.bus.{ IncomingJsonMessage, IncomingJsonMessageBus, ReceivedJsonMessage } import org.bigbluebutton.common2.bus.IncomingJsonMessage
import org.bigbluebutton.common2.bus.IncomingJsonMessageBus
import org.bigbluebutton.common2.bus.ReceivedJsonMessage
import org.bigbluebutton.common2.redis.RedisAppSubscriberActor
import org.bigbluebutton.common2.redis.RedisConfiguration
import org.bigbluebutton.common2.redis.RedisSubscriber
import akka.actor.Props
import redis.actors.RedisSubscriberActor
import redis.api.pubsub.Message
import redis.api.servers.ClientSetname import redis.api.servers.ClientSetname
import java.io.StringWriter
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import scala.concurrent.duration.DurationInt
import java.io.PrintWriter
object AppsRedisSubscriberActor extends SystemConfiguration { object AppsRedisSubscriberActor extends RedisSubscriber with RedisConfiguration {
val TO_AKKA_APPS = "bbb:to-akka-apps"
val channels = Seq(toAkkaAppsRedisChannel, fromVoiceConfRedisChannel) val channels = Seq(toAkkaAppsRedisChannel, fromVoiceConfRedisChannel)
val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*", "bigbluebutton:from-bbb-transcode:*") val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*", "bigbluebutton:from-bbb-transcode:*")
@ -29,9 +34,11 @@ object AppsRedisSubscriberActor extends SystemConfiguration {
class AppsRedisSubscriberActor(jsonMsgBus: IncomingJsonMessageBus, redisHost: String, class AppsRedisSubscriberActor(jsonMsgBus: IncomingJsonMessageBus, redisHost: String,
redisPort: Int, redisPort: Int,
channels: Seq[String] = Nil, patterns: Seq[String] = Nil) channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
extends RedisSubscriberActor( extends RedisSubscriberActor(
new InetSocketAddress(redisHost, redisPort), new InetSocketAddress(redisHost, redisPort),
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") })
with SystemConfiguration
with RedisAppSubscriberActor {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => { case e: Exception => {
@ -55,10 +62,4 @@ class AppsRedisSubscriberActor(jsonMsgBus: IncomingJsonMessageBus, redisHost: St
} }
} }
def onPMessage(pmessage: PMessage) {
// We don't use PSubscribe anymore, but an implementation of the method is required
//log.error("Should not be receiving a PMessage. It triggered on a match of pattern: " + pmessage.patternMatched)
//log.error(pmessage.data.utf8String)
}
} }

View File

@ -1,16 +0,0 @@
package org.bigbluebutton.endpoint.redis
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import akka.actor.ActorSystem
import org.bigbluebutton.SystemConfiguration
class KeepAliveRedisPublisher(val system: ActorSystem, sender: RedisPublisher) extends SystemConfiguration {
val startedOn = System.currentTimeMillis()
system.scheduler.schedule(2 seconds, 5 seconds) {
//val msg = new BbbAppsIsAliveMessage(startedOn, System.currentTimeMillis())
// sender.publish("bigbluebutton:from-bbb-apps:keepalive", msg.toJson())
}
}

View File

@ -1,21 +0,0 @@
package org.bigbluebutton.endpoint.redis
import redis.RedisClient
import akka.actor.ActorSystem
import org.bigbluebutton.SystemConfiguration
import akka.util.ByteString
class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
val redis = RedisClient(redisHost, redisPort)(system)
// Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli
redis.clientSetname("BbbAppsAkkaPub")
def publish(channel: String, data: String) {
//println("PUBLISH TO [" + channel + "]: \n [" + data + "]")
redis.publish(channel, ByteString(data))
}
}

View File

@ -14,8 +14,8 @@ object RedisRecorderActor {
} }
class RedisRecorderActor(val system: ActorSystem) class RedisRecorderActor(val system: ActorSystem)
extends SystemConfiguration extends SystemConfiguration
with Actor with ActorLogging { with Actor with ActorLogging {
val redis = RedisClient(redisHost, redisPort)(system) val redis = RedisClient(redisHost, redisPort)(system)
// Set the name of this client to be able to distinguish when doing // Set the name of this client to be able to distinguish when doing

View File

@ -9,7 +9,7 @@ import org.mockito.Mockito._
import org.scalatest.mockito.MockitoSugar import org.scalatest.mockito.MockitoSugar
class ReceivedJsonMsgHandlerTraitTests extends UnitSpec class ReceivedJsonMsgHandlerTraitTests extends UnitSpec
with AppsTestFixtures with MockitoSugar with SystemConfiguration { with AppsTestFixtures with MockitoSugar with SystemConfiguration {
class MessageRouter(val eventBus: BbbMsgRouterEventBus) extends ReceivedMessageRouter { class MessageRouter(val eventBus: BbbMsgRouterEventBus) extends ReceivedMessageRouter {

View File

@ -1,21 +1,31 @@
import org.bigbluebutton.build._
import scalariform.formatter.preferences._
import com.typesafe.sbt.SbtScalariform
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
import com.typesafe.sbt.SbtNativePackager.autoImport._
enablePlugins(JavaServerAppPackaging) enablePlugins(JavaServerAppPackaging)
name := "bbb-fsesl-akka" version := "0.0.2"
organization := "org.bigbluebutton" val compileSettings = Seq(
organization := "org.bigbluebutton",
version := "0.0.1" scalacOptions ++= List(
"-unchecked",
scalaVersion := "2.12.6" "-deprecation",
"-Xlint",
scalacOptions ++= Seq( "-Ywarn-dead-code",
"-unchecked", "-language:_",
"-deprecation", "-target:jvm-1.8",
"-Xlint", "-encoding", "UTF-8"
"-Ywarn-dead-code", ),
"-language:_", javacOptions ++= List(
"-target:jvm-1.8", "-Xlint:unchecked",
"-encoding", "UTF-8" "-Xlint:deprecation"
)
) )
resolvers ++= Seq( resolvers ++= Seq(
@ -37,63 +47,14 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console",
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports")
val akkaVersion = "2.5.14" Seq(Revolver.settings: _*)
val scalaTestV = "2.2.6" lazy val bbbFseslAkka = (project in file(".")).settings(name := "bbb-fsesl-akka", libraryDependencies ++= Dependencies.runtime).settings(compileSettings)
scalariformAutoformat := false
libraryDependencies ++= { scalariformPreferences := scalariformPreferences.value
Seq(
"ch.qos.logback" % "logback-classic" % "1.2.3" % "runtime",
"junit" % "junit" % "4.11",
"commons-codec" % "commons-codec" % "1.11",
"joda-time" % "joda-time" % "2.10",
"org.apache.commons" % "commons-lang3" % "3.7"
)}
libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT"
libraryDependencies += "org.bigbluebutton" % "bbb-fsesl-client" % "0.0.6"
// https://mvnrepository.com/artifact/org.scala-lang/scala-library
libraryDependencies += "org.scala-lang" % "scala-library" % scalaVersion.value
// https://mvnrepository.com/artifact/org.scala-lang/scala-compiler
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
// https://mvnrepository.com/artifact/com.typesafe.akka/akka-actor_2.12
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.12" % akkaVersion
// https://mvnrepository.com/artifact/com.typesafe.akka/akka-slf4j_2.12
libraryDependencies += "com.typesafe.akka" % "akka-slf4j_2.12" % akkaVersion
// https://mvnrepository.com/artifact/com.github.etaty/rediscala_2.12
libraryDependencies += "com.github.etaty" % "rediscala_2.12" % "1.8.0"
// For generating test reports
libraryDependencies += "org.pegdown" % "pegdown" % "1.6.0" % "test"
// https://mvnrepository.com/artifact/com.typesafe.akka/akka-testkit_2.12
libraryDependencies += "com.typesafe.akka" % "akka-testkit_2.12" % "2.5.14" % "test"
// https://mvnrepository.com/artifact/org.scalactic/scalactic_2.12
libraryDependencies += "org.scalactic" % "scalactic_2.12" % "3.0.5" % "test"
// https://mvnrepository.com/artifact/org.scalatest/scalatest_2.12
libraryDependencies += "org.scalatest" % "scalatest_2.12" % "3.0.5" % "test"
libraryDependencies += "org.mockito" % "mockito-core" % "2.21.0" % "test"
seq(Revolver.settings: _*)
import com.typesafe.sbt.SbtScalariform
import scalariform.formatter.preferences._
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
SbtScalariform.defaultScalariformSettings
ScalariformKeys.preferences := ScalariformKeys.preferences.value
.setPreference(AlignSingleLineCaseStatements, true) .setPreference(AlignSingleLineCaseStatements, true)
.setPreference(DoubleIndentClassDeclaration, true) .setPreference(DoubleIndentConstructorArguments, true)
.setPreference(AlignParameters, true) .setPreference(AlignParameters, true)
//----------- //-----------
@ -121,16 +82,7 @@ daemonUser in Linux := user
// group which will execute the application // group which will execute the application
daemonGroup in Linux := group daemonGroup in Linux := group
mappings in Universal <+= (packageBin in Compile, sourceDirectory ) map { (_, src) => mappings in(Universal, packageBin) += file("src/main/resources/application.conf") -> "conf/application.conf"
// Move the application.conf so the user can override settings here mappings in(Universal, packageBin) += file("src/main/resources/logback.xml") -> "conf/logback.xml"
val appConf = src / "main" / "resources" / "application.conf"
appConf -> "conf/application.conf"
}
mappings in Universal <+= (packageBin in Compile, sourceDirectory ) map { (_, src) =>
// Move logback.xml so the user can override settings here
val logConf = src / "main" / "resources" / "logback.xml"
logConf -> "conf/logback.xml"
}
debianPackageDependencies in Debian ++= Seq("java8-runtime-headless", "bash") debianPackageDependencies in Debian ++= Seq("java8-runtime-headless", "bash")

View File

@ -0,0 +1,76 @@
package org.bigbluebutton.build
import sbt._
import Keys._
object Dependencies {
object Versions {
// Scala
val scala = "2.12.7"
val junitInterface = "0.11"
val scalactic = "3.0.3"
// Libraries
val akkaVersion = "2.5.17"
val logback = "1.2.3"
// Apache Commons
val lang = "3.8.1"
val codec = "1.11"
// Redis
val redisScala = "1.8.0"
// BigBlueButton
val bbbCommons = "0.0.20-SNAPSHOT"
val bbbFsesl = "0.0.7"
// Test
val scalaTest = "3.0.5"
val akkaTestKit = "2.5.18"
val junit = "4.12"
}
object Compile {
val scalaLibrary = "org.scala-lang" % "scala-library" % Versions.scala
val scalaCompiler = "org.scala-lang" % "scala-compiler" % Versions.scala
val akkaActor = "com.typesafe.akka" % "akka-actor_2.12" % Versions.akkaVersion
val akkaSl4fj = "com.typesafe.akka" % "akka-slf4j_2.12" % Versions.akkaVersion
val logback = "ch.qos.logback" % "logback-classic" % Versions.logback % "runtime"
val commonsCodec = "commons-codec" % "commons-codec" % Versions.codec
val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang
val redisScala = "com.github.etaty" % "rediscala_2.12" % Versions.redisScala
val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons
val bbbFseslClient = "org.bigbluebutton" % "bbb-fsesl-client" % Versions.bbbFsesl
}
object Test {
val scalaTest = "org.scalatest" %% "scalatest" % Versions.scalaTest % "test"
val junit = "junit" % "junit" % Versions.junit % "test"
val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test"
val akkaTestKit = "com.typesafe.akka" %% "akka-testkit" % Versions.akkaTestKit % "test"
}
val testing = Seq(
Test.scalaTest,
Test.junit,
Test.scalactic,
Test.akkaTestKit)
val runtime = Seq(
Compile.scalaLibrary,
Compile.scalaCompiler,
Compile.akkaActor,
Compile.logback,
Compile.commonsCodec,
Compile.apacheLang,
Compile.redisScala,
Compile.bbbCommons,
Compile.bbbFseslClient) ++ testing
}

View File

@ -1 +1 @@
sbt.version=0.13.8 sbt.version=1.2.6

View File

@ -1,11 +1,11 @@
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.6") addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2")
addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.12")
addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8")
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")

View File

@ -2,7 +2,8 @@ package org.bigbluebutton
import akka.actor.{ ActorSystem } import akka.actor.{ ActorSystem }
import org.bigbluebutton.endpoint.redis.{ AppsRedisSubscriberActor, RedisPublisher } import org.bigbluebutton.common2.redis.RedisPublisher
import org.bigbluebutton.endpoint.redis.FSESLRedisSubscriberActor
import org.bigbluebutton.freeswitch.{ RxJsonMsgHdlrActor, VoiceConferenceService } import org.bigbluebutton.freeswitch.{ RxJsonMsgHdlrActor, VoiceConferenceService }
import org.bigbluebutton.freeswitch.bus.InsonMsgBus import org.bigbluebutton.freeswitch.bus.InsonMsgBus
import org.bigbluebutton.freeswitch.voice.FreeswitchConferenceEventListener import org.bigbluebutton.freeswitch.voice.FreeswitchConferenceEventListener
@ -13,7 +14,7 @@ object Boot extends App with SystemConfiguration {
implicit val system = ActorSystem("bigbluebutton-fsesl-system") implicit val system = ActorSystem("bigbluebutton-fsesl-system")
val redisPublisher = new RedisPublisher(system) val redisPublisher = new RedisPublisher(system, "BbbFsEslAkkaPub")
val eslConnection = new DefaultManagerConnection(eslHost, eslPort, eslPassword) val eslConnection = new DefaultManagerConnection(eslHost, eslPort, eslPassword)
@ -34,6 +35,5 @@ object Boot extends App with SystemConfiguration {
val redisMessageHandlerActor = system.actorOf(RxJsonMsgHdlrActor.props(fsApplication)) val redisMessageHandlerActor = system.actorOf(RxJsonMsgHdlrActor.props(fsApplication))
inJsonMsgBus.subscribe(redisMessageHandlerActor, toFsAppsJsonChannel) inJsonMsgBus.subscribe(redisMessageHandlerActor, toFsAppsJsonChannel)
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(system, inJsonMsgBus), "redis-subscriber") val redisSubscriberActor = system.actorOf(FSESLRedisSubscriberActor.props(system, inJsonMsgBus), "redis-subscriber")
} }

View File

@ -1,23 +1,15 @@
package org.bigbluebutton package org.bigbluebutton
import com.typesafe.config.ConfigFactory
import scala.util.Try import scala.util.Try
trait SystemConfiguration { import org.bigbluebutton.common2.redis.RedisConfiguration
val config = ConfigFactory.load()
trait SystemConfiguration extends RedisConfiguration {
lazy val eslHost = Try(config.getString("freeswitch.esl.host")).getOrElse("127.0.0.1") lazy val eslHost = Try(config.getString("freeswitch.esl.host")).getOrElse("127.0.0.1")
lazy val eslPort = Try(config.getInt("freeswitch.esl.port")).getOrElse(8021) lazy val eslPort = Try(config.getInt("freeswitch.esl.port")).getOrElse(8021)
lazy val eslPassword = Try(config.getString("freeswitch.esl.password")).getOrElse("ClueCon") lazy val eslPassword = Try(config.getString("freeswitch.esl.password")).getOrElse("ClueCon")
lazy val fsProfile = Try(config.getString("freeswitch.conf.profile")).getOrElse("cdquality") lazy val fsProfile = Try(config.getString("freeswitch.conf.profile")).getOrElse("cdquality")
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
lazy val toVoiceConfRedisChannel = Try(config.getString("redis.toVoiceConfRedisChannel")).getOrElse("to-voice-conf-redis-channel")
lazy val fromVoiceConfRedisChannel = Try(config.getString("redis.fromVoiceConfRedisChannel")).getOrElse("from-voice-conf-redis-channel")
lazy val toFsAppsJsonChannel = Try(config.getString("eventBus.toFsAppsChannel")).getOrElse("to-fs-apps-json-channel") lazy val toFsAppsJsonChannel = Try(config.getString("eventBus.toFsAppsChannel")).getOrElse("to-fs-apps-json-channel")
lazy val fromFsAppsJsonChannel = Try(config.getString("eventBus.fromFsAppsChannel")).getOrElse("from-fs-apps-json-channel") lazy val fromFsAppsJsonChannel = Try(config.getString("eventBus.fromFsAppsChannel")).getOrElse("from-fs-apps-json-channel")
} }

View File

@ -6,49 +6,54 @@ import java.net.InetSocketAddress
import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt import scala.concurrent.duration.DurationInt
import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.redis.RedisAppSubscriberActor
import org.bigbluebutton.common2.redis.RedisConfiguration
import org.bigbluebutton.common2.redis.RedisSubscriber
import org.bigbluebutton.freeswitch.bus.InJsonMsg
import org.bigbluebutton.freeswitch.bus.InsonMsgBus
import org.bigbluebutton.freeswitch.bus.ReceivedJsonMsg
import akka.actor.ActorSystem import akka.actor.ActorSystem
import akka.actor.OneForOneStrategy import akka.actor.OneForOneStrategy
import akka.actor.Props import akka.actor.Props
import akka.actor.SupervisorStrategy.Resume import akka.actor.SupervisorStrategy.Resume
import org.bigbluebutton.freeswitch.bus.{ InJsonMsg, InsonMsgBus, ReceivedJsonMsg }
import redis.actors.RedisSubscriberActor import redis.actors.RedisSubscriberActor
import redis.api.pubsub.Message import redis.api.pubsub.Message
import redis.api.pubsub.PMessage
import redis.api.servers.ClientSetname import redis.api.servers.ClientSetname
object AppsRedisSubscriberActor extends SystemConfiguration { object FSESLRedisSubscriberActor extends RedisSubscriber with RedisConfiguration {
val channels = Seq(toVoiceConfRedisChannel) val channels = Seq(toVoiceConfRedisChannel)
val patterns = Seq("bigbluebutton:to-voice-conf:*", "bigbluebutton:from-bbb-apps:*") val patterns = Seq("bigbluebutton:to-voice-conf:*", "bigbluebutton:from-bbb-apps:*")
def props(system: ActorSystem, inJsonMgBus: InsonMsgBus): Props = def props(system: ActorSystem, inJsonMgBus: InsonMsgBus): Props =
Props(classOf[AppsRedisSubscriberActor], system, inJsonMgBus, Props(classOf[FSESLRedisSubscriberActor], system, inJsonMgBus,
redisHost, redisPort, redisHost, redisPort,
channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher")
} }
class AppsRedisSubscriberActor( class FSESLRedisSubscriberActor(
val system: ActorSystem, val system: ActorSystem,
inJsonMgBus: InsonMsgBus, redisHost: String, inJsonMgBus: InsonMsgBus, redisHost: String,
redisPort: Int, redisPort: Int,
channels: Seq[String] = Nil, patterns: Seq[String] = Nil) channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
extends RedisSubscriberActor( extends RedisSubscriberActor(
new InetSocketAddress(redisHost, redisPort), new InetSocketAddress(redisHost, redisPort),
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") })
with SystemConfiguration
with RedisAppSubscriberActor {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => { case e: Exception => {
val sw: StringWriter = new StringWriter() val sw: StringWriter = new StringWriter()
sw.write("An exception has been thrown on AppsRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n") sw.write("An exception has been thrown on FSESlRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n")
e.printStackTrace(new PrintWriter(sw)) e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString()) log.error(sw.toString())
Resume Resume
} }
} }
// val decoder = new FromJsonDecoder()
var lastPongReceivedOn = 0L var lastPongReceivedOn = 0L
system.scheduler.schedule(10 seconds, 10 seconds)(checkPongMessage()) system.scheduler.schedule(10 seconds, 10 seconds)(checkPongMessage())
@ -71,12 +76,4 @@ class AppsRedisSubscriberActor(
inJsonMgBus.publish(InJsonMsg(toFsAppsJsonChannel, receivedJsonMessage)) inJsonMgBus.publish(InJsonMsg(toFsAppsJsonChannel, receivedJsonMessage))
} }
} }
def onPMessage(pmessage: PMessage) {
// log.debug(s"pattern message received: $pmessage")
}
def handleMessage(msg: String) {
log.warning("**** TODO: Handle pubsub messages. ****")
}
} }

View File

@ -1,20 +0,0 @@
package org.bigbluebutton.endpoint.redis
import redis.RedisClient
import akka.actor.ActorSystem
import org.bigbluebutton.SystemConfiguration
class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
val redis = RedisClient(redisHost, redisPort)(system)
// Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli
redis.clientSetname("BbbFsEslAkkaPub")
def publish(channel: String, data: String) {
//println("PUBLISH TO [" + channel + "]: \n [" + data + "]")
redis.publish(channel, data)
}
}

View File

@ -2,9 +2,9 @@ package org.bigbluebutton.freeswitch
import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.freeswitch.voice.IVoiceConferenceService import org.bigbluebutton.freeswitch.voice.IVoiceConferenceService
import org.bigbluebutton.endpoint.redis.RedisPublisher
import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.util.JsonUtil import org.bigbluebutton.common2.util.JsonUtil
import org.bigbluebutton.common2.redis.RedisPublisher
class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceService with SystemConfiguration { class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceService with SystemConfiguration {

View File

@ -46,7 +46,6 @@ libraryDependencies += "com.softwaremill.quicklens" %% "quicklens" % "1.4.11"
libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT" libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT"
libraryDependencies += "com.google.code.gson" % "gson" % "2.8.5" libraryDependencies += "com.google.code.gson" % "gson" % "2.8.5"
libraryDependencies += "redis.clients" % "jedis" % "2.9.0"
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.7" libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.7"

View File

@ -3,10 +3,12 @@ package org.bigbluebutton.client
import akka.actor.ActorSystem import akka.actor.ActorSystem
import akka.event.Logging import akka.event.Logging
import org.bigbluebutton.client.bus._ import org.bigbluebutton.client.bus._
import org.bigbluebutton.client.endpoint.redis.{AppsRedisSubscriberActor, MessageSender, RedisPublisher} import org.bigbluebutton.client.endpoint.redis.AppsRedisSubscriberActor
import org.bigbluebutton.client.meeting.MeetingManagerActor import org.bigbluebutton.client.meeting.MeetingManagerActor
import org.bigbluebutton.common2.redis.RedisPublisher
import scala.concurrent.duration._
import scala.concurrent.duration._
import org.bigbluebutton.common2.redis.MessageSender
class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfiguration{ class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfiguration{
@ -20,7 +22,7 @@ class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfig
private val msgToRedisEventBus = new MsgToRedisEventBus private val msgToRedisEventBus = new MsgToRedisEventBus
private val msgToClientEventBus = new MsgToClientEventBus private val msgToClientEventBus = new MsgToClientEventBus
private val redisPublisher = new RedisPublisher(system) private val redisPublisher = new RedisPublisher(system, "Red5AppsPub")
private val msgSender: MessageSender = new MessageSender(redisPublisher) private val msgSender: MessageSender = new MessageSender(redisPublisher)
private val meetingManagerActorRef = system.actorOf( private val meetingManagerActorRef = system.actorOf(

View File

@ -1,10 +1,10 @@
package org.bigbluebutton.client package org.bigbluebutton.client
import akka.actor.{Actor, ActorLogging, Props} import akka.actor.{ Actor, ActorLogging, Props }
import org.bigbluebutton.common2.msgs.BbbCommonEnvJsNodeMsg import org.bigbluebutton.common2.msgs.BbbCommonEnvJsNodeMsg
import org.bigbluebutton.common2.util.JsonUtil import org.bigbluebutton.common2.util.JsonUtil
import org.bigbluebutton.client.endpoint.redis.MessageSender
import org.bigbluebutton.common2.msgs.LookUpUserReqMsg import org.bigbluebutton.common2.msgs.LookUpUserReqMsg
import org.bigbluebutton.common2.redis.MessageSender
object MsgToRedisActor { object MsgToRedisActor {
def props(msgSender: MessageSender): Props = def props(msgSender: MessageSender): Props =
@ -20,11 +20,10 @@ class MsgToRedisActor(msgSender: MessageSender)
def handle(msg: BbbCommonEnvJsNodeMsg): Unit = { def handle(msg: BbbCommonEnvJsNodeMsg): Unit = {
val json = JsonUtil.toJson(msg) val json = JsonUtil.toJson(msg)
msg.envelope.name match { msg.envelope.name match {
case LookUpUserReqMsg.NAME => msgSender.send(toThirdPartyRedisChannel, json) case LookUpUserReqMsg.NAME => msgSender.send(toThirdPartyRedisChannel, json)
case _ => msgSender.send(toAkkaAppsRedisChannel, json) case _ => msgSender.send(toAkkaAppsRedisChannel, json)
} }
} }
} }

View File

@ -1,15 +1,10 @@
package org.bigbluebutton.client package org.bigbluebutton.client
import scala.util.Try import scala.util.Try
import com.typesafe.config.ConfigFactory
trait SystemConfiguration { import org.bigbluebutton.common2.redis.RedisConfiguration
val config = ConfigFactory.load()
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
trait SystemConfiguration extends RedisConfiguration {
lazy val toAkkaAppsRedisChannel = Try(config.getString("redis.toAkkaAppsRedisChannel")).getOrElse("to-akka-apps-redis-channel") lazy val toAkkaAppsRedisChannel = Try(config.getString("redis.toAkkaAppsRedisChannel")).getOrElse("to-akka-apps-redis-channel")
lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel") lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel")
lazy val toThirdPartyRedisChannel = Try(config.getString("redis.toThirdPartyRedisChannel")).getOrElse("to-third-party-redis-channel") lazy val toThirdPartyRedisChannel = Try(config.getString("redis.toThirdPartyRedisChannel")).getOrElse("to-third-party-redis-channel")

View File

@ -1,32 +0,0 @@
package org.bigbluebutton.client.bus
import akka.actor.ActorRef
import akka.event.{EventBus, LookupClassification}
case class JsonMsgFromAkkaApps(name: String, data: String)
case class JsonMsgFromAkkaAppsEvent(val topic: String, val payload: JsonMsgFromAkkaApps)
class JsonMsgFromAkkaAppsBus extends EventBus with LookupClassification {
type Event = JsonMsgFromAkkaAppsEvent
type Classifier = String
type Subscriber = ActorRef
// is used for extracting the classifier from the incoming events
override protected def classify(event: Event): Classifier = event.topic
// will be invoked for each event for all subscribers which registered themselves
// for the events classifier
override protected def publish(event: Event, subscriber: Subscriber): Unit = {
subscriber ! event.payload
}
// must define a full order over the subscribers, expressed as expected from
// `java.lang.Comparable.compare`
override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
a.compareTo(b)
// determines the initial size of the index data structure
// used internally (i.e. the expected number of different classifiers)
override protected def mapSize: Int = 128
}

View File

@ -1,31 +0,0 @@
package org.bigbluebutton.client.bus
import akka.actor.ActorRef
import akka.event.{EventBus, LookupClassification}
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvJsNodeMsg}
case class MsgFromAkkaApps(val topic: String, val payload: BbbCommonEnvJsNodeMsg)
class MsgFromAkkaAppsEventBus extends EventBus with LookupClassification {
type Event = MsgFromAkkaApps
type Classifier = String
type Subscriber = ActorRef
// is used for extracting the classifier from the incoming events
override protected def classify(event: Event): Classifier = event.topic
// will be invoked for each event for all subscribers which registered themselves
// for the events classifier
override protected def publish(event: Event, subscriber: Subscriber): Unit = {
subscriber ! event.payload
}
// must define a full order over the subscribers, expressed as expected from
// `java.lang.Comparable.compare`
override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
a.compareTo(b)
// determines the initial size of the index data structure
// used internally (i.e. the expected number of different classifiers)
override protected def mapSize: Int = 128
}

View File

@ -1,17 +0,0 @@
package org.bigbluebutton.client.endpoint.redis
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import akka.actor.ActorSystem
import org.bigbluebutton.client.SystemConfiguration
//import org.bigbluebutton.common.messages.BbbAppsIsAliveMessage
class KeepAliveRedisPublisher(val system: ActorSystem, sender: RedisPublisher) extends SystemConfiguration {
val startedOn = System.currentTimeMillis()
system.scheduler.schedule(2 seconds, 5 seconds) {
// val msg = new BbbAppsIsAliveMessage(startedOn, System.currentTimeMillis())
// sender.publish("bigbluebutton:from-bbb-apps:keepalive", msg.toJson())
}
}

View File

@ -1,8 +0,0 @@
package org.bigbluebutton.client.endpoint.redis
class MessageSender(publisher: RedisPublisher) {
def send(channel: String, data: String) {
publisher.publish(channel, data)
}
}

View File

@ -1,17 +1,18 @@
package org.bigbluebutton.client.endpoint.redis package org.bigbluebutton.client.endpoint.redis
import akka.actor.{ActorLogging, OneForOneStrategy, Props} import akka.actor.{ ActorLogging, OneForOneStrategy, Props }
import akka.actor.SupervisorStrategy.Resume import akka.actor.SupervisorStrategy.Resume
import java.io.{PrintWriter, StringWriter} import java.io.{ PrintWriter, StringWriter }
import java.net.InetSocketAddress import java.net.InetSocketAddress
import redis.actors.RedisSubscriberActor import redis.actors.RedisSubscriberActor
import redis.api.pubsub.{Message, PMessage} import redis.api.pubsub.{ Message, PMessage }
import scala.concurrent.duration._ import scala.concurrent.duration._
import org.bigbluebutton.client._ import org.bigbluebutton.client._
import org.bigbluebutton.client.bus.{JsonMsgFromAkkaApps, JsonMsgFromAkkaAppsBus, JsonMsgFromAkkaAppsEvent} import org.bigbluebutton.client.bus.{ JsonMsgFromAkkaApps, JsonMsgFromAkkaAppsBus, JsonMsgFromAkkaAppsEvent }
import redis.api.servers.ClientSetname import redis.api.servers.ClientSetname
import org.bigbluebutton.common2.redis.RedisAppSubscriberActor
object AppsRedisSubscriberActor extends SystemConfiguration { object AppsRedisSubscriberActor extends SystemConfiguration {
@ -26,10 +27,11 @@ object AppsRedisSubscriberActor extends SystemConfiguration {
class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, redisHost: String, class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, redisHost: String,
redisPort: Int, redisPort: Int,
channels: Seq[String] = Nil, patterns: Seq[String] = Nil) channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
extends RedisSubscriberActor(new InetSocketAddress(redisHost, redisPort), extends RedisSubscriberActor(
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) new InetSocketAddress(redisHost, redisPort),
with SystemConfiguration with ActorLogging { channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") })
with SystemConfiguration with ActorLogging with RedisAppSubscriberActor {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => { case e: Exception => {
@ -41,7 +43,6 @@ class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, redisHost: St
} }
} }
// Set the name of this client to be able to distinguish when doing // Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli // CLIENT LIST on redis-cli
write(ClientSetname("Red5AppsSub").encodedRequest) write(ClientSetname("Red5AppsSub").encodedRequest)
@ -54,9 +55,4 @@ class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, redisHost: St
} }
} }
def onPMessage(pmessage: PMessage) {
// We don't use PSubscribe anymore, but an implementation of the method is required
log.error("Should not be receiving a PMessage. It triggered on a match of pattern: " + pmessage.patternMatched)
}
} }

View File

@ -1,24 +0,0 @@
package org.bigbluebutton.client.endpoint.redis
import redis.RedisClient
import akka.actor.ActorSystem
import akka.event.Logging
import org.bigbluebutton.client.SystemConfiguration
import akka.util.ByteString
class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
val redis = RedisClient(redisHost, redisPort)(system)
val log = Logging(system, getClass)
// Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli
redis.clientSetname("Red5AppsPub")
def publish(channel: String, data: String) {
//log.debug("PUBLISH TO [" + channel + "]: \n [" + data + "]")
redis.publish(channel, ByteString(data))
}
}

View File

@ -2,8 +2,6 @@ import org.bigbluebutton.build._
version := "0.0.20-SNAPSHOT" version := "0.0.20-SNAPSHOT"
scalaVersion := "2.12.7"
val compileSettings = Seq( val compileSettings = Seq(
organization := "org.bigbluebutton", organization := "org.bigbluebutton",

View File

@ -11,12 +11,15 @@ object Dependencies {
val junit = "4.12" val junit = "4.12"
val junitInterface = "0.11" val junitInterface = "0.11"
val scalactic = "3.0.3" val scalactic = "3.0.3"
val pegdown = "1.6.0"
// Libraries // Libraries
val akkaVersion = "2.5.17"
val gson = "2.8.5" val gson = "2.8.5"
val jackson = "2.9.7" val jackson = "2.9.7"
val sl4j = "1.7.25" val sl4j = "1.7.25"
// Redis
val redisScala = "1.8.0"
val lettuce = "5.1.2.RELEASE" val lettuce = "5.1.2.RELEASE"
// Test // Test
@ -27,10 +30,14 @@ object Dependencies {
val scalaLibrary = "org.scala-lang" % "scala-library" % Versions.scala val scalaLibrary = "org.scala-lang" % "scala-library" % Versions.scala
val scalaCompiler = "org.scala-lang" % "scala-compiler" % Versions.scala val scalaCompiler = "org.scala-lang" % "scala-compiler" % Versions.scala
val akkaActor = "com.typesafe.akka" % "akka-actor_2.12" % Versions.akkaVersion
val googleGson = "com.google.code.gson" % "gson" % Versions.gson val googleGson = "com.google.code.gson" % "gson" % Versions.gson
val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson
val sl4jApi = "org.slf4j" % "slf4j-api" % Versions.sl4j val sl4jApi = "org.slf4j" % "slf4j-api" % Versions.sl4j
val lettuceCore = "io.lettuce" % "lettuce-core" % Versions.lettuce val lettuceCore = "io.lettuce" % "lettuce-core" % Versions.lettuce
val redisScala = "com.github.etaty" % "rediscala_2.12" % Versions.redisScala
} }
object Test { object Test {
@ -38,21 +45,21 @@ object Dependencies {
val junit = "junit" % "junit" % Versions.junit % "test" val junit = "junit" % "junit" % Versions.junit % "test"
val junitInteface = "com.novocode" % "junit-interface" % Versions.junitInterface % "test" val junitInteface = "com.novocode" % "junit-interface" % Versions.junitInterface % "test"
val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test" val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test"
val pegdown = "org.pegdown" % "pegdown" % Versions.pegdown % "test"
} }
val testing = Seq( val testing = Seq(
Test.scalaTest, Test.scalaTest,
Test.junit, Test.junit,
Test.junitInteface, Test.junitInteface,
Test.scalactic, Test.scalactic)
Test.pegdown)
val runtime = Seq( val runtime = Seq(
Compile.scalaLibrary, Compile.scalaLibrary,
Compile.scalaCompiler, Compile.scalaCompiler,
Compile.akkaActor,
Compile.googleGson, Compile.googleGson,
Compile.jacksonModule, Compile.jacksonModule,
Compile.sl4jApi, Compile.sl4jApi,
Compile.lettuceCore) ++ testing Compile.lettuceCore,
Compile.redisScala) ++ testing
} }

View File

@ -31,7 +31,6 @@ import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.dynamic.RedisCommandFactory; import io.lettuce.core.dynamic.RedisCommandFactory;
import io.lettuce.core.output.StatusOutput;
public class RedisStorageService { public class RedisStorageService {

View File

@ -1,4 +1,4 @@
package org.bigbluebutton.core.bus package org.bigbluebutton.common2.bus
import akka.actor.ActorRef import akka.actor.ActorRef
import akka.event.{ EventBus, LookupClassification } import akka.event.{ EventBus, LookupClassification }

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.api2.bus package org.bigbluebutton.common2.bus
import akka.actor.ActorRef import akka.actor.ActorRef
import akka.event.{EventBus, LookupClassification} import akka.event.{ EventBus, LookupClassification }
case class JsonMsgFromAkkaApps(name: String, data: String) case class JsonMsgFromAkkaApps(name: String, data: String)
case class JsonMsgFromAkkaAppsEvent(val topic: String, val payload: JsonMsgFromAkkaApps) case class JsonMsgFromAkkaAppsEvent(val topic: String, val payload: JsonMsgFromAkkaApps)
@ -23,7 +23,7 @@ class JsonMsgFromAkkaAppsBus extends EventBus with LookupClassification {
// must define a full order over the subscribers, expressed as expected from // must define a full order over the subscribers, expressed as expected from
// `java.lang.Comparable.compare` // `java.lang.Comparable.compare`
override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int = override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
a.compareTo(b) a.compareTo(b)
// determines the initial size of the index data structure // determines the initial size of the index data structure
// used internally (i.e. the expected number of different classifiers) // used internally (i.e. the expected number of different classifiers)

View File

@ -2,9 +2,9 @@ package org.bigbluebutton.api2.bus
import akka.actor.ActorRef import akka.actor.ActorRef
import akka.event.{EventBus, LookupClassification} import akka.event.{EventBus, LookupClassification}
import org.bigbluebutton.common2.msgs.{BbbCommonEnvCoreMsg} import org.bigbluebutton.common2.msgs.BbbCommonMsg
case class MsgFromAkkaApps(val topic: String, val payload: BbbCommonEnvCoreMsg) case class MsgFromAkkaApps(val topic: String, val payload: BbbCommonMsg)
class MsgFromAkkaAppsEventBus extends EventBus with LookupClassification { class MsgFromAkkaAppsEventBus extends EventBus with LookupClassification {
type Event = MsgFromAkkaApps type Event = MsgFromAkkaApps

View File

@ -1,7 +1,8 @@
package org.bigbluebutton.api2.bus package org.bigbluebutton.common2.bus
import akka.actor.ActorRef import akka.actor.ActorRef
import akka.event.{EventBus, LookupClassification} import akka.event.{EventBus, LookupClassification}
import akka.actor.actorRef2Scala
case class OldReceivedJsonMessage(pattern: String, channel: String, msg: String) case class OldReceivedJsonMessage(pattern: String, channel: String, msg: String)
case class OldIncomingJsonMessage(val topic: String, val payload: OldReceivedJsonMessage) case class OldIncomingJsonMessage(val topic: String, val payload: OldReceivedJsonMessage)
@ -11,7 +12,7 @@ class OldMessageEventBus extends EventBus with LookupClassification {
type Classifier = String type Classifier = String
type Subscriber = ActorRef type Subscriber = ActorRef
// is used for extracting the classifier from the incoming events // is used for extracting te classifier from the incoming events
override protected def classify(event: Event): Classifier = event.topic override protected def classify(event: Event): Classifier = event.topic
// will be invoked for each event for all subscribers which registered themselves // will be invoked for each event for all subscribers which registered themselves

View File

@ -1,4 +1,4 @@
package org.bigbluebutton.api2.endpoint.redis package org.bigbluebutton.common2.redis
class MessageSender(publisher: RedisPublisher) { class MessageSender(publisher: RedisPublisher) {

View File

@ -0,0 +1,18 @@
package org.bigbluebutton.common2.redis
import akka.actor.Actor
import akka.event.LoggingAdapter
import redis.api.pubsub.PMessage
trait RedisAppSubscriberActor extends Actor {
def log: LoggingAdapter
def handleMessage(msg: String) {
throw new UnsupportedOperationException();
}
def onPMessage(pmessage: PMessage) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,24 @@
package org.bigbluebutton.common2.redis
import scala.util.Try
import com.typesafe.config.ConfigFactory
trait RedisConfiguration {
val config = ConfigFactory.load()
// Redis server configuration
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
// Redis channels
lazy val toAkkaAppsRedisChannel = Try(config.getString("redis.toAkkaAppsRedisChannel")).getOrElse("to-akka-apps-redis-channel")
lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel")
lazy val toVoiceConfRedisChannel = Try(config.getString("redis.toVoiceConfRedisChannel")).getOrElse("to-voice-conf-redis-channel")
lazy val fromVoiceConfRedisChannel = Try(config.getString("redis.fromVoiceConfRedisChannel")).getOrElse("from-voice-conf-redis-channel")
lazy val fromAkkaAppsWbRedisChannel = Try(config.getString("redis.fromAkkaAppsWbRedisChannel")).getOrElse("from-akka-apps-wb-redis-channel")
lazy val fromAkkaAppsChatRedisChannel = Try(config.getString("redis.fromAkkaAppsChatRedisChannel")).getOrElse("from-akka-apps-chat-redis-channel")
lazy val fromAkkaAppsPresRedisChannel = Try(config.getString("redis.fromAkkaAppsPresRedisChannel")).getOrElse("from-akka-apps-pres-redis-channel")
}

View File

@ -1,12 +1,11 @@
package org.bigbluebutton.api2.endpoint.redis package org.bigbluebutton.common2.redis
import akka.actor.ActorSystem import akka.actor.ActorSystem
import akka.event.Logging import akka.event.Logging
import akka.util.ByteString import akka.util.ByteString
import org.bigbluebutton.api2.SystemConfiguration
import redis.RedisClient import redis.RedisClient
class RedisPublisher(val system: ActorSystem) extends SystemConfiguration { class RedisPublisher(val system: ActorSystem, val clientName: String) extends RedisConfiguration {
val redis = RedisClient(redisHost, redisPort)(system) val redis = RedisClient(redisHost, redisPort)(system)
@ -14,10 +13,9 @@ class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
// Set the name of this client to be able to distinguish when doing // Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli // CLIENT LIST on redis-cli
redis.clientSetname("BbbWebPub") redis.clientSetname(clientName)
def publish(channel: String, data: String) { def publish(channel: String, data: String) {
//log.debug("PUBLISH TO \n[" + channel + "]: \n " + data + "\n")
redis.publish(channel, ByteString(data)) redis.publish(channel, ByteString(data))
} }

View File

@ -0,0 +1,6 @@
package org.bigbluebutton.common2.redis
abstract class RedisSubscriber extends RedisConfiguration {
val channels: Seq[String]
val patterns: Seq[String]
}

View File

@ -2,8 +2,6 @@ import org.bigbluebutton.build._
version := "0.0.3-SNAPSHOT" version := "0.0.3-SNAPSHOT"
scalaVersion := "2.12.7"
val compileSettings = Seq( val compileSettings = Seq(
organization := "org.bigbluebutton", organization := "org.bigbluebutton",

View File

@ -11,7 +11,6 @@ object Dependencies {
val junit = "4.12" val junit = "4.12"
val junitInterface = "0.11" val junitInterface = "0.11"
val scalactic = "3.0.3" val scalactic = "3.0.3"
val pegdown = "1.6.0"
// Libraries // Libraries
val akkaVersion = "2.5.17" val akkaVersion = "2.5.17"
@ -83,15 +82,13 @@ object Dependencies {
val junit = "junit" % "junit" % Versions.junit % "test" val junit = "junit" % "junit" % Versions.junit % "test"
val junitInteface = "com.novocode" % "junit-interface" % Versions.junitInterface % "test" val junitInteface = "com.novocode" % "junit-interface" % Versions.junitInterface % "test"
val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test" val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test"
val pegdown = "org.pegdown" % "pegdown" % Versions.pegdown % "test"
} }
val testing = Seq( val testing = Seq(
Test.scalaTest, Test.scalaTest,
Test.junit, Test.junit,
Test.junitInteface, Test.junitInteface,
Test.scalactic, Test.scalactic)
Test.pegdown)
val runtime = Seq( val runtime = Seq(
Compile.scalaLibrary, Compile.scalaLibrary,

View File

@ -5,12 +5,14 @@ import akka.actor.ActorSystem
import akka.event.Logging import akka.event.Logging
import org.bigbluebutton.api.messaging.converters.messages._ import org.bigbluebutton.api.messaging.converters.messages._
import org.bigbluebutton.api2.bus._ import org.bigbluebutton.api2.bus._
import org.bigbluebutton.api2.endpoint.redis.{ AppsRedisSubscriberActor, MessageSender, RedisPublisher } import org.bigbluebutton.api2.endpoint.redis.{ WebRedisSubscriberActor }
import org.bigbluebutton.common2.redis.MessageSender
import org.bigbluebutton.api2.meeting.{ OldMeetingMsgHdlrActor, RegisterUser } import org.bigbluebutton.api2.meeting.{ OldMeetingMsgHdlrActor, RegisterUser }
import org.bigbluebutton.common2.domain._ import org.bigbluebutton.common2.domain._
import org.bigbluebutton.presentation.messages._ import org.bigbluebutton.presentation.messages._
import scala.concurrent.duration._
import scala.concurrent.duration._ import org.bigbluebutton.common2.redis._
import org.bigbluebutton.common2.bus._
class BbbWebApiGWApp( class BbbWebApiGWApp(
val oldMessageReceivedGW: OldMessageReceivedGW, val oldMessageReceivedGW: OldMessageReceivedGW,
@ -27,7 +29,7 @@ class BbbWebApiGWApp(
log.debug("*********** meetingManagerChannel = " + meetingManagerChannel) log.debug("*********** meetingManagerChannel = " + meetingManagerChannel)
private val jsonMsgToAkkaAppsBus = new JsonMsgToAkkaAppsBus private val jsonMsgToAkkaAppsBus = new JsonMsgToAkkaAppsBus
private val redisPublisher = new RedisPublisher(system) private val redisPublisher = new RedisPublisher(system, "BbbWebPub")
private val msgSender: MessageSender = new MessageSender(redisPublisher) private val msgSender: MessageSender = new MessageSender(redisPublisher)
private val messageSenderActorRef = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor") private val messageSenderActorRef = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor")
@ -55,7 +57,7 @@ class BbbWebApiGWApp(
msgToAkkaAppsEventBus.subscribe(msgToAkkaAppsToJsonActor, toAkkaAppsChannel) msgToAkkaAppsEventBus.subscribe(msgToAkkaAppsToJsonActor, toAkkaAppsChannel)
private val appsRedisSubscriberActor = system.actorOf( private val appsRedisSubscriberActor = system.actorOf(
AppsRedisSubscriberActor.props(receivedJsonMsgBus, oldMessageEventBus), "appsRedisSubscriberActor") WebRedisSubscriberActor.props(receivedJsonMsgBus, oldMessageEventBus), "appsRedisSubscriberActor")
private val receivedJsonMsgHdlrActor = system.actorOf( private val receivedJsonMsgHdlrActor = system.actorOf(
ReceivedJsonMsgHdlrActor.props(msgFromAkkaAppsEventBus), "receivedJsonMsgHdlrActor") ReceivedJsonMsgHdlrActor.props(msgFromAkkaAppsEventBus), "receivedJsonMsgHdlrActor")

View File

@ -3,16 +3,11 @@ package org.bigbluebutton.api2
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import scala.util.Try import scala.util.Try
import org.bigbluebutton.common2.redis.RedisConfiguration
trait SystemConfiguration { trait SystemConfiguration extends RedisConfiguration {
val config = ConfigFactory.load("bbb-web") override val config = ConfigFactory.load("bbb-web")
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
lazy val toAkkaAppsRedisChannel = Try(config.getString("redis.toAkkaAppsRedisChannel")).getOrElse("to-akka-apps-redis-channel")
lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel")
lazy val meetingManagerChannel = Try(config.getString("eventBus.meetingManagerChannel")).getOrElse("FOOOOOOOOO") lazy val meetingManagerChannel = Try(config.getString("eventBus.meetingManagerChannel")).getOrElse("FOOOOOOOOO")
lazy val fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-channel") lazy val fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-channel")
lazy val toAkkaAppsChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-channel") lazy val toAkkaAppsChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-channel")

View File

@ -4,7 +4,7 @@ import java.io.{PrintWriter, StringWriter}
import akka.actor.SupervisorStrategy.Resume import akka.actor.SupervisorStrategy.Resume
import akka.actor.{Actor, ActorLogging, OneForOneStrategy, Props} import akka.actor.{Actor, ActorLogging, OneForOneStrategy, Props}
import org.bigbluebutton.api2.endpoint.redis.MessageSender import org.bigbluebutton.common2.redis.MessageSender
import scala.concurrent.duration._ import scala.concurrent.duration._
object MessageSenderActor { object MessageSenderActor {

View File

@ -1,6 +1,7 @@
package org.bigbluebutton.api2.bus package org.bigbluebutton.api2.bus
import akka.actor.{Actor, ActorLogging, Props} import akka.actor.{Actor, ActorLogging, Props}
import org.bigbluebutton.common2.bus.OldReceivedJsonMessage
object OldMessageJsonReceiverActor{ object OldMessageJsonReceiverActor{
def props(gw: OldMessageReceivedGW): Props = Props(classOf[OldMessageJsonReceiverActor], gw) def props(gw: OldMessageReceivedGW): Props = Props(classOf[OldMessageJsonReceiverActor], gw)

View File

@ -1,6 +1,7 @@
package org.bigbluebutton.api2.bus package org.bigbluebutton.api2.bus
import org.bigbluebutton.api2.SystemConfiguration import org.bigbluebutton.api2.SystemConfiguration
import org.bigbluebutton.common2.bus._
import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.common2.msgs._
import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.JsonNode
import akka.actor.Actor import akka.actor.Actor

View File

@ -1,16 +1,14 @@
package org.bigbluebutton.api2.endpoint.redis package org.bigbluebutton.api2.endpoint.redis
import akka.actor.{Actor, ActorLogging, ActorSystem, Props} import akka.actor.{ Actor, ActorLogging, ActorSystem, Props }
import org.bigbluebutton.api2.SystemConfiguration import org.bigbluebutton.api2.SystemConfiguration
import redis.RedisClient import redis.RedisClient
case class RecordMeetingInfoMsg(meetingId: String, info: collection.immutable.Map[String, String]) case class RecordMeetingInfoMsg(meetingId: String, info: collection.immutable.Map[String, String])
case class RecordBreakoutInfoMsg(meetingId: String, info: collection.immutable.Map[String, String]) case class RecordBreakoutInfoMsg(meetingId: String, info: collection.immutable.Map[String, String])
case class AddBreakoutRoomMsg(parentId: String, breakoutId: String) case class AddBreakoutRoomMsg(parentId: String, breakoutId: String)
case class RemoveMeetingMsg(meetingId: String) case class RemoveMeetingMsg(meetingId: String)
object RedisDataStorageActor { object RedisDataStorageActor {
def props(system: ActorSystem): Props = Props(classOf[RedisDataStorageActor], system) def props(system: ActorSystem): Props = Props(classOf[RedisDataStorageActor], system)
} }
@ -24,13 +22,12 @@ class RedisDataStorageActor(val system: ActorSystem) extends Actor with ActorLog
redis.clientSetname("BbbWebStore") redis.clientSetname("BbbWebStore")
def receive = { def receive = {
case msg: RecordMeetingInfoMsg => handleRecordMeetingInfoMsg(msg) case msg: RecordMeetingInfoMsg => handleRecordMeetingInfoMsg(msg)
case msg: RecordBreakoutInfoMsg => handleRecordBreakoutInfoMsg(msg) case msg: RecordBreakoutInfoMsg => handleRecordBreakoutInfoMsg(msg)
case msg: AddBreakoutRoomMsg => handleAddBreakoutRoomMsg(msg) case msg: AddBreakoutRoomMsg => handleAddBreakoutRoomMsg(msg)
case msg: RemoveMeetingMsg => handleRemoveMeetingMsg(msg) case msg: RemoveMeetingMsg => handleRemoveMeetingMsg(msg)
} }
def handleRecordMeetingInfoMsg(msg: RecordMeetingInfoMsg): Unit = { def handleRecordMeetingInfoMsg(msg: RecordMeetingInfoMsg): Unit = {
redis.hmset("meeting:info:" + msg.meetingId, msg.info) redis.hmset("meeting:info:" + msg.meetingId, msg.info)
} }

View File

@ -1,34 +1,39 @@
package org.bigbluebutton.api2.endpoint.redis package org.bigbluebutton.api2.endpoint.redis
import java.io.{PrintWriter, StringWriter} import java.io.{ PrintWriter, StringWriter }
import java.net.InetSocketAddress import java.net.InetSocketAddress
import akka.actor.SupervisorStrategy.Resume import akka.actor.SupervisorStrategy.Resume
import akka.actor.{OneForOneStrategy, Props} import akka.actor.{ OneForOneStrategy, Props }
import redis.api.servers.ClientSetname import redis.api.servers.ClientSetname
import redis.actors.RedisSubscriberActor import redis.actors.RedisSubscriberActor
import redis.api.pubsub.{Message, PMessage} import redis.api.pubsub.{ Message, PMessage }
import scala.concurrent.duration._ import scala.concurrent.duration._
import org.bigbluebutton.api2.SystemConfiguration import org.bigbluebutton.api2._
import org.bigbluebutton.api2.bus._ import org.bigbluebutton.common2.redis._
import org.bigbluebutton.common2.redis.RedisConfiguration
import org.bigbluebutton.common2.bus._
object AppsRedisSubscriberActor extends SystemConfiguration { object WebRedisSubscriberActor extends RedisSubscriber with RedisConfiguration {
val channels = Seq(fromAkkaAppsRedisChannel) val channels = Seq(fromAkkaAppsRedisChannel)
val patterns = Seq("bigbluebutton:from-bbb-apps:*") val patterns = Seq("bigbluebutton:from-bbb-apps:*")
def props(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus): Props = def props(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus): Props =
Props(classOf[AppsRedisSubscriberActor], jsonMsgBus, oldMessageEventBus, Props(classOf[WebRedisSubscriberActor], jsonMsgBus, oldMessageEventBus,
redisHost, redisPort, redisHost, redisPort,
channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher")
} }
class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus, redisHost: String, class WebRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus, redisHost: String,
redisPort: Int, redisPort: Int,
channels: Seq[String] = Nil, patterns: Seq[String] = Nil) channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
extends RedisSubscriberActor(new InetSocketAddress(redisHost, redisPort), extends RedisSubscriberActor(
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { new InetSocketAddress(redisHost, redisPort),
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") })
with SystemConfiguration
with RedisAppSubscriberActor {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => { case e: Exception => {
@ -40,7 +45,6 @@ class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEve
} }
} }
// Set the name of this client to be able to distinguish when doing // Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli // CLIENT LIST on redis-cli
write(ClientSetname("Red5AppsSub").encodedRequest) write(ClientSetname("Red5AppsSub").encodedRequest)
@ -53,9 +57,10 @@ class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEve
} }
} }
def onPMessage(pmessage: PMessage) { override def onPMessage(pmessage: PMessage) {
log.debug(s"RECEIVED:\n ${pmessage.data.utf8String} \n") log.debug(s"RECEIVED:\n ${pmessage.data.utf8String} \n")
val receivedJsonMessage = new OldReceivedJsonMessage(pmessage.patternMatched, val receivedJsonMessage = new OldReceivedJsonMessage(
pmessage.patternMatched,
pmessage.channel, pmessage.data.utf8String) pmessage.channel, pmessage.data.utf8String)
oldMessageEventBus.publish(OldIncomingJsonMessage(fromAkkaAppsOldJsonChannel, receivedJsonMessage)) oldMessageEventBus.publish(OldIncomingJsonMessage(fromAkkaAppsOldJsonChannel, receivedJsonMessage))

View File

@ -1,23 +1,21 @@
package org.bigbluebutton.api.util package org.bigbluebutton.api.util
import org.scalatest._ class ParamsUtilTest extends UnitSpec {
class ParamsUtilTest extends UnitSpec { it should "strip out control chars from text" in {
val text = "a\u0000b\u0007c\u008fd"
it should "strip out control chars from text" in { val cleaned = ParamsUtil.stripControlChars(text)
val text = "a\u0000b\u0007c\u008fd" assert("abcd" == cleaned)
val cleaned = ParamsUtil.stripControlChars(text) }
assert("abcd" == cleaned)
} it should "complain about invalid chars in meetingId" in {
val meetingId = "Demo , Meeting"
it should "complain about invalid chars in meetingId" in { assert(ParamsUtil.isValidMeetingId(meetingId) == false)
val meetingId = "Demo , Meeting" }
assert(ParamsUtil.isValidMeetingId(meetingId) == false)
} it should "accept valid chars in meetingId" in {
val meetingId = "Demo Meeting - 123"
it should "accept valid chars in meetingId" in { assert(ParamsUtil.isValidMeetingId(meetingId) == true)
val meetingId = "Demo Meeting - 123" }
assert(ParamsUtil.isValidMeetingId(meetingId) == true)
} }
}

View File

@ -1,8 +1,7 @@
package org.bigbluebutton.api.util package org.bigbluebutton.api.util
import org.scalatest.FlatSpec import org.scalatest.FlatSpec
import org.scalatest.BeforeAndAfterAll import org.scalatest.BeforeAndAfterAll
import org.scalatest.WordSpec import org.scalatest.Matchers
import org.scalatest.Matchers
abstract class UnitSpec extends FlatSpec with Matchers with BeforeAndAfterAll
abstract class UnitSpec extends FlatSpec with Matchers with BeforeAndAfterAll

View File

@ -32,7 +32,7 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console",
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports")
Seq(Revolver.settings: _*) Seq(Revolver.settings: _*)
lazy val commonMessage = (project in file(".")).settings(name := "bbb-fsesl-client", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) lazy val bbbFSESLClient = (project in file(".")).settings(name := "bbb-fsesl-client", libraryDependencies ++= Dependencies.runtime).settings(compileSettings)
//----------- //-----------
// Packaging // Packaging
@ -52,7 +52,7 @@ crossPaths := false
// This forbids including Scala related libraries into the dependency // This forbids including Scala related libraries into the dependency
autoScalaLibrary := false autoScalaLibrary := false
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository"))) publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath + "/.m2/repository")))
//publishTo := { //publishTo := {
// val nexus = "https://oss.sonatype.org/" // val nexus = "https://oss.sonatype.org/"
@ -70,10 +70,10 @@ publishArtifact in Test := false
// http://www.scala-sbt.org/release/docs/Artifacts.html // http://www.scala-sbt.org/release/docs/Artifacts.html
// disable publishing the main API jar // disable publishing the main API jar
publishArtifact in (Compile, packageDoc) := false publishArtifact in(Compile, packageDoc) := false
// disable publishing the main sources jar // disable publishing the main sources jar
publishArtifact in (Compile, packageSrc) := false publishArtifact in(Compile, packageSrc) := false
pomIncludeRepository := { _ => false } pomIncludeRepository := { _ => false }
@ -82,14 +82,14 @@ pomExtra := (
<url>git@github.com:bigbluebutton/bigbluebutton.git</url> <url>git@github.com:bigbluebutton/bigbluebutton.git</url>
<connection>scm:git:git@github.com:bigbluebutton/bigbluebutton.git</connection> <connection>scm:git:git@github.com:bigbluebutton/bigbluebutton.git</connection>
</scm> </scm>
<developers> <developers>
<developer> <developer>
<id>ritzalam</id> <id>ritzalam</id>
<name>Richard Alam</name> <name>Richard Alam</name>
<url>http://www.bigbluebutton.org</url> <url>http://www.bigbluebutton.org</url>
</developer> </developer>
</developers>) </developers>)
licenses := Seq("Apache License, Version 2.0" -> url("http://opensource.org/licenses/Apache-2.0")) licenses := Seq("Apache License, Version 2.0" -> url("http://opensource.org/licenses/Apache-2.0"))
homepage := Some(url("http://www.bigbluebutton.org")) homepage := Some(url("http://www.bigbluebutton.org"))

View File

@ -1,16 +1,10 @@
package org.bigbluebutton.app.screenshare package org.bigbluebutton.app.screenshare
import scala.util.Try import scala.util.Try
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import org.bigbluebutton.common2.redis.RedisConfiguration
trait SystemConfiguration { trait SystemConfiguration extends RedisConfiguration {
//val config = ConfigFactory.load("screenshare-app")
val config = ConfigFactory.load()
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
lazy val meetingManagerChannel = Try(config.getString("eventBus.meetingManagerChannel")).getOrElse("NOT FROM APP CONF") lazy val meetingManagerChannel = Try(config.getString("eventBus.meetingManagerChannel")).getOrElse("NOT FROM APP CONF")

View File

@ -1,31 +0,0 @@
package org.bigbluebutton.app.screenshare.redis
import akka.actor.ActorRef
import akka.event.{ EventBus, LookupClassification }
case class ReceivedJsonMessage(channel: String, data: String)
case class IncomingJsonMessage(val topic: String, val payload: ReceivedJsonMessage)
class IncomingJsonMessageBus extends EventBus with LookupClassification {
type Event = IncomingJsonMessage
type Classifier = String
type Subscriber = ActorRef
// is used for extracting the classifier from the incoming events
override protected def classify(event: Event): Classifier = event.topic
// will be invoked for each event for all subscribers which registered themselves
// for the events classifier
override protected def publish(event: Event, subscriber: Subscriber): Unit = {
subscriber ! event.payload
}
// must define a full order over the subscribers, expressed as expected from
// `java.lang.Comparable.compare`
override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
a.compareTo(b)
// determines the initial size of the index data structure
// used internally (i.e. the expected number of different classifiers)
override protected def mapSize: Int = 128
}

View File

@ -57,7 +57,6 @@ dependencies {
compile 'org.easymock:easymock:3.6@jar' compile 'org.easymock:easymock:3.6@jar'
//redis //redis
compile "redis.clients:jedis:2.9.0"
compile 'org.apache.commons:commons-pool2:2.6.0' compile 'org.apache.commons:commons-pool2:2.6.0'
compile 'com.google.code.gson:gson:2.8.5' compile 'com.google.code.gson:gson:2.8.5'

View File

@ -26,10 +26,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
http://www.springframework.org/schema/util http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd http://www.springframework.org/schema/util/spring-util-2.0.xsd
"> ">
<!--
<bean id="redisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg index="0" value="${redis.host}"/>
<constructor-arg index="1" value="${redis.port}"/>
</bean>
-->
</beans> </beans>