diff --git a/akka-bbb-apps/build.sbt b/akka-bbb-apps/build.sbt index af6c93edc018133d6157c388642194f9447837e8..1a4da064d35b82d6e584ef2784cba7290eb5db75 100755 --- a/akka-bbb-apps/build.sbt +++ b/akka-bbb-apps/build.sbt @@ -1,33 +1,34 @@ -enablePlugins(JavaServerAppPackaging) - -name := "bbb-apps-akka" - -organization := "org.bigbluebutton" +import org.bigbluebutton.build._ -version := "0.0.2" +import scalariform.formatter.preferences._ +import com.typesafe.sbt.SbtScalariform +import com.typesafe.sbt.SbtScalariform.ScalariformKeys -scalaVersion := "2.12.6" +import com.typesafe.sbt.SbtNativePackager.autoImport._ -scalacOptions ++= Seq( - "-unchecked", - "-deprecation", - "-Xlint", - "-Ywarn-dead-code", - "-language:_", - "-target:jvm-1.8", - "-encoding", "UTF-8" -) +enablePlugins(JavaServerAppPackaging) -resolvers ++= Seq( - "spray repo" at "http://repo.spray.io/", - "rediscala" at "http://dl.bintray.com/etaty/maven", - "blindside-repos" at "http://blindside.googlecode.com/svn/repository/" +version := "0.0.3" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) ) -resolvers += Resolver.sonatypeRepo("releases") -resolvers += Resolver.typesafeRepo("releases") - -publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) ) +publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath + "/dev/repo/maven-repo/releases"))) // We want to have our jar files in lib_managed dir. // This way we'll have the right path when we import @@ -38,75 +39,15 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") -val akkaVersion = "2.5.14" -val scalaTestVersion = "3.0.5" - -libraryDependencies ++= { - Seq( - "ch.qos.logback" % "logback-classic" % "1.2.3" % "runtime", - "junit" % "junit" % "4.11", - "commons-codec" % "commons-codec" % "1.11", - "org.apache.commons" % "commons-lang3" % "3.7" - ) -} - -libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT" - -// 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" - -libraryDependencies += "com.softwaremill.quicklens" %% "quicklens" % "1.4.11" -libraryDependencies += "com.google.code.gson" % "gson" % "2.8.5" -libraryDependencies += "joda-time" % "joda-time" % "2.10" -libraryDependencies += "io.spray" % "spray-json_2.12" % "1.3.4" -libraryDependencies += "org.parboiled" % "parboiled-scala_2.12" % "1.1.8" - -// https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-scala_2.12 -libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.12" % "2.9.6" +lazy val bbbAppsAkka = (project in file(".")).settings(name := "bbb-apps-akka", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) +scalariformAutoformat := false -// 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" % akkaVersion % "test" - -// https://mvnrepository.com/artifact/org.scalactic/scalactic_2.12 -libraryDependencies += "org.scalactic" % "scalactic_2.12" % "3.0.3" % "test" - -// https://mvnrepository.com/artifact/org.scalatest/scalatest_2.12 -libraryDependencies += "org.scalatest" % "scalatest_2.12" % scalaTestVersion % "test" - -libraryDependencies += "org.mockito" % "mockito-core" % "2.21.0" % "test" - - - - -import com.typesafe.sbt.SbtScalariform - -import scalariform.formatter.preferences._ -import com.typesafe.sbt.SbtScalariform.ScalariformKeys - -SbtScalariform.defaultScalariformSettings - -ScalariformKeys.preferences := ScalariformKeys.preferences.value +scalariformPreferences := scalariformPreferences.value .setPreference(AlignSingleLineCaseStatements, true) - .setPreference(DoubleIndentClassDeclaration, true) + .setPreference(DoubleIndentConstructorArguments, true) .setPreference(AlignParameters, true) - - - //----------- // Packaging // @@ -127,19 +68,12 @@ val user = "bigbluebutton" val group = "bigbluebutton" // user which will execute the application -daemonUser in Linux := user +daemonUser in Linux := user // group which will execute the application -daemonGroup in Linux := group - -mappings in Universal <+= (packageBin in Compile, sourceDirectory ) map { (_, src) => - // Move the application.conf so the user can override settings here - 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" -} +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/logback.xml") -> "conf/logback.xml" + +debianPackageDependencies in Debian ++= Seq("java8-runtime-headless", "bash") diff --git a/akka-bbb-apps/project/Build.scala b/akka-bbb-apps/project/Build.scala deleted file mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/akka-bbb-apps/project/Dependencies.scala b/akka-bbb-apps/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..005bd86a3736ad7367cc7d73366786e266a29072 --- /dev/null +++ b/akka-bbb-apps/project/Dependencies.scala @@ -0,0 +1,83 @@ +package org.bigbluebutton.build + +import sbt._ +import Keys._ + +object Dependencies { + + object Versions { + // Scala + val scala = "2.12.7" + val junit = "4.12" + val junitInterface = "0.11" + val scalactic = "3.0.3" + + // Libraries + val akkaVersion = "2.5.17" + val gson = "2.8.5" + val jackson = "2.9.7" + val logback = "1.2.3" + val quicklens = "1.4.11" + val spray = "1.3.4" + + // Apache Commons + val lang = "3.8.1" + val codec = "1.11" + + // BigBlueButton + val bbbCommons = "0.0.20-SNAPSHOT" + + // Test + val scalaTest = "3.0.5" + val mockito = "2.23.0" + val akkaTestKit = "2.5.18" + } + + 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 googleGson = "com.google.code.gson" % "gson" % Versions.gson + val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson + val quicklens = "com.softwaremill.quicklens" %% "quicklens" % Versions.quicklens + val logback = "ch.qos.logback" % "logback-classic" % Versions.logback % "runtime" + val commonsCodec = "commons-codec" % "commons-codec" % Versions.codec + val sprayJson = "io.spray" % "spray-json_2.12" % Versions.spray + + val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang + + val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons + } + + object Test { + val scalaTest = "org.scalatest" %% "scalatest" % Versions.scalaTest % "test" + val junit = "junit" % "junit" % Versions.junit % "test" + val mockitoCore = "org.mockito" % "mockito-core" % Versions.mockito % "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.mockitoCore, + Test.scalactic, + Test.akkaTestKit) + + val runtime = Seq( + Compile.scalaLibrary, + Compile.scalaCompiler, + Compile.akkaActor, + Compile.akkaSl4fj, + Compile.googleGson, + Compile.jacksonModule, + Compile.quicklens, + Compile.logback, + Compile.commonsCodec, + Compile.sprayJson, + Compile.apacheLang, + Compile.bbbCommons) ++ testing +} \ No newline at end of file diff --git a/akka-bbb-apps/project/build.properties b/akka-bbb-apps/project/build.properties index a6e117b61042ee81c62ba3a0fc5210d9502944df..2e6e3d24608ee15e892ed3b16d84224f7667e808 100755 --- a/akka-bbb-apps/project/build.properties +++ b/akka-bbb-apps/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=1.2.6 \ No newline at end of file diff --git a/akka-bbb-apps/project/plugins.sbt b/akka-bbb-apps/project/plugins.sbt index ec155bbffce66550d65b058d63ef45fea0fa8b56..bc8c448553a2010f0c76ea69ccb7917f51ffef8a 100755 --- a/akka-bbb-apps/project/plugins.sbt +++ b/akka-bbb-apps/project/plugins.sbt @@ -1,11 +1,11 @@ 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" % "2.2.0") +addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2") -addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.6") +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.12") -addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") +addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") diff --git a/akka-bbb-apps/run.sh b/akka-bbb-apps/run.sh index 4015c4f1373a8caa1271bb9fa175c5940624bf89..fb253febdd48027f6337030036ed2384a76c1714 100755 --- a/akka-bbb-apps/run.sh +++ b/akka-bbb-apps/run.sh @@ -1,3 +1 @@ -sbt clean -sbt run - +sbt clean run diff --git a/akka-bbb-apps/src/main/resources/application.conf b/akka-bbb-apps/src/main/resources/application.conf index e6904f7e9d99b9aae44fb0428072f15ebef56a5c..591f22a88f5ef2613020407b8dc6f493bb6cf046 100755 --- a/akka-bbb-apps/src/main/resources/application.conf +++ b/akka-bbb-apps/src/main/resources/application.conf @@ -10,7 +10,7 @@ akka { loggers = ["akka.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" - rediscala-publish-worker-dispatcher { + redis-publish-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. @@ -18,7 +18,7 @@ akka { throughput = 512 } - rediscala-subscriber-worker-dispatcher { + redis-subscriber-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala index 74a852b9a5ce018e90f1a4db00c0762c53475526..82b54478421679653cf4b56766a8146660b531dc 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala @@ -1,12 +1,18 @@ package org.bigbluebutton -import akka.event.Logging -import akka.actor.ActorSystem -import org.bigbluebutton.endpoint.redis.{ AppsRedisSubscriberActor, KeepAliveRedisPublisher, RedisPublisher, RedisRecorderActor } +import org.bigbluebutton.common2.redis.RedisPublisher import org.bigbluebutton.core._ import org.bigbluebutton.core.bus._ 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 { @@ -22,7 +28,7 @@ object Boot extends App with SystemConfiguration { val outGW = new OutMessageGatewayImp(outBus2) - val redisPublisher = new RedisPublisher(system) + val redisPublisher = new RedisPublisher(system, "BbbAppsAkkaPub") val msgSender = new MessageSender(redisPublisher) val redisRecorderActor = system.actorOf(RedisRecorderActor.props(system), "redisRecorderActor") @@ -46,8 +52,5 @@ object Boot extends App with SystemConfiguration { val redisMessageHandlerActor = system.actorOf(ReceivedJsonMsgHandlerActor.props(bbbMsgBus, incomingJsonMessageBus)) incomingJsonMessageBus.subscribe(redisMessageHandlerActor, toAkkaAppsJsonChannel) - val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(incomingJsonMessageBus), "redis-subscriber") - - val keepAliveRedisPublisher = new KeepAliveRedisPublisher(system, redisPublisher) - + val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(system, incomingJsonMessageBus), "redis-subscriber") } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala index d2986d262a88d84363f7870e563f11d981312a6f..743a4894c4acec763614b2f9d50ca560e59ba24b 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala @@ -1,15 +1,10 @@ package org.bigbluebutton -import com.typesafe.config.ConfigFactory import scala.util.Try -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 bbbWebHost = Try(config.getString("services.bbbWebHost")).getOrElse("localhost") 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 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 fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-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 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 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 voiceConfRecordPath = Try(config.getString("voiceConf.recordPath")).getOrElse("/var/freeswitch/meetings") diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSender.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSender.scala deleted file mode 100755 index 250b1b3fba8c2b5f3a122f5cd54c168b7fdf30c4..0000000000000000000000000000000000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSender.scala +++ /dev/null @@ -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) - } -} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala index b9ed6467939bf9dfa7d6b605361704b0524cdf01..1659cea34f42f3158217f41a95c6488a2661e88c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala @@ -22,7 +22,6 @@ trait RegisterUserReqMsgHdlr { BbbCommonEnvCoreMsg(envelope, event) } - val guestPolicy = liveMeeting.guestsWaiting.getGuestPolicy().policy val guestStatus = msg.body.guestStatus val regUser = RegisteredUsers.create(msg.body.intUserId, msg.body.extUserId, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index 7d762dbb11a7ba9e0a4d168621abb52967782224..639adf2ca10bf647b747d88e3ce40b85b2161391 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -6,7 +6,9 @@ import com.fasterxml.jackson.databind.JsonNode import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.bus._ 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 { def props(eventBus: BbbMsgRouterEventBus, incomingJsonMessageBus: IncomingJsonMessageBus): Props = diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/RecordEvent.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/RecordEvent.scala index 3dfb958767ff633bdacc8d637a4f6d5bd743af33..cc18aec6b2d2f62dc28331fb8f88290ff4813588 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/RecordEvent.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/RecordEvent.scala @@ -21,7 +21,9 @@ package org.bigbluebutton.core.record.events import java.text.SimpleDateFormat +import scala.collection.Map import scala.collection.mutable.HashMap + import org.bigbluebutton.core.api.TimestampGenerator trait RecordEvent { @@ -70,6 +72,7 @@ trait RecordEvent { eventMap.put(EVENT, event) } + // @fixme : not used anymore /** * Convert the event into a Map to be recorded. * @return @@ -77,6 +80,7 @@ trait RecordEvent { final def toMap(): Map[String, String] = { eventMap.toMap } + } object RecordEvent extends RecordEvent { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala index 2dcaaf0f1f44a96019243bbd968727a8ecc684ff..0061b110d6c0e6437a8ae2a1f9386594b08935ce 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala @@ -3,8 +3,8 @@ package org.bigbluebutton.core2 import akka.actor.{ Actor, ActorLogging, Props } import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.common2.util.JsonUtil -import org.bigbluebutton.core.MessageSender +import org.bigbluebutton.common2.util.JsonUtil +import org.bigbluebutton.common2.redis.MessageSender object FromAkkaAppsMsgSenderActor { def props(msgSender: MessageSender): Props = Props(classOf[FromAkkaAppsMsgSenderActor], msgSender) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala new file mode 100755 index 0000000000000000000000000000000000000000..8e8ba2ebc6cdceb55bc6e8df8cb003267dd2bbb5 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AkkaAppsRedisSubscriberActor.scala @@ -0,0 +1,32 @@ +package org.bigbluebutton.endpoint.redis + +import org.bigbluebutton.SystemConfiguration +import org.bigbluebutton.common2.bus.IncomingJsonMessageBus +import org.bigbluebutton.common2.redis.{ RedisSubscriber, RedisSubscriberProvider } + +import akka.actor.ActorSystem +import akka.actor.Props + +object AppsRedisSubscriberActor extends RedisSubscriber { + + val channels = Seq(toAkkaAppsRedisChannel, fromVoiceConfRedisChannel) + val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*", "bigbluebutton:from-bbb-transcode:*") + + def props(system: ActorSystem, jsonMsgBus: IncomingJsonMessageBus): Props = + Props( + classOf[AppsRedisSubscriberActor], + system, jsonMsgBus, + redisHost, redisPort, + channels, patterns).withDispatcher("akka.redis-subscriber-worker-dispatcher") +} + +class AppsRedisSubscriberActor( + system: ActorSystem, + jsonMsgBus: IncomingJsonMessageBus, + redisHost: String, redisPort: Int, + channels: Seq[String] = Nil, patterns: Seq[String] = Nil) + extends RedisSubscriberProvider(system, "BbbAppsAkkaSub", channels, patterns, jsonMsgBus) with SystemConfiguration { + + addListener(toAkkaAppsJsonChannel) + subscribe() +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AppsRedisSubscriberActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AppsRedisSubscriberActor.scala deleted file mode 100755 index 5a5a1424f59eaee4f6c91c2714e74bead3251766..0000000000000000000000000000000000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/AppsRedisSubscriberActor.scala +++ /dev/null @@ -1,64 +0,0 @@ -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 redis.actors.RedisSubscriberActor -import redis.api.pubsub.{ Message, PMessage } - -import scala.concurrent.duration._ -import org.bigbluebutton.SystemConfiguration -import org.bigbluebutton.core.bus.{ IncomingJsonMessage, IncomingJsonMessageBus, ReceivedJsonMessage } -import redis.api.servers.ClientSetname - -object AppsRedisSubscriberActor extends SystemConfiguration { - - val TO_AKKA_APPS = "bbb:to-akka-apps" - val channels = Seq(toAkkaAppsRedisChannel, fromVoiceConfRedisChannel) - val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*", "bigbluebutton:from-bbb-transcode:*") - - def props(jsonMsgBus: IncomingJsonMessageBus): Props = - Props(classOf[AppsRedisSubscriberActor], jsonMsgBus, - redisHost, redisPort, - channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") -} - -class AppsRedisSubscriberActor(jsonMsgBus: IncomingJsonMessageBus, redisHost: String, - redisPort: Int, - channels: Seq[String] = Nil, patterns: Seq[String] = Nil) - extends RedisSubscriberActor( - new InetSocketAddress(redisHost, redisPort), - channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { - - override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { - case e: Exception => { - val sw: StringWriter = new StringWriter() - sw.write("An exception has been thrown on AppsRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n") - e.printStackTrace(new PrintWriter(sw)) - log.error(sw.toString()) - Resume - } - } - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - write(ClientSetname("BbbAppsAkkaSub").encodedRequest) - - def onMessage(message: Message) { - if (message.channel == toAkkaAppsRedisChannel || message.channel == fromVoiceConfRedisChannel) { - val receivedJsonMessage = new ReceivedJsonMessage(message.channel, message.data.utf8String) - //log.debug(s"RECEIVED:\n [${receivedJsonMessage.channel}] \n ${receivedJsonMessage.data} \n") - jsonMsgBus.publish(IncomingJsonMessage(toAkkaAppsJsonChannel, receivedJsonMessage)) - } - } - - 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) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/KeepAliveRedisPublisher.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/KeepAliveRedisPublisher.scala deleted file mode 100755 index 74aa6e4b7885620de866627bba075e45e28dba75..0000000000000000000000000000000000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/KeepAliveRedisPublisher.scala +++ /dev/null @@ -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()) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisPublisher.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisPublisher.scala deleted file mode 100755 index 6af8a64ebb05093023cc7e90a0f445cce3170b8b..0000000000000000000000000000000000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisPublisher.scala +++ /dev/null @@ -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)) - } - -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala index 7a01783d5b6448ad53fd98eb53a235f2829d284b..c3c68f726ad22021d7a1c68fc02aac5fb46cd217 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala @@ -1,40 +1,30 @@ package org.bigbluebutton.endpoint.redis -import akka.actor.{ Actor, ActorLogging, ActorSystem, Props } -import org.bigbluebutton.SystemConfiguration -import redis.RedisClient -import scala.concurrent.ExecutionContext.Implicits.global import scala.collection.immutable.StringOps +import scala.collection.JavaConverters._ + +import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.record.events._ +import org.bigbluebutton.common2.redis.RedisStorageProvider import org.bigbluebutton.core.apps.groupchats.GroupChatApp +import org.bigbluebutton.core.record.events._ + +import akka.actor.Actor +import akka.actor.ActorLogging +import akka.actor.ActorSystem +import akka.actor.Props object RedisRecorderActor { def props(system: ActorSystem): Props = Props(classOf[RedisRecorderActor], system) } -class RedisRecorderActor(val system: ActorSystem) - extends SystemConfiguration - with Actor with ActorLogging { - 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("BbbAppsAkkaRecorder") - - val COLON = ":" - - private def record(session: String, message: collection.immutable.Map[String, String]): Unit = { - for { - msgid <- redis.incr("global:nextRecordedMsgId") - key = "recording" + COLON + session + COLON + msgid - _ <- redis.hmset(key.mkString, message) - _ <- redis.expire(key.mkString, keysExpiresInSec) - key2 = "meeting" + COLON + session + COLON + "recordings" - _ <- redis.rpush(key2.mkString, msgid.toString) - result <- redis.expire(key2.mkString, keysExpiresInSec) - } yield result +class RedisRecorderActor(system: ActorSystem) + extends RedisStorageProvider(system, "BbbAppsAkkaRecorder") + with SystemConfiguration + with Actor with ActorLogging { + private def record(session: String, message: java.util.Map[java.lang.String, java.lang.String]): Unit = { + redis.recordAndExpire(session, message) } def receive = { @@ -121,7 +111,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMessage(msg.body.msg.message) ev.setColor(msg.body.msg.color) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } } @@ -129,7 +119,7 @@ class RedisRecorderActor(val system: ActorSystem) val ev = new ClearPublicChatRecordEvent() ev.setMeetingId(msg.header.meetingId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handlePresentationConversionCompletedEvtMsg(msg: PresentationConversionCompletedEvtMsg) { @@ -139,7 +129,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPresentationName(msg.body.presentation.id) ev.setOriginalFilename(msg.body.presentation.name) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) if (msg.body.presentation.current) { recordSharePresentationEvent(msg.header.meetingId, msg.body.podId, msg.body.presentation.id) @@ -154,7 +144,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setSlide(getPageNum(msg.body.pageId)) ev.setId(msg.body.pageId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleResizeAndMovePageEvtMsg(msg: ResizeAndMovePageEvtMsg) { @@ -168,7 +158,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setWidthRatio(msg.body.widthRatio) ev.setHeightRatio(msg.body.heightRatio) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleRemovePresentationEvtMsg(msg: RemovePresentationEvtMsg) { @@ -177,7 +167,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPodId(msg.body.podId) ev.setPresentationName(msg.body.presentationId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleSetPresentationDownloadableEvtMsg(msg: SetPresentationDownloadableEvtMsg) { @@ -187,7 +177,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPresentationName(msg.body.presentationId) ev.setDownloadable(msg.body.downloadable) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleSetCurrentPresentationEvtMsg(msg: SetCurrentPresentationEvtMsg) { @@ -200,7 +190,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPodId(msg.body.podId) ev.setCurrentPresenter(msg.body.currentPresenterId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleRemovePresentationPodEvtMsg(msg: RemovePresentationPodEvtMsg) { @@ -208,7 +198,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMeetingId(msg.header.meetingId) ev.setPodId(msg.body.podId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleSetPresenterInPodRespMsg(msg: SetPresenterInPodRespMsg) { @@ -217,7 +207,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPodId(msg.body.podId) ev.setNextPresenterId(msg.body.nextPresenterId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def recordSharePresentationEvent(meetingId: String, podId: String, presentationId: String) { @@ -227,7 +217,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPresentationName(presentationId) ev.setShare(true) - record(meetingId, ev.toMap) + record(meetingId, ev.toMap.asJava) } private def getPageNum(id: String): Integer = { @@ -266,7 +256,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPosition(annotation.position) ev.addAnnotation(annotation.annotationInfo) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleSendCursorPositionEvtMsg(msg: SendCursorPositionEvtMsg) { @@ -279,7 +269,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setXPercent(msg.body.xPercent) ev.setYPercent(msg.body.yPercent) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleClearWhiteboardEvtMsg(msg: ClearWhiteboardEvtMsg) { @@ -291,7 +281,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setUserId(msg.body.userId) ev.setFullClear(msg.body.fullClear) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUndoWhiteboardEvtMsg(msg: UndoWhiteboardEvtMsg) { @@ -302,7 +292,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setWhiteboardId(msg.body.whiteboardId) ev.setUserId(msg.body.userId) ev.setShapeId(msg.body.annotationId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserJoinedMeetingEvtMsg(msg: UserJoinedMeetingEvtMsg): Unit = { @@ -313,7 +303,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setName(msg.body.name) ev.setRole(msg.body.role) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserLeftMeetingEvtMsg(msg: UserLeftMeetingEvtMsg): Unit = { @@ -321,7 +311,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMeetingId(msg.header.meetingId) ev.setUserId(msg.body.intId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handlePresenterAssignedEvtMsg(msg: PresenterAssignedEvtMsg): Unit = { @@ -331,7 +321,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setName(msg.body.presenterName) ev.setAssignedBy(msg.body.assignedBy) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserEmojiChangedEvtMsg(msg: UserEmojiChangedEvtMsg) { handleUserStatusChange(msg.header.meetingId, msg.body.userId, "emojiStatus", msg.body.emoji) @@ -352,7 +342,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setStatus(statusName) ev.setValue(statusValue) - record(meetingId, ev.toMap) + record(meetingId, ev.toMap.asJava) } private def handleUserJoinedVoiceConfToClientEvtMsg(msg: UserJoinedVoiceConfToClientEvtMsg) { @@ -365,7 +355,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMuted(msg.body.muted) ev.setTalking(msg.body.talking) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserLeftVoiceConfToClientEvtMsg(msg: UserLeftVoiceConfToClientEvtMsg) { @@ -374,7 +364,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setBridge(msg.body.voiceConf) ev.setParticipant(msg.body.intId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserMutedVoiceEvtMsg(msg: UserMutedVoiceEvtMsg) { @@ -384,7 +374,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setParticipant(msg.body.intId) ev.setMuted(msg.body.muted) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserTalkingVoiceEvtMsg(msg: UserTalkingVoiceEvtMsg) { @@ -394,7 +384,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setParticipant(msg.body.intId) ev.setTalking(msg.body.talking) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleVoiceRecordingStartedEvtMsg(msg: VoiceRecordingStartedEvtMsg) { @@ -404,7 +394,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setRecordingTimestamp(msg.body.timestamp) ev.setFilename(msg.body.stream) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleVoiceRecordingStoppedEvtMsg(msg: VoiceRecordingStoppedEvtMsg) { @@ -414,7 +404,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setRecordingTimestamp(msg.body.timestamp) ev.setFilename(msg.body.stream) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleEditCaptionHistoryEvtMsg(msg: EditCaptionHistoryEvtMsg) { @@ -426,7 +416,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setLocaleCode(msg.body.localeCode) ev.setText(msg.body.text) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleScreenshareRtmpBroadcastStartedEvtMsg(msg: ScreenshareRtmpBroadcastStartedEvtMsg) { @@ -434,7 +424,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMeetingId(msg.header.meetingId) ev.setStreamPath(msg.body.stream) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleScreenshareRtmpBroadcastStoppedEvtMsg(msg: ScreenshareRtmpBroadcastStoppedEvtMsg) { @@ -442,7 +432,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMeetingId(msg.header.meetingId) ev.setStreamPath(msg.body.stream) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } /* @@ -462,7 +452,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setUserId(msg.body.setBy) ev.setRecordingStatus(msg.body.recording) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleRecordStatusResetSysMsg(msg: RecordStatusResetSysMsg) { @@ -471,7 +461,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setUserId(msg.body.setBy) ev.setRecordingStatus(msg.body.recording) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleWebcamsOnlyForModeratorChangedEvtMsg(msg: WebcamsOnlyForModeratorChangedEvtMsg) { @@ -480,14 +470,14 @@ class RedisRecorderActor(val system: ActorSystem) ev.setUserId(msg.body.setBy) ev.setWebcamsOnlyForModerator(msg.body.webcamsOnlyForModerator) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleEndAndKickAllSysMsg(msg: EndAndKickAllSysMsg): Unit = { val ev = new EndAndKickAllRecordEvent() ev.setMeetingId(msg.header.meetingId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleRecordingChapterBreakSysMsg(msg: RecordingChapterBreakSysMsg): Unit = { @@ -495,7 +485,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setMeetingId(msg.header.meetingId) ev.setChapterBreakTimestamp(msg.body.timestamp) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handlePollStartedEvtMsg(msg: PollStartedEvtMsg): Unit = { @@ -503,7 +493,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setPollId(msg.body.pollId) ev.setAnswers(msg.body.poll.answers) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handleUserRespondedToPollRecordMsg(msg: UserRespondedToPollRecordMsg): Unit = { @@ -512,7 +502,7 @@ class RedisRecorderActor(val system: ActorSystem) ev.setUserId(msg.header.userId) ev.setAnswerId(msg.body.answerId) - record(msg.header.meetingId, ev.toMap) + record(msg.header.meetingId, ev.toMap.asJava) } private def handlePollStoppedEvtMsg(msg: PollStoppedEvtMsg): Unit = { @@ -527,6 +517,6 @@ class RedisRecorderActor(val system: ActorSystem) val ev = new PollStoppedRecordEvent() ev.setPollId(pollId) - record(meetingId, ev.toMap) + record(meetingId, ev.toMap.asJava) } } diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala index fb2b3f5e7694a60e7140ea4158684e103b4a882b..3e57891347a7b653e8fe4392aea6854d7065ddc1 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala @@ -15,10 +15,16 @@ trait AppsTestFixtures { val meetingName = "test meeting" val record = false val voiceConfId = "85115" + val muteOnStart = true val deskshareConfId = "85115-DESKSHARE" val durationInMinutes = 10 val maxInactivityTimeoutMinutes = 120 - val warnMinutesBeforeMax = 5 + val warnMinutesBeforeMax = 30 + val meetingExpireIfNoUserJoinedInMinutes = 5 + val meetingExpireWhenLastUserLeftInMinutes = 10 + val userInactivityInspectTimerInMinutes = 60 + val userInactivityThresholdInMinutes = 10 + val userActivitySignResponseDelayInMinutes = 5 val autoStartRecording = false val allowStartStopRecording = false val webcamsOnlyForModerator = false; @@ -38,24 +44,19 @@ trait AppsTestFixtures { val red5DeskShareAppTestFixtures = "red5App" val metadata: collection.immutable.Map[String, String] = Map("foo" -> "bar", "bar" -> "baz", "baz" -> "foo") val screenshareProps = ScreenshareProps("TODO", "TODO", "TODO") - val breakoutProps = BreakoutProps(parentMeetingId, sequence, Vector()) + val breakoutProps = BreakoutProps(parentId = parentMeetingId, sequence = sequence, freeJoin = false, breakoutRooms = Vector()) val meetingProp = MeetingProp(name = meetingName, extId = externalMeetingId, intId = meetingId, isBreakout = isBreakout.booleanValue()) - val durationProps = DurationProps( - duration = durationInMinutes, - createdTime = createTime, createdDate = createDate, - maxInactivityTimeoutMinutes = maxInactivityTimeoutMinutes, - warnMinutesBeforeMax = warnMinutesBeforeMax, - meetingExpireIfNoUserJoinedInMinutes = 5, - meetingExpireWhenLastUserLeftInMinutes = 1 - ) + val durationProps = DurationProps(duration = durationInMinutes, createdTime = createTime, createdDate = createDate, maxInactivityTimeoutMinutes = maxInactivityTimeoutMinutes, warnMinutesBeforeMax = warnMinutesBeforeMax, + meetingExpireIfNoUserJoinedInMinutes = meetingExpireIfNoUserJoinedInMinutes, meetingExpireWhenLastUserLeftInMinutes = meetingExpireWhenLastUserLeftInMinutes, + userInactivityInspectTimerInMinutes = userInactivityInspectTimerInMinutes, userInactivityThresholdInMinutes = userInactivityInspectTimerInMinutes, userActivitySignResponseDelayInMinutes = userActivitySignResponseDelayInMinutes) val password = PasswordProp(moderatorPass = moderatorPassword, viewerPass = viewerPassword) val recordProp = RecordProp(record = record, autoStartRecording = autoStartRecording, allowStartStopRecording = allowStartStopRecording) val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg, modOnlyMessage = modOnlyMessage) - val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber) + val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart) val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, guestPolicy = guestPolicy) val metadataProp = new MetadataProp(metadata) @@ -84,7 +85,6 @@ trait AppsTestFixtures { val layouts = new Layouts() val wbModel = new WhiteboardModel() val presModel = new PresentationModel() - val breakoutRooms = new BreakoutRooms() val captionModel = new CaptionModel() val notesModel = new SharedNotesModel() val registeredUsers = new RegisteredUsers diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/domain/MeetingInactivityTrackerTests.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/domain/MeetingInactivityTrackerTests.scala index 6a09dc346bd76bba763afeea65f961be87b4daed..95f8ab07d9f674a95c649813b873fe8e5c11c6da 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/domain/MeetingInactivityTrackerTests.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/domain/MeetingInactivityTrackerTests.scala @@ -1,7 +1,6 @@ package org.bigbluebutton.core.domain import org.bigbluebutton.core.UnitSpec -import org.bigbluebutton.core.running.MeetingExpiryTrackerHelper import org.bigbluebutton.core.util.TimeUtil class MeetingInactivityTrackerTests extends UnitSpec { diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/GroupsChatTests.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/GroupsChatTests.scala index ca600fa0a2c3bff3f0db4fb9d6a95797f61ae74d..60246a571a7341bd1abca9ce3c484d690e92168a 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/GroupsChatTests.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/models/GroupsChatTests.scala @@ -2,7 +2,6 @@ package org.bigbluebutton.core.models import org.bigbluebutton.common2.msgs.{ GroupChatAccess, GroupChatUser } import org.bigbluebutton.core.UnitSpec -import org.bigbluebutton.core.domain.BbbSystemConst class GroupsChatTests extends UnitSpec { @@ -10,7 +9,7 @@ class GroupsChatTests extends UnitSpec { val gcId = "gc-id" val chatName = "Public" val userId = "uid-1" - val createBy = GroupChatUser(BbbSystemConst.SYSTEM_USER, BbbSystemConst.SYSTEM_USER) + val createBy = GroupChatUser("groupId", "groupname") val gc = GroupChatFactory.create(gcId, chatName, GroupChatAccess.PUBLIC, createBy, Vector.empty, Vector.empty) val user = GroupChatUser(userId, "User 1") val gc2 = gc.add(user) @@ -25,18 +24,16 @@ class GroupsChatTests extends UnitSpec { } "A GroupChat" should "be able to add, update, and remove msg" in { - val createBy = GroupChatUser(BbbSystemConst.SYSTEM_USER, BbbSystemConst.SYSTEM_USER) + val createBy = GroupChatUser("groupId", "groupname") val gcId = "gc-id" val chatName = "Public" - val userId = "uid-1" val gc = GroupChatFactory.create(gcId, chatName, GroupChatAccess.PUBLIC, createBy, Vector.empty, Vector.empty) val msgId1 = "msgid-1" val ts = System.currentTimeMillis() val hello = "Hello World!" val msg1 = GroupChatMessage(id = msgId1, timestamp = ts, correlationId = "cordId1", createdOn = ts, - updatedOn = ts, sender = createBy, - font = "arial", size = 12, color = "red", message = hello) + updatedOn = ts, sender = createBy, color = "red", message = hello) val gc2 = gc.add(msg1) assert(gc2.msgs.size == 1) @@ -45,8 +42,7 @@ class GroupsChatTests extends UnitSpec { val foo = "Foo bar" val ts2 = System.currentTimeMillis() val msg2 = GroupChatMessage(id = msgId2, timestamp = ts2, correlationId = "cordId2", createdOn = ts2, - updatedOn = ts2, sender = createBy, - font = "arial", size = 12, color = "red", message = foo) + updatedOn = ts2, sender = createBy, color = "red", message = foo) val gc3 = gc2.add(msg2) assert(gc3.msgs.size == 2) @@ -55,8 +51,7 @@ class GroupsChatTests extends UnitSpec { val msgId3 = "msgid-3" val ts3 = System.currentTimeMillis() val msg3 = GroupChatMessage(id = msgId3, timestamp = ts3, correlationId = "cordId3", createdOn = ts3, - updatedOn = ts3, sender = createBy, - font = "arial", size = 12, color = "red", message = baz) + updatedOn = ts3, sender = createBy, color = "red", message = baz) val gc4 = gc3.update(msg3) gc4.findMsgWithId(msgId3) match { diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/pubsub/sender/ReceivedJsonMsgHandlerTraitTests.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/pubsub/sender/ReceivedJsonMsgHandlerTraitTests.scala index 8de72a97a547dd9e08f8c75d76089b406df4574e..329383ad1512275c9afab734496cd35dfee05273 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/pubsub/sender/ReceivedJsonMsgHandlerTraitTests.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/pubsub/sender/ReceivedJsonMsgHandlerTraitTests.scala @@ -3,13 +3,13 @@ package org.bigbluebutton.core.pubsub.sender import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.{ AppsTestFixtures, UnitSpec } -import org.bigbluebutton.core.bus.{ BbbMsgEvent, BbbMsgRouterEventBus, ReceivedJsonMessage } +import org.bigbluebutton.core.bus.{ BbbMsgEvent, BbbMsgRouterEventBus } import org.bigbluebutton.core2.ReceivedMessageRouter import org.mockito.Mockito._ import org.scalatest.mockito.MockitoSugar class ReceivedJsonMsgHandlerTraitTests extends UnitSpec - with AppsTestFixtures with MockitoSugar with SystemConfiguration { + with AppsTestFixtures with MockitoSugar with SystemConfiguration { class MessageRouter(val eventBus: BbbMsgRouterEventBus) extends ReceivedMessageRouter { diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala index d4789a43739f5a05ca2d49e1d5eb65c9a844e564..907d352379aec626bc70dbb139878d14d3d7b412 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala @@ -46,9 +46,9 @@ object TestDataGen { def createUserFor(liveMeeting: LiveMeeting, regUser: RegisteredUser, presenter: Boolean): UserState = { val u = UserState(intId = regUser.id, extId = regUser.externId, name = regUser.name, role = regUser.role, guest = regUser.guest, authed = regUser.authed, guestStatus = regUser.guestStatus, - emoji = "none", locked = false, presenter, avatar = regUser.avatarURL) + emoji = "none", locked = false, presenter = false, avatar = regUser.avatarURL, clientType = "unknown", + userLeftFlag = UserLeftFlag(false, 0)) Users2x.add(liveMeeting.users2x, u) - u } } diff --git a/akka-bbb-fsesl/build.sbt b/akka-bbb-fsesl/build.sbt index 319345d682c45b7255b457ba2a3adafae985b767..020426a651d37ecdf2f70f96a43d7518c3f52d8d 100755 --- a/akka-bbb-fsesl/build.sbt +++ b/akka-bbb-fsesl/build.sbt @@ -1,26 +1,35 @@ -enablePlugins(JavaServerAppPackaging) - -name := "bbb-fsesl-akka" +import org.bigbluebutton.build._ -organization := "org.bigbluebutton" +import scalariform.formatter.preferences._ +import com.typesafe.sbt.SbtScalariform +import com.typesafe.sbt.SbtScalariform.ScalariformKeys -version := "0.0.1" +import com.typesafe.sbt.SbtNativePackager.autoImport._ -scalaVersion := "2.12.6" +enablePlugins(JavaServerAppPackaging) -scalacOptions ++= Seq( - "-unchecked", - "-deprecation", - "-Xlint", - "-Ywarn-dead-code", - "-language:_", - "-target:jvm-1.8", - "-encoding", "UTF-8" +version := "0.0.2" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) ) resolvers ++= Seq( "spray repo" at "http://repo.spray.io/", - "rediscala" at "http://dl.bintray.com/etaty/maven", "blindside-repos" at "http://blindside.googlecode.com/svn/repository/" ) @@ -37,63 +46,14 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") -val akkaVersion = "2.5.14" -val scalaTestV = "2.2.6" - - -libraryDependencies ++= { - 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 +Seq(Revolver.settings: _*) +lazy val bbbFseslAkka = (project in file(".")).settings(name := "bbb-fsesl-akka", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) -SbtScalariform.defaultScalariformSettings +scalariformAutoformat := false -ScalariformKeys.preferences := ScalariformKeys.preferences.value +scalariformPreferences := scalariformPreferences.value .setPreference(AlignSingleLineCaseStatements, true) - .setPreference(DoubleIndentClassDeclaration, true) + .setPreference(DoubleIndentConstructorArguments, true) .setPreference(AlignParameters, true) //----------- @@ -121,16 +81,7 @@ daemonUser in Linux := user // group which will execute the application daemonGroup in Linux := group -mappings in Universal <+= (packageBin in Compile, sourceDirectory ) map { (_, src) => - // Move the application.conf so the user can override settings here - 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" -} +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" debianPackageDependencies in Debian ++= Seq("java8-runtime-headless", "bash") diff --git a/akka-bbb-fsesl/project/Build.scala b/akka-bbb-fsesl/project/Build.scala deleted file mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/akka-bbb-fsesl/project/Dependencies.scala b/akka-bbb-fsesl/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..6eab6d49d1aef1ed3e82de5be48f8e915e1f741b --- /dev/null +++ b/akka-bbb-fsesl/project/Dependencies.scala @@ -0,0 +1,71 @@ +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" + + // BigBlueButton + val bbbCommons = "0.0.20-SNAPSHOT" + val bbbFsesl = "0.0.7-SNAPSHOT" + + // 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 + val commonsCodec = "commons-codec" % "commons-codec" % Versions.codec + + val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang + + 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.akkaSl4fj, + Compile.logback, + Compile.commonsCodec, + Compile.apacheLang, + Compile.bbbCommons, + Compile.bbbFseslClient) ++ testing +} diff --git a/akka-bbb-fsesl/project/build.properties b/akka-bbb-fsesl/project/build.properties index a6e117b61042ee81c62ba3a0fc5210d9502944df..2e6e3d24608ee15e892ed3b16d84224f7667e808 100755 --- a/akka-bbb-fsesl/project/build.properties +++ b/akka-bbb-fsesl/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=1.2.6 \ No newline at end of file diff --git a/akka-bbb-fsesl/project/plugins.sbt b/akka-bbb-fsesl/project/plugins.sbt index 56e1e39f39dc0e78ca98f35d7c98f4c833509120..bc8c448553a2010f0c76ea69ccb7917f51ffef8a 100755 --- a/akka-bbb-fsesl/project/plugins.sbt +++ b/akka-bbb-fsesl/project/plugins.sbt @@ -1,11 +1,11 @@ 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.sbt" % "sbt-native-packager" % "1.3.6") +addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2") + +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.12") -addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") +addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") diff --git a/akka-bbb-fsesl/run.sh b/akka-bbb-fsesl/run.sh index 4015c4f1373a8caa1271bb9fa175c5940624bf89..97d3f3534508e5c4b3e816a8481bb4ae16b80644 100755 --- a/akka-bbb-fsesl/run.sh +++ b/akka-bbb-fsesl/run.sh @@ -1,3 +1 @@ -sbt clean -sbt run - +sbt clean run \ No newline at end of file diff --git a/akka-bbb-fsesl/src/main/resources/application.conf b/akka-bbb-fsesl/src/main/resources/application.conf index 37ac46cfee4c9c4a83c09df12747a5bbfeda6ac0..ac1acc3b350de7a5059eccf75d229db145a5a592 100755 --- a/akka-bbb-fsesl/src/main/resources/application.conf +++ b/akka-bbb-fsesl/src/main/resources/application.conf @@ -1,37 +1,37 @@ -akka { - actor { - debug { - receive = on - } - } - loggers = ["akka.event.slf4j.Slf4jLogger"] - loglevel = "DEBUG" - stdout-loglevel = "DEBUG" - - rediscala-subscriber-worker-dispatcher { - mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" - # Throughput defines the maximum number of messages to be - # processed per actor before the thread jumps to the next actor. - # Set to 1 for as fair as possible. - throughput = 512 - } -} - - -freeswitch { - esl { - host="127.0.0.1" - port=8021 - password="ClueCon" - } - conf { - profile="cdquality" - } -} - -redis { - host="127.0.0.1" - port=6379 - password="" -} - +akka { + actor { + debug { + receive = on + } + } + loggers = ["akka.event.slf4j.Slf4jLogger"] + loglevel = "DEBUG" + stdout-loglevel = "DEBUG" + + redis-subscriber-worker-dispatcher { + mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" + # Throughput defines the maximum number of messages to be + # processed per actor before the thread jumps to the next actor. + # Set to 1 for as fair as possible. + throughput = 512 + } +} + + +freeswitch { + esl { + host="127.0.0.1" + port=8021 + password="ClueCon" + } + conf { + profile="cdquality" + } +} + +redis { + host="127.0.0.1" + port=6379 + password="" +} + diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/Boot.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/Boot.scala index 1ab8664c2b09a3489ca5c8aa60322a67ca47f57e..aad91e4ddd34681322d68a2a89cf912849dbfb55 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/Boot.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/Boot.scala @@ -1,19 +1,20 @@ package org.bigbluebutton -import akka.actor.{ ActorSystem } - -import org.bigbluebutton.endpoint.redis.{ AppsRedisSubscriberActor, RedisPublisher } +import org.bigbluebutton.common2.bus.IncomingJsonMessageBus +import org.bigbluebutton.common2.redis.RedisPublisher +import org.bigbluebutton.endpoint.redis.FSESLRedisSubscriberActor import org.bigbluebutton.freeswitch.{ RxJsonMsgHdlrActor, VoiceConferenceService } -import org.bigbluebutton.freeswitch.bus.InsonMsgBus import org.bigbluebutton.freeswitch.voice.FreeswitchConferenceEventListener import org.bigbluebutton.freeswitch.voice.freeswitch.{ ConnectionManager, ESLEventListener, FreeswitchApplication } import org.freeswitch.esl.client.manager.DefaultManagerConnection +import akka.actor.ActorSystem + object Boot extends App with SystemConfiguration { 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) @@ -30,10 +31,9 @@ object Boot extends App with SystemConfiguration { val fsApplication = new FreeswitchApplication(connManager, fsProfile) fsApplication.start() - val inJsonMsgBus = new InsonMsgBus + val inJsonMsgBus = new IncomingJsonMessageBus val redisMessageHandlerActor = system.actorOf(RxJsonMsgHdlrActor.props(fsApplication)) inJsonMsgBus.subscribe(redisMessageHandlerActor, toFsAppsJsonChannel) - val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(system, inJsonMsgBus), "redis-subscriber") - + val redisSubscriberActor = system.actorOf(FSESLRedisSubscriberActor.props(system, inJsonMsgBus), "redis-subscriber") } diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/SystemConfiguration.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/SystemConfiguration.scala index c9c776a410d714d2e28627a173e97a075500050e..188d202835c68438d44ba8fc7f26308fb929d5d2 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/SystemConfiguration.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/SystemConfiguration.scala @@ -1,23 +1,15 @@ package org.bigbluebutton -import com.typesafe.config.ConfigFactory import scala.util.Try -trait SystemConfiguration { - - val config = ConfigFactory.load() +import org.bigbluebutton.common2.redis.RedisConfiguration +trait SystemConfiguration extends RedisConfiguration { 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 eslPassword = Try(config.getString("freeswitch.esl.password")).getOrElse("ClueCon") 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 fromFsAppsJsonChannel = Try(config.getString("eventBus.fromFsAppsChannel")).getOrElse("from-fs-apps-json-channel") } diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/AppsRedisSubscriberActor.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/AppsRedisSubscriberActor.scala deleted file mode 100755 index 4f969be0b6465347544e038f95917fa3c8a1794e..0000000000000000000000000000000000000000 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/AppsRedisSubscriberActor.scala +++ /dev/null @@ -1,82 +0,0 @@ -package org.bigbluebutton.endpoint.redis - -import java.io.PrintWriter -import java.io.StringWriter -import java.net.InetSocketAddress - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.duration.DurationInt -import org.bigbluebutton.SystemConfiguration -import akka.actor.ActorSystem -import akka.actor.OneForOneStrategy -import akka.actor.Props -import akka.actor.SupervisorStrategy.Resume -import org.bigbluebutton.freeswitch.bus.{ InJsonMsg, InsonMsgBus, ReceivedJsonMsg } -import redis.actors.RedisSubscriberActor -import redis.api.pubsub.Message -import redis.api.pubsub.PMessage -import redis.api.servers.ClientSetname - -object AppsRedisSubscriberActor extends SystemConfiguration { - - val channels = Seq(toVoiceConfRedisChannel) - val patterns = Seq("bigbluebutton:to-voice-conf:*", "bigbluebutton:from-bbb-apps:*") - - def props(system: ActorSystem, inJsonMgBus: InsonMsgBus): Props = - Props(classOf[AppsRedisSubscriberActor], system, inJsonMgBus, - redisHost, redisPort, - channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") -} - -class AppsRedisSubscriberActor( - val system: ActorSystem, - inJsonMgBus: InsonMsgBus, redisHost: String, - redisPort: Int, - channels: Seq[String] = Nil, patterns: Seq[String] = Nil) - extends RedisSubscriberActor( - new InetSocketAddress(redisHost, redisPort), - channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { - - override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { - case e: Exception => { - val sw: StringWriter = new StringWriter() - sw.write("An exception has been thrown on AppsRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n") - e.printStackTrace(new PrintWriter(sw)) - log.error(sw.toString()) - Resume - } - } - - // val decoder = new FromJsonDecoder() - - var lastPongReceivedOn = 0L - system.scheduler.schedule(10 seconds, 10 seconds)(checkPongMessage()) - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - write(ClientSetname("BbbFsEslAkkaSub").encodedRequest) - - def checkPongMessage() { - val now = System.currentTimeMillis() - - if (lastPongReceivedOn != 0 && (now - lastPongReceivedOn > 30000)) { - log.error("FSESL pubsub error!"); - } - } - - def onMessage(message: Message) { - if (message.channel == toVoiceConfRedisChannel) { - val receivedJsonMessage = new ReceivedJsonMsg(message.channel, message.data.utf8String) - log.debug(s"RECEIVED:\n [${receivedJsonMessage.channel}] \n ${receivedJsonMessage.data} \n") - 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. ****") - } -} diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/FSESLRedisSubscriberActor.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/FSESLRedisSubscriberActor.scala new file mode 100755 index 0000000000000000000000000000000000000000..016bc9890b42407769b824287b1705f415063b9e --- /dev/null +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/FSESLRedisSubscriberActor.scala @@ -0,0 +1,46 @@ +package org.bigbluebutton.endpoint.redis + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.duration.DurationInt + +import org.bigbluebutton.SystemConfiguration +import org.bigbluebutton.common2.bus.IncomingJsonMessageBus +import org.bigbluebutton.common2.redis.{ RedisSubscriber, RedisSubscriberProvider } + +import akka.actor.ActorSystem +import akka.actor.Props + +object FSESLRedisSubscriberActor extends RedisSubscriber { + + val channels = Seq(toVoiceConfRedisChannel) + val patterns = Seq("bigbluebutton:to-voice-conf:*", "bigbluebutton:from-bbb-apps:*") + + def props(system: ActorSystem, inJsonMgBus: IncomingJsonMessageBus): Props = + Props( + classOf[FSESLRedisSubscriberActor], + system, inJsonMgBus, + redisHost, redisPort, + channels, patterns).withDispatcher("akka.redis-subscriber-worker-dispatcher") +} + +class FSESLRedisSubscriberActor( + system: ActorSystem, + inJsonMgBus: IncomingJsonMessageBus, + redisHost: String, redisPort: Int, + channels: Seq[String] = Nil, patterns: Seq[String] = Nil) + extends RedisSubscriberProvider(system, "BbbFsEslAkkaSub", channels, patterns, inJsonMgBus) with SystemConfiguration { + + var lastPongReceivedOn = 0L + system.scheduler.schedule(10 seconds, 10 seconds)(checkPongMessage()) + + def checkPongMessage() { + val now = System.currentTimeMillis() + + if (lastPongReceivedOn != 0 && (now - lastPongReceivedOn > 30000)) { + log.error("FSESL pubsub error!"); + } + } + + addListener(toFsAppsJsonChannel) + subscribe() +} \ No newline at end of file diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/RedisPublisher.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/RedisPublisher.scala deleted file mode 100755 index 11acf3d06d30cd2574e3e38a26befc09fae7166d..0000000000000000000000000000000000000000 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/endpoint/redis/RedisPublisher.scala +++ /dev/null @@ -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) - } - -} diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala index 378210c50ca7307ba0927d0d84fc0f18997471ee..dc839a9f3162c165c0ec3521fd1fa0a931147fd3 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/RxJsonMsgHdlrActor.scala @@ -1,12 +1,16 @@ package org.bigbluebutton.freeswitch -import akka.actor.{ Actor, ActorLogging, Props } -import com.fasterxml.jackson.databind.JsonNode import org.bigbluebutton.SystemConfiguration +import org.bigbluebutton.common2.bus.ReceivedJsonMessage import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.freeswitch.bus.ReceivedJsonMsg import org.bigbluebutton.freeswitch.voice.freeswitch.FreeswitchApplication +import com.fasterxml.jackson.databind.JsonNode + +import akka.actor.Actor +import akka.actor.ActorLogging +import akka.actor.Props + object RxJsonMsgHdlrActor { def props(fsApp: FreeswitchApplication): Props = Props(classOf[RxJsonMsgHdlrActor], fsApp) @@ -15,13 +19,13 @@ object RxJsonMsgHdlrActor { class RxJsonMsgHdlrActor(val fsApp: FreeswitchApplication) extends Actor with ActorLogging with SystemConfiguration with RxJsonMsgDeserializer { def receive = { - case msg: ReceivedJsonMsg => + case msg: ReceivedJsonMessage => log.debug("handling {} - {}", msg.channel, msg.data) handleReceivedJsonMessage(msg) case _ => // do nothing } - def handleReceivedJsonMessage(msg: ReceivedJsonMsg): Unit = { + def handleReceivedJsonMessage(msg: ReceivedJsonMessage): Unit = { for { envJsonNode <- JsonDeserializer.toBbbCommonEnvJsNodeMsg(msg.data) } yield handle(envJsonNode.envelope, envJsonNode.core) diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala index f82d08080087570a5b1102f2e972443904c10163..a72302e7f3fdbbd6093f8d7c206668e7fe251aca 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala @@ -2,9 +2,9 @@ package org.bigbluebutton.freeswitch import org.bigbluebutton.SystemConfiguration import org.bigbluebutton.freeswitch.voice.IVoiceConferenceService -import org.bigbluebutton.endpoint.redis.RedisPublisher 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 { diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/bus/InJsonMsgBus.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/bus/InJsonMsgBus.scala deleted file mode 100755 index 6f7bb865ea8c1002d7f6ff16655a3c2eb016568e..0000000000000000000000000000000000000000 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/bus/InJsonMsgBus.scala +++ /dev/null @@ -1,31 +0,0 @@ -package org.bigbluebutton.freeswitch.bus - -import akka.actor.ActorRef -import akka.event.{ EventBus, LookupClassification } - -case class ReceivedJsonMsg(channel: String, data: String) -case class InJsonMsg(val topic: String, val payload: ReceivedJsonMsg) - -class InsonMsgBus extends EventBus with LookupClassification { - type Event = InJsonMsg - 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 event’s 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 -} diff --git a/bbb-apps-common/build.sbt b/bbb-apps-common/build.sbt index 693e0e360cde0a9ce16593b4d235f9a6e0d9eb10..9a31293e2a7201ccbe2e0c514da9c4b7a4ac3c33 100755 --- a/bbb-apps-common/build.sbt +++ b/bbb-apps-common/build.sbt @@ -1,20 +1,23 @@ - -name := "bbb-apps-common" - -organization := "org.bigbluebutton" - -version := "0.0.3-SNAPSHOT" - -scalaVersion := "2.12.6" - -scalacOptions ++= Seq( - "-unchecked", - "-deprecation", - "-Xlint", - "-Ywarn-dead-code", - "-language:_", - "-target:jvm-1.8", - "-encoding", "UTF-8" +import org.bigbluebutton.build._ + +version := "0.0.4-SNAPSHOT" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) ) // We want to have our jar files in lib_managed dir. @@ -22,57 +25,8 @@ scalacOptions ++= Seq( // into eclipse. retrieveManaged := true -testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", "junitxml") - -testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") - -val akkaVersion = "2.5.14" -val scalaTestV = "2.2.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" % "2.5.1" -// https://mvnrepository.com/artifact/com.typesafe.akka/akka-slf4j_2.12 -libraryDependencies += "com.typesafe.akka" % "akka-slf4j_2.12" % "2.5.1" - -// https://mvnrepository.com/artifact/com.github.etaty/rediscala_2.12 -libraryDependencies += "com.github.etaty" % "rediscala_2.12" % "1.8.0" - -libraryDependencies += "com.softwaremill.quicklens" %% "quicklens" % "1.4.11" - -libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT" - -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 -libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.7" -libraryDependencies += "commons-io" % "commons-io" % "2.4" -libraryDependencies += "org.apache.commons" % "commons-pool2" % "2.6.0" -libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.23" % "provided" - - -libraryDependencies += "junit" % "junit" % "4.12" % "test" -libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" - -// 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.1" % "test" - -// https://mvnrepository.com/artifact/org.scalactic/scalactic_2.12 -libraryDependencies += "org.scalactic" % "scalactic_2.12" % "3.0.3" % "test" - -// https://mvnrepository.com/artifact/org.scalatest/scalatest_2.12 -libraryDependencies += "org.scalatest" % "scalatest_2.12" % "3.0.3" % "test" - -libraryDependencies += "org.mockito" % "mockito-core" % "2.7.22" % "test" - -seq(Revolver.settings: _*) +Seq(Revolver.settings: _*) +lazy val appsCommons = (project in file(".")).settings(name := "bbb-apps-common", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) //----------- // Packaging @@ -133,5 +87,3 @@ pomExtra := ( licenses := Seq("LGPL-3.0" -> url("http://opensource.org/licenses/LGPL-3.0")) homepage := Some(url("http://www.bigbluebutton.org")) - - diff --git a/bbb-apps-common/deploy.sh b/bbb-apps-common/deploy.sh index ccba754eaaf8182e665e94d1210571e23ebfb7b4..f829bc13dc598da480ee4e512a87c9436925a359 100755 --- a/bbb-apps-common/deploy.sh +++ b/bbb-apps-common/deploy.sh @@ -1,2 +1 @@ -sbt clean -sbt publish publishLocal +sbt clean publish publishLocal diff --git a/bbb-apps-common/project/Dependencies.scala b/bbb-apps-common/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..86f51a25ef7c86fa3e7f0a0f0a11c094d9bbf46d --- /dev/null +++ b/bbb-apps-common/project/Dependencies.scala @@ -0,0 +1,57 @@ +package org.bigbluebutton.build + +import sbt._ +import Keys._ + +object Dependencies { + + object Versions { + // Scala + val scala = "2.12.7" + + // Libraries + val akkaVersion = "2.5.17" + val gson = "2.8.5" + val sl4j = "1.7.25" + val quicklens = "1.4.11" + + // Apache Commons + val lang = "3.8.1" + val io = "2.6" + val pool = "2.6.0" + + // BigBlueButton + val bbbCommons = "0.0.20-SNAPSHOT" + } + + 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 googleGson = "com.google.code.gson" % "gson" % Versions.gson + val quicklens = "com.softwaremill.quicklens" %% "quicklens" % Versions.quicklens + val sl4jApi = "org.slf4j" % "slf4j-api" % Versions.sl4j % "provided" + + val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang + val apacheIo = "commons-io" % "commons-io" % Versions.io + val apachePool2 = "org.apache.commons" % "commons-pool2" % Versions.pool + + val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons + } + + val runtime = Seq( + Compile.scalaLibrary, + Compile.scalaCompiler, + Compile.akkaActor, + Compile.akkaSl4fj, + Compile.googleGson, + Compile.quicklens, + Compile.sl4jApi, + Compile.apacheLang, + Compile.apacheIo, + Compile.apachePool2, + Compile.bbbCommons) +} diff --git a/bbb-apps-common/project/build.properties b/bbb-apps-common/project/build.properties index a6e117b61042ee81c62ba3a0fc5210d9502944df..2e6e3d24608ee15e892ed3b16d84224f7667e808 100755 --- a/bbb-apps-common/project/build.properties +++ b/bbb-apps-common/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=1.2.6 \ No newline at end of file diff --git a/bbb-apps-common/project/plugins.sbt b/bbb-apps-common/project/plugins.sbt index 1a99bbcaf45749dbd833d7f6141744e2062bb181..3559bf68d62ef19f25fa810533bbe596eb022d02 100755 --- a/bbb-apps-common/project/plugins.sbt +++ b/bbb-apps-common/project/plugins.sbt @@ -1,9 +1,9 @@ -addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2") +addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") -addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") +addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ClientGWApplication.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ClientGWApplication.scala index 9f0bf267da240b1da0d28ae1f8231cfed4f00891..bad84e615018bd9a435aad7f8f63a3f95855270d 100644 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ClientGWApplication.scala +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ClientGWApplication.scala @@ -3,12 +3,16 @@ package org.bigbluebutton.client import akka.actor.ActorSystem import akka.event.Logging import org.bigbluebutton.client.bus._ -import org.bigbluebutton.client.endpoint.redis.{AppsRedisSubscriberActor, MessageSender, RedisPublisher} +import org.bigbluebutton.client.endpoint.redis.Red5AppsRedisSubscriberActor import org.bigbluebutton.client.meeting.MeetingManagerActor +import org.bigbluebutton.common2.redis.RedisPublisher import scala.concurrent.duration._ +import org.bigbluebutton.common2.redis.MessageSender +import org.bigbluebutton.api2.bus.MsgFromAkkaAppsEventBus +import org.bigbluebutton.common2.bus.JsonMsgFromAkkaAppsBus -class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfiguration{ +class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfiguration { implicit val system = ActorSystem("bbb-apps-common") implicit val timeout = akka.util.Timeout(3 seconds) @@ -20,7 +24,7 @@ class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfig private val msgToRedisEventBus = new MsgToRedisEventBus 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 meetingManagerActorRef = system.actorOf( @@ -41,19 +45,17 @@ class ClientGWApplication(val msgToClientGW: MsgToClientGW) extends SystemConfig msgToClientEventBus.subscribe(msgToClientJsonActor, toClientChannel) - private val appsRedisSubscriberActor = system.actorOf( - AppsRedisSubscriberActor.props(receivedJsonMsgBus), "appsRedisSubscriberActor") + private val appsRedisSubscriberActor = system.actorOf(Red5AppsRedisSubscriberActor.props(system, receivedJsonMsgBus), "appsRedisSubscriberActor") private val receivedJsonMsgHdlrActor = system.actorOf( ReceivedJsonMsgHdlrActor.props(msgFromAkkaAppsEventBus), "receivedJsonMsgHdlrActor") receivedJsonMsgBus.subscribe(receivedJsonMsgHdlrActor, fromAkkaAppsJsonChannel) - /** - * - * External Interface for Gateway - */ + * + * External Interface for Gateway + */ def connect(connInfo: ConnInfo): Unit = { //log.debug("**** ClientGWApplication connect " + connInfo) diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/MsgToRedisActor.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/MsgToRedisActor.scala index 94b37ae92489caf176caa2a5b3191dbaeb4d3fd4..5a3ce496ff2c1827b741c8106adf66693af2f2c1 100644 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/MsgToRedisActor.scala +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/MsgToRedisActor.scala @@ -1,10 +1,10 @@ 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.util.JsonUtil -import org.bigbluebutton.client.endpoint.redis.MessageSender +import org.bigbluebutton.common2.util.JsonUtil import org.bigbluebutton.common2.msgs.LookUpUserReqMsg +import org.bigbluebutton.common2.redis.MessageSender object MsgToRedisActor { def props(msgSender: MessageSender): Props = @@ -20,11 +20,10 @@ class MsgToRedisActor(msgSender: MessageSender) def handle(msg: BbbCommonEnvJsNodeMsg): Unit = { val json = JsonUtil.toJson(msg) - + msg.envelope.name match { case LookUpUserReqMsg.NAME => msgSender.send(toThirdPartyRedisChannel, json) - case _ => msgSender.send(toAkkaAppsRedisChannel, json) + case _ => msgSender.send(toAkkaAppsRedisChannel, json) } } - } diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedJsonMsgHdlrActor.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedJsonMsgHdlrActor.scala index d18cb333ed7e2cbd1066db5c11e61bf3e50160e8..ea6c3a3b660418de17a5c7969212f142d6f9e95e 100755 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedJsonMsgHdlrActor.scala +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedJsonMsgHdlrActor.scala @@ -1,11 +1,13 @@ package org.bigbluebutton.client import akka.actor.{Actor, ActorLogging, Props} -import org.bigbluebutton.client.bus.{JsonMsgFromAkkaApps, MsgFromAkkaApps, MsgFromAkkaAppsEventBus} import org.bigbluebutton.common2.msgs.BbbCommonEnvJsNodeMsg import org.bigbluebutton.common2.util.JsonUtil -import scala.util.{Failure, Success} +import scala.util.{Failure, Success} +import org.bigbluebutton.common2.bus.JsonMsgFromAkkaApps +import org.bigbluebutton.api2.bus.MsgFromAkkaAppsEventBus +import org.bigbluebutton.api2.bus.MsgFromAkkaApps object ReceivedJsonMsgHdlrActor { diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedMessageRouter.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedMessageRouter.scala index 701be0b1654e89eb0a0d7b7cad51305b7b72be7d..232720efbf4c61140f6ec0d5ddfe963e189cfd27 100755 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedMessageRouter.scala +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/ReceivedMessageRouter.scala @@ -1,6 +1,6 @@ -package org.bigbluebutton.client - -import org.bigbluebutton.client.bus.{MsgFromAkkaApps, MsgFromAkkaAppsEventBus} +package org.bigbluebutton.client + +import org.bigbluebutton.api2.bus.{ MsgFromAkkaApps, MsgFromAkkaAppsEventBus } trait ReceivedMessageRouter { val msgFromAkkaAppsEventBus: MsgFromAkkaAppsEventBus diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/SystemConfiguration.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/SystemConfiguration.scala index 26e7528bbbb99e0b0424c9ca0e269c0cde477089..0f9d34cfadcaa854d871330a1434928744281ebd 100644 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/SystemConfiguration.scala +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/SystemConfiguration.scala @@ -1,17 +1,10 @@ package org.bigbluebutton.client import scala.util.Try -import com.typesafe.config.ConfigFactory -trait SystemConfiguration { - val config = ConfigFactory.load() +import org.bigbluebutton.common2.redis.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 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") +trait SystemConfiguration extends RedisConfiguration { lazy val toThirdPartyRedisChannel = Try(config.getString("redis.toThirdPartyRedisChannel")).getOrElse("to-third-party-redis-channel") lazy val fromThirdPartyRedisChannel = Try(config.getString("redis.fromThirdPartyRedisChannel")).getOrElse("from-third-party-redis-channel") lazy val fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-channel") @@ -19,8 +12,4 @@ trait SystemConfiguration { lazy val fromClientChannel = Try(config.getString("eventBus.fromClientChannel")).getOrElse("from-client-channel") lazy val toClientChannel = Try(config.getString("eventBus.toClientChannel")).getOrElse("to-client-channel") lazy val fromAkkaAppsJsonChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-json-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") } diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/bus/JsonMsgFromAkkaAppsBus.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/bus/JsonMsgFromAkkaAppsBus.scala deleted file mode 100755 index ad28aa0618eb0ce5298feb8be9383ff2850d4c5c..0000000000000000000000000000000000000000 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/bus/JsonMsgFromAkkaAppsBus.scala +++ /dev/null @@ -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 event’s 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 - -} diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/bus/MsgFromAkkaAppsEventBus.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/bus/MsgFromAkkaAppsEventBus.scala deleted file mode 100755 index 20dc5055368e2084c2f8c3dc50e6fcf88f870135..0000000000000000000000000000000000000000 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/bus/MsgFromAkkaAppsEventBus.scala +++ /dev/null @@ -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 event’s 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 -} diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/AppsRedisSubscriberActor.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/AppsRedisSubscriberActor.scala deleted file mode 100644 index 2d3a30fe97fac898b5d91ae743c4c096d5c67658..0000000000000000000000000000000000000000 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/AppsRedisSubscriberActor.scala +++ /dev/null @@ -1,62 +0,0 @@ -package org.bigbluebutton.client.endpoint.redis - -import akka.actor.{ActorLogging, OneForOneStrategy, Props} -import akka.actor.SupervisorStrategy.Resume -import java.io.{PrintWriter, StringWriter} -import java.net.InetSocketAddress - -import redis.actors.RedisSubscriberActor -import redis.api.pubsub.{Message, PMessage} - -import scala.concurrent.duration._ -import org.bigbluebutton.client._ -import org.bigbluebutton.client.bus.{JsonMsgFromAkkaApps, JsonMsgFromAkkaAppsBus, JsonMsgFromAkkaAppsEvent} -import redis.api.servers.ClientSetname - -object AppsRedisSubscriberActor extends SystemConfiguration { - - val channels = Seq(fromAkkaAppsRedisChannel, fromAkkaAppsWbRedisChannel, fromAkkaAppsChatRedisChannel, fromAkkaAppsPresRedisChannel, fromThirdPartyRedisChannel) - val patterns = Seq("bigbluebutton:from-bbb-apps:*") - - def props(jsonMsgBus: JsonMsgFromAkkaAppsBus): Props = - Props(classOf[AppsRedisSubscriberActor], jsonMsgBus, - redisHost, redisPort, - channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") -} - -class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, redisHost: String, - redisPort: Int, - channels: Seq[String] = Nil, patterns: Seq[String] = Nil) - extends RedisSubscriberActor(new InetSocketAddress(redisHost, redisPort), - channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) - with SystemConfiguration with ActorLogging { - - override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { - case e: Exception => { - val sw: StringWriter = new StringWriter() - sw.write("An exception has been thrown on AppsRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n") - e.printStackTrace(new PrintWriter(sw)) - log.error(sw.toString()) - Resume - } - } - - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - write(ClientSetname("Red5AppsSub").encodedRequest) - - def onMessage(message: Message) { - if (channels.contains(message.channel)) { - //log.debug(s"RECEIVED:\n ${message.data.utf8String} \n") - val receivedJsonMessage = new JsonMsgFromAkkaApps(message.channel, message.data.utf8String) - jsonMsgBus.publish(JsonMsgFromAkkaAppsEvent(fromAkkaAppsJsonChannel, receivedJsonMessage)) - } - - } - - 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) - } -} diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/KeepAliveRedisPublisher.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/KeepAliveRedisPublisher.scala deleted file mode 100755 index 131a2d46ceec85cc9d5f870ca32f381c70f797d9..0000000000000000000000000000000000000000 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/KeepAliveRedisPublisher.scala +++ /dev/null @@ -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()) - } -} diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/MessageSender.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/MessageSender.scala deleted file mode 100755 index 191af624c8c0e67aa8be845784a1ca9942ed3255..0000000000000000000000000000000000000000 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/MessageSender.scala +++ /dev/null @@ -1,8 +0,0 @@ -package org.bigbluebutton.client.endpoint.redis - -class MessageSender(publisher: RedisPublisher) { - - def send(channel: String, data: String) { - publisher.publish(channel, data) - } -} diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/Red5AppsRedisSubscriberActor.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/Red5AppsRedisSubscriberActor.scala new file mode 100644 index 0000000000000000000000000000000000000000..0281a091f34ae86e23e4494eef8682934775e904 --- /dev/null +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/Red5AppsRedisSubscriberActor.scala @@ -0,0 +1,50 @@ +package org.bigbluebutton.client.endpoint.redis + +import org.bigbluebutton.common2.redis.RedisSubscriberProvider +import io.lettuce.core.pubsub.RedisPubSubListener +import org.bigbluebutton.common2.bus.JsonMsgFromAkkaApps +import org.bigbluebutton.common2.redis.RedisConfiguration +import org.bigbluebutton.client.SystemConfiguration +import akka.actor.ActorSystem +import org.bigbluebutton.common2.redis.RedisSubscriber +import org.bigbluebutton.common2.bus.JsonMsgFromAkkaAppsBus +import akka.actor.Props +import org.bigbluebutton.common2.bus.JsonMsgFromAkkaAppsEvent + +object Red5AppsRedisSubscriberActor extends RedisSubscriber with RedisConfiguration with SystemConfiguration { + + val channels = Seq(fromAkkaAppsRedisChannel, fromAkkaAppsWbRedisChannel, fromAkkaAppsChatRedisChannel, fromAkkaAppsPresRedisChannel, fromThirdPartyRedisChannel) + val patterns = Seq("bigbluebutton:from-bbb-apps:*") + + def props(system: ActorSystem, jsonMsgBus: JsonMsgFromAkkaAppsBus): Props = + Props( + classOf[Red5AppsRedisSubscriberActor], + system, jsonMsgBus, + redisHost, redisPort, + channels, patterns).withDispatcher("akka.redis-subscriber-worker-dispatcher") +} + +class Red5AppsRedisSubscriberActor(system: ActorSystem, jsonMsgBus: JsonMsgFromAkkaAppsBus, + redisHost: String, redisPort: Int, + channels: Seq[String] = Nil, patterns: Seq[String] = Nil) + extends RedisSubscriberProvider(system, "Red5AppsSub", channels, patterns, null) with SystemConfiguration { + + override def addListener(appChannel: String) { + connection.addListener(new RedisPubSubListener[String, String] { + def message(channel: String, message: String): Unit = { + if (channels.contains(channel)) { + val receivedJsonMessage = new JsonMsgFromAkkaApps(channel, message) + jsonMsgBus.publish(JsonMsgFromAkkaAppsEvent(fromAkkaAppsJsonChannel, receivedJsonMessage)) + } + } + def message(pattern: String, channel: String, message: String): Unit = { log.info("Subscribed to channel {} with pattern {}", channel, pattern) } + def psubscribed(pattern: String, count: Long): Unit = { log.info("Subscribed to pattern {}", pattern) } + def punsubscribed(pattern: String, count: Long): Unit = { log.info("Unsubscribed from pattern {}", pattern) } + def subscribed(channel: String, count: Long): Unit = { log.info("Subscribed to pattern {}", channel) } + def unsubscribed(channel: String, count: Long): Unit = { log.info("Unsubscribed from channel {}", channel) } + }) + } + + addListener(null) + subscribe() +} diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/RedisPublisher.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/RedisPublisher.scala deleted file mode 100755 index 379b15f5dec53f025e454613d7c8b2a08bdcf042..0000000000000000000000000000000000000000 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/endpoint/redis/RedisPublisher.scala +++ /dev/null @@ -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)) - } - -} diff --git a/bbb-common-message/build.sbt b/bbb-common-message/build.sbt index 29cf68bec63494dc7c7a58eb54b78c7748c6a525..054aa4acd34f7ae83ac5ea420818bfcf71ade0fd 100755 --- a/bbb-common-message/build.sbt +++ b/bbb-common-message/build.sbt @@ -1,19 +1,23 @@ -name := "bbb-common-message" - -organization := "org.bigbluebutton" - -version := "0.0.19-SNAPSHOT" - -scalaVersion := "2.12.6" - -scalacOptions ++= Seq( - "-unchecked", - "-deprecation", - "-Xlint", - "-Ywarn-dead-code", - "-language:_", - "-target:jvm-1.8", - "-encoding", "UTF-8" +import org.bigbluebutton.build._ + +version := "0.0.20-SNAPSHOT" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) ) resolvers += Resolver.sonatypeRepo("releases") @@ -26,32 +30,8 @@ retrieveManaged := true testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", "junitxml") testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") -libraryDependencies ++= { - Seq( - "com.google.code.gson" % "gson" % "2.5" - )} - -// 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 - -libraryDependencies += "junit" % "junit" % "4.12" % "test" -libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" - -// https://mvnrepository.com/artifact/org.scalactic/scalactic_2.12 -libraryDependencies += "org.scalactic" % "scalactic_2.12" % "3.0.3" % "test" - -// For generating test reports -libraryDependencies += "org.pegdown" % "pegdown" % "1.6.0" % "test" - -// https://mvnrepository.com/artifact/org.scalatest/scalatest_2.12 -libraryDependencies += "org.scalatest" % "scalatest_2.12" % "3.0.3" % "test" - -// https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-scala_2.12 -libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.12" % "2.9.6" - -seq(Revolver.settings: _*) +Seq(Revolver.settings: _*) +lazy val commonMessage = (project in file(".")).settings(name := "bbb-common-message", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) //----------- // Packaging @@ -71,12 +51,12 @@ seq(Revolver.settings: _*) // This forbids including Scala related libraries into the dependency //autoScalaLibrary := false -/*************************** -* When developing, change the version above to x.x.x-SNAPSHOT then use the file resolver to -* publish to the local maven repo using "sbt publish" -*/ +/** ************************* + * When developing, change the version above to x.x.x-SNAPSHOT then use the file resolver to + * publish to the local maven repo using "sbt publish" + */ // Uncomment this to publish to local maven repo while commenting out the nexus repo -publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository"))) +publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath + "/.m2/repository"))) // Comment this out when publishing to local maven repo using SNAPSHOT version. @@ -101,15 +81,14 @@ pomExtra := ( <url>git@github.com:bigbluebutton/bigbluebutton.git</url> <connection>scm:git:git@github.com:bigbluebutton/bigbluebutton.git</connection> </scm> - <developers> - <developer> - <id>ritzalam</id> - <name>Richard Alam</name> - <url>http://www.bigbluebutton.org</url> - </developer> - </developers>) - + <developers> + <developer> + <id>ritzalam</id> + <name>Richard Alam</name> + <url>http://www.bigbluebutton.org</url> + </developer> + </developers>) + licenses := Seq("LGPL-3.0" -> url("http://opensource.org/licenses/LGPL-3.0")) homepage := Some(url("http://www.bigbluebutton.org")) - diff --git a/bbb-common-message/deploy.sh b/bbb-common-message/deploy.sh index ccba754eaaf8182e665e94d1210571e23ebfb7b4..f829bc13dc598da480ee4e512a87c9436925a359 100755 --- a/bbb-common-message/deploy.sh +++ b/bbb-common-message/deploy.sh @@ -1,2 +1 @@ -sbt clean -sbt publish publishLocal +sbt clean publish publishLocal diff --git a/bbb-common-message/project/Build.scala b/bbb-common-message/project/Build.scala deleted file mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bbb-common-message/project/Dependencies.scala b/bbb-common-message/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..c8d886208a730623e74fade96419511c92e62676 --- /dev/null +++ b/bbb-common-message/project/Dependencies.scala @@ -0,0 +1,68 @@ +package org.bigbluebutton.build + +import sbt._ +import Keys._ + +object Dependencies { + + object Versions { + // Scala + val scala = "2.12.7" + val junit = "4.12" + val junitInterface = "0.11" + val scalactic = "3.0.3" + + // Libraries + val akkaVersion = "2.5.17" + val gson = "2.8.5" + val jackson = "2.9.7" + val sl4j = "1.7.25" + val red5 = "1.0.10-M5" + val pool = "2.6.0" + + // Redis + val lettuce = "5.1.3.RELEASE" + + // Test + val scalaTest = "3.0.5" + } + + 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 googleGson = "com.google.code.gson" % "gson" % Versions.gson + val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson + val sl4jApi = "org.slf4j" % "slf4j-api" % Versions.sl4j % "runtime" + val red5 = "org.red5" % "red5-server-common" % Versions.red5 + val apachePool2 = "org.apache.commons" % "commons-pool2" % Versions.pool + + val lettuceCore = "io.lettuce" % "lettuce-core" % Versions.lettuce + } + + object Test { + val scalaTest = "org.scalatest" %% "scalatest" % Versions.scalaTest % "test" + val junit = "junit" % "junit" % Versions.junit % "test" + val junitInteface = "com.novocode" % "junit-interface" % Versions.junitInterface % "test" + val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test" + } + + val testing = Seq( + Test.scalaTest, + Test.junit, + Test.junitInteface, + Test.scalactic) + + val runtime = Seq( + Compile.scalaLibrary, + Compile.scalaCompiler, + Compile.akkaActor, + Compile.googleGson, + Compile.jacksonModule, + Compile.sl4jApi, + Compile.red5, + Compile.apachePool2, + Compile.lettuceCore) ++ testing +} diff --git a/bbb-common-message/project/build.properties b/bbb-common-message/project/build.properties index a6e117b61042ee81c62ba3a0fc5210d9502944df..2e6e3d24608ee15e892ed3b16d84224f7667e808 100755 --- a/bbb-common-message/project/build.properties +++ b/bbb-common-message/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=1.2.6 \ No newline at end of file diff --git a/bbb-common-message/project/plugins.sbt b/bbb-common-message/project/plugins.sbt index 5ab7b095f69a2b3d8a3bf5350fa7e7e1a64f8f2f..3559bf68d62ef19f25fa810533bbe596eb022d02 100755 --- a/bbb-common-message/project/plugins.sbt +++ b/bbb-common-message/project/plugins.sbt @@ -2,8 +2,8 @@ addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") -addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") +addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/EventRecordingService.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/Keys.java old mode 100755 new mode 100644 similarity index 50% rename from bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/EventRecordingService.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/Keys.java index d534387e2e99c3a2a0c0b38bdb7511a69bf0a0d3..96509383d5f8e564b9f480baa862bc2277a6b0c0 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/EventRecordingService.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/Keys.java @@ -1,7 +1,7 @@ /** * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ * -* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). * * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software @@ -16,28 +16,13 @@ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. * */ -package org.bigbluebutton.app.screenshare; +package org.bigbluebutton.common2.redis; -import java.util.Map; - -import redis.clients.jedis.Jedis; - -public class EventRecordingService { - private static final String COLON = ":"; - - private final String host; - private final int port; - - public EventRecordingService(String host, int port) { - this.host = host; - this.port = port; - } - - public void record(String meetingId, Map<String, String> event) { - Jedis jedis = new Jedis(host, port); - Long msgid = jedis.incr("global:nextRecordedMsgId"); - jedis.hmset("recording:" + meetingId + COLON + msgid, event); - jedis.rpush("meeting:" + meetingId + COLON + "recordings", msgid.toString()); - } +public final class Keys { + public static final String MEETING = "meeting-"; + public static final String MEETINGS = "meetings"; + public static final String MEETING_INFO = "meeting:info:"; + public static final String BREAKOUT_MEETING = "meeting:breakout:"; + public static final String BREAKOUT_ROOMS = "meeting:breakout:rooms:"; } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/RedisAwareCommunicator.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/RedisAwareCommunicator.java new file mode 100644 index 0000000000000000000000000000000000000000..23dc26d26f04721273a3a8f552001d87dfd0ed8a --- /dev/null +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/RedisAwareCommunicator.java @@ -0,0 +1,98 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ + +package org.bigbluebutton.common2.redis; + +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.slf4j.Logger; + +import io.lettuce.core.RedisClient; +import io.lettuce.core.event.Event; +import io.lettuce.core.event.EventBus; +import io.lettuce.core.event.connection.ConnectedEvent; +import io.lettuce.core.event.connection.ConnectionActivatedEvent; +import io.lettuce.core.event.connection.ConnectionDeactivatedEvent; +import io.lettuce.core.event.connection.DisconnectedEvent; +import reactor.core.Disposable; + +public abstract class RedisAwareCommunicator { + + protected RedisClient redisClient; + + protected Disposable eventBusSubscription; + + protected EventBus eventBus; + + protected String host; + protected String password; + protected int port; + protected String clientName; + protected int expireKey; + + public abstract void start(); + + public abstract void stop(); + + public void setPassword(String password) { + this.password = password; + } + + protected void connectionStatusHandler(Event event, Logger log) { + if (event instanceof ConnectedEvent) { + log.info("Connected to redis"); + } else if (event instanceof ConnectionActivatedEvent) { + log.info("Connected to redis activated"); + } else if (event instanceof DisconnectedEvent) { + log.info("Disconnected from redis"); + } else if (event instanceof ConnectionDeactivatedEvent) { + log.info("Connected to redis deactivated"); + } + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public void setHost(String host) { + this.host = host; + } + + public void setPort(int port) { + this.port = port; + } + + public void setExpireKey(int expireKey) { + this.expireKey = expireKey; + } + + protected GenericObjectPoolConfig createPoolingConfig() { + GenericObjectPoolConfig config = new GenericObjectPoolConfig(); + config.setMaxTotal(32); + config.setMaxIdle(8); + config.setMinIdle(1); + config.setTestOnBorrow(true); + config.setTestOnReturn(true); + config.setTestWhileIdle(true); + config.setNumTestsPerEvictionRun(12); + config.setMaxWaitMillis(5000); + config.setTimeBetweenEvictionRunsMillis(60000); + config.setBlockWhenExhausted(true); + return config; + } +} diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/RedisStorageService.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/RedisStorageService.java new file mode 100644 index 0000000000000000000000000000000000000000..19f844bc159ef7979c4dbcf1b9f546d2067adb0e --- /dev/null +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/RedisStorageService.java @@ -0,0 +1,116 @@ +/** +* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ +* +* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +* +* This program is free software; you can redistribute it and/or modify it under the +* terms of the GNU Lesser General Public License as published by the Free Software +* Foundation; either version 3.0 of the License, or (at your option) any later +* version. +* +* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License along +* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. +* +*/ + +package org.bigbluebutton.common2.redis; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.api.sync.RedisCommands; + +public class RedisStorageService extends RedisAwareCommunicator { + + private static Logger log = LoggerFactory.getLogger(RedisStorageService.class); + + StatefulRedisConnection<String, String> connection; + + public void start() { + log.info("Starting RedisStorageService with client name: {}", clientName); + RedisURI redisUri = RedisURI.Builder.redis(this.host, this.port).withClientName(this.clientName) + .withPassword(this.password).build(); + + redisClient = RedisClient.create(redisUri); + redisClient.setOptions(ClientOptions.builder().autoReconnect(true).build()); + eventBus = redisClient.getResources().eventBus(); + eventBusSubscription = eventBus.get().subscribe(e -> connectionStatusHandler(e, log)); + + connection = redisClient.connect(); + } + + public void stop() { + eventBusSubscription.dispose(); + connection.close(); + redisClient.shutdown(); + log.info("RedisStorageService Stopped"); + } + + public void recordMeetingInfo(String meetingId, Map<String, String> info) { + log.debug("Storing meeting {} metadata {}", meetingId, info); + recordMeeting(Keys.MEETING_INFO + meetingId, info); + } + + public void recordBreakoutInfo(String meetingId, Map<String, String> breakoutInfo) { + log.debug("Saving breakout metadata in {}", meetingId); + recordMeeting(Keys.BREAKOUT_MEETING + meetingId, breakoutInfo); + } + + public void addBreakoutRoom(String parentId, String breakoutId) { + log.debug("Saving breakout room for meeting {}", parentId); + RedisCommands<String, String> commands = connection.sync(); + commands.sadd(Keys.BREAKOUT_ROOMS + parentId, breakoutId); + } + + public void record(String meetingId, Map<String, String> event) { + log.debug("Recording meeting event {} inside a transaction", meetingId); + RedisCommands<String, String> commands = connection.sync(); + Long msgid = commands.incr("global:nextRecordedMsgId"); + commands.hmset("recording:" + meetingId + ":" + msgid, event); + commands.rpush("meeting:" + meetingId + ":" + "recordings", Long.toString(msgid)); + } + + // @fixme: not used anywhere + public void removeMeeting(String meetingId) { + log.debug("Removing meeting meeting {} inside a transaction", meetingId); + RedisCommands<String, String> commands = connection.sync(); + commands.del(Keys.MEETING + meetingId); + commands.srem(Keys.MEETINGS + meetingId); + } + + public void recordAndExpire(String meetingId, Map<String, String> event) { + log.debug("Recording meeting event {} inside a transaction", meetingId); + RedisCommands<String, String> commands = connection.sync(); + + Long msgid = commands.incr("global:nextRecordedMsgId"); + String key = "recording:" + meetingId + ":" + msgid; + commands.hmset(key, event); + /** + * We set the key to expire after 14 days as we are still recording the + * event into redis even if the meeting is not recorded. (ralam sept 23, + * 2015) + */ + commands.expire(key, expireKey); + key = "meeting:" + meetingId + ":recordings"; + commands.rpush(key, Long.toString(msgid)); + commands.expire(key, expireKey); + } + + private String recordMeeting(String key, Map<String, String> info) { + log.debug("Storing metadata {}", info); + String result = ""; + RedisCommands<String, String> commands = connection.sync(); + result = commands.hmset(key, info); + return result; + } +} \ No newline at end of file diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageDistributor.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageDistributor.java similarity index 89% rename from bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageDistributor.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageDistributor.java index b51ed206c8f6ea6b5da5e3681709dbfe103f6f3b..89c8e9e46587090caa945a3a28fd8cb8529add65 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageDistributor.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageDistributor.java @@ -1,4 +1,4 @@ -package org.bigbluebutton.red5.pubsub; +package org.bigbluebutton.common2.redis.pubsub; import java.util.Set; @@ -22,4 +22,4 @@ public class MessageDistributor { listener.handleMessage(pattern, channel, message); } } -} \ No newline at end of file +} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageHandler.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageHandler.java similarity index 85% rename from bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageHandler.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageHandler.java index b94db88559d8e7d351690cd88b72ad4ba228099a..95bbde9e690becf55776d73e61a8ddd548e32365 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageHandler.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageHandler.java @@ -16,8 +16,8 @@ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. * */ -package org.bigbluebutton.voiceconf.messaging; +package org.bigbluebutton.common2.redis.pubsub; public interface MessageHandler { - void handleMessage(String pattern, String channel, String message); + void handleMessage(String pattern, String channel, String message); } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageReceiver.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageReceiver.java new file mode 100755 index 0000000000000000000000000000000000000000..ade4b5d648f11a4da9ba29adbb72de43d921edce --- /dev/null +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageReceiver.java @@ -0,0 +1,121 @@ +package org.bigbluebutton.common2.redis.pubsub; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.bigbluebutton.common2.redis.RedisAwareCommunicator; +import org.red5.logging.Red5LoggerFactory; +import org.slf4j.Logger; + +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.RedisURI; +import io.lettuce.core.pubsub.RedisPubSubListener; +import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; +import io.lettuce.core.pubsub.api.async.RedisPubSubAsyncCommands; +import io.lettuce.core.support.ConnectionPoolSupport; + +public class MessageReceiver extends RedisAwareCommunicator { + private static Logger log = Red5LoggerFactory.getLogger(MessageReceiver.class, "video"); + + private ReceivedMessageHandler handler; + + GenericObjectPool<StatefulRedisPubSubConnection<String, String>> connectionPool; + + private final Executor runExec = Executors.newSingleThreadExecutor(); + + private volatile boolean receiveMessage = false; + + private final String FROM_BBB_APPS_PATTERN = "from-akka-apps-redis-channel"; + + public void start() { + log.info("Ready to receive messages from Redis pubsub."); + receiveMessage = true; + + RedisURI redisUri = RedisURI.Builder.redis(this.host, this.port).withClientName(this.clientName).build(); + if (!this.password.isEmpty()) { + redisUri.setPassword(this.password); + } + + redisClient = RedisClient.create(redisUri); + redisClient.setOptions(ClientOptions.builder().autoReconnect(true).build()); + eventBus = redisClient.getResources().eventBus(); + eventBusSubscription = eventBus.get().subscribe(e -> connectionStatusHandler(e, log)); + + connectionPool = ConnectionPoolSupport.createGenericObjectPool(() -> redisClient.connectPubSub(), + createPoolingConfig()); + + Runnable messageReceiver = new Runnable() { + public void run() { + if (receiveMessage) { + try (StatefulRedisPubSubConnection<String, String> connection = connectionPool.borrowObject()) { + if (receiveMessage) { + connection.addListener(new MessageListener()); + + RedisPubSubAsyncCommands<String, String> async = connection.async(); + RedisFuture<Void> future = async.subscribe(FROM_BBB_APPS_PATTERN); + } + } catch (Exception e) { + log.error("Error resubscribing to channels: ", e); + } + } + } + }; + + runExec.execute(messageReceiver); + } + + public void stop() { + receiveMessage = false; + connectionPool.close(); + redisClient.shutdown(); + log.info("MessageReceiver Stopped"); + } + + public void setMessageHandler(ReceivedMessageHandler handler) { + this.handler = handler; + } + + private class MessageListener implements RedisPubSubListener<String, String> { + + @Override + public void message(String channel, String message) { + handler.handleMessage("", channel, message); + } + + @Override + public void message(String pattern, String channel, String message) { + log.debug("RECEIVED onPMessage" + channel + " message=\n" + message); + Runnable task = new Runnable() { + public void run() { + handler.handleMessage(pattern, channel, message); + } + }; + + runExec.execute(task); + } + + @Override + public void subscribed(String channel, long count) { + log.debug("Subscribed to the channel: " + channel); + } + + @Override + public void psubscribed(String pattern, long count) { + log.debug("Subscribed to the pattern: " + pattern); + } + + @Override + public void unsubscribed(String channel, long count) { + log.debug("Unsubscribed from the channel: " + channel); + } + + @Override + public void punsubscribed(String pattern, long count) { + log.debug("Unsubscribed from the pattern: " + pattern); + } + } + +} diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageSender.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageSender.java new file mode 100755 index 0000000000000000000000000000000000000000..8209f5bf76934d9959a385861ef773f184845bd4 --- /dev/null +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageSender.java @@ -0,0 +1,94 @@ +package org.bigbluebutton.common2.redis.pubsub; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.bigbluebutton.common2.redis.RedisAwareCommunicator; +import org.red5.logging.Red5LoggerFactory; +import org.slf4j.Logger; + +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.async.RedisAsyncCommands; +import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; +import io.lettuce.core.support.ConnectionPoolSupport; + +public class MessageSender extends RedisAwareCommunicator { + private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton"); + + GenericObjectPool<StatefulRedisPubSubConnection<String, String>> connectionPool; + + private volatile boolean sendMessage = false; + + private final Executor msgSenderExec = Executors.newSingleThreadExecutor(); + private final Executor runExec = Executors.newSingleThreadExecutor(); + private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>(); + + public void stop() { + sendMessage = false; + connectionPool.close(); + redisClient.shutdown(); + } + + public void start() { + RedisURI redisUri = RedisURI.Builder.redis(this.host, this.port).withClientName(this.clientName).build(); + if (!this.password.isEmpty()) { + redisUri.setPassword(this.password); + } + + redisClient = RedisClient.create(redisUri); + redisClient.setOptions(ClientOptions.builder().autoReconnect(true).build()); + eventBus = redisClient.getResources().eventBus(); + eventBusSubscription = eventBus.get().subscribe(e -> connectionStatusHandler(e, log)); + + connectionPool = ConnectionPoolSupport.createGenericObjectPool(() -> redisClient.connectPubSub(), + createPoolingConfig()); + + log.info("Redis org.bigbluebutton.red5.pubsub.message publisher starting!"); + try { + sendMessage = true; + + Runnable messageSender = new Runnable() { + public void run() { + while (sendMessage) { + try { + MessageToSend msg = messages.take(); + publish(msg.getChannel(), msg.getMessage()); + } catch (InterruptedException e) { + log.warn("Failed to get org.bigbluebutton.common2.redis.pubsub from queue."); + } + } + } + }; + msgSenderExec.execute(messageSender); + } catch (Exception e) { + log.error("Error subscribing to channels: " + e.getMessage()); + } + + } + + public void send(String channel, String message) { + MessageToSend msg = new MessageToSend(channel, message); + messages.add(msg); + } + + private void publish(final String channel, final String message) { + Runnable task = new Runnable() { + public void run() { + try (StatefulRedisPubSubConnection<String, String> connection = connectionPool.borrowObject()) { + RedisAsyncCommands<String, String> async = connection.async(); + RedisFuture<Long> future = async.publish(channel, message); + } catch (Exception e) { + log.warn("Cannot publish the org.bigbluebutton.red5.pubsub.message to redis", e); + } + } + }; + + runExec.execute(task); + } +} diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageToSend.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageToSend.java new file mode 100755 index 0000000000000000000000000000000000000000..dba49444b87ae7ac2d2e9040ff7d44a6ffd81bd9 --- /dev/null +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/MessageToSend.java @@ -0,0 +1,19 @@ +package org.bigbluebutton.common2.redis.pubsub; + +public class MessageToSend { + private final String channel; + private final String message; + + public MessageToSend(String channel, String message) { + this.channel = channel; + this.message = message; + } + + public String getChannel() { + return channel; + } + + public String getMessage() { + return message; + } +} diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessage.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/ReceivedMessage.java similarity index 87% rename from bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessage.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/ReceivedMessage.java index 41c775f739fc95f8e0c827ff1aa4a2adf6976ee5..01f893f309ef0ae497cdcc54a6808e0f252c72a2 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessage.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/ReceivedMessage.java @@ -1,4 +1,4 @@ -package org.bigbluebutton.red5.pubsub; +package org.bigbluebutton.common2.redis.pubsub; public class ReceivedMessage { private final String pattern; diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessageHandler.java b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/ReceivedMessageHandler.java similarity index 90% rename from bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessageHandler.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/ReceivedMessageHandler.java index ddafee0b6e8b2897c8da27a344c24e7ad63cd8fe..ed296626114b185eaf805ef21a73e665416778f3 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessageHandler.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common2/redis/pubsub/ReceivedMessageHandler.java @@ -1,15 +1,16 @@ -package org.bigbluebutton.red5.pubsub; +package org.bigbluebutton.common2.redis.pubsub; - -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; +import org.red5.logging.Red5LoggerFactory; +import org.slf4j.Logger; + public class ReceivedMessageHandler { - private static Logger log = Red5LoggerFactory.getLogger(ReceivedMessageHandler.class, "video"); + private static Logger log = Red5LoggerFactory + .getLogger(ReceivedMessageHandler.class/* , "video" */); private BlockingQueue<ReceivedMessage> receivedMessages = new LinkedBlockingQueue<ReceivedMessage>(); diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/bus/IncomingJsonMessageBus.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/IncomingJsonMessageBus.scala old mode 100755 new mode 100644 similarity index 94% rename from akka-bbb-apps/src/main/scala/org/bigbluebutton/core/bus/IncomingJsonMessageBus.scala rename to bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/IncomingJsonMessageBus.scala index f2e9aa281de9441af7bf0fe3fe1c7e63f91fa59d..96dbff59b4312665dcd909d73d3e3a3d1b102731 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/bus/IncomingJsonMessageBus.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/IncomingJsonMessageBus.scala @@ -1,4 +1,4 @@ -package org.bigbluebutton.core.bus +package org.bigbluebutton.common2.bus import akka.actor.ActorRef import akka.event.{ EventBus, LookupClassification } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/JsonMsgFromAkkaAppsBus.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/JsonMsgFromAkkaAppsBus.scala old mode 100755 new mode 100644 similarity index 88% rename from bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/JsonMsgFromAkkaAppsBus.scala rename to bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/JsonMsgFromAkkaAppsBus.scala index 5d26e2c23bb7a1c4f27a150d64a8a1fe4f4a0907..871f6f76f9948b4fc7b7fd0abbdf3cbb9bdd6c6b --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/JsonMsgFromAkkaAppsBus.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/JsonMsgFromAkkaAppsBus.scala @@ -1,7 +1,7 @@ -package org.bigbluebutton.api2.bus +package org.bigbluebutton.common2.bus import akka.actor.ActorRef -import akka.event.{EventBus, LookupClassification} +import akka.event.{ EventBus, LookupClassification } case class JsonMsgFromAkkaApps(name: String, data: String) 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 // `java.lang.Comparable.compare` override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int = - a.compareTo(b) + a.compareTo(b) // determines the initial size of the index data structure // used internally (i.e. the expected number of different classifiers) diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MsgFromAkkaAppsEventBus.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/MsgFromAkkaAppsEventBus.scala old mode 100755 new mode 100644 similarity index 91% rename from bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MsgFromAkkaAppsEventBus.scala rename to bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/MsgFromAkkaAppsEventBus.scala index e9f25b91a5f9e2f8f224bed7e482334204ea806a..097df4a29c433f8e7b8e3dc1702696f1b8a2ad12 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MsgFromAkkaAppsEventBus.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/MsgFromAkkaAppsEventBus.scala @@ -2,9 +2,9 @@ package org.bigbluebutton.api2.bus import akka.actor.ActorRef 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 { type Event = MsgFromAkkaApps diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageEventBus.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/OldMessageEventBus.scala similarity index 86% rename from bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageEventBus.scala rename to bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/OldMessageEventBus.scala index cccd288cdcbf317ad7ea7da62761dcbdfcb4e9f6..9b7c6bdd0b248a80efe49dc062501f0d472338dc 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageEventBus.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/bus/OldMessageEventBus.scala @@ -1,7 +1,8 @@ -package org.bigbluebutton.api2.bus +package org.bigbluebutton.common2.bus import akka.actor.ActorRef import akka.event.{EventBus, LookupClassification} +import akka.actor.actorRef2Scala case class OldReceivedJsonMessage(pattern: String, channel: String, msg: String) case class OldIncomingJsonMessage(val topic: String, val payload: OldReceivedJsonMessage) @@ -11,7 +12,7 @@ class OldMessageEventBus extends EventBus with LookupClassification { type Classifier = String 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 // will be invoked for each event for all subscribers which registered themselves diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/MessageSender.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/MessageSender.scala similarity index 71% rename from bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/MessageSender.scala rename to bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/MessageSender.scala index be38ef420165f015adbeb0a6675f4f213dacd304..2426a353e6d687ebfe073acc28337f48b961444a 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/MessageSender.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/MessageSender.scala @@ -1,4 +1,4 @@ -package org.bigbluebutton.api2.endpoint.redis +package org.bigbluebutton.common2.redis class MessageSender(publisher: RedisPublisher) { diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisClientProvider.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisClientProvider.scala new file mode 100644 index 0000000000000000000000000000000000000000..afeba57bf44c5604908cbc22711342ee580fa1a0 --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisClientProvider.scala @@ -0,0 +1,15 @@ +package org.bigbluebutton.common2.redis + +import akka.actor.ActorSystem +import io.lettuce.core.ClientOptions +import io.lettuce.core.RedisClient +import io.lettuce.core.RedisURI + +abstract class RedisClientProvider(val system: ActorSystem, val clientName: String) extends RedisConfiguration { + // Set the name of this client to be able to distinguish when doing + // CLIENT LIST on redis-cli + val redisUri = RedisURI.Builder.redis(redisHost, redisPort).withClientName(clientName).withPassword(redisPassword).build() + + var redis = RedisClient.create(redisUri) + redis.setOptions(ClientOptions.builder().autoReconnect(true).build()) +} diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisConfiguration.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisConfiguration.scala new file mode 100644 index 0000000000000000000000000000000000000000..8dcfd16ff578dc24aa0049318a72e050b8344881 --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisConfiguration.scala @@ -0,0 +1,25 @@ +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("") + lazy val redisExpireKey = Try(config.getInt("redis.keyExpiry")).getOrElse(1209600) + + // 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") +} diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisConnectionHandler.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisConnectionHandler.scala new file mode 100644 index 0000000000000000000000000000000000000000..c30003c95da1becaaff67d45c705d67bcf09a650 --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisConnectionHandler.scala @@ -0,0 +1,29 @@ +package org.bigbluebutton.common2.redis + +import io.lettuce.core.RedisClient +import io.lettuce.core.event.Event +import io.lettuce.core.event.EventBus +import io.lettuce.core.event.connection.{ ConnectionDeactivatedEvent, ConnectionActivatedEvent, ConnectedEvent, DisconnectedEvent } +import reactor.core.Disposable +import akka.event.LoggingAdapter + +trait RedisConnectionHandler { + + def subscribeToEventBus(redis: RedisClient, log: LoggingAdapter) { + val eventBus: EventBus = redis.getResources().eventBus(); + // @todo : unsubscribe when connection is closed + val eventBusSubscription: Disposable = eventBus.get().subscribe(e => connectionStatusHandler(e, log)) + } + + def connectionStatusHandler(event: Event, log: LoggingAdapter) { + if (event.isInstanceOf[ConnectedEvent]) { + log.info("Connected to redis"); + } else if (event.isInstanceOf[ConnectionActivatedEvent]) { + log.info("Connection to redis activated"); + } else if (event.isInstanceOf[DisconnectedEvent]) { + log.info("Disconnected from redis"); + } else if (event.isInstanceOf[ConnectionDeactivatedEvent]) { + log.info("Connection to redis deactivated"); + } + } +} diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisPublisher.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisPublisher.scala new file mode 100755 index 0000000000000000000000000000000000000000..47c5af6f10dcba75a018bcc1658bfebd12219fb2 --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisPublisher.scala @@ -0,0 +1,21 @@ +package org.bigbluebutton.common2.redis + +import akka.actor.ActorSystem +import akka.event.Logging + +class RedisPublisher(system: ActorSystem, clientName: String) extends RedisClientProvider(system, clientName) with RedisConnectionHandler { + + val log = Logging(system, getClass) + + subscribeToEventBus(redis, log) + + val connection = redis.connectPubSub() + + redis.connect() + + def publish(channel: String, data: String) { + val async = connection.async(); + async.publish(channel, data); + } + +} diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisStorageProvider.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisStorageProvider.scala new file mode 100644 index 0000000000000000000000000000000000000000..71fc9df41a4c2d2f755c794a949d42db41b46203 --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisStorageProvider.scala @@ -0,0 +1,13 @@ +package org.bigbluebutton.common2.redis + +import akka.actor.ActorSystem + +abstract class RedisStorageProvider(system: ActorSystem, clientName: String) extends RedisConfiguration { + var redis = new RedisStorageService() + redis.setHost(redisHost) + redis.setPort(redisPort) + redis.setPassword(redisPassword) + redis.setExpireKey(redisExpireKey) + redis.setClientName(clientName) + redis.start(); +} diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisSubscriber.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisSubscriber.scala new file mode 100644 index 0000000000000000000000000000000000000000..5c65a338577604ac1c9b342740bc99f7641b8591 --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisSubscriber.scala @@ -0,0 +1,6 @@ +package org.bigbluebutton.common2.redis + +trait RedisSubscriber extends RedisConfiguration { + val channels: Seq[String] + val patterns: Seq[String] +} diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisSubscriberProvider.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisSubscriberProvider.scala new file mode 100644 index 0000000000000000000000000000000000000000..e091e9ad25919454973ae8f4bf450c712d89eccc --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/redis/RedisSubscriberProvider.scala @@ -0,0 +1,62 @@ +package org.bigbluebutton.common2.redis + +import akka.actor.ActorSystem +import org.bigbluebutton.common2.bus.ReceivedJsonMessage +import org.bigbluebutton.common2.bus.IncomingJsonMessage +import io.lettuce.core.pubsub.RedisPubSubListener +import org.bigbluebutton.common2.bus.IncomingJsonMessageBus +import akka.actor.ActorLogging +import akka.actor.Actor + +import akka.actor.ActorSystem +import akka.actor.OneForOneStrategy +import akka.actor.SupervisorStrategy.Resume +import java.io.StringWriter +import scala.concurrent.duration._ +import java.io.PrintWriter + +abstract class RedisSubscriberProvider(system: ActorSystem, clientName: String, + channels: Seq[String], patterns: Seq[String], + jsonMsgBus: IncomingJsonMessageBus) + extends RedisClientProvider(system, clientName) with RedisConnectionHandler with Actor with ActorLogging { + + subscribeToEventBus(redis, log) + + var connection = redis.connectPubSub() + + def addListener(appChannel: String) { + connection.addListener(new RedisPubSubListener[String, String] { + def message(channel: String, message: String): Unit = { + if (channels.contains(channel)) { + val receivedJsonMessage = new ReceivedJsonMessage(channel, message) + jsonMsgBus.publish(IncomingJsonMessage(appChannel, receivedJsonMessage)) + } + } + def message(pattern: String, channel: String, message: String): Unit = { log.info("Subscribed to channel {} with pattern {}", channel, pattern) } + def psubscribed(pattern: String, count: Long): Unit = { log.info("Subscribed to pattern {}", pattern) } + def punsubscribed(pattern: String, count: Long): Unit = { log.info("Unsubscribed from pattern {}", pattern) } + def subscribed(channel: String, count: Long): Unit = { log.info("Subscribed to pattern {}", channel) } + def unsubscribed(channel: String, count: Long): Unit = { log.info("Unsubscribed from channel {}", channel) } + }) + } + + def subscribe() { + val async = connection.async() + for (channel <- channels) async.subscribe(channel) + for (pattern <- patterns) async.psubscribe(pattern) + } + + override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { + case e: Exception => { + val sw: StringWriter = new StringWriter() + sw.write("An exception has been thrown on " + getClass + ", exception message [" + e.getMessage + "] (full stacktrace below)\n") + e.printStackTrace(new PrintWriter(sw)) + log.error(sw.toString()) + Resume + } + } + + def receive = { + case _ => // do nothing + } +} diff --git a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala index d2a42e7dffe3c62f49da15b23c8f54b205409559..ccfa4e929a14eaa1bd2f6100e3872be1433271a8 100755 --- a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala +++ b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala @@ -2,7 +2,6 @@ package org.bigbluebutton.common2 import org.bigbluebutton.common2.domain._ - trait TestFixtures { val meetingId = "testMeetingId" val externalMeetingId = "testExternalMeetingId" @@ -12,6 +11,15 @@ trait TestFixtures { val record = false val voiceConfId = "85115" val durationInMinutes = 10 + + val maxInactivityTimeoutMinutes = 120 + val warnMinutesBeforeMax = 30 + val meetingExpireIfNoUserJoinedInMinutes = 5 + val meetingExpireWhenLastUserLeftInMinutes = 10 + val userInactivityInspectTimerInMinutes = 60 + val userInactivityThresholdInMinutes = 10 + val userActivitySignResponseDelayInMinutes = 5 + val autoStartRecording = false val allowStartStopRecording = false val webcamsOnlyForModerator = false @@ -25,19 +33,23 @@ trait TestFixtures { val modOnlyMessage = "Moderator only message" val dialNumber = "613-555-1234" val maxUsers = 25 + val muteOnStart = false val guestPolicy = "ALWAYS_ASK" val metadata: collection.immutable.Map[String, String] = Map("foo" -> "bar", "bar" -> "baz", "baz" -> "foo") val meetingProp = MeetingProp(name = meetingName, extId = externalMeetingId, intId = meetingId, isBreakout = isBreakout.booleanValue()) - val breakoutProps = BreakoutProps(parentId = parentMeetingId, sequence = sequence, breakoutRooms = Vector()) - val durationProps = DurationProps(duration = durationInMinutes, createdTime = createTime, createdDate = createDate) + val breakoutProps = BreakoutProps(parentId = parentMeetingId, sequence = sequence, freeJoin = false, breakoutRooms = Vector()) + + val durationProps = DurationProps(duration = durationInMinutes, createdTime = createTime, createdDate = createDate, maxInactivityTimeoutMinutes = maxInactivityTimeoutMinutes, warnMinutesBeforeMax = warnMinutesBeforeMax, + meetingExpireIfNoUserJoinedInMinutes = meetingExpireIfNoUserJoinedInMinutes, meetingExpireWhenLastUserLeftInMinutes = meetingExpireWhenLastUserLeftInMinutes, + userInactivityInspectTimerInMinutes = userInactivityInspectTimerInMinutes, userInactivityThresholdInMinutes = userInactivityInspectTimerInMinutes, userActivitySignResponseDelayInMinutes = userActivitySignResponseDelayInMinutes) val password = PasswordProp(moderatorPass = moderatorPassword, viewerPass = viewerPassword) val recordProp = RecordProp(record = record, autoStartRecording = autoStartRecording, allowStartStopRecording = allowStartStopRecording) val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg, modOnlyMessage = modOnlyMessage) - val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber) + val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart) val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, guestPolicy = guestPolicy) val metadataProp = new MetadataProp(metadata) diff --git a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/messages/DeserializerTests.scala b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/messages/DeserializerTests.scala index b3050e3bf264eaee2c50e9779e6c603ba8d3e66d..6eccd3d56cef3de2b3ba6b859085eb7520f941f6 100755 --- a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/messages/DeserializerTests.scala +++ b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/messages/DeserializerTests.scala @@ -1,12 +1,11 @@ package org.bigbluebutton.common2.messages import com.fasterxml.jackson.databind.JsonNode -import org.bigbluebutton.common2.messages.MessageBody.CreateMeetingReqMsgBody +import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.common2.util.JsonUtil -import org.bigbluebutton.common2.{TestFixtures, UnitSpec2} - -import scala.util.{Failure, Success} +import org.bigbluebutton.common2.{ TestFixtures, UnitSpec2 } +import scala.util.{ Failure, Success } class DeserializerTests extends UnitSpec2 with TestFixtures { @@ -28,7 +27,7 @@ class DeserializerTests extends UnitSpec2 with TestFixtures { println(map) map match { case Success(envJsNodeMsg) => assert(envJsNodeMsg.core.isInstanceOf[JsonNode]) - case Failure(ex) => fail("Failed to decode json message " + ex) + case Failure(ex) => fail("Failed to decode json message " + ex) } } @@ -46,11 +45,12 @@ class DeserializerTests extends UnitSpec2 with TestFixtures { println(map) map match { - case Success(envJsNodeMsg) => assert(envJsNodeMsg.core.isInstanceOf[JsonNode]) - val createMeetingReqMsg = Deserializer.toCreateMeetingReqMsg(envJsNodeMsg.envelope, envJsNodeMsg.core) - createMeetingReqMsg match { + case Success(envJsNodeMsg) => + assert(envJsNodeMsg.core.isInstanceOf[JsonNode]) + val (msg, exception) = Deserializer.toBbbCommonMsg[CreateMeetingReqMsg](envJsNodeMsg.core) + msg match { case Some(cmrq) => assert(cmrq.isInstanceOf[CreateMeetingReqMsg]) - case None => fail("Failed to decode CreateMeetingReqMsg") + case None => fail("Failed to decode CreateMeetingReqMsg") } case Failure(ex) => fail("Failed to decode json message " + ex) } @@ -71,11 +71,12 @@ class DeserializerTests extends UnitSpec2 with TestFixtures { println(map) map match { - case Success(envJsNodeMsg) => assert(envJsNodeMsg.core.isInstanceOf[JsonNode]) + case Success(envJsNodeMsg) => + assert(envJsNodeMsg.core.isInstanceOf[JsonNode]) val (msg, exception) = Deserializer.toBbbCommonMsg[CreateMeetingReqMsg](envJsNodeMsg.core) msg match { case Some(cmrq) => assert(cmrq.isInstanceOf[CreateMeetingReqMsg]) - case None => fail("Should have successfully decoded CreateMeetingReqMsg ") + case None => fail("Should have successfully decoded CreateMeetingReqMsg ") } case Failure(ex) => fail("Failed to decode json message " + ex) } @@ -103,7 +104,7 @@ class DeserializerTests extends UnitSpec2 with TestFixtures { val (result, error) = Deserializer.toBbbCoreMessageFromClient(jsonMsg) result match { case Some(msg) => assert(msg.header.name == "foo") - case None => fail("Should have deserialized message but failed with error: " + error) + case None => fail("Should have deserialized message but failed with error: " + error) } } } diff --git a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala index f701a432de2a92dc520fe585b4b17ec5b00d13ae..7d65d24d2b53db9acc5d623cb40ec2640a6676e1 100755 --- a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala +++ b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala @@ -1,14 +1,12 @@ package org.bigbluebutton.common2.util -import org.bigbluebutton.common2.{TestFixtures, UnitSpec2} -import org.bigbluebutton.common2.messages._ +import org.bigbluebutton.common2.{ TestFixtures, UnitSpec2 } +import org.bigbluebutton.common2.msgs._ import scala.collection.immutable.List import com.fasterxml.jackson.databind.JsonNode -import org.bigbluebutton.common2.messages.MessageBody.ValidateAuthTokenReqMsgBody - -import scala.util.{Failure, Success} +import scala.util.{ Failure, Success } case class Person(name: String, age: Int) case class Group(name: String, persons: Seq[Person], leader: Person) @@ -26,7 +24,7 @@ class JsonUtilTest extends UnitSpec2 with TestFixtures { // map: Map[String,Seq[Int]] = Map(a -> List(1, 2), b -> List(3, 4, 5), c -> List()) println(map) map match { - case Success(a) => assert(a.values.size == 3) + case Success(a) => assert(a.values.size == 3) case Failure(ex) => fail("Failed to decode json message") } } @@ -38,7 +36,7 @@ class JsonUtilTest extends UnitSpec2 with TestFixtures { val jeroen = Person("Jeroen", 26) val martin = Person("Martin", 54) - val originalGroup = Group("Scala ppl", Seq(jeroen,martin), martin) + val originalGroup = Group("Scala ppl", Seq(jeroen, martin), martin) // originalGroup: Group = Group(Scala ppl,List(Person(Jeroen,26), Person(Martin,54)),Person(Martin,54)) println(originalGroup) @@ -52,7 +50,7 @@ class JsonUtilTest extends UnitSpec2 with TestFixtures { } "JsonUtil" should "unmarshall a ValidateAuthTokenReq" in { - val header: BbbCoreHeaderWithMeetingId = new BbbCoreHeaderWithMeetingId("foo", "mId") + val header: BbbClientMsgHeader = new BbbClientMsgHeader("foo", "mId", "uId") val body: ValidateAuthTokenReqMsgBody = new ValidateAuthTokenReqMsgBody(userId = "uId", authToken = "myToken") val msg: ValidateAuthTokenReqMsg = new ValidateAuthTokenReqMsg(header, body) val json = JsonUtil.toJson(msg) diff --git a/bbb-common-web/build.sbt b/bbb-common-web/build.sbt index 11ff1b07e84f78a5e330ea98ddf8763bd2cb50aa..0519059e3804bb645328d651ae678ce0ef83224d 100755 --- a/bbb-common-web/build.sbt +++ b/bbb-common-web/build.sbt @@ -1,19 +1,23 @@ -name := "bbb-common-web" - -organization := "org.bigbluebutton" - -version := "0.0.2-SNAPSHOT" - -scalaVersion := "2.12.6" - -scalacOptions ++= Seq( - "-unchecked", - "-deprecation", - "-Xlint", - "-Ywarn-dead-code", - "-language:_", - "-target:jvm-1.8", - "-encoding", "UTF-8" +import org.bigbluebutton.build._ + +version := "0.0.3-SNAPSHOT" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) ) // We want to have our jar files in lib_managed dir. @@ -25,82 +29,8 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") -val akkaVersion = "2.5.14" - -// 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" - -libraryDependencies += "com.softwaremill.quicklens" %% "quicklens" % "1.4.11" - -libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT" -// https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-scala_2.12 -libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.12" % "2.9.6" - -libraryDependencies += "redis.clients" % "jedis" % "2.9.0" -libraryDependencies += "com.google.code.gson" % "gson" % "2.8.5" - -// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.7" -libraryDependencies += "commons-io" % "commons-io" % "2.6" -libraryDependencies += "org.apache.commons" % "commons-pool2" % "2.6.0" -libraryDependencies += "com.zaxxer" % "nuprocess" % "1.2.4" - -// https://mvnrepository.com/artifact/org.jodconverter/jodconverter-core -libraryDependencies += "org.jodconverter" % "jodconverter-local" % "4.2.0" - -// https://mvnrepository.com/artifact/org.libreoffice/unoil -libraryDependencies += "org.libreoffice" % "unoil" % "5.4.2" - -// https://mvnrepository.com/artifact/org.libreoffice/ridl -libraryDependencies += "org.libreoffice" % "ridl" % "5.4.2" - -// https://mvnrepository.com/artifact/org.libreoffice/juh -libraryDependencies += "org.libreoffice" % "juh" % "5.4.2" - -// https://mvnrepository.com/artifact/org.libreoffice/jurt -libraryDependencies += "org.libreoffice" % "jurt" % "5.4.2" - - -libraryDependencies += "org.apache.poi" % "poi-ooxml" % "3.17" - -libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.25" - -// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -libraryDependencies += "org.apache.httpcomponents" % "httpclient" % "4.5.6" -// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpasyncclient -libraryDependencies += "org.apache.httpcomponents" % "httpasyncclient" % "4.1.4" - -libraryDependencies += "org.freemarker" % "freemarker" % "2.3.28" -libraryDependencies += "com.fasterxml.jackson.dataformat" % "jackson-dataformat-xml" % "2.9.6" -// https://mvnrepository.com/artifact/org.codehaus.woodstox/woodstox-core-asl -libraryDependencies += "org.codehaus.woodstox" % "woodstox-core-asl" % "4.4.1" - -libraryDependencies += "org.pegdown" % "pegdown" % "1.4.0" % "test" -libraryDependencies += "junit" % "junit" % "4.12" % "test" -libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" -// https://mvnrepository.com/artifact/org.mockito/mockito-core -libraryDependencies += "org.mockito" % "mockito-core" % "2.7.12" % "test" -libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.1" % "test" -libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test" - -// https://mvnrepository.com/artifact/com.typesafe.akka/akka-testkit_2.12 -libraryDependencies += "com.typesafe.akka" % "akka-testkit_2.12" % akkaVersion % "test" - -// https://mvnrepository.com/artifact/org.scala-lang.modules/scala-xml_2.12 -libraryDependencies += "org.scala-lang.modules" % "scala-xml_2.12" % "1.1.0" - - -seq(Revolver.settings: _*) +Seq(Revolver.settings: _*) +lazy val commonWeb = (project in file(".")).settings(name := "bbb-common-web", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) //----------- // Packaging @@ -120,12 +50,12 @@ crossPaths := false // This forbids including Scala related libraries into the dependency autoScalaLibrary := false -/*************************** -* When developing, change the version above to x.x.x-SNAPSHOT then use the file resolver to -* publish to the local maven repo using "sbt publish" -*/ +/** ************************* + * When developing, change the version above to x.x.x-SNAPSHOT then use the file resolver to + * publish to the local maven repo using "sbt publish" + */ // Uncomment this to publish to local maven repo while commenting out the nexus repo -publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository"))) +publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath + "/.m2/repository"))) // Comment this out when publishing to local maven repo using SNAPSHOT version. @@ -150,16 +80,14 @@ pomExtra := ( <url>git@github.com:bigbluebutton/bigbluebutton.git</url> <connection>scm:git:git@github.com:bigbluebutton/bigbluebutton.git</connection> </scm> - <developers> - <developer> - <id>ritzalam</id> - <name>Richard Alam</name> - <url>http://www.bigbluebutton.org</url> - </developer> - </developers>) - + <developers> + <developer> + <id>ritzalam</id> + <name>Richard Alam</name> + <url>http://www.bigbluebutton.org</url> + </developer> + </developers>) + licenses := Seq("LGPL-3.0" -> url("http://opensource.org/licenses/LGPL-3.0")) homepage := Some(url("http://www.bigbluebutton.org")) - - diff --git a/bbb-common-web/deploy.sh b/bbb-common-web/deploy.sh index 948f5634178c0655544d5ab9148e6df8cc177ffc..f829bc13dc598da480ee4e512a87c9436925a359 100755 --- a/bbb-common-web/deploy.sh +++ b/bbb-common-web/deploy.sh @@ -1,3 +1 @@ -sbt clean -sbt publish publishLocal - +sbt clean publish publishLocal diff --git a/bbb-common-web/project/Build.scala b/bbb-common-web/project/Build.scala deleted file mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bbb-common-web/project/Dependencies.scala b/bbb-common-web/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..11f02264ce17223db982de1bb0ef02a5c983b1cb --- /dev/null +++ b/bbb-common-web/project/Dependencies.scala @@ -0,0 +1,103 @@ +package org.bigbluebutton.build + +import sbt._ +import Keys._ + +object Dependencies { + + object Versions { + // Scala + val scala = "2.12.7" + val junit = "4.12" + val junitInterface = "0.11" + val scalactic = "3.0.3" + + // Libraries + val akkaVersion = "2.5.17" + val gson = "2.8.5" + val jackson = "2.9.7" + val freemaker = "2.3.28" + val apacheHttp = "4.5.6" + val apacheHttpAsync = "4.1.4" + + // Office and document conversion + val apacheOffice = "4.0.0" + val jodConverter = "4.2.1" + val apachePoi = "3.17" + val nuProcess = "1.2.4" + val libreOffice = "5.4.2" + + // Apache Commons + val lang = "3.8.1" + val io = "2.6" + val pool = "2.6.0" + + // BigBlueButton + val bbbCommons = "0.0.20-SNAPSHOT" + + // Test + val scalaTest = "3.0.5" + } + + 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 % "runtime" + + val googleGson = "com.google.code.gson" % "gson" % Versions.gson + val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson + val jacksonXml = "com.fasterxml.jackson.dataformat" % "jackson-dataformat-xml" % Versions.jackson + val freeMaker = "org.freemarker" % "freemarker" % Versions.freemaker + val apacheHttp = "org.apache.httpcomponents" % "httpclient" % Versions.apacheHttp + val apacheHttpAsync = "org.apache.httpcomponents" % "httpasyncclient" % Versions.apacheHttpAsync + + val poiXml = "org.apache.poi" % "poi-ooxml" % Versions.apachePoi + val jodConverter = "org.jodconverter" % "jodconverter-local" % Versions.jodConverter + val nuProcess = "com.zaxxer" % "nuprocess" % Versions.nuProcess + + val officeUnoil = "org.libreoffice" % "unoil" % Versions.libreOffice + val officeRidl = "org.libreoffice" % "ridl" % Versions.libreOffice + val officeJuh = "org.libreoffice" % "juh" % Versions.libreOffice + val officejurt = "org.libreoffice" % "jurt" % Versions.libreOffice + + val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang + val apacheIo = "commons-io" % "commons-io" % Versions.io + val apachePool2 = "org.apache.commons" % "commons-pool2" % Versions.pool + + val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons + } + + object Test { + val scalaTest = "org.scalatest" %% "scalatest" % Versions.scalaTest % "test" + val junit = "junit" % "junit" % Versions.junit % "test" + val junitInteface = "com.novocode" % "junit-interface" % Versions.junitInterface % "test" + val scalactic = "org.scalactic" % "scalactic_2.12" % Versions.scalactic % "test" + } + + val testing = Seq( + Test.scalaTest, + Test.junit, + Test.junitInteface, + Test.scalactic) + + val runtime = Seq( + Compile.scalaLibrary, + Compile.scalaCompiler, + Compile.akkaActor, + Compile.akkaSl4fj, + Compile.googleGson, + Compile.jacksonModule, + Compile.jacksonXml, + Compile.freeMaker, + Compile.apacheHttp, + Compile.apacheHttpAsync, + Compile.poiXml, + Compile.jodConverter, + Compile.nuProcess, + Compile.apacheLang, + Compile.apacheIo, + Compile.apachePool2, + Compile.bbbCommons) ++ testing +} diff --git a/bbb-common-web/project/build.properties b/bbb-common-web/project/build.properties index a6e117b61042ee81c62ba3a0fc5210d9502944df..2e6e3d24608ee15e892ed3b16d84224f7667e808 100755 --- a/bbb-common-web/project/build.properties +++ b/bbb-common-web/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=1.2.6 \ No newline at end of file diff --git a/bbb-common-web/project/plugins.sbt b/bbb-common-web/project/plugins.sbt index b91f89e4a637ce583af1b0e09615d2f9044e033b..4eb70b26c5aeae53a81b4c122607bda9733ec175 100755 --- a/bbb-common-web/project/plugins.sbt +++ b/bbb-common-web/project/plugins.sbt @@ -2,9 +2,7 @@ addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") - -addSbtPlugin("com.artima.supersafe" % "sbtplugin" % "1.1.7") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java index b55af510e8eba9d48d0700d4fe44f72b52dbdc8b..825d0deea84dd58dc6a186cf6ab21bc84c37c299 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java @@ -48,7 +48,6 @@ import org.bigbluebutton.api.domain.RegisteredUser; import org.bigbluebutton.api.domain.User; import org.bigbluebutton.api.domain.UserSession; import org.bigbluebutton.api.messaging.MessageListener; -import org.bigbluebutton.api.messaging.RedisStorageService; import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage; import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage; import org.bigbluebutton.api.messaging.messages.CreateBreakoutRoom; @@ -77,6 +76,7 @@ import org.bigbluebutton.api.messaging.messages.UserStatusChanged; import org.bigbluebutton.api.messaging.messages.UserUnsharedWebcam; import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.bigbluebutton.api2.domain.UploadedTrack; +import org.bigbluebutton.common2.redis.RedisStorageService; import org.bigbluebutton.presentation.PresentationUrlDownloadService; import org.bigbluebutton.web.services.RegisteredUserCleanupTimerTask; import org.bigbluebutton.web.services.callback.CallbackUrlService; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java index d6f2837b40f3c7a4bc0df3744d340a689531b39a..007d16d51d374da794faf6dcc5027571841e3ea3 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java @@ -5,23 +5,23 @@ import java.util.Set; import org.bigbluebutton.api.messaging.messages.IMessage; public class MessageDistributor { - private ReceivedMessageHandler handler; - private Set<MessageListener> listeners; + private ReceivedMessageHandler handler; + private Set<MessageListener> listeners; - public void setMessageListeners(Set<MessageListener> listeners) { - this.listeners = listeners; - } + public void setMessageListeners(Set<MessageListener> listeners) { + this.listeners = listeners; + } - public void setMessageHandler(ReceivedMessageHandler handler) { - this.handler = handler; - if (handler != null) { - handler.setMessageDistributor(this); + public void setMessageHandler(ReceivedMessageHandler handler) { + this.handler = handler; + if (handler != null) { + handler.setMessageDistributor(this); + } } - } - public void notifyListeners(IMessage message) { - for (MessageListener listener : listeners) { - listener.handle(message); + public void notifyListeners(IMessage message) { + for (MessageListener listener : listeners) { + listener.handle(message); + } } - } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java index 38690c4b1e1810135b329130eb6b436bfd8fd3c0..9a1171de745952d9d915efabcd3490a3328a8ab6 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java @@ -11,65 +11,65 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ReceivedMessageHandler implements IReceivedOldMessageHandler { - private static Logger log = LoggerFactory.getLogger(ReceivedMessageHandler.class); + private static Logger log = LoggerFactory.getLogger(ReceivedMessageHandler.class); - private BlockingQueue<ReceivedMessage> receivedMessages = new LinkedBlockingQueue<>(); + private BlockingQueue<ReceivedMessage> receivedMessages = new LinkedBlockingQueue<>(); - private volatile boolean processMessage = false; + private volatile boolean processMessage = false; - private final Executor msgProcessorExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); + private final Executor msgProcessorExec = Executors.newSingleThreadExecutor(); + private final Executor runExec = Executors.newSingleThreadExecutor(); - private MessageDistributor outGW; + private MessageDistributor outGW; - public void stop() { - processMessage = false; - } + public void stop() { + processMessage = false; + } - public void start() { - log.info("Ready to handle messages from Redis pubsub!"); + public void start() { + log.info("Ready to handle messages from Redis pubsub!"); + + try { + processMessage = true; + + Runnable messageProcessor = new Runnable() { + public void run() { + while (processMessage) { + try { + ReceivedMessage msg = receivedMessages.take(); + processMessage(msg); + } catch (InterruptedException e) { + log.warn("Error while taking received message from queue."); + } + } + } + }; + msgProcessorExec.execute(messageProcessor); + } catch (Exception e) { + log.error("Error subscribing to channels: {}", e); + } + } - try { - processMessage = true; + private void notifyListeners(IMessage message) { + outGW.notifyListeners(message); + } - Runnable messageProcessor = new Runnable() { - public void run() { - while (processMessage) { - try { - ReceivedMessage msg = receivedMessages.take(); - processMessage(msg); - } catch (InterruptedException e) { - log.warn("Error while taking received message from queue."); + private void processMessage(final ReceivedMessage msg) { + Runnable task = new Runnable() { + public void run() { + notifyListeners(msg.getMessage()); } - } - } - }; - msgProcessorExec.execute(messageProcessor); - } catch (Exception e) { - log.error("Error subscribing to channels: {}", e); + }; + + runExec.execute(task); + } + + public void handleMessage(IMessage message) { + ReceivedMessage rm = new ReceivedMessage(message); + receivedMessages.add(rm); + } + + public void setMessageDistributor(MessageDistributor outGW) { + this.outGW = outGW; } - } - - private void notifyListeners(IMessage message) { - outGW.notifyListeners(message); - } - - private void processMessage(final ReceivedMessage msg) { - Runnable task = new Runnable() { - public void run() { - notifyListeners(msg.getMessage()); - } - }; - - runExec.execute(task); - } - - public void handleMessage(IMessage message) { - ReceivedMessage rm = new ReceivedMessage(message); - receivedMessages.add(rm); - } - - public void setMessageDistributor(MessageDistributor outGW) { - this.outGW = outGW; - } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java deleted file mode 100755 index 180c95e5ce1517133df3bf5fb72d55aa967a6680..0000000000000000000000000000000000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.bigbluebutton.api.messaging; - -import java.util.Map; - -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.Protocol; - -public class RedisStorageService { - private static Logger log = LoggerFactory.getLogger(RedisStorageService.class); - - private JedisPool redisPool; - private String host; - private int port; - - public void stop() { - - } - - public void start() { - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - redisPool = new JedisPool(new GenericObjectPoolConfig<Object>(), host, port, Protocol.DEFAULT_TIMEOUT, null, - Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub"); - } - - public void recordMeetingInfo(String meetingId, Map<String, String> info) { - Jedis jedis = redisPool.getResource(); - try { - if (log.isDebugEnabled()) { - for (Map.Entry<String,String> entry : info.entrySet()) { - log.debug("Storing metadata {} = {}", entry.getKey(), entry.getValue()); - } - } - - log.debug("Saving metadata in {}", meetingId); - jedis.hmset("meeting:info:" + meetingId, info); - } catch (Exception e) { - log.warn("Cannot record the info meeting: {}", meetingId, e); - } finally { - jedis.close(); - } - } - - public void recordBreakoutInfo(String meetingId, Map<String, String> breakoutInfo) { - Jedis jedis = redisPool.getResource(); - try { - log.debug("Saving breakout metadata in {}", meetingId); - jedis.hmset("meeting:breakout:" + meetingId, breakoutInfo); - } catch (Exception e) { - log.warn("Cannot record the info meeting: {}", meetingId, e); - } finally { - jedis.close(); - } - } - - public void addBreakoutRoom(String parentId, String breakoutId) { - Jedis jedis = redisPool.getResource(); - try { - - log.debug("Saving breakout room for meeting {}", parentId); - jedis.sadd("meeting:breakout:rooms:" + parentId, breakoutId); - } catch (Exception e) { - log.warn("Cannot record the info meeting:" + parentId, e); - } finally { - jedis.close(); - } - } - - public void removeMeeting(String meetingId) { - Jedis jedis = redisPool.getResource(); - try { - jedis.del("meeting-" + meetingId); - jedis.srem("meetings", meetingId); - } finally { - jedis.close(); - } - } - - public void setHost(String host) { - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } -} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/RedisStorageService.java b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/RedisStorageService.java deleted file mode 100755 index 3a45aedfd144ec9a6803672d81432e1c21420f7d..0000000000000000000000000000000000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/RedisStorageService.java +++ /dev/null @@ -1,92 +0,0 @@ -/** -* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ -* -* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). -* -* This program is free software; you can redistribute it and/or modify it under the -* terms of the GNU Lesser General Public License as published by the Free Software -* Foundation; either version 3.0 of the License, or (at your option) any later -* version. -* -* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. -* -*/ - -package org.bigbluebutton.web.services; - -import java.util.HashMap; -import java.util.Map; - -import org.bigbluebutton.api.domain.Poll; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; - -public class RedisStorageService implements IStorageService{ - JedisPool jedisPool; - - private static final String SEPARATOR = ":"; - private static final String ID_SEED = "nextID"; - - /* Meeting Patterns */ - private static final String MEETING = "meeting"; - private static final String POLL = "poll"; - private static final String POLL_ANSWER = "answer"; - private static final String POLL_RESULTS = "results"; - - /* -meeting:<id>:poll:list [1,2,3] <-- list -meeting:<id>:poll:<pollid> title, date <-- hash -meeting:<id>:poll:<pollid>:answer:list [1,2,3] <-- list -meeting:<id>:poll:<pollid>:answer:<answerid> answertext <-- key/value - -meeting:<id>:poll:<pollid>:answer:<answerid>:results [<userid>|1] <-- Set - */ - - public String generatePollID(String meetingID){ - Jedis jedis = (Jedis) jedisPool.getResource(); - String pattern = getPollRedisPattern(meetingID); - String pollID = Long.toString(jedis.incr(pattern + SEPARATOR + ID_SEED)); - jedisPool.returnResource(jedis); - return pollID; - } - - public String generatePollAnswerID(String meetingID){ - Jedis jedis = jedisPool.getResource(); - String pattern = getPollRedisPattern(meetingID); - String pollID = Long.toString(jedis.incr(pattern + SEPARATOR + POLL_ANSWER + SEPARATOR + ID_SEED)); - jedisPool.returnResource(jedis); - return pollID; - } - - public void storePoll(Poll p){ - Jedis jedis = jedisPool.getResource(); - String pattern = getPollRedisPattern(p.getMeetingID()); - - HashMap<String,String> pollMap = p.toMap(); - jedis.hmset(pattern + SEPARATOR + p.getPollID(), pollMap); - jedisPool.returnResource(jedis); - } - - public void storePollAnswers(String meetingID, String pollID, Map<String,String> answers){ - Jedis jedis = jedisPool.getResource(); - String pattern = getPollRedisPattern(meetingID); - - //HashMap<String,String> pollMap = p.toMap(); - //jedis.hmset(pattern + SEPARATOR + p.getPollID + SEPARATOR + POLL_ANSWER + SEPARATOR + ID_SEED, pollMap); - //jedisPool.returnResource(jedis); - } - - private String getPollRedisPattern(String meetingID){ - return MEETING + SEPARATOR + meetingID + SEPARATOR + POLL; - } - - public void setJedisPool(JedisPool jedisPool){ - this.jedisPool = jedisPool; - } -} \ No newline at end of file diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala index 053c62ad567117e2120f8eb817a85ae55db7b081..6d62c007f4b22d54d1943c9533b207da058a0c62 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala @@ -5,12 +5,14 @@ import akka.actor.ActorSystem import akka.event.Logging import org.bigbluebutton.api.messaging.converters.messages._ 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.common2.domain._ import org.bigbluebutton.presentation.messages._ - import scala.concurrent.duration._ +import org.bigbluebutton.common2.redis._ +import org.bigbluebutton.common2.bus._ class BbbWebApiGWApp( val oldMessageReceivedGW: OldMessageReceivedGW, @@ -24,10 +26,8 @@ class BbbWebApiGWApp( val log = Logging(system, getClass) - log.debug("*********** meetingManagerChannel = " + meetingManagerChannel) - 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 messageSenderActorRef = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor") @@ -54,8 +54,7 @@ class BbbWebApiGWApp( msgToAkkaAppsEventBus.subscribe(msgToAkkaAppsToJsonActor, toAkkaAppsChannel) - private val appsRedisSubscriberActor = system.actorOf( - AppsRedisSubscriberActor.props(receivedJsonMsgBus, oldMessageEventBus), "appsRedisSubscriberActor") + private val appsRedisSubscriberActor = system.actorOf(WebRedisSubscriberActor.props(system, receivedJsonMsgBus, oldMessageEventBus), "appsRedisSubscriberActor") private val receivedJsonMsgHdlrActor = system.actorOf( ReceivedJsonMsgHdlrActor.props(msgFromAkkaAppsEventBus), "receivedJsonMsgHdlrActor") diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/SystemConfiguration.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/SystemConfiguration.scala index 0eb67da98170ac2b5304922e745ffcd835351719..71d5d402c9dbc462ff2206677a22e5912f4ed5eb 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/SystemConfiguration.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/SystemConfiguration.scala @@ -3,17 +3,11 @@ package org.bigbluebutton.api2 import com.typesafe.config.ConfigFactory import scala.util.Try +import org.bigbluebutton.common2.redis.RedisConfiguration -trait SystemConfiguration { - val config = ConfigFactory.load("bbb-web") +trait SystemConfiguration extends RedisConfiguration { + 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 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 fromClientChannel = Try(config.getString("eventBus.fromClientChannel")).getOrElse("from-client-channel") diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MessageSenderActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MessageSenderActor.scala index f4dc981cc96c2d79547f5d62693aa8da83c33558..e21612025c28d43587c0f715fe81455e67ffd03b 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MessageSenderActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/MessageSenderActor.scala @@ -4,7 +4,7 @@ import java.io.{PrintWriter, StringWriter} import akka.actor.SupervisorStrategy.Resume import akka.actor.{Actor, ActorLogging, OneForOneStrategy, Props} -import org.bigbluebutton.api2.endpoint.redis.MessageSender +import org.bigbluebutton.common2.redis.MessageSender import scala.concurrent.duration._ object MessageSenderActor { diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala index f996ad30ef5c87f4b417d238639ffc3facd34f76..ab5af661bf3f1fec0935d364ce2e9c027538813d 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala @@ -1,6 +1,7 @@ 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{ def props(gw: OldMessageReceivedGW): Props = Props(classOf[OldMessageJsonReceiverActor], gw) diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala index e63f2d454eecd42ea026bab87933fa10d02dde58..174e4951dfd5fad4a2a6c1dbd980207d78999111 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala @@ -1,6 +1,7 @@ package org.bigbluebutton.api2.bus import org.bigbluebutton.api2.SystemConfiguration +import org.bigbluebutton.common2.bus._ import org.bigbluebutton.common2.msgs._ import com.fasterxml.jackson.databind.JsonNode import akka.actor.Actor diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/AppsRedisSubscriberActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/AppsRedisSubscriberActor.scala deleted file mode 100755 index 3b566c6f2f90eedc8969cb7b3346aef349c69a02..0000000000000000000000000000000000000000 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/AppsRedisSubscriberActor.scala +++ /dev/null @@ -1,63 +0,0 @@ -package org.bigbluebutton.api2.endpoint.redis - -import java.io.{PrintWriter, StringWriter} -import java.net.InetSocketAddress - -import akka.actor.SupervisorStrategy.Resume -import akka.actor.{OneForOneStrategy, Props} -import redis.api.servers.ClientSetname -import redis.actors.RedisSubscriberActor -import redis.api.pubsub.{Message, PMessage} -import scala.concurrent.duration._ - -import org.bigbluebutton.api2.SystemConfiguration -import org.bigbluebutton.api2.bus._ - -object AppsRedisSubscriberActor extends SystemConfiguration { - - val channels = Seq(fromAkkaAppsRedisChannel) - val patterns = Seq("bigbluebutton:from-bbb-apps:*") - - def props(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus): Props = - Props(classOf[AppsRedisSubscriberActor], jsonMsgBus, oldMessageEventBus, - redisHost, redisPort, - channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") -} - -class AppsRedisSubscriberActor(jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus, redisHost: String, - redisPort: Int, - channels: Seq[String] = Nil, patterns: Seq[String] = Nil) - extends RedisSubscriberActor(new InetSocketAddress(redisHost, redisPort), - channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { - - override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { - case e: Exception => { - val sw: StringWriter = new StringWriter() - sw.write("An exception has been thrown on AppsRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n") - e.printStackTrace(new PrintWriter(sw)) - log.error(sw.toString()) - Resume - } - } - - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - write(ClientSetname("Red5AppsSub").encodedRequest) - - def onMessage(message: Message) { - //log.error(s"SHOULD NOT BE RECEIVING: $message") - if (message.channel == fromAkkaAppsRedisChannel) { - val receivedJsonMessage = new JsonMsgFromAkkaApps(message.channel, message.data.utf8String) - jsonMsgBus.publish(JsonMsgFromAkkaAppsEvent(fromAkkaAppsJsonChannel, receivedJsonMessage)) - } - } - - def onPMessage(pmessage: PMessage) { - log.debug(s"RECEIVED:\n ${pmessage.data.utf8String} \n") - val receivedJsonMessage = new OldReceivedJsonMessage(pmessage.patternMatched, - pmessage.channel, pmessage.data.utf8String) - - oldMessageEventBus.publish(OldIncomingJsonMessage(fromAkkaAppsOldJsonChannel, receivedJsonMessage)) - } -} diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisDataStorageActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisDataStorageActor.scala index 8fb2731d4204bd661b5c1762549593439adf1066..e4d6628018a0a84ee2c596c3b12221c4b1393c86 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisDataStorageActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisDataStorageActor.scala @@ -1,51 +1,48 @@ package org.bigbluebutton.api2.endpoint.redis -import akka.actor.{Actor, ActorLogging, ActorSystem, Props} import org.bigbluebutton.api2.SystemConfiguration -import redis.RedisClient +import org.bigbluebutton.common2.redis.RedisStorageProvider +import akka.actor.Actor +import akka.actor.ActorLogging +import akka.actor.ActorSystem +import akka.actor.Props case class RecordMeetingInfoMsg(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 RemoveMeetingMsg(meetingId: String) - object RedisDataStorageActor { def props(system: ActorSystem): Props = Props(classOf[RedisDataStorageActor], system) } -class RedisDataStorageActor(val system: ActorSystem) extends Actor with ActorLogging with 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("BbbWebStore") +class RedisDataStorageActor(val system: ActorSystem) + extends RedisStorageProvider(system, "BbbWebStore") + with SystemConfiguration + with Actor with ActorLogging { def receive = { - case msg: RecordMeetingInfoMsg => handleRecordMeetingInfoMsg(msg) + case msg: RecordMeetingInfoMsg => handleRecordMeetingInfoMsg(msg) case msg: RecordBreakoutInfoMsg => handleRecordBreakoutInfoMsg(msg) - case msg: AddBreakoutRoomMsg => handleAddBreakoutRoomMsg(msg) - case msg: RemoveMeetingMsg => handleRemoveMeetingMsg(msg) + case msg: AddBreakoutRoomMsg => handleAddBreakoutRoomMsg(msg) + case msg: RemoveMeetingMsg => handleRemoveMeetingMsg(msg) } - def handleRecordMeetingInfoMsg(msg: RecordMeetingInfoMsg): Unit = { - redis.hmset("meeting:info:" + msg.meetingId, msg.info) + redis.recordMeetingInfo(msg.meetingId, msg.info.asInstanceOf[java.util.Map[java.lang.String, java.lang.String]]); } def handleRecordBreakoutInfoMsg(msg: RecordBreakoutInfoMsg): Unit = { - redis.hmset("meeting:breakout:" + msg.meetingId, msg.info) + redis.recordBreakoutInfo(msg.meetingId, msg.info.asInstanceOf[java.util.Map[java.lang.String, java.lang.String]]) } def handleAddBreakoutRoomMsg(msg: AddBreakoutRoomMsg): Unit = { - redis.sadd("meeting:breakout:rooms:" + msg.parentId, msg.breakoutId) + redis.addBreakoutRoom(msg.parentId, msg.breakoutId) } def handleRemoveMeetingMsg(msg: RemoveMeetingMsg): Unit = { - redis.del("meeting-" + msg.meetingId) - redis.srem("meetings", msg.meetingId) + redis.removeMeeting(msg.meetingId) } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisPublisher.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisPublisher.scala deleted file mode 100755 index 23e47ddd06d00f8173032f08c5d585c354129f5f..0000000000000000000000000000000000000000 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/RedisPublisher.scala +++ /dev/null @@ -1,24 +0,0 @@ -package org.bigbluebutton.api2.endpoint.redis - -import akka.actor.ActorSystem -import akka.event.Logging -import akka.util.ByteString -import org.bigbluebutton.api2.SystemConfiguration -import redis.RedisClient - -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("BbbWebPub") - - def publish(channel: String, data: String) { - //log.debug("PUBLISH TO \n[" + channel + "]: \n " + data + "\n") - redis.publish(channel, ByteString(data)) - } - -} diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/WebRedisSubscriberActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/WebRedisSubscriberActor.scala new file mode 100755 index 0000000000000000000000000000000000000000..bcb2e4b3d26ebbe6d7d9b7573849162364e3f35b --- /dev/null +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/endpoint/redis/WebRedisSubscriberActor.scala @@ -0,0 +1,53 @@ +package org.bigbluebutton.api2.endpoint.redis + +import org.bigbluebutton.api2.SystemConfiguration +import org.bigbluebutton.common2.bus._ +import org.bigbluebutton.common2.redis.{ RedisConfiguration, RedisSubscriber, RedisSubscriberProvider } + +import akka.actor.ActorSystem +import akka.actor.Props +import io.lettuce.core.pubsub.RedisPubSubListener + +object WebRedisSubscriberActor extends RedisSubscriber with RedisConfiguration { + + val channels = Seq(fromAkkaAppsRedisChannel) + val patterns = Seq("bigbluebutton:from-bbb-apps:*") + + def props(system: ActorSystem, jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus): Props = + Props( + classOf[WebRedisSubscriberActor], + system, jsonMsgBus, oldMessageEventBus, + redisHost, redisPort, + channels, patterns).withDispatcher("akka.redis-subscriber-worker-dispatcher") +} + +class WebRedisSubscriberActor( + system: ActorSystem, + jsonMsgBus: JsonMsgFromAkkaAppsBus, oldMessageEventBus: OldMessageEventBus, redisHost: String, + redisPort: Int, + channels: Seq[String] = Nil, patterns: Seq[String] = Nil) + extends RedisSubscriberProvider(system, "BbbWebSub", channels, patterns, null) with SystemConfiguration { + + override def addListener(appChannel: String) { + connection.addListener(new RedisPubSubListener[String, String] { + def message(channel: String, message: String): Unit = { + if (channels.contains(channel)) { + val receivedJsonMessage = new JsonMsgFromAkkaApps(channel, message) + jsonMsgBus.publish(JsonMsgFromAkkaAppsEvent(fromAkkaAppsJsonChannel, receivedJsonMessage)) + } + } + def message(pattern: String, channel: String, message: String): Unit = { + log.debug(s"RECEIVED:\n ${message} \n") + val receivedJsonMessage = new OldReceivedJsonMessage(pattern, channel, message) + oldMessageEventBus.publish(OldIncomingJsonMessage(fromAkkaAppsOldJsonChannel, receivedJsonMessage)) + } + def psubscribed(pattern: String, count: Long): Unit = { log.info("Subscribed to pattern {}", pattern) } + def punsubscribed(pattern: String, count: Long): Unit = { log.info("Unsubscribed from pattern {}", pattern) } + def subscribed(channel: String, count: Long): Unit = { log.info("Subscribed to pattern {}", channel) } + def unsubscribed(channel: String, count: Long): Unit = { log.info("Unsubscribed from channel {}", channel) } + }) + } + + addListener(fromAkkaAppsJsonChannel) + subscribe() +} diff --git a/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/ParamsUtilTest.scala b/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/ParamsUtilTest.scala index 6cf5716b067425c1a5a4e5372b58049bc24d2632..460701c67a52074344736bacfea2d03adfbb3066 100755 --- a/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/ParamsUtilTest.scala +++ b/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/ParamsUtilTest.scala @@ -1,23 +1,21 @@ -package org.bigbluebutton.api.util - -import org.scalatest._ - -class ParamsUtilTest extends UnitSpec { - - it should "strip out control chars from text" in { - val text = "a\u0000b\u0007c\u008fd" - val cleaned = ParamsUtil.stripControlChars(text) - assert("abcd" == cleaned) - } - - it should "complain about invalid chars in meetingId" in { - val meetingId = "Demo , Meeting" - assert(ParamsUtil.isValidMeetingId(meetingId) == false) - } - - it should "accept valid chars in meetingId" in { - val meetingId = "Demo Meeting - 123" - assert(ParamsUtil.isValidMeetingId(meetingId) == true) - } - -} +package org.bigbluebutton.api.util + +class ParamsUtilTest extends UnitSpec { + + it should "strip out control chars from text" in { + val text = "a\u0000b\u0007c\u008fd" + val cleaned = ParamsUtil.stripControlChars(text) + assert("abcd" == cleaned) + } + + it should "complain about invalid chars in meetingId" in { + val meetingId = "Demo , Meeting" + assert(ParamsUtil.isValidMeetingId(meetingId) == false) + } + + it should "accept valid chars in meetingId" in { + val meetingId = "Demo Meeting - 123" + assert(ParamsUtil.isValidMeetingId(meetingId) == true) + } + +} diff --git a/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/UnitSpec.scala b/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/UnitSpec.scala index fef2d5a231b50c2ea1597f488d4533cd972b040c..6c5694d0c06fd995a03851556746f84cefeeabc4 100755 --- a/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/UnitSpec.scala +++ b/bbb-common-web/src/test/scala/org/bigbluebutton/api/util/UnitSpec.scala @@ -1,8 +1,7 @@ -package org.bigbluebutton.api.util - -import org.scalatest.FlatSpec -import org.scalatest.BeforeAndAfterAll -import org.scalatest.WordSpec -import org.scalatest.Matchers - -abstract class UnitSpec extends FlatSpec with Matchers with BeforeAndAfterAll +package org.bigbluebutton.api.util + +import org.scalatest.FlatSpec +import org.scalatest.BeforeAndAfterAll +import org.scalatest.Matchers + +abstract class UnitSpec extends FlatSpec with Matchers with BeforeAndAfterAll diff --git a/bbb-fsesl-client/build.gradle b/bbb-fsesl-client/build.gradle deleted file mode 100755 index ad7449677b1d7cfcb3a84f1b5ad1a2b3524472c1..0000000000000000000000000000000000000000 --- a/bbb-fsesl-client/build.gradle +++ /dev/null @@ -1,72 +0,0 @@ -apply plugin: 'java' -apply plugin: 'eclipse' - -version = '0.9.0' -jar.enabled = true - -def appName = 'fs-esl-client' - -archivesBaseName = appName - -task resolveDeps(type: Copy) { - into('lib') - from configurations.default - from configurations.default.allArtifacts.file -} - - -artifacts { - archives jar -} - -repositories { - add(new org.apache.ivy.plugins.resolver.ChainResolver()) { - name = 'remote' - returnFirst = true - add(new org.apache.ivy.plugins.resolver.URLResolver()) { - name = "googlecode" - addArtifactPattern "http://red5.googlecode.com/svn/repository/[artifact](-[revision]).[ext]" - addArtifactPattern "http://red5.googlecode.com/svn/repository/[organisation]/[artifact](-[revision]).[ext]" - } - add(new org.apache.ivy.plugins.resolver.URLResolver()) { - name = "blindside-repos" - addArtifactPattern "http://blindside.googlecode.com/svn/repository/[artifact](-[revision]).[ext]" - addArtifactPattern "http://blindside.googlecode.com/svn/repository/[organisation]/[artifact](-[revision]).[ext]" - } - add(new org.apache.ivy.plugins.resolver.URLResolver()) { - name = "maven2-central" - m2compatible = true - addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact](-[revision]).[ext]" - addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[artifact]/[revision]/[artifact](-[revision]).[ext]" - } - add(new org.apache.ivy.plugins.resolver.URLResolver()) { - name = "netty-dependency" - m2compatible = true - addArtifactPattern "http://repository.jboss.org/nexus/content/groups/public-jboss/[organisation]/[module]/[revision]/[artifact](-[revision]).[ext]" - addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[artifact]/[revision]/[artifact](-[revision]).[ext]" - } - } - flatDir name: 'fileRepo', dirs: "/home/firstuser/dev/repo" -} - -dependencies { - // Logging - compile 'ch.qos.logback:logback-core:1.2.3@jar' - compile 'ch.qos.logback:logback-classic:1.2.3@jar' - compile 'org.slf4j:log4j-over-slf4j:1.7.25@jar' - compile 'org.slf4j:jcl-over-slf4j:1.7.25@jar' - compile 'org.slf4j:jul-to-slf4j:1.7.25@jar' - compile 'org.slf4j:slf4j-api:1.7.25@jar' - - testRuntime 'junit:junit:4.8.1.@jar' - compile 'org.jboss.netty:netty:3.2.10.Final@jar' -} - - -uploadArchives { - uploadDescriptor = false - repositories { - add project.repositories.fileRepo - } -} - diff --git a/bbb-fsesl-client/build.sbt b/bbb-fsesl-client/build.sbt index 6cc930898e0964d5da423f80eab0781b35b9b812..4399efc2a4eb945ecde60540463bfe99b225e001 100755 --- a/bbb-fsesl-client/build.sbt +++ b/bbb-fsesl-client/build.sbt @@ -1,10 +1,26 @@ -name := "bbb-fsesl-client" +import org.bigbluebutton.build._ description := "BigBlueButton custom FS-ESL client built on top of FS-ESL Java library." -organization := "org.bigbluebutton" - -version := "0.0.6" +version := "0.0.7-SNAPSHOT" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) +) // We want to have our jar files in lib_managed dir. // This way we'll have the right path when we import @@ -15,14 +31,8 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") -libraryDependencies ++= { - Seq( - "org.jboss.netty" % "netty" % "3.2.10.Final", - "junit" % "junit" % "4.12", - "ch.qos.logback" % "logback-classic" % "1.2.3" - )} - -seq(Revolver.settings: _*) +Seq(Revolver.settings: _*) +lazy val bbbFSESLClient = (project in file(".")).settings(name := "bbb-fsesl-client", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) //----------- // Packaging @@ -42,7 +52,7 @@ crossPaths := false // This forbids including Scala related libraries into the dependency 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 := { // val nexus = "https://oss.sonatype.org/" @@ -60,10 +70,10 @@ publishArtifact in Test := false // http://www.scala-sbt.org/release/docs/Artifacts.html // disable publishing the main API jar -publishArtifact in (Compile, packageDoc) := false +publishArtifact in(Compile, packageDoc) := false // disable publishing the main sources jar -publishArtifact in (Compile, packageSrc) := false +publishArtifact in(Compile, packageSrc) := false pomIncludeRepository := { _ => false } @@ -72,14 +82,14 @@ pomExtra := ( <url>git@github.com:bigbluebutton/bigbluebutton.git</url> <connection>scm:git:git@github.com:bigbluebutton/bigbluebutton.git</connection> </scm> - <developers> - <developer> - <id>ritzalam</id> - <name>Richard Alam</name> - <url>http://www.bigbluebutton.org</url> - </developer> - </developers>) - + <developers> + <developer> + <id>ritzalam</id> + <name>Richard Alam</name> + <url>http://www.bigbluebutton.org</url> + </developer> + </developers>) + licenses := Seq("Apache License, Version 2.0" -> url("http://opensource.org/licenses/Apache-2.0")) homepage := Some(url("http://www.bigbluebutton.org")) diff --git a/bbb-fsesl-client/deploy.sh b/bbb-fsesl-client/deploy.sh index a5f14b0d75d69db2a5f3bfb38226a0f1f643c13d..fdfce32665453b90bcea6d522bcaf673fb56f93b 100644 --- a/bbb-fsesl-client/deploy.sh +++ b/bbb-fsesl-client/deploy.sh @@ -1,2 +1 @@ -sbt clean -sbt publish publishLocal +sbt clean publish publishLocal diff --git a/bbb-fsesl-client/project/Build.scala b/bbb-fsesl-client/project/Build.scala deleted file mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bbb-fsesl-client/project/Dependencies.scala b/bbb-fsesl-client/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..9da6506153827201f161ef66183863558c91b4f2 --- /dev/null +++ b/bbb-fsesl-client/project/Dependencies.scala @@ -0,0 +1,40 @@ +package org.bigbluebutton.build + +import sbt._ +import Keys._ + +object Dependencies { + + object Versions { + // Scala + val scala = "2.12.7" + + // Libraries + val netty = "3.2.10.Final" + val logback = "1.2.3" + + // Test + 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 netty = "org.jboss.netty" % "netty" % Versions.netty + val logback = "ch.qos.logback" % "logback-classic" % Versions.logback + } + + object Test { + val junit = "junit" % "junit" % Versions.junit % "test" + } + + val testing = Seq( + Test.junit) + + val runtime = Seq( + Compile.scalaLibrary, + Compile.scalaCompiler, + Compile.netty, + Compile.logback) ++ testing +} diff --git a/bbb-fsesl-client/project/build.properties b/bbb-fsesl-client/project/build.properties index a6e117b61042ee81c62ba3a0fc5210d9502944df..2e6e3d24608ee15e892ed3b16d84224f7667e808 100755 --- a/bbb-fsesl-client/project/build.properties +++ b/bbb-fsesl-client/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.8 +sbt.version=1.2.6 \ No newline at end of file diff --git a/bbb-fsesl-client/project/plugins.sbt b/bbb-fsesl-client/project/plugins.sbt index 5ab7b095f69a2b3d8a3bf5350fa7e7e1a64f8f2f..3559bf68d62ef19f25fa810533bbe596eb022d02 100755 --- a/bbb-fsesl-client/project/plugins.sbt +++ b/bbb-fsesl-client/project/plugins.sbt @@ -2,8 +2,8 @@ addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") -addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") +addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") diff --git a/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/inbound/ClientTest.java b/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/inbound/ClientTest.java index e3577e52fd6de92f692f7531c168fecbaf4ab252..fb15b27bd2cd7c0b16219291cc0451d43e58ed01 100644 --- a/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/inbound/ClientTest.java +++ b/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/inbound/ClientTest.java @@ -17,12 +17,11 @@ package org.freeswitch.esl.client.inbound; import java.util.Map.Entry; -import org.freeswitch.esl.client.IEslEventListener; -import org.freeswitch.esl.client.inbound.Client; -import org.freeswitch.esl.client.inbound.InboundConnectionFailure; +import org.freeswitch.esl.client.example.EslEventListener; import org.freeswitch.esl.client.transport.event.EslEvent; -import org.freeswitch.esl.client.transport.message.EslMessage; import org.freeswitch.esl.client.transport.message.EslHeaders.Name; +import org.freeswitch.esl.client.transport.message.EslMessage; +import org.jboss.netty.channel.ExceptionEvent; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,7 +39,7 @@ public class ClientTest { Client client = new Client(); - client.addEventListener( new IEslEventListener() + client.addEventListener( new EslEventListener() { public void eventReceived( EslEvent event ) { diff --git a/bbb-screenshare/app/build.sbt b/bbb-screenshare/app/build.sbt index dc47de3dedc1ee69a30ebd348a40ddcf5f1ebd44..a49598ac7d645e2454021d987f743758ef29001e 100755 --- a/bbb-screenshare/app/build.sbt +++ b/bbb-screenshare/app/build.sbt @@ -1,28 +1,30 @@ +import org.bigbluebutton.build._ //enablePlugins(JavaServerAppPackaging) enablePlugins(JettyPlugin) -name := "bbb-screenshare-akka" - -organization := "org.bigbluebutton" - -version := "0.0.2" - -scalaVersion := "2.12.6" - -scalacOptions ++= Seq( - "-unchecked", - "-deprecation", - "-Xlint", - "-Ywarn-dead-code", - "-language:_", - "-target:jvm-1.8", - "-encoding", "UTF-8" +version := "0.0.3" + +val compileSettings = Seq( + organization := "org.bigbluebutton", + + scalacOptions ++= List( + "-unchecked", + "-deprecation", + "-Xlint", + "-Ywarn-dead-code", + "-language:_", + "-target:jvm-1.8", + "-encoding", "UTF-8" + ), + javacOptions ++= List( + "-Xlint:unchecked", + "-Xlint:deprecation" + ) ) resolvers ++= Seq( "spray repo" at "http://repo.spray.io/", - "rediscala" at "http://dl.bintray.com/etaty/maven", "blindside-repos" at "http://blindside.googlecode.com/svn/repository/" ) @@ -39,45 +41,8 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console", testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports") -val akkaVersion = "2.5.14" -val scalaTestV = "2.2.6" - -libraryDependencies ++= { - val springVersion = "4.3.12.RELEASE" - Seq( - "com.typesafe.akka" %% "akka-actor" % akkaVersion, - "com.typesafe.akka" %% "akka-testkit" % akkaVersion % "test", - "com.typesafe.akka" %% "akka-slf4j" % akkaVersion, - "com.typesafe" % "config" % "1.3.0", - "ch.qos.logback" % "logback-classic" % "1.2.3" % "runtime", - "commons-codec" % "commons-codec" % "1.11", - "redis.clients" % "jedis" % "2.9.0", - "org.apache.commons" % "commons-pool2" % "2.6.0", - "org.red5" % "red5-server" % "1.0.10-M5", - "com.google.code.gson" % "gson" % "2.8.5", - "org.springframework" % "spring-web" % springVersion, - "org.springframework" % "spring-beans" % springVersion, - "org.springframework" % "spring-context" % springVersion, - "org.springframework" % "spring-core" % springVersion, - "org.springframework" % "spring-webmvc" % springVersion, - "org.springframework" % "spring-aop" % springVersion, - "javax.servlet" % "servlet-api" % "2.5" - )} - -// https://mvnrepository.com/artifact/org.scala-lang/scala-library -libraryDependencies += "org.scala-lang" % "scala-library" % scalaVersion.value -libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value - -libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT" -// https://mvnrepository.com/artifact/com.github.etaty/rediscala_2.12 -libraryDependencies += "com.github.etaty" % "rediscala_2.12" % "1.8.0" -// https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-scala_2.12 -libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.12" % "2.9.6" - -//seq(Revolver.settings: _*) -// -//scalariformSettings - +Seq(Revolver.settings: _*) +lazy val bbbScreenshareAkka = (project in file(".")).settings(name := "bbb-screenshare-akka", libraryDependencies ++= Dependencies.runtime).settings(compileSettings) //----------- // Packaging diff --git a/bbb-screenshare/app/deploy.sh b/bbb-screenshare/app/deploy.sh index a21a310dbb12dcf7258fdfd49cb43ee187c31545..69d99a0f08fa0b716c734b4a525efc203e0c6922 100755 --- a/bbb-screenshare/app/deploy.sh +++ b/bbb-screenshare/app/deploy.sh @@ -1,52 +1,45 @@ #!/bin/bash # deploying 'screenshare' to /usr/share/red5/webapps -sbt clean -sbt compile -sbt package +sbt clean compile package + if [[ -d /usr/share/red5/webapps/screenshare ]]; then sudo rm -r /usr/share/red5/webapps/screenshare fi sudo cp -r target/webapp/ /usr/share/red5/webapps/screenshare - sudo rm -rf /usr/share/red5/webapps/screenshare/WEB-INF/lib/* -sudo cp ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/bbb-screenshare-akka_2.12-0.0.2.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/scala-library-* \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/scala-reflect-* \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/jackson-* \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/paranamer-2.8.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/akka-* \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/config-1.3.3.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/gson-2.8.5.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/jedis-2.9.0.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/commons-pool2-2.6.0.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/spring-webmvc-4.3.12.RELEASE.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/rediscala_2.12-1.8.0.jar \ - ~/dev/bigbluebutton/bbb-screenshare/app/target/webapp/WEB-INF/lib/bbb-common-message_2.12-0.0.19-SNAPSHOT.jar \ +sudo cp target/webapp/WEB-INF/lib/bbb-screenshare-akka_2.12-0.0.3.jar \ + target/webapp/WEB-INF/lib/scala-library.jar \ + target/webapp/WEB-INF/lib/scala-reflect.jar \ + target/webapp/WEB-INF/lib/jackson-* \ + target/webapp/WEB-INF/lib/paranamer-2.8.jar \ + target/webapp/WEB-INF/lib/akka-* \ + target/webapp/WEB-INF/lib/config-1.3.3.jar \ + target/webapp/WEB-INF/lib/gson-2.8.5.jar \ + target/webapp/WEB-INF/lib/commons-pool2-2.6.0.jar \ + target/webapp/WEB-INF/lib/spring-webmvc-4.3.12.RELEASE.jar \ + target/webapp/WEB-INF/lib/bbb-common-message_2.12-0.0.20-SNAPSHOT.jar \ + target/webapp/WEB-INF/lib/lettuce-core-5.1.3.RELEASE.jar \ + target/webapp/WEB-INF/lib/netty-* \ + target/webapp/WEB-INF/lib/reactor-core-3.2.3.RELEASE.jar \ + target/webapp/WEB-INF/lib/reactive-streams-1.0.2.jar \ /usr/share/red5/webapps/screenshare/WEB-INF/lib/ - #sudo mkdir /usr/share/red5/webapps/screenshare/WEB-INF/classes #cd /usr/share/red5/webapps/screenshare/WEB-INF/classes/ -#sudo jar -xf ../lib/bbb-screenshare-akka_2.12-0.0.2.jar -#sudo rm /usr/share/red5/webapps/screenshare/WEB-INF/lib/bbb-screenshare-akka_2.12-0.0.2.jar +#sudo jar -xf .lib/bbb-screenshare-akka_2.12-0.0.3.jar +#sudo rm /usr/share/red5/webapps/screenshare/WEB-INF/lib/bbb-screenshare-akka_2.12-0.0.3.jar -cd /usr/share/red5/webapps/screenshare -sudo mkdir lib -cd lib -sudo cp -r ~/dev/bigbluebutton/bbb-screenshare/app/jws/lib/* . -cd .. -sudo cp ~/dev/bigbluebutton/bbb-screenshare/app/jws/screenshare.jnlp . -sudo cp ~/dev/bigbluebutton/bbb-screenshare/app/jws/screenshare.jnlp.h264 . +sudo mkdir -p /usr/share/red5/webapps/screenshare/lib +sudo cp -r jws/lib/* /usr/share/red5/webapps/screenshare/lib +sudo cp jws/screenshare.jnlp /usr/share/red5/webapps/screenshare +sudo cp jws/screenshare.jnlp.h264 /usr/share/red5/webapps/screenshare sudo chmod -R 777 /usr/share/red5/webapps/screenshare sudo chown -R red5:red5 /usr/share/red5/webapps/screenshare -# TODO change the owner username to 'firstuser' - # // Dev only #sudo service red5 restart #sudo service tomcat7 restart #sudo service bbb-apps-akka restart - diff --git a/bbb-screenshare/app/project/Dependencies.scala b/bbb-screenshare/app/project/Dependencies.scala new file mode 100644 index 0000000000000000000000000000000000000000..447f11e573748718d87aa46a0e05c95e78e7b0a1 --- /dev/null +++ b/bbb-screenshare/app/project/Dependencies.scala @@ -0,0 +1,105 @@ +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 gson = "2.8.5" + val jackson = "2.9.7" + val logback = "1.2.3" + val springVersion = "4.3.12.RELEASE" + val red5 = "1.0.10-M5" + val servlet = "2.5" + val ffmpeg = "4.0.2-1.4.3" + val openCv = "1.4.3" + + // Apache Commons + val lang = "3.7" + val codec = "1.11" + val pool2 = "2.6.0" + + // Redis + val lettuce = "5.1.3.RELEASE" + + // BigBlueButton + val bbbCommons = "0.0.20-SNAPSHOT" + + // Test + val scalaTest = "3.0.5" + val akkaTestKit = "2.5.18" + } + + object Compile { + val scalaLibrary = "org.scala-lang" % "scala-library" % Versions.scala + val scalaReflect = "org.scala-lang" % "scala-reflect" % 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 googleGson = "com.google.code.gson" % "gson" % Versions.gson + val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson + val logback = "ch.qos.logback" % "logback-classic" % Versions.logback % "runtime" + val red5Server = "org.red5" % "red5-server" % Versions.red5 + val javaServlet = "javax.servlet" % "servlet-api" % Versions.servlet + val ffmpeg = "org.bytedeco.javacpp-presets" % "ffmpeg" % Versions.ffmpeg + val openCv = "org.bytedeco" % "javacv" % Versions.openCv + + val springWeb = "org.springframework" % "spring-web" % Versions.springVersion + val springBeans = "org.springframework" % "spring-beans" % Versions.springVersion + val springContext = "org.springframework" % "spring-context" % Versions.springVersion + val springCore = "org.springframework" % "spring-core" % Versions.springVersion + val springWebmvc = "org.springframework" % "spring-webmvc" % Versions.springVersion + val springAop = "org.springframework" % "spring-aop" % Versions.springVersion + + val commonsCodec = "commons-codec" % "commons-codec" % Versions.codec + val apacheLang = "org.apache.commons" % "commons-lang3" % Versions.lang + val apachePool2 = "org.apache.commons" % "commons-pool2" % Versions.pool2 + + val lettuceCore = "io.lettuce" % "lettuce-core" % Versions.lettuce + + val bbbCommons = "org.bigbluebutton" % "bbb-common-message_2.12" % Versions.bbbCommons + } + + object Test { + val scalaTest = "org.scalatest" %% "scalatest" % Versions.scalaTest % "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.scalactic, + Test.akkaTestKit) + + val runtime = Seq( + Compile.scalaLibrary, + Compile.scalaReflect, + Compile.akkaActor, + Compile.akkaSl4fj, + Compile.googleGson, + Compile.jacksonModule, + Compile.red5Server, + Compile.javaServlet, + Compile.ffmpeg, + Compile.openCv, + Compile.logback, + Compile.springWeb, + Compile.springBeans, + Compile.springContext, + Compile.springWebmvc, + Compile.springAop, + Compile.commonsCodec, + Compile.apacheLang, + Compile.apachePool2, + Compile.lettuceCore, + Compile.bbbCommons) ++ testing +} diff --git a/bbb-screenshare/app/project/build.properties b/bbb-screenshare/app/project/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..7c58a83abffb36afce7051243bff3a50e3fa3dab --- /dev/null +++ b/bbb-screenshare/app/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.2.6 diff --git a/bbb-screenshare/app/project/plugins.sbt b/bbb-screenshare/app/project/plugins.sbt index 1c5c911f1db806157b151442a8ed6230cbd9afe9..0a2cbd1dd31631fd8a7a856591f2deeaf85a7840 100644 --- a/bbb-screenshare/app/project/plugins.sbt +++ b/bbb-screenshare/app/project/plugins.sbt @@ -1,15 +1,13 @@ 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.sbt" % "sbt-native-packager" % "1.3.6") - -addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.1.0") +addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.2") -//addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.7.9") +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.12") -addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.7") +addSbtPlugin("net.vonbuchholtz" % "sbt-dependency-check" % "0.2.8") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") + +addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.0.2") diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/ScreenshareStreamListener.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/ScreenshareStreamListener.java index 1e90ff0111d506485d1bf5cf12daa99acbbcf73a..7cbecf986d010a8f1a957462773b2ea41640f055 100755 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/ScreenshareStreamListener.java +++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/ScreenshareStreamListener.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.apache.mina.core.buffer.IoBuffer; +import org.bigbluebutton.common2.redis.RedisStorageService; import org.red5.server.api.IConnection; import org.red5.server.api.Red5; import org.red5.server.api.stream.IBroadcastStream; @@ -46,11 +47,11 @@ import org.red5.server.net.rtmp.event.VideoData; * */ public class ScreenshareStreamListener implements IStreamListener { - private EventRecordingService recordingService; + private RedisStorageService recordingService; private volatile boolean firstPacketReceived = false; private String recordingDir; - public ScreenshareStreamListener(EventRecordingService s, String recordingDir) { + public ScreenshareStreamListener(RedisStorageService s, String recordingDir) { this.recordingService = s; this.recordingDir = recordingDir; } diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/VideoStreamListener.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/VideoStreamListener.java index 41468e7ed845331d4706df0ab30a711a6d70f35a..bf91a9770f607ffc91bb3974ec24d4ac6bf37cb1 100755 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/VideoStreamListener.java +++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/VideoStreamListener.java @@ -17,24 +17,24 @@ */ package org.bigbluebutton.app.screenshare; +import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import org.apache.mina.core.buffer.IoBuffer; +import org.bigbluebutton.common2.redis.RedisStorageService; +import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.scheduling.IScheduledJob; import org.red5.server.api.scheduling.ISchedulingService; -import org.red5.server.api.scope.IScope; import org.red5.server.api.stream.IBroadcastStream; import org.red5.server.api.stream.IStreamListener; import org.red5.server.api.stream.IStreamPacket; import org.red5.server.net.rtmp.event.VideoData; import org.red5.server.scheduling.QuartzSchedulingService; import org.slf4j.Logger; -import org.red5.logging.Red5LoggerFactory; import com.google.gson.Gson; -import java.text.SimpleDateFormat; /** * Class to listen for the first video packet of the webcam. @@ -54,7 +54,7 @@ import java.text.SimpleDateFormat; public class VideoStreamListener implements IStreamListener { private static final Logger log = Red5LoggerFactory.getLogger(VideoStreamListener.class, "screenshare"); - private EventRecordingService recordingService; + private RedisStorageService redisStorageService; private volatile boolean firstPacketReceived = false; // Maximum time between video packets @@ -96,14 +96,14 @@ public class VideoStreamListener implements IStreamListener { public VideoStreamListener(String meetingId, String streamId, Boolean record, String recordingDir, int packetTimeout, QuartzSchedulingService scheduler, - EventRecordingService recordingService) { + RedisStorageService recordingService) { this.meetingId = meetingId; this.streamId = streamId; this.record = record; this.videoTimeout = packetTimeout; this.recordingDir = recordingDir; this.scheduler = scheduler; - this.recordingService = recordingService; + this.redisStorageService = recordingService; // start the worker to monitor if we are still receiving video packets timeoutJobName = scheduler.addScheduledJob(videoTimeout, new TimeoutJob()); @@ -166,7 +166,7 @@ public class VideoStreamListener implements IStreamListener { event.put(DATE, sdf.format(recordingStartTime)); event.put("eventName", "DeskshareStartedEvent"); - recordingService.record(meetingId, event); + redisStorageService.record(meetingId, event); Gson gson = new Gson(); @@ -233,7 +233,7 @@ public class VideoStreamListener implements IStreamListener { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX"); event.put(DATE, sdf.format(now)); event.put("eventName", "DeskshareStoppedEvent"); - recordingService.record(meetingId, event); + redisStorageService.record(meetingId, event); Gson gson = new Gson(); String logStr = gson.toJson(event); diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/messaging/redis/MessageSender.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/messaging/redis/MessageSender.java deleted file mode 100755 index 182ab1dac605fa0b6cdc2e7216ab476de0afecdc..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/messaging/redis/MessageSender.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.bigbluebutton.app.screenshare.messaging.redis; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; - -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.Protocol; - -public class MessageSender { - private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton"); - - private volatile boolean sendMessage = false; - private final Executor msgSenderExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>(); - - private JedisPool redisPool; - private String host; - private int port; - - public void stop() { - sendMessage = false; - redisPool.destroy(); - } - - public void start() { - GenericObjectPoolConfig config = new GenericObjectPoolConfig(); - config.setMaxTotal(32); - config.setMaxIdle(8); - config.setMinIdle(1); - config.setTestOnBorrow(true); - config.setTestOnReturn(true); - config.setTestWhileIdle(true); - config.setNumTestsPerEvictionRun(12); - config.setMaxWaitMillis(5000); - config.setTimeBetweenEvictionRunsMillis(60000); - config.setBlockWhenExhausted(true); - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null, - Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub"); - - log.info("Redis message publisher starting!"); - try { - sendMessage = true; - - Runnable messageSender = new Runnable() { - public void run() { - while (sendMessage) { - try { - MessageToSend msg = messages.take(); - publish(msg.getChannel(), msg.getMessage()); - } catch (InterruptedException e) { - log.warn("Failed to get message from queue."); - } - } - } - }; - msgSenderExec.execute(messageSender); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - public void send(String channel, String message) { - MessageToSend msg = new MessageToSend(channel, message); - messages.add(msg); - } - - private void publish(final String channel, final String message) { - Runnable task = new Runnable() { - public void run() { - Jedis jedis = redisPool.getResource(); - try { - jedis.publish(channel, message); - } catch(Exception e){ - log.warn("Cannot publish the message to redis", e); - } finally { - jedis.close(); - } - } - }; - - runExec.execute(task); - } - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } -} diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java index 432f4049a08a30376e42869588daf798d68a6749..142b9a2a50c8f7d2bb93572521a0b0e61ab6cb69 100755 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java +++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java @@ -24,24 +24,22 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bigbluebutton.app.screenshare.IScreenShareApplication; +import org.bigbluebutton.app.screenshare.MeetingManager; +import org.bigbluebutton.app.screenshare.VideoStream; +import org.bigbluebutton.app.screenshare.VideoStreamListener; +import org.bigbluebutton.common2.redis.RedisStorageService; import org.red5.logging.Red5LoggerFactory; import org.red5.server.adapter.MultiThreadedApplicationAdapter; import org.red5.server.api.IConnection; import org.red5.server.api.Red5; import org.red5.server.api.scope.IScope; import org.red5.server.api.stream.IBroadcastStream; -import org.red5.server.api.stream.IServerStream; -import org.red5.server.api.stream.IStreamListener; +import org.red5.server.scheduling.QuartzSchedulingService; import org.red5.server.stream.ClientBroadcastStream; import org.slf4j.Logger; -import org.red5.server.scheduling.QuartzSchedulingService; + import com.google.gson.Gson; -import org.bigbluebutton.app.screenshare.MeetingManager; -import org.bigbluebutton.app.screenshare.VideoStreamListener; -import org.bigbluebutton.app.screenshare.VideoStream; -import org.bigbluebutton.app.screenshare.EventRecordingService; -import org.bigbluebutton.app.screenshare.IScreenShareApplication; -import org.bigbluebutton.app.screenshare.ScreenshareStreamListener; public class Red5AppAdapter extends MultiThreadedApplicationAdapter { private static Logger log = Red5LoggerFactory.getLogger(Red5AppAdapter.class, "screenshare"); @@ -49,7 +47,7 @@ public class Red5AppAdapter extends MultiThreadedApplicationAdapter { // Scheduler private QuartzSchedulingService scheduler; - private EventRecordingService recordingService; + private RedisStorageService redisStorageService; private IScreenShareApplication app; private String streamBaseUrl; private ConnectionInvokerService sender; @@ -196,7 +194,7 @@ public class Red5AppAdapter extends MultiThreadedApplicationAdapter { log.info(logStr2); VideoStreamListener listener = new VideoStreamListener(meetingId, streamId, - recordVideoStream, recordingDirectory, packetTimeout, scheduler, recordingService); + recordVideoStream, recordingDirectory, packetTimeout, scheduler, redisStorageService); ClientBroadcastStream cstream = (ClientBroadcastStream) this.getBroadcastStream(conn.getScope(), stream.getPublishedName()); stream.addStreamListener(listener); VideoStream vstream = new VideoStream(stream, listener, cstream); @@ -255,8 +253,8 @@ public class Red5AppAdapter extends MultiThreadedApplicationAdapter { this.meetingManager = meetingManager; } - public void setEventRecordingService(EventRecordingService s) { - recordingService = s; + public void setRedisStorageService(RedisStorageService s) { + redisStorageService = s; } public void setStreamBaseUrl(String baseUrl) { diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java index da895535568acdabfc6d19509c72c25b3318e650..1e459fafa28e53ad935c41966c408f2adb361f0a 100755 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java +++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java @@ -3,19 +3,18 @@ package org.bigbluebutton.app.screenshare.red5; import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; -import org.bigbluebutton.app.screenshare.messaging.redis.MessageSender; + import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.IConnection; import org.red5.server.api.Red5; import org.slf4j.Logger; + import com.google.gson.Gson; public class Red5AppService { private static Logger log = Red5LoggerFactory.getLogger(Red5AppService.class, "screenshare"); private Red5AppHandler handler; - private MessageSender red5RedisSender; /** * Called from the client to pass us the userId. @@ -180,15 +179,7 @@ public class Red5AppService { handler.screenShareClientPongMessage(meetingId, userId, streamId, timestamp.longValue()); } - private Long genTimestamp() { - return TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - } - public void setAppHandler(Red5AppHandler handler) { this.handler = handler; } - - public void setRed5RedisSender(MessageSender red5RedisSender) { - this.red5RedisSender = red5RedisSender; - } } diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/server/recorder/EventRecorder.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/server/recorder/EventRecorder.java deleted file mode 100755 index ec4452c66ea6600f878cfd91355bd3283aed6aa2..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/server/recorder/EventRecorder.java +++ /dev/null @@ -1,59 +0,0 @@ -/** -* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ -* -* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). -* -* This program is free software; you can redistribute it and/or modify it under the -* terms of the GNU Lesser General Public License as published by the Free Software -* Foundation; either version 3.0 of the License, or (at your option) any later -* version. -* -* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. -* -*/ -package org.bigbluebutton.app.screenshare.server.recorder; - -import java.util.concurrent.TimeUnit; - -import org.bigbluebutton.app.screenshare.server.recorder.event.AbstractDeskshareRecordEvent; -import org.bigbluebutton.app.screenshare.server.recorder.event.RecordEvent; -import org.bigbluebutton.app.screenshare.server.recorder.event.RecordStartedEvent; -import org.bigbluebutton.app.screenshare.server.recorder.event.RecordStoppedEvent; - -import redis.clients.jedis.Jedis; - -public class EventRecorder implements RecordStatusListener { - private static final String COLON=":"; - private String host; - private int port; - - public EventRecorder(String host, int port){ - this.host = host; - this.port = port; - } - - private Long genTimestamp() { - return TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - } - - private void record(String session, RecordEvent message) { - Jedis jedis = new Jedis(host, port); - Long msgid = jedis.incr("global:nextRecordedMsgId"); - jedis.hmset("recording" + COLON + session + COLON + msgid, message.toMap()); - jedis.rpush("meeting" + COLON + session + COLON + "recordings", msgid.toString()); - } - - @Override - public void notify(RecordEvent event) { - if ((event instanceof RecordStoppedEvent) || (event instanceof RecordStartedEvent)) { - event.setTimestamp(genTimestamp()); - event.setMeetingId(((AbstractDeskshareRecordEvent)event).getSession()); - record(((AbstractDeskshareRecordEvent)event).getSession(), event); - } - } -} diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/store/redis/RedisDataStore.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/store/redis/RedisDataStore.java deleted file mode 100755 index e1900231febfe63631debd14a2c6a61702f4e220..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/store/redis/RedisDataStore.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.bigbluebutton.app.screenshare.store.redis; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; - -public class RedisDataStore { - private static Logger log = Red5LoggerFactory.getLogger(RedisDataStore.class, "screenshare"); - - private JedisPool redisPool; - private volatile boolean sendMessage = false; - private int maxThreshold = 1024; - private final Executor msgSenderExec = Executors.newSingleThreadExecutor(); - private BlockingQueue<IScreenShareData> dataToStore = new LinkedBlockingQueue<IScreenShareData>(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - - public void stop() { - sendMessage = false; - } - - public void start() { - try { - sendMessage = true; - - Runnable messageSender = new Runnable() { - public void run() { - while (sendMessage) { - try { - IScreenShareData data = dataToStore.take(); - storeData(data); - } catch (InterruptedException e) { - log.warn("Failed to get data from queue."); - } - } - } - }; - msgSenderExec.execute(messageSender); - } catch (Exception e) { - log.error("Error storing data into redis: " + e.getMessage()); - } - } - - public void store(IScreenShareData data) { - if (dataToStore.size() > maxThreshold) { - log.warn("Queued number of data [{}] is greater than threshold [{}]", dataToStore.size(), maxThreshold); - } - dataToStore.add(data); - } - - private void storeData(IScreenShareData data) { - Runnable task = new Runnable() { - public void run() { - Jedis jedis = redisPool.getResource(); - try { - // jedis.publish(channel, message); - } catch(Exception e){ - log.warn("Cannot publish the message to redis", e); - } finally { - redisPool.returnResource(jedis); - } - } - }; - - runExec.execute(task); - } - - public void setRedisPool(JedisPool redisPool){ - this.redisPool = redisPool; - } - - public void setMaxThreshold(int threshold) { - maxThreshold = threshold; - } -} diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala index cb3082f1a6e119ab56337eab61cfdacc2035430a..d1c42cdd8c86e4d22ef02f7add2d8e3f287a8b0b 100755 --- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala +++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala @@ -26,10 +26,11 @@ import org.bigbluebutton.app.screenshare.server.sessions.ScreenshareManager import org.bigbluebutton.app.screenshare.server.sessions.messages._ import org.bigbluebutton.app.screenshare.server.util.LogHelper import akka.actor.ActorSystem -import org.bigbluebutton.app.screenshare.redis.{ AppsRedisSubscriberActor, IncomingJsonMessageBus, ReceivedJsonMsgHandlerActor } +import org.bigbluebutton.app.screenshare.redis.{ ScreenshareRedisSubscriberActor, ReceivedJsonMsgHandlerActor } import scala.concurrent.{ Await, Future, TimeoutException } import scala.concurrent.duration._ +import org.bigbluebutton.common2.bus.IncomingJsonMessageBus class ScreenShareApplication(val bus: IEventsMessageBus, val jnlpFile: String, val streamBaseUrl: String) extends IScreenShareApplication @@ -46,7 +47,7 @@ class ScreenShareApplication(val bus: IEventsMessageBus, val jnlpFile: String, //logger.debug("*********** meetingManagerChannel = " + meetingManagerChannel) val incomingJsonMessageBus = new IncomingJsonMessageBus - val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(incomingJsonMessageBus), "redis-subscriber") + val redisSubscriberActor = system.actorOf(ScreenshareRedisSubscriberActor.props(system, incomingJsonMessageBus), "redis-subscriber") val screenShareManager = system.actorOf(ScreenshareManager.props(system, bus), "screenshare-manager") diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/SystemConfiguration.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/SystemConfiguration.scala index c25b684048db28d44b04cc90e5eef302c56ccb50..a838726e128301e5f91b955e81e123f832ac8523 100755 --- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/SystemConfiguration.scala +++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/SystemConfiguration.scala @@ -2,18 +2,11 @@ package org.bigbluebutton.app.screenshare import scala.util.Try import com.typesafe.config.ConfigFactory +import org.bigbluebutton.common2.redis.RedisConfiguration -trait SystemConfiguration { - - //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("") +trait SystemConfiguration extends RedisConfiguration { lazy val meetingManagerChannel = Try(config.getString("eventBus.meetingManagerChannel")).getOrElse("NOT FROM APP CONF") lazy val toScreenshareAppsJsonChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-screenshare-apps-json-channel") - lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel") } diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/AppsRedisSubscriberActor.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/AppsRedisSubscriberActor.scala deleted file mode 100755 index 36bbc477fc0d0201f1a875f03bdb1dbad7599324..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/AppsRedisSubscriberActor.scala +++ /dev/null @@ -1,59 +0,0 @@ -package org.bigbluebutton.app.screenshare.redis - -import java.io.{ PrintWriter, StringWriter } -import java.net.InetSocketAddress - -import akka.actor.{ OneForOneStrategy, Props } -import akka.actor.SupervisorStrategy.Resume -import org.bigbluebutton.app.screenshare.SystemConfiguration -import redis.actors.RedisSubscriberActor -import redis.api.servers.ClientSetname -import redis.actors.RedisSubscriberActor -import redis.api.pubsub.{ Message, PMessage } -import scala.concurrent.duration._ - -object AppsRedisSubscriberActor extends SystemConfiguration { - - val channels = Seq(fromAkkaAppsRedisChannel) - val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*") - - def props(jsonMsgBus: IncomingJsonMessageBus): Props = - Props(classOf[AppsRedisSubscriberActor], jsonMsgBus, - redisHost, redisPort, - channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher") -} - -class AppsRedisSubscriberActor(jsonMsgBus: IncomingJsonMessageBus, redisHost: String, - redisPort: Int, - channels: Seq[String] = Nil, patterns: Seq[String] = Nil) - extends RedisSubscriberActor( - new InetSocketAddress(redisHost, redisPort), - channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration { - - override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { - case e: Exception => { - val sw: StringWriter = new StringWriter() - sw.write("An exception has been thrown on AppsRedisSubscriberActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n") - e.printStackTrace(new PrintWriter(sw)) - log.error(sw.toString()) - Resume - } - } - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - write(ClientSetname("BbbScreenshareAkkaSub").encodedRequest) - - def onMessage(message: Message) { - //log.error(s"SHOULD NOT BE RECEIVING: $message") - if (message.channel == fromAkkaAppsRedisChannel) { - val receivedJsonMessage = new ReceivedJsonMessage(message.channel, message.data.utf8String) - //log.debug(s"RECEIVED:\n [${receivedJsonMessage.channel}] \n ${receivedJsonMessage.data} \n") - jsonMsgBus.publish(IncomingJsonMessage(toScreenshareAppsJsonChannel, receivedJsonMessage)) - } - } - - def onPMessage(pmessage: PMessage) { - //log.debug(s"RECEIVED:\n ${pmessage.data.utf8String} \n") - } -} diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/IncomingJsonMessageBus.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/IncomingJsonMessageBus.scala deleted file mode 100755 index 532b120a86c332aaec568ed93dd0941bc21f5fcf..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/IncomingJsonMessageBus.scala +++ /dev/null @@ -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 event’s 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 -} diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ReceivedJsonMsgHandlerActor.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ReceivedJsonMsgHandlerActor.scala index 36d638988c3a31b63c4149b6f53b8cd2b6db2af0..ca57f9d59956fbd81963126d41fb0903f7637b59 100755 --- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ReceivedJsonMsgHandlerActor.scala +++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ReceivedJsonMsgHandlerActor.scala @@ -5,7 +5,8 @@ import org.bigbluebutton.app.screenshare.server.sessions.messages.{ MeetingCreat import akka.actor.{ Actor, ActorLogging, ActorRef, Props } import scala.reflect.runtime.universe._ -import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.common2.bus.ReceivedJsonMessage object ReceivedJsonMsgHandlerActor { def props(screenshareManager: ActorRef): Props = diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ScreenshareRedisSubscriberActor.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ScreenshareRedisSubscriberActor.scala new file mode 100755 index 0000000000000000000000000000000000000000..8c4875497e4d2065644e23aa1469ceca4a1d959d --- /dev/null +++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/redis/ScreenshareRedisSubscriberActor.scala @@ -0,0 +1,32 @@ +package org.bigbluebutton.app.screenshare.redis + +import org.bigbluebutton.app.screenshare.SystemConfiguration +import org.bigbluebutton.common2.bus.IncomingJsonMessageBus +import org.bigbluebutton.common2.redis.RedisSubscriberProvider + +import akka.actor.ActorSystem +import akka.actor.Props + +object ScreenshareRedisSubscriberActor extends SystemConfiguration { + + val channels = Seq(fromAkkaAppsRedisChannel) + val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*") + + def props(system: ActorSystem, jsonMsgBus: IncomingJsonMessageBus): Props = + Props( + classOf[ScreenshareRedisSubscriberActor], + system, jsonMsgBus, + redisHost, redisPort, + channels, patterns).withDispatcher("akka.redis-subscriber-worker-dispatcher") +} + +class ScreenshareRedisSubscriberActor( + system: ActorSystem, + jsonMsgBus: IncomingJsonMessageBus, + redisHost: String, redisPort: Int, + channels: Seq[String] = Nil, patterns: Seq[String] = Nil) + extends RedisSubscriberProvider(system, "BbbScreenshareAkkaSub", channels, patterns, jsonMsgBus) with SystemConfiguration { + + addListener(toScreenshareAppsJsonChannel) + subscribe() +} diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/util/LogHelper.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/util/LogHelper.scala index dbe83dc52d9a768277f146622f565f816d6b2033..2ed8ee87d1a79cd87144b8b0c09b2e4bc9d4c960 100755 --- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/util/LogHelper.scala +++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/util/LogHelper.scala @@ -1,6 +1,5 @@ package org.bigbluebutton.app.screenshare.server.util -import org.slf4j.Logger import org.red5.logging.Red5LoggerFactory /** diff --git a/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-red5-redis-pubsub.xml b/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-red5-redis-pubsub.xml deleted file mode 100755 index d056fd28aa14a8c318a9a45c428f294edc6cadee..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-red5-redis-pubsub.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - -BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ - -Copyright (c) 2014 BigBlueButton Inc. and by respective authors (see below). - -This program is free software; you can redistribute it and/or modify it under the -terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 3.0 of the License, or (at your option) any later -version. - -BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along -with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. - ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util-2.0.xsd - "> - - <bean id="red5RedisSender" - class="org.bigbluebutton.app.screenshare.messaging.redis.MessageSender" - init-method="start" destroy-method="stop"> - <property name="host" value="${redis.host}" /> - <property name="port" value="${redis.port}" /> - </bean> - -</beans> diff --git a/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-redis-pool.xml b/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-redis-messaging.xml similarity index 78% rename from bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-redis-pool.xml rename to bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-redis-messaging.xml index 5aa3cc5f9aefa4a4b8af09abc545e26a898800db..49057aa845d009416b86f9763d1602060c0ae688 100755 --- a/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-redis-pool.xml +++ b/bbb-screenshare/app/src/main/webapp/WEB-INF/bbb-redis-messaging.xml @@ -27,10 +27,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. 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 id="redisStorageService" + class="org.bigbluebutton.common2.redis.RedisStorageService" + init-method="start" destroy-method="stop"> + <property name="host" value="${redis.host}" /> + <property name="port" value="${redis.port}" /> + <property name="password" value="${redis.password:}" /> + <property name="clientName" value="BbbScreenshare" /> </bean> ---> </beans> diff --git a/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/application.conf b/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/application.conf index 74183500ea75522d1927e5742c4f93d2722b1269..3b72838eb4bbe89bb4f2c7d26663b8c90cbd2a2b 100755 --- a/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/application.conf +++ b/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/application.conf @@ -10,7 +10,7 @@ akka { loggers = ["akka.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" - rediscala-publish-worker-dispatcher { + redis-publish-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. @@ -18,7 +18,7 @@ akka { throughput = 512 } - rediscala-subscriber-worker-dispatcher { + redis-subscriber-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. diff --git a/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/screenshare-app.conf b/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/screenshare-app.conf index 7a46eb9c45206cb1b304a93596212cf8b9595647..32a843bfaf817b1ee334bcdbe3ec5fba9b793ff5 100755 --- a/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/screenshare-app.conf +++ b/bbb-screenshare/app/src/main/webapp/WEB-INF/classes/screenshare-app.conf @@ -10,7 +10,7 @@ akka { loggers = ["akka.event.slf4j.Slf4jLoggerDDD"] loglevel = "DEBUG" - rediscala-publish-worker-dispatcher { + redis-publish-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. @@ -18,7 +18,7 @@ akka { throughput = 512 } - rediscala-subscriber-worker-dispatcher { + redis-subscriber-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. diff --git a/bbb-screenshare/app/src/main/webapp/WEB-INF/red5-web.xml b/bbb-screenshare/app/src/main/webapp/WEB-INF/red5-web.xml index 1fd0b7bfc69867548f365a3042d4383967e17aa1..91e61cb370d46ab8fc3a57cefcea8e19ecf720a0 100755 --- a/bbb-screenshare/app/src/main/webapp/WEB-INF/red5-web.xml +++ b/bbb-screenshare/app/src/main/webapp/WEB-INF/red5-web.xml @@ -35,6 +35,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. </property> </bean> + <bean id="screenShareApplication" class="org.bigbluebutton.app.screenshare.ScreenShareApplication"> + <constructor-arg index="0" ref="messageBus"/> + <constructor-arg index="1" value="${jnlpFile}"/> + <constructor-arg index="2" value="${streamBaseUrl}"/> + </bean> + + <bean id="connectionInvokerService" class="org.bigbluebutton.app.screenshare.red5.ConnectionInvokerService" + init-method="start" destroy-method="stop"> + </bean> + + <bean id="meetingManager" class="org.bigbluebutton.app.screenshare.MeetingManager"/> + <bean id="web.context" class="org.red5.server.Context" autowire="byType"/> <bean id="web.scope" class="org.red5.server.scope.WebScope" init-method="register"> @@ -48,36 +60,27 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <bean id="web.handler" class="org.bigbluebutton.app.screenshare.red5.Red5AppAdapter"> <property name="streamBaseUrl" value="${streamBaseUrl}"/> - <property name="eventRecordingService" ref="eventRecordingService"/> + <property name="redisStorageService" ref="redisStorageService"/> <property name="recordingDirectory" value="${recordingDirectory}"/> <property name="application" ref="screenShareApplication"/> <property name="messageSender" ref="connectionInvokerService"/> <property name="meetingManager" ref="meetingManager"/> </bean> - <bean id="meetingManager" class="org.bigbluebutton.app.screenshare.MeetingManager"/> - - <bean id="screenshare.service" class="org.bigbluebutton.app.screenshare.red5.Red5AppService"> - <property name="appHandler" ref="red5AppHandler"/> - <property name="red5RedisSender" ref="red5RedisSender"/> - </bean> - <bean id="red5AppHandler" class="org.bigbluebutton.app.screenshare.red5.Red5AppHandler"> <property name="application" ref="screenShareApplication"/> <property name="messageSender" ref="connectionInvokerService"/> </bean> + + <bean id="screenshare.service" class="org.bigbluebutton.app.screenshare.red5.Red5AppService"> + <property name="appHandler" ref="red5AppHandler"/> + </bean> <!-- The IoHandler implementation --> <bean id="screenCaptureHandler" class="org.bigbluebutton.app.screenshare.server.socket.BlockStreamEventMessageHandler"> <property name="application" ref="screenShareApplication"/> </bean> - <bean id="screenShareApplication" class="org.bigbluebutton.app.screenshare.ScreenShareApplication"> - <constructor-arg index="0" ref="messageBus"/> - <constructor-arg index="1" value="${jnlpFile}"/> - <constructor-arg index="2" value="${streamBaseUrl}"/> - </bean> - <bean id="eventListenerImp" class="org.bigbluebutton.app.screenshare.red5.EventListenerImp"> <property name="messageSender" ref="connectionInvokerService"/> <property name="meetingManager" ref="meetingManager"/> @@ -100,21 +103,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. </property> </bean> - <bean id="connectionInvokerService" class="org.bigbluebutton.app.screenshare.red5.ConnectionInvokerService" - init-method="start" destroy-method="stop"> - </bean> - - <bean id="eventRecordingService" class="org.bigbluebutton.app.screenshare.EventRecordingService"> - <constructor-arg index="0" value="${redis.host}"/> - <constructor-arg index="1" value="${redis.port}"/> - </bean> - - <bean id="redisRecorder" class="org.bigbluebutton.app.screenshare.server.recorder.EventRecorder"> - <constructor-arg index="0" value="${redis.host}"/> - <constructor-arg index="1" value="${redis.port}"/> - </bean> - + <import resource="bbb-redis-messaging.xml"/> - <import resource="bbb-redis-pool.xml"/> - <import resource="bbb-red5-redis-pubsub.xml"/> </beans> diff --git a/bbb-screenshare/app/src/main/webapp/WEB-INF/screenshare.properties b/bbb-screenshare/app/src/main/webapp/WEB-INF/screenshare.properties index 55bd99c50f97b91fe009d1446db69a6948d04348..808616484c689c8d140c98c061b29fc0dd0b591a 100755 --- a/bbb-screenshare/app/src/main/webapp/WEB-INF/screenshare.properties +++ b/bbb-screenshare/app/src/main/webapp/WEB-INF/screenshare.properties @@ -1,30 +1,29 @@ -# -# NOTE: default properties. -# -# NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!! -# When making changes that you don't want checked-in, do -# git update-index --assume-unchanged <file> -# -# To have git track the changes again -# git update-index --no-assume-unchanged <file> -# - -recordingDirectory=/usr/share/red5/webapps/screenshare/streams - -redis.host=127.0.0.1 -redis.port=6379 - - -streamBaseUrl=rtmp://192.168.23.22/screenshare -jnlpUrl=http://192.168.23.22/screenshare -jnlpFile=http://192.168.23.22/screenshare/screenshare.jnlp -useH264=false - -# NOTES: -# 1. GOP (group of pictures) is calculated as frameRate * keyFrameInterval -# 2. intra-refresh=1 doesn't work in Chrome. Late comers can't view the stream as -# the user missed the key frame -# 3. keyFrameInterval is in seconds -# 4. Make sure you encode & into & as it will break the JNLP XML -#codecOptions=crf=36&preset=veryfast&tune=animation,zerolatency&frameRate=12.0&keyFrameInterval=6 -codecOptions=crf=38&preset=veryfast&tune=zerolatency&frameRate=5.0&keyFrameInterval=5 +# +# NOTE: default properties. +# +# NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!! +# When making changes that you don't want checked-in, do +# git update-index --assume-unchanged <file> +# +# To have git track the changes again +# git update-index --no-assume-unchanged <file> +# + +recordingDirectory=/usr/share/red5/webapps/screenshare/streams + +redis.host=127.0.0.1 +redis.port=6379 + +streamBaseUrl=rtmp://192.168.23.22/screenshare +jnlpUrl=http://192.168.23.22/screenshare +jnlpFile=http://192.168.23.22/screenshare/screenshare.jnlp +useH264=false + +# NOTES: +# 1. GOP (group of pictures) is calculated as frameRate * keyFrameInterval +# 2. intra-refresh=1 doesn't work in Chrome. Late comers can't view the stream as +# the user missed the key frame +# 3. keyFrameInterval is in seconds +# 4. Make sure you encode & into & as it will break the JNLP XML +#codecOptions=crf=36&preset=veryfast&tune=animation,zerolatency&frameRate=12.0&keyFrameInterval=6 +codecOptions=crf=38&preset=veryfast&tune=zerolatency&frameRate=5.0&keyFrameInterval=5 diff --git a/bbb-screenshare/app/src/test/java/org/bigbluebutton/deskshare/server/recorder/FileRecorderTest.java b/bbb-screenshare/app/src/test/java/org/bigbluebutton/deskshare/server/recorder/FileRecorderTest.java deleted file mode 100755 index f5491111f761d49201584918ff900cdd51a8c3d3..0000000000000000000000000000000000000000 --- a/bbb-screenshare/app/src/test/java/org/bigbluebutton/deskshare/server/recorder/FileRecorderTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bigbluebutton.deskshare.server.recorder; - -import org.testng.Assert; -import org.testng.annotations.Test; - -public class FileRecorderTest { - - @Test - public void testHello() { - Assert.assertEquals(true, true); - } -} diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/h264/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/h264/sign-jar.sh index 01e78770a36a2cd553bea92b1646eb6e25e27319..09225a39145e51797093fae83685c958b7b4a4bd 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/h264/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/h264/sign-jar.sh @@ -1,18 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-linux-x86-h264.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-linux-x86.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-linux-x86.jar -cp org/bytedeco/javacpp/linux-x86/*.so* ../src/main/resources -cd .. -gradle jar -cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86-h264-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86-h264.jar -rm -rf workdir -rm -rf src - - +FFMPEG=ffmpeg-3.0.2-1.2-linux-x86-h264.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-linux-x86.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-linux-x86.jar +cp org/bytedeco/javacpp/linux-x86/*.so* ../src/main/resources +cd .. +gradle jar +cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86-h264-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86-h264.jar +rm -rf workdir +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/svc2/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/svc2/sign-jar.sh index e82feeb760ee234e2a44d540c57802b734831493..ae658006f6ca72a6223abd5b90346d192c1c03e7 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/svc2/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86/svc2/sign-jar.sh @@ -1,18 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-linux-x86-svc2.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-linux-x86.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-linux-x86.jar -cp org/bytedeco/javacpp/linux-x86/*.so* ../src/main/resources -cd .. -gradle jar -cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86-svc2-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86-svc2.jar -rm -rf workdir -rm -rf src - - +FFMPEG=ffmpeg-3.0.2-1.2-linux-x86-svc2.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-linux-x86.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-linux-x86.jar +cp org/bytedeco/javacpp/linux-x86/*.so* ../src/main/resources +cd .. +gradle jar +cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86-svc2-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-linux-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86-svc2.jar +rm -rf workdir +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/h264/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/h264/sign-jar.sh index 2ffaf065ce97591bfc898cbd2a6cadefa6d6b715..d9c1ba9c026dbb71e1bd3ed53c167783280f669b 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/h264/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/h264/sign-jar.sh @@ -1,17 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-linux-x86_64-h264.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-linux-x86_64.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-linux-x86_64.jar -cp org/bytedeco/javacpp/linux-x86_64/*.so* ../src/main/resources -cd .. -gradle jar -cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86_64-h264-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86_64-h264.jar -rm -rf workdir -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-linux-x86_64-h264.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-linux-x86_64.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-linux-x86_64.jar +cp org/bytedeco/javacpp/linux-x86_64/*.so* ../src/main/resources +cd .. +gradle jar +cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86_64-h264-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86_64-h264.jar +rm -rf workdir +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/svc2/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/svc2/sign-jar.sh index 781bc3e084016be9de8a136cc2ad0806c86e83d9..72f4872670e8eb4171f6ff2919c98d2469535729 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/svc2/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-linux-x86_64/svc2/sign-jar.sh @@ -1,17 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-linux-x86_64-svc2.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-linux-x86_64.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-linux-x86_64.jar -cp org/bytedeco/javacpp/linux-x86_64/*.so* ../src/main/resources -cd .. -gradle jar -cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86_64-svc2-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86_64-svc2.jar -rm -rf workdir -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-linux-x86_64-svc2.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-linux-x86_64.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-linux-x86_64.jar +cp org/bytedeco/javacpp/linux-x86_64/*.so* ../src/main/resources +cd .. +gradle jar +cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-linux-x86_64-svc2-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-linux-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-linux-x86_64-svc2.jar +rm -rf workdir +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/h264/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/h264/sign-jar.sh index 61c91813178c545c9770e7e7aa91596c78e22cdb..d8255408d3d9025dd48518325b9cf59797cd872e 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/h264/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/h264/sign-jar.sh @@ -1,16 +1,15 @@ -FFMPEG=ffmpeg-3.0.2-1.2-macosx-x86_64-h264.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-macosx-x86_64.jar -rm -rf src -mkdir -p src/main/resources -cd workdir -jar xvf ffmpeg-macosx-x86_64.jar -cp org/bytedeco/javacpp/macosx-x86_64/* ../src/main/resources -cd .. -rm -rf workdir -gradle jar -cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-macosx-x86_64-h264-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-macosx-x86_64-h264.jar -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-macosx-x86_64-h264.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-macosx-x86_64.jar +rm -rf src +mkdir -p src/main/resources +cd workdir +jar xvf ffmpeg-macosx-x86_64.jar +cp org/bytedeco/javacpp/macosx-x86_64/* ../src/main/resources +cd .. +rm -rf workdir +gradle jar +cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-macosx-x86_64-h264-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-macosx-x86_64-h264.jar +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/svc2/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/svc2/sign-jar.sh index 159d670c4b56cf9386e2b59600b9011f25ec7f1b..1639a806d0892dd8ca0350a592fd1ebaceccf7cc 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/svc2/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-macosx-x86_64/svc2/sign-jar.sh @@ -1,16 +1,15 @@ -FFMPEG=ffmpeg-3.0.2-1.2-macosx-x86_64-svc2.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-macosx-x86_64.jar -rm -rf src -mkdir -p src/main/resources -cd workdir -jar xvf ffmpeg-macosx-x86_64.jar -cp org/bytedeco/javacpp/macosx-x86_64/* ../src/main/resources -cd .. -rm -rf workdir -gradle jar -cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-macosx-x86_64-svc2-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-macosx-x86_64-svc2.jar -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-macosx-x86_64-svc2.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-macosx-x86_64.jar +rm -rf src +mkdir -p src/main/resources +cd workdir +jar xvf ffmpeg-macosx-x86_64.jar +cp org/bytedeco/javacpp/macosx-x86_64/* ../src/main/resources +cd .. +rm -rf workdir +gradle jar +cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-macosx-x86_64-svc2-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-macosx-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-macosx-x86_64-svc2.jar +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/h264/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/h264/sign-jar.sh index 1fbfa0ec41526a3a280e8e6fad206b611f733a8f..4f7c36064ba816126685d5410e81bf7b1fbc599b 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/h264/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/h264/sign-jar.sh @@ -1,17 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-windows-x86-h264.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-windows-x86.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-windows-x86.jar -cp org/bytedeco/javacpp/windows-x86/*.dll ../src/main/resources -cd .. -rm -rf workdir -gradle jar -cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86-h264-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86-h264.jar -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-windows-x86-h264.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-windows-x86.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-windows-x86.jar +cp org/bytedeco/javacpp/windows-x86/*.dll ../src/main/resources +cd .. +rm -rf workdir +gradle jar +cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86-h264-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86-h264.jar +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/svc2/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/svc2/sign-jar.sh index 1e8a5d3afb9c94885b7053e981e22560c2e9b39e..320f34680b98c219c449c9eacd21a611ca31ae06 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/svc2/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86/svc2/sign-jar.sh @@ -1,17 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-windows-x86-svc2.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-windows-x86.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-windows-x86.jar -cp org/bytedeco/javacpp/windows-x86/*.dll ../src/main/resources -cd .. -rm -rf workdir -gradle jar -cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86-svc2-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86-svc2.jar -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-windows-x86-svc2.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-windows-x86.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-windows-x86.jar +cp org/bytedeco/javacpp/windows-x86/*.dll ../src/main/resources +cd .. +rm -rf workdir +gradle jar +cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86-svc2-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-windows-x86-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86-svc2.jar +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/h264/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/h264/sign-jar.sh index 94ed509cc73fc2cfc9d6bce5a50e71b46ddbf683..7ace75cc22b9316e8bea64d1aa17e372858be86d 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/h264/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/h264/sign-jar.sh @@ -1,17 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-windows-x86_64-h264.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-windows-x86_64.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-windows-x86_64.jar -cp org/bytedeco/javacpp/windows-x86_64/*.dll ../src/main/resources -cd .. -rm -rf workdir -gradle jar -cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86_64-h264-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86_64-h264.jar -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-windows-x86_64-h264.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-windows-x86_64.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-windows-x86_64.jar +cp org/bytedeco/javacpp/windows-x86_64/*.dll ../src/main/resources +cd .. +rm -rf workdir +gradle jar +cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86_64-h264-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86_64-h264.jar +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/svc2/sign-jar.sh b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/svc2/sign-jar.sh index 4b8c8c1023acdb7649988c76470fbb13ebac00ee..0c67733b6a4defa15d824876a17133ffbe6e9962 100755 --- a/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/svc2/sign-jar.sh +++ b/bbb-screenshare/jws/native-libs/ffmpeg-windows-x86_64/svc2/sign-jar.sh @@ -1,17 +1,16 @@ -FFMPEG=ffmpeg-3.0.2-1.2-windows-x86_64-svc2.jar -mkdir workdir -cp $FFMPEG workdir/ffmpeg-windows-x86_64.jar -rm -rf src -mkdir -p src/main/resources -mkdir -p src/main/java -cd workdir -jar xvf ffmpeg-windows-x86_64.jar -cp org/bytedeco/javacpp/windows-x86_64/*.dll ../src/main/resources -cd .. -rm -rf workdir -gradle jar -cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86_64-svc2-unsigned.jar -ant sign-jar -cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86_64-svc2.jar -rm -rf src - +FFMPEG=ffmpeg-3.0.2-1.2-windows-x86_64-svc2.jar +mkdir workdir +cp $FFMPEG workdir/ffmpeg-windows-x86_64.jar +rm -rf src +mkdir -p src/main/resources +mkdir -p src/main/java +cd workdir +jar xvf ffmpeg-windows-x86_64.jar +cp org/bytedeco/javacpp/windows-x86_64/*.dll ../src/main/resources +cd .. +rm -rf workdir +gradle jar +cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../unsigned-jars/ffmpeg-win-x86_64-svc2-unsigned.jar +ant sign-jar +cp build/libs/ffmpeg-windows-x86_64-0.0.1.jar ../../../../app/jws/lib/ffmpeg-win-x86_64-svc2.jar +rm -rf src diff --git a/bbb-screenshare/jws/native-libs/unsigned-jars/sign-ffmpeg.sh b/bbb-screenshare/jws/native-libs/unsigned-jars/sign-ffmpeg.sh index 6cb98b0ea9930b6e4a4863e4c46fa0dc3d435a05..0ea0ec71b4c7e1e6115076ad991b3bfc52b603d0 100755 --- a/bbb-screenshare/jws/native-libs/unsigned-jars/sign-ffmpeg.sh +++ b/bbb-screenshare/jws/native-libs/unsigned-jars/sign-ffmpeg.sh @@ -1,16 +1,15 @@ -FFMPEG=ffmpeg-3.0.2-1.2.jar -if [ -d "workdir" ]; then - rm -rf workdir -fi -mkdir workdir -cp $FFMPEG workdir -cd workdir -jar xf $FFMPEG -rm $FFMPEG -rm -rf META-INF -jar cf ffmpeg.jar * -cd .. -ant sign-ffmpeg-jar -cp workdir/ffmpeg.jar ../../../app/jws/lib/ -rm -rf workdir - +FFMPEG=ffmpeg-3.0.2-1.2.jar +if [ -d "workdir" ]; then + rm -rf workdir +fi +mkdir workdir +cp $FFMPEG workdir +cd workdir +jar xf $FFMPEG +rm $FFMPEG +rm -rf META-INF +jar cf ffmpeg.jar * +cd .. +ant sign-ffmpeg-jar +cp workdir/ffmpeg.jar ../../../app/jws/lib/ +rm -rf workdir diff --git a/bbb-screenshare/jws/webstart/build.sh b/bbb-screenshare/jws/webstart/build.sh index 7074eba05053fb7e50983b4a92274174da04f6fd..fec75ea03c9b57d17e66cce5ad66a63e48f080a3 100755 --- a/bbb-screenshare/jws/webstart/build.sh +++ b/bbb-screenshare/jws/webstart/build.sh @@ -1,11 +1,10 @@ -if [ -d "lib" ]; then - rm -rf lib -fi -mkdir lib -cp ../../app/jws/lib/ffmpeg.jar lib -gradle clean -gradle jar -ant sign-jar -cp build/libs/javacv-screenshare-0.0.1.jar ../../app/jws/lib/ -rm -rf lib - +if [ -d "lib" ]; then + rm -rf lib +fi +mkdir lib +cp ../../app/jws/lib/ffmpeg.jar lib +gradle clean +gradle jar +ant sign-jar +cp build/libs/javacv-screenshare-0.0.1.jar ../../app/jws/lib/ +rm -rf lib diff --git a/bbb-screenshare/jws/webstart/deploy.sh b/bbb-screenshare/jws/webstart/deploy.sh index d8322cc8028df17d13f92a3e5de60fec086d9173..e49c761f5592b2ee5439484e40c99141912801c7 100755 --- a/bbb-screenshare/jws/webstart/deploy.sh +++ b/bbb-screenshare/jws/webstart/deploy.sh @@ -1,2 +1 @@ -cp build/libs/javacv-screenshare-0.0.1.jar /usr/share/red5/webapps/screenshare/lib - +cp build/libs/javacv-screenshare-0.0.1.jar /usr/share/red5/webapps/screenshare/lib diff --git a/bbb-video/build.gradle b/bbb-video/build.gradle index 88d9a056cc948c10ab31da12063df7dea0fb82cc..a174e2254606d89c26178d1069e5ac98cc8e2a12 100755 --- a/bbb-video/build.gradle +++ b/bbb-video/build.gradle @@ -17,6 +17,13 @@ repositories { mavenLocal() } +configurations { + runtime.exclude group: "org.slf4j", module: "slf4j-api" + runtime.exclude group: "org.red5", module: "red5-server" + runtime.exclude group: "org.red5", module: "red5-server-common" + runtime.exclude group: "org.red5", module: "red5-io" +} + dependencies { // Servlet providedCompile 'javax.servlet:servlet-api:2.5@jar' @@ -28,10 +35,11 @@ dependencies { // Spring providedCompile 'org.springframework:spring-web:4.3.12.RELEASE@jar' - providedCompile 'org.springframework:spring-beans:4.3.12.RELEASE@jar' + providedCompile 'org.springframework:spring-beans:4.3.12.RELEASE@jar' providedCompile 'org.springframework:spring-context:4.3.12.RELEASE@jar' providedCompile 'org.springframework:spring-core:4.3.12.RELEASE@jar' + // Red5 providedCompile 'org.red5:red5-server:1.0.10-M5@jar' providedCompile 'org.red5:red5-server-common:1.0.10-M5@jar' providedCompile 'org.red5:red5-io:1.0.10-M5@jar' @@ -49,23 +57,12 @@ dependencies { providedCompile 'org.springframework:spring-aop:4.3.12.RELEASE@jar' compile 'aopalliance:aopalliance:1.0@jar' - // Testing - compile 'org.easymock:easymock:2.4@jar' - - // Testing - testRuntime 'org.easymock:easymock:2.4@jar' - //redis - compile 'redis.clients:jedis:2.9.0' - compile 'org.apache.commons:commons-pool2:2.3' - compile 'com.google.code.gson:gson:2.5' - - compile 'org.apache.commons:commons-lang3:3.7' - compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.19-SNAPSHOT' -} + compile 'org.apache.commons:commons-pool2:2.6.0' + compile 'com.google.code.gson:gson:2.8.5' -test { - useTestNG() + providedCompile 'org.apache.commons:commons-lang3:3.7' + compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.20-SNAPSHOT' } war.doLast { @@ -76,6 +73,7 @@ war.doLast { task deploy() << { def red5AppsDir = '/usr/share/red5/webapps' def videoDir = new File("${red5AppsDir}/video") + println "Deleting $videoDir" if (videoDir.exists()) ant.delete(dir: videoDir) ant.mkdir(dir: videoDir) ant.copy(todir: videoDir) { diff --git a/bbb-video/deploy.sh b/bbb-video/deploy.sh index ff71c3ac7c685a5db422d9161f25a82b6c186300..b7cab36a4bc4e2ff6e2b72d8bb9bf36079ce3149 100755 --- a/bbb-video/deploy.sh +++ b/bbb-video/deploy.sh @@ -1,11 +1,10 @@ #!/bin/bash # deploying 'bigbluebutton-apps' to /usr/share/red5/webapps -sudo chown -R red5.red5 /usr/share/red5/webapps +sudo chmod -R 777 /usr/share/red5/webapps/* gradle clean gradle resolveDeps gradle war deploy -sudo chown -R red5.red5 /usr/share/red5/webapps - +sudo chown -R red5:red5 /usr/share/red5/webapps diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/EventRecordingService.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/EventRecordingService.java deleted file mode 100755 index 4bdec5c1df4e6b7f547df283519762cddc6c5006..0000000000000000000000000000000000000000 --- a/bbb-video/src/main/java/org/bigbluebutton/app/video/EventRecordingService.java +++ /dev/null @@ -1,78 +0,0 @@ -/** -* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ -* -* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). -* -* This program is free software; you can redistribute it and/or modify it under the -* terms of the GNU Lesser General Public License as published by the Free Software -* Foundation; either version 3.0 of the License, or (at your option) any later -* version. -* -* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. -* -*/ -package org.bigbluebutton.app.video; - -import java.util.Map; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.Protocol; - -public class EventRecordingService { - private static Logger log = Red5LoggerFactory.getLogger(EventRecordingService.class, "video"); - - private static final String COLON = ":"; - - private JedisPool redisPool; - private final String host; - private final int port; - private final int keyExpiry; - - public EventRecordingService(String host, int port, int keyExpiry) { - this.host = host; - this.port = port; - this.keyExpiry = keyExpiry; - } - - public void record(String meetingId, Map<String, String> event) { - Jedis jedis = redisPool.getResource(); - try { - Long msgid = jedis.incr("global:nextRecordedMsgId"); - String key = "recording:" + meetingId + COLON + msgid; - jedis.hmset(key, event); - /** - * We set the key to expire after 14 days as we are still - * recording the event into redis even if the meeting is not - * recorded. (ralam sept 23, 2015) - */ - jedis.expire(key, keyExpiry); - key = "meeting:" + meetingId + COLON + "recordings"; - jedis.rpush(key, msgid.toString()); - jedis.expire(key, keyExpiry); - } catch (Exception e) { - log.warn("Cannot record the info meeting:" + meetingId, e); - } finally { - jedis.close(); - } - - } - - public void stop() { - - } - - public void start() { - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - redisPool = new JedisPool(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null, - Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub"); - } -} diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java index 3b48025cc4ff4462867d0dae92ed5d4b14c6d1b0..054b5ca6f0fc5b8b9f0146f5e8f5d45da2a33c8b 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java +++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java @@ -21,11 +21,16 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + import org.bigbluebutton.app.video.converter.H263Converter; import org.bigbluebutton.app.video.converter.VideoRotator; +import org.bigbluebutton.common2.redis.RedisStorageService; import org.bigbluebutton.red5.pubsub.MessagePublisher; import org.red5.logging.Red5LoggerFactory; import org.red5.server.adapter.MultiThreadedApplicationAdapter; @@ -39,11 +44,9 @@ import org.red5.server.api.stream.ISubscriberStream; import org.red5.server.scheduling.QuartzSchedulingService; import org.red5.server.stream.ClientBroadcastStream; import org.slf4j.Logger; -import com.google.gson.Gson; import org.springframework.util.StringUtils; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; + +import com.google.gson.Gson; public class VideoApplication extends MultiThreadedApplicationAdapter { @@ -53,7 +56,7 @@ public class VideoApplication extends MultiThreadedApplicationAdapter { private QuartzSchedulingService scheduler; private MessagePublisher publisher; - private EventRecordingService recordingService; + private RedisStorageService recordingService; private final Map<String, IStreamListener> streamListeners = new HashMap<String, IStreamListener>(); private int packetTimeout = 10000; @@ -518,7 +521,7 @@ public class VideoApplication extends MultiThreadedApplicationAdapter { event.put("stream", stream.getPublishedName()); event.put("duration", new Long(publishDuration).toString()); event.put("eventName", "StopWebcamShareEvent"); - recordingService.record(scopeName, event); + recordingService.recordAndExpire(scopeName, event); } } @@ -526,7 +529,7 @@ public class VideoApplication extends MultiThreadedApplicationAdapter { this.packetTimeout = timeout; } - public void setEventRecordingService(EventRecordingService s) { + public void setEventRecordingService(RedisStorageService s) { recordingService = s; } diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoStreamListener.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoStreamListener.java index d1cb002298338ea060787a12cfc30b0e8f5e0728..f235e0574780141a6a14f82ef028fedd7f7de873 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoStreamListener.java +++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoStreamListener.java @@ -18,24 +18,24 @@ package org.bigbluebutton.app.video; +import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import org.apache.mina.core.buffer.IoBuffer; +import org.bigbluebutton.common2.redis.RedisStorageService; +import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.scheduling.IScheduledJob; import org.red5.server.api.scheduling.ISchedulingService; -import org.red5.server.api.scope.IScope; import org.red5.server.api.stream.IBroadcastStream; import org.red5.server.api.stream.IStreamListener; import org.red5.server.api.stream.IStreamPacket; import org.red5.server.net.rtmp.event.VideoData; import org.red5.server.scheduling.QuartzSchedulingService; import org.slf4j.Logger; -import org.red5.logging.Red5LoggerFactory; import com.google.gson.Gson; -import java.text.SimpleDateFormat; /** * Class to listen for the first video packet of the webcam. @@ -55,7 +55,7 @@ import java.text.SimpleDateFormat; public class VideoStreamListener implements IStreamListener { private static final Logger log = Red5LoggerFactory.getLogger(VideoStreamListener.class, "video"); - private EventRecordingService recordingService; + private RedisStorageService recordingService; private volatile boolean firstPacketReceived = false; // Maximum time between video packets @@ -98,7 +98,7 @@ public class VideoStreamListener implements IStreamListener { public VideoStreamListener(String meetingId, String streamId, Boolean record, String userId, int packetTimeout, QuartzSchedulingService scheduler, - EventRecordingService recordingService) { + RedisStorageService recordingService) { this.meetingId = meetingId; this.streamId = streamId; this.record = record; @@ -160,7 +160,7 @@ public class VideoStreamListener implements IStreamListener { event.put(DATE, sdf.format(recordingStartTime)); event.put("eventName", "StartWebcamShareEvent"); - recordingService.record(meetingId, event); + recordingService.recordAndExpire(meetingId, event); Gson gson = new Gson(); String logStr = gson.toJson(event); @@ -229,7 +229,7 @@ public class VideoStreamListener implements IStreamListener { event.put(DATE, sdf.format(now)); event.put("eventName", "StopWebcamShareEvent"); - recordingService.record(meetingId, event); + recordingService.recordAndExpire(meetingId, event); Gson gson = new Gson(); String logStr = gson.toJson(event); diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java index 14d8b61a8e3f40a1bbe8f1ae69056864cf6740b2..13b183125a22ae66a56f21f4ffe334fd3af045f0 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java +++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java @@ -1,19 +1,20 @@ package org.bigbluebutton.red5.pubsub; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import org.bigbluebutton.app.video.ConnectionInvokerService; import org.bigbluebutton.app.video.MeetingManager; +import org.bigbluebutton.common2.redis.pubsub.MessageHandler; import org.bigbluebutton.red5.pubsub.message.RecordChapterBreakMessage; import org.bigbluebutton.red5.pubsub.message.ValidateConnTokenRespMsg; import org.red5.logging.Red5LoggerFactory; import org.slf4j.Logger; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + public class MeetingMessageHandler implements MessageHandler { private static Logger log = Red5LoggerFactory.getLogger(MeetingMessageHandler.class, "video"); - private final String HEADER = "header"; private final String NAME = "name"; private final String BODY = "body"; @@ -61,8 +62,7 @@ public class MeetingMessageHandler implements MessageHandler { String logStr = gson.toJson(body); log.debug("HANDLE: {}", logStr); - if (body.has(MEETING_ID) && body.has(USERID) - && body.has(AUTHZED) && body.has(CONN) && body.has(APP)) { + if (body.has(MEETING_ID) && body.has(USERID) && body.has(AUTHZED) && body.has(CONN) && body.has(APP)) { String meetingId = body.get(MEETING_ID).getAsString(); String userId = body.get(USERID).getAsString(); diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageHandler.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageHandler.java deleted file mode 100755 index 8f197312c290d0ef21e0baed37478d9d7bfb94e3..0000000000000000000000000000000000000000 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageHandler.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.bigbluebutton.red5.pubsub; - -public interface MessageHandler { - void handleMessage(String pattern, String channel, String message); -} diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java index 0326ff3651835846f109ccab38c23b7978cd580b..f2619b6341e2e52da76d55349c42c1548915a677 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java +++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java @@ -1,11 +1,21 @@ package org.bigbluebutton.red5.pubsub; -import com.google.gson.Gson; -import org.bigbluebutton.common2.msgs.*; import java.util.HashMap; import java.util.Map; +import org.bigbluebutton.common2.msgs.BbbClientMsgHeader; +import org.bigbluebutton.common2.msgs.BbbCoreBaseHeader; +import org.bigbluebutton.common2.msgs.UserBroadcastCamStartMsg; +import org.bigbluebutton.common2.msgs.UserBroadcastCamStartMsgBody; +import org.bigbluebutton.common2.msgs.UserBroadcastCamStopMsg; +import org.bigbluebutton.common2.msgs.UserBroadcastCamStopMsgBody; +import org.bigbluebutton.common2.msgs.ValidateConnAuthTokenSysMsg; +import org.bigbluebutton.common2.msgs.ValidateConnAuthTokenSysMsgBody; +import org.bigbluebutton.common2.redis.pubsub.MessageSender; + +import com.google.gson.Gson; + public class MessagePublisher { private MessageSender sender; diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageReceiver.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageReceiver.java deleted file mode 100755 index fc215cdba5811e3f5ea061a18268c1bca4d6e821..0000000000000000000000000000000000000000 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageReceiver.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.bigbluebutton.red5.pubsub; - -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPubSub; -import redis.clients.jedis.exceptions.JedisConnectionException; - -public class MessageReceiver { - private static Logger log = Red5LoggerFactory.getLogger(MessageReceiver.class, "video"); - - private ReceivedMessageHandler handler; - - private Jedis jedis; - private volatile boolean receiveMessage = false; - - private final Executor msgReceiverExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - - private final String FROM_BBB_APPS_PATTERN = "from-akka-apps-redis-channel"; - - private String host; - private int port; - - public void stop() { - receiveMessage = false; - } - - public void start() { - log.info("Ready to receive messages from Redis pubsub."); - try { - receiveMessage = true; - jedis = new Jedis(host, port); - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - jedis.clientSetname("BbbRed5VideoSub"); - - Runnable messageReceiver = new Runnable() { - public void run() { - if (receiveMessage) { - try { - jedis.subscribe(new PubSubListener(), FROM_BBB_APPS_PATTERN); - } catch(JedisConnectionException ex) { - log.warn("Exception on Jedis connection. Resubscribing to pubsub."); - start(); - } catch (Exception e) { - log.error("Error resubscribing to channels: " + e.getMessage()); - } - } - } - }; - msgReceiverExec.execute(messageReceiver); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setMessageHandler(ReceivedMessageHandler handler) { - this.handler = handler; - } - - private class PubSubListener extends JedisPubSub { - - public PubSubListener() { - super(); - } - - @Override - public void onMessage(String channel, String message) { - // Not used. - Runnable task = new Runnable() { - public void run() { - handler.handleMessage("", channel, message); - } - }; - - runExec.execute(task); - } - - @Override - public void onPMessage(final String pattern, final String channel, final String message) { - System.out.println("RECEIVED onPMessage" + channel + " message=\n" + message); - Runnable task = new Runnable() { - public void run() { - handler.handleMessage(pattern, channel, message); - } - }; - - runExec.execute(task); - } - - @Override - public void onPSubscribe(String pattern, int subscribedChannels) { - log.debug("Subscribed to the pattern: " + pattern); - } - - @Override - public void onPUnsubscribe(String pattern, int subscribedChannels) { - // Not used. - } - - @Override - public void onSubscribe(String channel, int subscribedChannels) { - // Not used. - } - - @Override - public void onUnsubscribe(String channel, int subscribedChannels) { - // Not used. - } - } -} - diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java deleted file mode 100755 index 0b732de4e99d98c2a1d6dda54777fa585f1a6eed..0000000000000000000000000000000000000000 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.bigbluebutton.red5.pubsub; - -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.Protocol; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; - -public class MessageSender { - private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton"); - - private JedisPool redisPool; - private volatile boolean sendMessage = false; - - private final Executor msgSenderExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>(); - private String host; - private int port; - - public void stop() { - sendMessage = false; - redisPool.destroy(); - } - - public void start() { - - GenericObjectPoolConfig config = new GenericObjectPoolConfig(); - config.setMaxTotal(32); - config.setMaxIdle(8); - config.setMinIdle(1); - config.setTestOnBorrow(true); - config.setTestOnReturn(true); - config.setTestWhileIdle(true); - config.setNumTestsPerEvictionRun(12); - config.setMaxWaitMillis(5000); - config.setTimeBetweenEvictionRunsMillis(60000); - config.setBlockWhenExhausted(true); - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null, - Protocol.DEFAULT_DATABASE, "BbbRed5VideoPub"); - - log.info("Redis message publisher starting!"); - - try { - sendMessage = true; - - Runnable messageSender = new Runnable() { - public void run() { - while (sendMessage) { - try { - MessageToSend msg = messages.take(); - publish(msg.getChannel(), msg.getMessage()); - } catch (InterruptedException e) { - log.warn("Failed to get org.bigbluebutton.red5.pubsub.message from queue."); - } - } - } - }; - msgSenderExec.execute(messageSender); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - public void send(String channel, String message) { - MessageToSend msg = new MessageToSend(channel, message); - messages.add(msg); - } - - private void publish(final String channel, final String message) { - Runnable task = new Runnable() { - public void run() { - Jedis jedis = redisPool.getResource(); - try { - jedis.publish(channel, message); - } catch(Exception e){ - log.warn("Cannot publish the org.bigbluebutton.red5.pubsub.message to redis", e); - } finally { - redisPool.returnResource(jedis); - } - } - }; - - runExec.execute(task); - } - - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } -} diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageToSend.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageToSend.java deleted file mode 100755 index 3ae3874039b4637af954bf7d5d176bc80d268405..0000000000000000000000000000000000000000 --- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageToSend.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.bigbluebutton.red5.pubsub; - -public class MessageToSend { - private final String channel; - private final String message; - - public MessageToSend(String channel, String message) { - this.channel = channel; - this.message = message; - } - - public String getChannel() { - return channel; - } - - public String getMessage() { - return message; - } -} diff --git a/bbb-video/src/main/webapp/WEB-INF/bbb-redis-messaging.xml b/bbb-video/src/main/webapp/WEB-INF/bbb-redis-messaging.xml new file mode 100755 index 0000000000000000000000000000000000000000..918167fe436ec37521319e311f84e2f639da9775 --- /dev/null +++ b/bbb-video/src/main/webapp/WEB-INF/bbb-redis-messaging.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + +BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + +Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). + +This program is free software; you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 3.0 of the License, or (at your option) any later +version. + +BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. + +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd + http://www.springframework.org/schema/util + http://www.springframework.org/schema/util/spring-util-2.0.xsd + "> + + <bean id="meetingMessageHandler" class="org.bigbluebutton.red5.pubsub.MeetingMessageHandler"> + <property name="meetingManager" ref="meetingManager"/> + <property name="connInvokerService" ref="connInvokerService"/> + </bean> + + <bean id="receivedMessageHandler" class="org.bigbluebutton.common2.redis.pubsub.ReceivedMessageHandler" + init-method="start" destroy-method="stop"> + </bean> + + <bean id="redisStorageService" + class="org.bigbluebutton.common2.redis.RedisStorageService" + init-method="start" destroy-method="stop"> + <property name="host" value="${redis.host}" /> + <property name="port" value="${redis.port}" /> + <property name="password" value="${redis.password:}" /> + <property name="expireKey" value="${redis.keyExpiry}" /> + <property name="clientName" value="BbbRed5VideoStore" /> + </bean> + + <bean id="messageReceiver" class="org.bigbluebutton.common2.redis.pubsub.MessageReceiver" + init-method="start" destroy-method="stop"> + <property name="host" value="${redis.host}" /> + <property name="port" value="${redis.port}" /> + <property name="password" value="${redis.password:}" /> + <property name="clientName" value="BbbRed5VideoReceiver" /> + <property name="messageHandler" ref="receivedMessageHandler"/> + </bean> + + <bean id="redisSender" class="org.bigbluebutton.common2.redis.pubsub.MessageSender" + init-method="start" destroy-method="stop"> + <property name="host" value="${redis.host}" /> + <property name="port" value="${redis.port}" /> + <property name="password" value="${redis.password:}" /> + <property name="clientName" value="BbbRed5VideoSender" /> + </bean> + + <bean id="redisPublisher" class="org.bigbluebutton.red5.pubsub.MessagePublisher"> + <property name="messageSender" ref="redisSender"/> + </bean> + + <bean id="messageDistributor" class="org.bigbluebutton.common2.redis.pubsub.MessageDistributor"> + <property name="messageHandler" ref="receivedMessageHandler"/> + <property name="messageListeners"> + <set> + <ref bean="meetingMessageHandler" /> + </set> + </property> + </bean> + +</beans> diff --git a/bbb-video/src/main/webapp/WEB-INF/bbb-redis-pool.xml b/bbb-video/src/main/webapp/WEB-INF/bbb-redis-pool.xml deleted file mode 100755 index 2d3cfd9098a5141b93f859828d18f65c5a5348b7..0000000000000000000000000000000000000000 --- a/bbb-video/src/main/webapp/WEB-INF/bbb-redis-pool.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - -BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ - -Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). - -This program is free software; you can redistribute it and/or modify it under the -terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 3.0 of the License, or (at your option) any later -version. - -BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along -with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. - ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util-2.0.xsd - "> - - -</beans> diff --git a/bbb-video/src/main/webapp/WEB-INF/bigbluebutton-video.properties b/bbb-video/src/main/webapp/WEB-INF/bigbluebutton-video.properties index 5f8030de0c73cfb61b1eb9fa6816b9cec420445a..c8b4ea2405ecdd8772b5af5a7ee2aebdbe15a2f5 100755 --- a/bbb-video/src/main/webapp/WEB-INF/bigbluebutton-video.properties +++ b/bbb-video/src/main/webapp/WEB-INF/bigbluebutton-video.properties @@ -1,4 +1,5 @@ -redis.host=127.0.0.1 -redis.port=6379 -# recording keys should expire in 14 days -redis.keyExpiry=1209600 +redis.host=127.0.0.1 +redis.port=6379 +redis.password= +# recording keys should expire in 14 days +redis.keyExpiry=1209600 diff --git a/bbb-video/src/main/webapp/WEB-INF/red5-web.xml b/bbb-video/src/main/webapp/WEB-INF/red5-web.xml index e4c7b3adc83ee1d7e20c2a2f0ca62ddb48976a4f..fc80adb5503af93a9b1ff65584cf5f5928bc6df5 100755 --- a/bbb-video/src/main/webapp/WEB-INF/red5-web.xml +++ b/bbb-video/src/main/webapp/WEB-INF/red5-web.xml @@ -21,8 +21,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd - http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.0.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + http://www.springframework.org/schema/lang + http://www.springframework.org/schema/lang/spring-lang-2.0.xsd"> <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> @@ -32,6 +34,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. </list> </property> </bean> + + <bean id="meetingManager" class="org.bigbluebutton.app.video.MeetingManager"/> + + <bean id="connInvokerService" class="org.bigbluebutton.app.video.ConnectionInvokerService" + init-method="start" destroy-method="stop"/> <bean id="web.context" class="org.red5.server.Context" autowire="byType" /> @@ -44,59 +51,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <property name="contextPath" value="${webapp.contextPath}" /> <property name="virtualHosts" value="${webapp.virtualHosts}" /> </bean> - + <bean id="web.handler" class="org.bigbluebutton.app.video.VideoApplication"> <property name="packetTimeout" value="10000"/> - <property name="eventRecordingService" ref="redisRecorder"/> + <property name="eventRecordingService" ref="redisStorageService"/> <property name="messagePublisher" ref="redisPublisher"/> <property name="meetingManager" ref="meetingManager"/> <property name="connInvokerService" ref="connInvokerService"/> </bean> + + <import resource="bbb-redis-messaging.xml"/> - <bean id="connInvokerService" class="org.bigbluebutton.app.video.ConnectionInvokerService" - init-method="start" destroy-method="stop"/> - - <bean id="meetingManager" class="org.bigbluebutton.app.video.MeetingManager"/> - - <bean id="redisPublisher" class="org.bigbluebutton.red5.pubsub.MessagePublisher"> - <property name="messageSender" ref="redisSender"/> - </bean> - - <bean id="redisRecorder" class="org.bigbluebutton.app.video.EventRecordingService" - init-method="start" destroy-method="stop"> - <constructor-arg index="0" value="${redis.host}"/> - <constructor-arg index="1" value="${redis.port}"/> - <constructor-arg index="2" value="${redis.keyExpiry}"/> - </bean> - - <bean id="messageReceiver" class="org.bigbluebutton.red5.pubsub.MessageReceiver" - init-method="start" destroy-method="stop"> - <property name="host" value="${redis.host}"/> - <property name="port" value="${redis.port}"/> - <property name="messageHandler" ref="receivedMessageHandler"/> - </bean> - - <bean id="messageDistributor" class="org.bigbluebutton.red5.pubsub.MessageDistributor"> - <property name="messageHandler" ref="receivedMessageHandler"/> - <property name="messageListeners"> - <set> - <ref bean="meetingMessageHandler" /> - </set> - </property> - </bean> - - <bean id="meetingMessageHandler" class="org.bigbluebutton.red5.pubsub.MeetingMessageHandler"> - <property name="meetingManager" ref="meetingManager"/> - <property name="connInvokerService" ref="connInvokerService"/> - </bean> - - <bean id="receivedMessageHandler" class="org.bigbluebutton.red5.pubsub.ReceivedMessageHandler" - init-method="start" destroy-method="stop"> - </bean> - - <bean id="redisSender" class="org.bigbluebutton.red5.pubsub.MessageSender" - init-method="start" destroy-method="stop"> - <property name="host" value="${redis.host}"/> - <property name="port" value="${redis.port}"/> - </bean> </beans> diff --git a/bbb-video/src/main/webapp/WEB-INF/web.xml b/bbb-video/src/main/webapp/WEB-INF/web.xml index af135b12d6da7c523b765161022e49ef73f4d134..24e0b09f9ff3286ff18d193120143b2d298121b3 100755 --- a/bbb-video/src/main/webapp/WEB-INF/web.xml +++ b/bbb-video/src/main/webapp/WEB-INF/web.xml @@ -29,7 +29,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <param-name>webAppRootKey</param-name> <param-value>/video</param-value> </context-param> - <listener> <listener-class>org.red5.logging.ContextLoggingListener</listener-class> diff --git a/bbb-voice/build.gradle b/bbb-voice/build.gradle index e364181721d6b9c86df523f55c5b1fc51c0ed0d5..8828b83c349c1b22150e5d4b425191e86d16ee29 100755 --- a/bbb-voice/build.gradle +++ b/bbb-voice/build.gradle @@ -17,8 +17,14 @@ repositories { mavenLocal() } +configurations { + runtime.exclude group: "org.slf4j", module: "slf4j-api" + runtime.exclude group: "org.red5", module: "red5-server" + runtime.exclude group: "org.red5", module: "red5-server-common" + runtime.exclude group: "org.red5", module: "red5-io" +} -dependencies { +dependencies { // Servlet providedCompile 'javax.servlet:servlet-api:2.5@jar' @@ -26,17 +32,18 @@ dependencies { providedCompile 'org.apache.mina:mina-core:2.0.17@jar' providedCompile 'org.apache.mina:mina-integration-beans:2.0.17@jar' providedCompile 'org.apache.mina:mina-integration-jmx:2.0.17@jar' - - // Spring + + // Spring providedCompile 'org.springframework:spring-web:4.3.12.RELEASE@jar' - providedCompile 'org.springframework:spring-beans:4.3.12.RELEASE@jar' + providedCompile 'org.springframework:spring-beans:4.3.12.RELEASE@jar' providedCompile 'org.springframework:spring-context:4.3.12.RELEASE@jar' providedCompile 'org.springframework:spring-core:4.3.12.RELEASE@jar' + // Red5 providedCompile 'org.red5:red5-server:1.0.10-M5@jar' providedCompile 'org.red5:red5-server-common:1.0.10-M5@jar' providedCompile 'org.red5:red5-io:1.0.10-M5@jar' - + // Logging providedCompile 'ch.qos.logback:logback-core:1.2.3@jar' providedCompile 'ch.qos.logback:logback-classic:1.2.3@jar' @@ -49,28 +56,19 @@ dependencies { // Otherwise we get exception on aop utils class not found. providedCompile 'org.springframework:spring-aop:4.3.12.RELEASE@jar' compile 'aopalliance:aopalliance:1.0@jar' - + //redis - compile 'redis.clients:jedis:2.9.0' compile 'org.apache.commons:commons-pool2:2.6.0' compile 'com.google.code.gson:gson:2.8.5' - compile 'org.apache.commons:commons-lang3:3.7' - compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.19-SNAPSHOT' - - // Testing - testRuntime 'org.easymock:easymock:3.6@jar' -} - -test { - useTestNG() + providedCompile 'org.apache.commons:commons-lang3:3.7' + compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.20-SNAPSHOT' } war.doLast { ant.unzip(src: war.archivePath, dest: "$buildDir/sip") } - task deploy() << { def red5AppsDir = '/usr/share/red5/webapps' def sipDir = new File("${red5AppsDir}/sip") @@ -80,5 +78,4 @@ task deploy() << { ant.copy(todir: sipDir) { fileset(dir: "$buildDir/sip") } -} - +} diff --git a/bbb-voice/deploy.sh b/bbb-voice/deploy.sh index ebd457e9196547175c1de294c08b6bc833e310c8..b7cab36a4bc4e2ff6e2b72d8bb9bf36079ce3149 100755 --- a/bbb-voice/deploy.sh +++ b/bbb-voice/deploy.sh @@ -1,13 +1,10 @@ #!/bin/bash # deploying 'bigbluebutton-apps' to /usr/share/red5/webapps -sudo chmod -R 777 /usr/share/red5/webapps -sudo chown -R red5.red5 /usr/share/red5/webapps +sudo chmod -R 777 /usr/share/red5/webapps/* gradle clean gradle resolveDeps gradle war deploy -sudo chown -R red5.red5 /usr/share/red5/webapps -sudo chmod -R 777 /usr/share/red5/webapps - +sudo chown -R red5:red5 /usr/share/red5/webapps diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java index 04623357859b93ae1dcb41d49aff0bc66994cbe4..847c837c186a5a48f5639e15a17448169e8134f5 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java @@ -3,6 +3,8 @@ package org.bigbluebutton.voiceconf.messaging; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; + +import org.bigbluebutton.common2.redis.pubsub.MessageHandler; import org.bigbluebutton.voiceconf.messaging.messages.ValidateConnTokenRespMsg; import org.bigbluebutton.voiceconf.red5.ConnectionInvokerService; import org.red5.logging.Red5LoggerFactory; diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageDistributor.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageDistributor.java deleted file mode 100755 index 595bf905cbc5bc84f3f03640c9bf26e6f2e0eda0..0000000000000000000000000000000000000000 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageDistributor.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.bigbluebutton.voiceconf.messaging; - -import java.util.Set; - -public class MessageDistributor { - private ReceivedMessageHandler handler; - private Set<MessageHandler> listeners; - - public void setMessageListeners(Set<MessageHandler> listeners) { - this.listeners = listeners; - } - - public void setMessageHandler(ReceivedMessageHandler handler) { - this.handler = handler; - if (handler != null) { - handler.setMessageDistributor(this); - } - } - - public void notifyListeners(String pattern, String channel, String message) { - for (MessageHandler listener : listeners) { - listener.handleMessage(pattern, channel, message); - } - } -} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java deleted file mode 100755 index 9033abe06a9a511d90f42520cf8c5daae97b5df6..0000000000000000000000000000000000000000 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.bigbluebutton.voiceconf.messaging; - -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPubSub; -import redis.clients.jedis.exceptions.JedisConnectionException; - -public class MessageReceiver { - private static Logger log = Red5LoggerFactory.getLogger(MessageReceiver.class, "bigbluebutton"); - - private ReceivedMessageHandler handler; - - private Jedis jedis; - private volatile boolean receiveMessage = false; - - private final Executor msgReceiverExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - - private final String FROM_BBB_APPS_PATTERN = "from-akka-apps-redis-channel"; - - private String host; - private int port; - - public void stop() { - receiveMessage = false; - } - - public void start() { - log.info("Ready to receive messages from Redis pubsub."); - try { - receiveMessage = true; - jedis = new Jedis(host, port); - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - jedis.clientSetname("BbbRed5VoiceSub"); - - Runnable messageReceiver = new Runnable() { - public void run() { - if (receiveMessage) { - try { - jedis.subscribe(new PubSubListener(), FROM_BBB_APPS_PATTERN); - } catch(JedisConnectionException ex) { - log.warn("Exception on Jedis connection. Resubscribing to pubsub."); - start(); - } catch (Exception e) { - log.error("Error resubscribing to channels: " + e.getMessage()); - } - } - } - }; - msgReceiverExec.execute(messageReceiver); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setMessageHandler(ReceivedMessageHandler handler) { - this.handler = handler; - } - - private class PubSubListener extends JedisPubSub { - - public PubSubListener() { - super(); - } - - @Override - public void onMessage(String channel, String message) { - // Not used. - Runnable task = new Runnable() { - public void run() { - handler.handleMessage("", channel, message); - } - }; - - runExec.execute(task); - } - - @Override - public void onPMessage(final String pattern, final String channel, final String message) { - System.out.println("RECEIVED onPMessage" + channel + "\n" + message); - Runnable task = new Runnable() { - public void run() { - handler.handleMessage(pattern, channel, message); - } - }; - - runExec.execute(task); - } - - @Override - public void onPSubscribe(String pattern, int subscribedChannels) { - log.debug("Subscribed to the pattern: " + pattern); - } - - @Override - public void onPUnsubscribe(String pattern, int subscribedChannels) { - // Not used. - } - - @Override - public void onSubscribe(String channel, int subscribedChannels) { - // Not used. - } - - @Override - public void onUnsubscribe(String channel, int subscribedChannels) { - // Not used. - } - } -} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java deleted file mode 100755 index 67869c13367f6892a4a7b3e0cf82fcd393844227..0000000000000000000000000000000000000000 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.bigbluebutton.voiceconf.messaging; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.Protocol; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; - -public class MessageSender { - private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton"); - - private JedisPool redisPool; - private volatile boolean sendMessage = false; - - private final Executor msgSenderExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>(); - private String host; - private int port; - - public void stop() { - sendMessage = false; - redisPool.destroy(); - } - - public void start() { - - GenericObjectPoolConfig config = new GenericObjectPoolConfig(); - config.setMaxTotal(32); - config.setMaxIdle(8); - config.setMinIdle(1); - config.setTestOnBorrow(true); - config.setTestOnReturn(true); - config.setTestWhileIdle(true); - config.setNumTestsPerEvictionRun(12); - config.setMaxWaitMillis(5000); - config.setTimeBetweenEvictionRunsMillis(60000); - config.setBlockWhenExhausted(true); - - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null, - Protocol.DEFAULT_DATABASE, "BbbRed5VoicePub"); - - log.info("Redis org.bigbluebutton.red5.pubsub.message publisher starting!"); - try { - sendMessage = true; - - Runnable messageSender = new Runnable() { - public void run() { - while (sendMessage) { - try { - MessageToSend msg = messages.take(); - publish(msg.getChannel(), msg.getMessage()); - } catch (InterruptedException e) { - log.warn("Failed to get org.bigbluebutton.red5.pubsub.message from queue."); - } - } - } - }; - msgSenderExec.execute(messageSender); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - public void send(String channel, String message) { - MessageToSend msg = new MessageToSend(channel, message); - messages.add(msg); - } - - private void publish(final String channel, final String message) { - Runnable task = new Runnable() { - public void run() { - Jedis jedis = redisPool.getResource(); - try { - jedis.publish(channel, message); - } catch(Exception e){ - log.warn("Cannot publish the org.bigbluebutton.red5.pubsub.message to redis", e); - } finally { - redisPool.returnResource(jedis); - } - } - }; - - runExec.execute(task); - } - - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } -} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageToSend.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageToSend.java deleted file mode 100755 index a72c9c6efe90da652577f9c7de285302abbbe3af..0000000000000000000000000000000000000000 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageToSend.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.bigbluebutton.voiceconf.messaging; - -public class MessageToSend { - private final String channel; - private final String message; - - public MessageToSend(String channel, String message) { - this.channel = channel; - this.message = message; - } - - public String getChannel() { - return channel; - } - - public String getMessage() { - return message; - } -} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/ReceivedMessage.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/ReceivedMessage.java deleted file mode 100755 index 82d14824b11570bb36446b5d29be9977f27ae72f..0000000000000000000000000000000000000000 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/ReceivedMessage.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.bigbluebutton.voiceconf.messaging; - -public class ReceivedMessage { - - private final String pattern; - private final String channel; - private final String message; - - public ReceivedMessage(String pattern, String channel, String message) { - this.pattern = pattern; - this.channel = channel; - this.message = message; - } - - public String getPattern() { - return pattern; - } - - public String getChannel() { - return channel; - } - - public String getMessage() { - return message; - } - - -} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/ReceivedMessageHandler.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/ReceivedMessageHandler.java deleted file mode 100755 index 596710e10cd61f3cfa0284ef3a85a83b3d6fc7e7..0000000000000000000000000000000000000000 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/ReceivedMessageHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.bigbluebutton.voiceconf.messaging; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; - -import org.red5.logging.Red5LoggerFactory; -import org.slf4j.Logger; - -public class ReceivedMessageHandler { - private static Logger log = Red5LoggerFactory.getLogger(ReceivedMessageHandler.class, "bigbluebutton"); - - private BlockingQueue<ReceivedMessage> receivedMessages = new LinkedBlockingQueue<ReceivedMessage>(); - - private volatile boolean processMessage = false; - - private final Executor msgProcessorExec = Executors.newSingleThreadExecutor(); - - - private MessageDistributor handler; - - public void stop() { - processMessage = false; - } - - public void start() { - log.info("Ready to handle messages from Redis pubsub!"); - - try { - processMessage = true; - - Runnable messageProcessor = new Runnable() { - public void run() { - while (processMessage) { - try { - ReceivedMessage msg = receivedMessages.take(); - processMessage(msg); - } catch (InterruptedException e) { - log.warn("Error while taking received message from queue."); - } - } - } - }; - msgProcessorExec.execute(messageProcessor); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - private void processMessage(ReceivedMessage msg) { - if (handler != null) { - log.debug("Let's process this message: " + msg.getMessage()); - - handler.notifyListeners(msg.getPattern(), msg.getChannel(), msg.getMessage()); - } else { - log.warn("No listeners interested in messages from Redis!"); - } - } - - public void handleMessage(String pattern, String channel, String message) { - ReceivedMessage rm = new ReceivedMessage(pattern, channel, message); - receivedMessages.add(rm); - } - - public void setMessageDistributor(MessageDistributor h) { - this.handler = h; - } -} diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java index 11da04a9f7c525a296437691cacb8284b2a82f91..853f5fd4fefc59230ae20d9d00151b3dd210f381 100755 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java @@ -5,6 +5,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bigbluebutton.common2.msgs.*; +import org.bigbluebutton.common2.redis.pubsub.MessageSender; + import com.google.gson.Gson; import org.bigbluebutton.voiceconf.messaging.messages.UserConnectedToGlobalAudio; import org.bigbluebutton.voiceconf.messaging.messages.UserDisconnectedFromGlobalAudio; diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java index b81cdd554ab63b8384a45994d09b36d6edc0356d..51b77259fb3571d468a49190c72fa62bbba33a56 100644 --- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java +++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/SipToFlashAudioStream.java @@ -19,16 +19,16 @@ package org.bigbluebutton.voiceconf.red5.media; import java.net.DatagramSocket; + import org.apache.mina.core.buffer.IoBuffer; import org.bigbluebutton.voiceconf.red5.media.transcoder.SipToFlashTranscoder; import org.bigbluebutton.voiceconf.red5.media.transcoder.TranscodedAudioDataListener; import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.IContext; import org.red5.server.api.scope.IScope; -import org.red5.server.net.rtmp.event.AudioData; +import org.red5.server.net.rtmp.event.AudioData; import org.red5.server.net.rtmp.event.Notify; import org.red5.server.net.rtmp.message.Constants; -import org.red5.server.scope.Scope; import org.red5.server.stream.IProviderService; import org.slf4j.Logger; diff --git a/bbb-voice/src/main/java/org/red5/app/sip/stream/ListenStream.java b/bbb-voice/src/main/java/org/red5/app/sip/stream/ListenStream.java index e0c4543b911c92fb53ae5e5fd505bf0c120d4fa0..ab41d32d89850cc2861b721fee91411bccd30f7b 100755 --- a/bbb-voice/src/main/java/org/red5/app/sip/stream/ListenStream.java +++ b/bbb-voice/src/main/java/org/red5/app/sip/stream/ListenStream.java @@ -5,13 +5,13 @@ import org.red5.app.sip.trancoders.TranscodedAudioDataListener; import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.IContext; import org.red5.server.api.scope.IScope; -import org.red5.server.net.rtmp.event.AudioData; +import org.red5.server.net.rtmp.event.AudioData; import org.red5.server.scope.Scope; import org.red5.server.stream.IProviderService; import org.slf4j.Logger; public class ListenStream implements TranscodedAudioDataListener { - final private Logger log = Red5LoggerFactory.getLogger(ListenStream.class, "sip"); + private final Logger log = Red5LoggerFactory.getLogger(ListenStream.class, "sip"); private AudioStream broadcastStream; private IScope scope; diff --git a/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml b/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml index fe19d06cc39a355141fc0d48cf604f7b9f8913bb..8da566658471941dd04c309f0028c4ba32835f4b 100755 --- a/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml +++ b/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml @@ -24,42 +24,45 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 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="messagingService" class="org.bigbluebutton.voiceconf.messaging.RedisMessagingService"> - <property name="redisMessageSender"> <ref bean="redisMessageSender"/></property> + <bean id="redisMessageDistributor" class="org.bigbluebutton.common2.redis.pubsub.MessageDistributor"> + <property name="messageHandler"> <ref local="redisMessageHandler"/> </property> + <property name="messageListeners"> + <set> + <ref bean="meetingMessageHandler" /> + </set> + </property> + </bean> + + <bean id="redisMessageHandler" class="org.bigbluebutton.common2.redis.pubsub.ReceivedMessageHandler" + init-method="start" destroy-method="stop"> + <property name="messageDistributor"><ref bean="redisMessageDistributor" /></property> </bean> - <bean id="redisMessageSender" class="org.bigbluebutton.voiceconf.messaging.MessageSender" + <bean id="redisMessageSender" class="org.bigbluebutton.common2.redis.pubsub.MessageSender" init-method="start" destroy-method="stop"> <property name="host" value="${redis.host}"/> <property name="port" value="${redis.port}"/> + <property name="clientName" value="BbbRed5VoiceSender" /> + <property name="password" value="${redis.password:}" /> + </bean> + + <bean id="messagingService" class="org.bigbluebutton.voiceconf.messaging.RedisMessagingService"> + <property name="redisMessageSender"> <ref bean="redisMessageSender"/></property> </bean> <bean id="meetingMessageHandler" class="org.bigbluebutton.voiceconf.messaging.MeetingMessageHandler"> <property name="connInvokerService" ref="connInvokerService"/> </bean> - <bean id="redisMessageReceiver" class="org.bigbluebutton.voiceconf.messaging.MessageReceiver" + <bean id="redisMessageReceiver" class="org.bigbluebutton.common2.redis.pubsub.MessageReceiver" init-method="start" destroy-method="stop"> <property name="host" value="${redis.host}"/> <property name="port" value="${redis.port}"/> + <property name="password" value="${redis.password:}" /> + <property name="clientName" value="BbbRed5VideoReceiver" /> <property name="messageHandler"> <ref local="redisMessageHandler"/> </property> </bean> - <bean id="redisMessageHandler" class="org.bigbluebutton.voiceconf.messaging.ReceivedMessageHandler" - init-method="start" destroy-method="stop"> - <property name="messageDistributor"><ref bean="redisMessageDistributor" /></property> - </bean> - - <bean id="redisMessageDistributor" class="org.bigbluebutton.voiceconf.messaging.MessageDistributor"> - <property name="messageHandler"> <ref local="redisMessageHandler"/> </property> - <property name="messageListeners"> - <set> - <ref bean="meetingMessageHandler" /> - </set> - </property> - </bean> - </beans> diff --git a/bbb-voice/src/main/webapp/WEB-INF/bigbluebutton-sip.properties b/bbb-voice/src/main/webapp/WEB-INF/bigbluebutton-sip.properties index 370990a1859ac2180df786079036a1d379702eaf..3dc265ff1bea57288d330def75ba2f334fd931fd 100755 --- a/bbb-voice/src/main/webapp/WEB-INF/bigbluebutton-sip.properties +++ b/bbb-voice/src/main/webapp/WEB-INF/bigbluebutton-sip.properties @@ -7,7 +7,6 @@ bbb.sip.app.port=5070 sip.server.username=bbbuser sip.server.password=secret - # The ip and port of the FreeSWITCH server freeswitch.ip=192.168.23.53 freeswitch.port=5060 @@ -19,8 +18,7 @@ stopAudioPort=16383 redis.host=127.0.0.1 redis.port=6379 -redis.pass= - +redis.password= # If you want mjsip stack (red5/log/*access*.log) to minimize the amount of logs it # generates, set this to a lower value (e.g. 3). diff --git a/bbb-voice/src/main/webapp/WEB-INF/red5-web.properties b/bbb-voice/src/main/webapp/WEB-INF/red5-web.properties index 1e17dff094bfb42a2837817c705fdfe500fbb960..5d646d514744049abf439aca1a0e28163e07dc78 100644 --- a/bbb-voice/src/main/webapp/WEB-INF/red5-web.properties +++ b/bbb-voice/src/main/webapp/WEB-INF/red5-web.properties @@ -1,2 +1,2 @@ -webapp.contextPath=/sip -webapp.virtualHosts=*, localhost, localhost:8088, 127.0.0.1:8088 +webapp.contextPath=/sip +webapp.virtualHosts=*, localhost, localhost:8088, 127.0.0.1:8088 diff --git a/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml b/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml index 12f3bb8eebe8e7b6c2f0778a9aabf5983d045e08..610836054c018196d4416822c6ab1049a4cd1df7 100755 --- a/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml +++ b/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml @@ -1,5 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> - <!-- BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ @@ -36,6 +35,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. </property> </bean> + <import resource="bbb-redis-messaging.xml"/> + + <bean id="clientConnectionManager" class="org.bigbluebutton.voiceconf.red5.ClientConnectionManager"/> + + <bean id="connInvokerService" class="org.bigbluebutton.voiceconf.red5.ConnectionInvokerService" + init-method="start" destroy-method="stop"/> <bean id="web.context" class="org.red5.server.Context" autowire="byType" /> @@ -49,6 +54,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <property name="contextPath" value="${webapp.contextPath}" /> <property name="virtualHosts" value="${webapp.virtualHosts}" /> </bean> + + <bean id="sipPeerManager" class="org.bigbluebutton.voiceconf.sip.SipPeerManager"> + <property name="sipStackDebugLevel" value="${sipStackDebugLevel}"/> + <property name="sipRemotePort" value="${freeswitch.port}"/> + <property name="messagingService" ref="messagingService"/> + </bean> + + <bean id="voiceconf.service" class="org.bigbluebutton.voiceconf.red5.Service"> + <property name="sipPeerManager" ref="sipPeerManager"/> + </bean> <bean id="web.handler" class="org.bigbluebutton.voiceconf.red5.Application"> <property name="sipClientRtpIp" value="${bbb.sip.app.ip}" /> @@ -64,22 +79,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <property name="messagingService" ref="messagingService"/> </bean> - <bean id="voiceconf.service" class="org.bigbluebutton.voiceconf.red5.Service"> - <property name="sipPeerManager" ref="sipPeerManager"/> - </bean> - - <bean id="connInvokerService" class="org.bigbluebutton.voiceconf.red5.ConnectionInvokerService" - init-method="start" destroy-method="stop"/> - - <bean id="sipPeerManager" class="org.bigbluebutton.voiceconf.sip.SipPeerManager"> - <property name="sipStackDebugLevel" value="${sipStackDebugLevel}"/> - <property name="sipRemotePort" value="${freeswitch.port}"/> - <property name="messagingService" ref="messagingService"/> - - </bean> - - <bean id="clientConnectionManager" class="org.bigbluebutton.voiceconf.red5.ClientConnectionManager"/> - - <import resource="bbb-redis-messaging.xml"/> - </beans> diff --git a/bigbluebutton-apps/build.gradle b/bigbluebutton-apps/build.gradle index 85dc33cbaf3f8d581abaa6ec6da1cfb687110869..df9dbcd3cf6a98e021ac262074a385a87b31a3ce 100755 --- a/bigbluebutton-apps/build.gradle +++ b/bigbluebutton-apps/build.gradle @@ -21,6 +21,13 @@ repositories { mavenLocal() } +configurations { + runtime.exclude group: "org.slf4j", module: "slf4j-api" + runtime.exclude group: "org.red5", module: "red5-server" + runtime.exclude group: "org.red5", module: "red5-server-common" + runtime.exclude group: "org.red5", module: "red5-io" +} + dependencies { // Servlet providedCompile 'javax.servlet:servlet-api:2.5@jar' @@ -34,12 +41,13 @@ dependencies { providedCompile 'org.springframework:spring-web:4.3.12.RELEASE@jar' providedCompile 'org.springframework:spring-beans:4.3.12.RELEASE@jar' providedCompile 'org.springframework:spring-context:4.3.12.RELEASE@jar' - providedCompile 'org.springframework:spring-core:4.3.13.RELEASE@jar' + providedCompile 'org.springframework:spring-core:4.3.12.RELEASE@jar' // Red5 providedCompile 'org.red5:red5-server:1.0.10-M5@jar' providedCompile 'org.red5:red5-server-common:1.0.10-M5@jar' - + providedCompile 'org.red5:red5-io:1.0.10-M5@jar' + // Logging providedCompile 'ch.qos.logback:logback-core:1.2.3@jar' providedCompile 'ch.qos.logback:logback-classic:1.2.3@jar' @@ -57,14 +65,13 @@ dependencies { compile 'org.easymock:easymock:3.6@jar' //redis - compile "redis.clients:jedis:2.9.0" compile 'org.apache.commons:commons-pool2:2.6.0' - compile 'com.google.code.gson:gson:2.8.5' - providedCompile 'org.apache.commons:commons-lang3:3.7' + compile 'com.google.code.gson:gson:2.8.5' + providedCompile 'org.apache.commons:commons-lang3:3.7' - compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.19-SNAPSHOT' - compile 'org.bigbluebutton:bbb-apps-common_2.12:0.0.3-SNAPSHOT' + compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.20-SNAPSHOT' + compile 'org.bigbluebutton:bbb-apps-common_2.12:0.0.4-SNAPSHOT' } test { diff --git a/bigbluebutton-apps/deploy.sh b/bigbluebutton-apps/deploy.sh index b002c6f858b83aa29961ec5a1b9193b600bbbade..b7cab36a4bc4e2ff6e2b72d8bb9bf36079ce3149 100755 --- a/bigbluebutton-apps/deploy.sh +++ b/bigbluebutton-apps/deploy.sh @@ -1,18 +1,10 @@ #!/bin/bash # deploying 'bigbluebutton-apps' to /usr/share/red5/webapps -sudo chown -R red5.red5 /usr/share/red5/webapps +sudo chmod -R 777 /usr/share/red5/webapps/* gradle clean gradle resolveDeps gradle war deploy -sudo chown -R red5.red5 /usr/share/red5/webapps - -# Remove slf4j jar as it conflicts with logging with red5 -FILE=/usr/share/red5/webapps/bigbluebutton/WEB-INF/lib/slf4j-api-1.7.25.jar -if [ -f $FILE ] -then - sudo rm $FILE -fi - +sudo chown -R red5:red5 /usr/share/red5/webapps diff --git a/bigbluebutton-apps/gradle.properties b/bigbluebutton-apps/gradle.properties deleted file mode 100644 index a0cdfb5b63d4667c2cdcd67631f5017fd006f34e..0000000000000000000000000000000000000000 --- a/bigbluebutton-apps/gradle.properties +++ /dev/null @@ -1,16 +0,0 @@ -## Dependecies Version - -# Logging -log4jVersion = 1.2.17 -slf4jVersion = 1.6.6 - -# Common libraries -springVersion = 3.1.4.RELEASE -springRedisVersion = 1.1.0.RELEASE -jacksonVersion = 1.8.3 - -# Testing -junitVersion = 4.8.1 -mockitoVersion = 1.8.5 - - diff --git a/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-redis-pool.xml b/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-redis-pool.xml deleted file mode 100755 index b72ba93cd2670e60586dec23400a791ac34031de..0000000000000000000000000000000000000000 --- a/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-redis-pool.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - -BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ - -Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). - -This program is free software; you can redistribute it and/or modify it under the -terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 3.0 of the License, or (at your option) any later -version. - -BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along -with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. - ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/util - 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> diff --git a/bigbluebutton-apps/src/main/webapp/WEB-INF/classes/application.conf b/bigbluebutton-apps/src/main/webapp/WEB-INF/classes/application.conf index 74183500ea75522d1927e5742c4f93d2722b1269..3b72838eb4bbe89bb4f2c7d26663b8c90cbd2a2b 100755 --- a/bigbluebutton-apps/src/main/webapp/WEB-INF/classes/application.conf +++ b/bigbluebutton-apps/src/main/webapp/WEB-INF/classes/application.conf @@ -10,7 +10,7 @@ akka { loggers = ["akka.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" - rediscala-publish-worker-dispatcher { + redis-publish-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. @@ -18,7 +18,7 @@ akka { throughput = 512 } - rediscala-subscriber-worker-dispatcher { + redis-subscriber-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. diff --git a/bigbluebutton-apps/src/main/webapp/WEB-INF/red5-web.xml b/bigbluebutton-apps/src/main/webapp/WEB-INF/red5-web.xml index 8891ce3b5af9e5a0f53a1552ac80e00323fb2f8d..2023fa50935836d8464329a04c76eee9125187e1 100755 --- a/bigbluebutton-apps/src/main/webapp/WEB-INF/red5-web.xml +++ b/bigbluebutton-apps/src/main/webapp/WEB-INF/red5-web.xml @@ -36,7 +36,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. </property> </bean> + <bean id="msgToClientGW" class="org.bigbluebutton.client.MsgToClientGW" > + <constructor-arg index="0" ref="connInvokerService"/> + </bean> + + <bean id="clientGWApp" class="org.bigbluebutton.client.ClientGWApplication" destroy-method="shutdown"> + <constructor-arg index="0" ref="msgToClientGW"/> + </bean> + <bean id="web.context" class="org.red5.server.Context" autowire="byType" /> + + <bean id="connInvokerService" class="org.bigbluebutton.red5.client.messaging.ConnectionInvokerService" + init-method="start" destroy-method="stop"/> <bean id="web.scope" class="org.red5.server.scope.WebScope" init-method="register"> @@ -47,6 +58,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <property name="contextPath" value="${webapp.contextPath}" /> <property name="virtualHosts" value="${webapp.virtualHosts}" /> </bean> + + <bean id="clientInGW" class="org.bigbluebutton.client.ClientInGW" > + <constructor-arg index="0" ref="clientGWApp"/> + </bean> <bean id="web.handler" class="org.bigbluebutton.red5.BigBlueButtonApplication"> <property name="connInvokerService"><ref bean="connInvokerService"/></property> @@ -54,25 +69,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <property name="maxMessageLength" value="${maxMessageLength}"/> </bean> - <bean id="clientInGW" class="org.bigbluebutton.client.ClientInGW" > - <constructor-arg index="0" ref="clientGWApp"/> - </bean> - - <bean id="msgToClientGW" class="org.bigbluebutton.client.MsgToClientGW" > - <constructor-arg index="0" ref="connInvokerService"/> - </bean> - - <bean id="clientGWApp" class="org.bigbluebutton.client.ClientGWApplication" destroy-method="shutdown"> - <constructor-arg index="0" ref="msgToClientGW"/> - </bean> - - <bean id="connInvokerService" class="org.bigbluebutton.red5.client.messaging.ConnectionInvokerService" - init-method="start" destroy-method="stop"/> - <bean id="bbbAppsIsAliveMonitorService" class="org.bigbluebutton.red5.monitoring.BbbAppsIsAliveMonitorService" init-method="start" destroy-method="stop"> <property name="connectionInvokerService"> <ref bean="connInvokerService"/></property> </bean> - - <import resource="bbb-redis-pool.xml"/> </beans> diff --git a/bigbluebutton-apps/src/main/webapp/WEB-INF/spring/applicationContext-redis.xml b/bigbluebutton-apps/src/main/webapp/WEB-INF/spring/applicationContext-redis.xml deleted file mode 100755 index ebc657b8c66a89465b13937687f52376c5cc3243..0000000000000000000000000000000000000000 --- a/bigbluebutton-apps/src/main/webapp/WEB-INF/spring/applicationContext-redis.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:p="http://www.springframework.org/schema/p" - xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation=" - http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context.xsd"> - - <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" - p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"/> - - <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" - p:connection-factory-ref="connectionFactory"/> - -</beans> diff --git a/bigbluebutton-web/build.gradle b/bigbluebutton-web/build.gradle index e896556837ac125afde499b1e96e1196d07edd4c..1da581703e573a0f15b9a7c83bedd670346f009f 100755 --- a/bigbluebutton-web/build.gradle +++ b/bigbluebutton-web/build.gradle @@ -2,9 +2,9 @@ apply plugin: 'java' apply plugin: 'eclipse' task resolveDeps(type: Copy) { - into('lib') - from configurations.default - from configurations.default.allArtifacts.file + into('lib') + from configurations.default + from configurations.default.allArtifacts.file } repositories { @@ -12,41 +12,34 @@ repositories { mavenLocal() } +configurations { + runtime.exclude group: "org.slf4j", module: "slf4j-api" + compile.exclude group: "org.red5", module: "red5-server-common" +} + dependencies { - compile 'org.bigbluebutton:bbb-common-web:0.0.2-SNAPSHOT' - + compile 'org.bigbluebutton:bbb-common-web:0.0.3-SNAPSHOT' // XML creation speedup compile 'org.freemarker:freemarker:2.3.28' - //junit - compile 'junit:junit:4.8.2' + //junit + testCompile 'junit:junit:4.12' - // Testing - testCompile 'org.testng:testng:5.8@jar' - testCompile 'org.easymock:easymock:2.4@jar' + // Testing + testCompile 'org.testng:testng:6.14.3@jar' + testCompile 'org.easymock:easymock:4.0.1@jar' } sourceSets { - main { - java { - srcDir 'src/java' - } - resources { - srcDir 'src/resources' - } - } - test { - java { - srcDir 'test/unit' - } - resources { - srcDir 'test/resources' - } -} -} - -test { - useTestNG() + main { + java { srcDir 'src/java' } + resources { srcDir 'src/resources' } + } + test { + java { srcDir 'test/unit' } + resources { srcDir 'test/resources' } + } } +test { useTestNG() } diff --git a/bigbluebutton-web/build.sh b/bigbluebutton-web/build.sh index f725095d2b29cef1098d538598406c12e3a0aff8..a18f016ad30ffbe69eec5c567c0a45f69920c398 100755 --- a/bigbluebutton-web/build.sh +++ b/bigbluebutton-web/build.sh @@ -1,4 +1,3 @@ gradle clean gradle resolveDeps grails clean - diff --git a/bigbluebutton-web/grails-app/conf/application.conf b/bigbluebutton-web/grails-app/conf/application.conf index f5ba5981ea95dd5f9aa8871e4a5e9b524822df44..c6fc978954d01f9506e65f33ab525eb6dbbe82c3 100644 --- a/bigbluebutton-web/grails-app/conf/application.conf +++ b/bigbluebutton-web/grails-app/conf/application.conf @@ -10,7 +10,7 @@ akka { loggers = ["akka.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" - rediscala-publish-worker-dispatcher { + redis-publish-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. @@ -18,7 +18,7 @@ akka { throughput = 512 } - rediscala-subscriber-worker-dispatcher { + redis-subscriber-worker-dispatcher { mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be # processed per actor before the thread jumps to the next actor. diff --git a/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml b/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml index 3c8c2765b3a45a1703d8b3ef705fd6d3b52a4ba6..4c95196bdb63128883c2d7732e8b2467dd547699 100755 --- a/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml +++ b/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml @@ -3,7 +3,7 @@ BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ -Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). +Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -19,14 +19,38 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. --> <beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:util="http://www.springframework.org/schema/util" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd "> - - + <bean id="redisStorageService" + class="org.bigbluebutton.common2.redis.RedisStorageService" + init-method="start" destroy-method="stop"> + <property name="host" value="${redisHost}" /> + <property name="port" value="${redisPort}" /> + <property name="password" value="${redisPassword:}" /> + <property name="clientName" value="BbbWeb" /> + </bean> + + <bean id="redisMessageHandler" + class="org.bigbluebutton.api.messaging.ReceivedMessageHandler" + init-method="start" destroy-method="stop"> + </bean> + + <bean id="redisMessageDistributor" + class="org.bigbluebutton.api.messaging.MessageDistributor"> + <property name="messageHandler"> + <ref local="redisMessageHandler" /> + </property> + <property name="messageListeners"> + <set> + <ref bean="meetingService" /> + <ref bean="keepAliveService" /> + </set> + </property> + </bean> </beans> diff --git a/bigbluebutton-web/grails-app/conf/spring/bbb-redis-pool.xml b/bigbluebutton-web/grails-app/conf/spring/bbb-redis-pool.xml deleted file mode 100755 index 7de4b5722c6c893f3b0e1a700523af21c34a7624..0000000000000000000000000000000000000000 --- a/bigbluebutton-web/grails-app/conf/spring/bbb-redis-pool.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - -BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ - -Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). - -This program is free software; you can redistribute it and/or modify it under the -terms of the GNU Lesser General Public License as published by the Free Software -Foundation; either version 3.0 of the License, or (at your option) any later -version. - -BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along -with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. - ---> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util-2.0.xsd - "> - - - -</beans> diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml index 098e37e48cc009e85761c5ae90804a1ee2b029fa..7a94317cf177761d6f872050d147997241495779 100755 --- a/bigbluebutton-web/grails-app/conf/spring/resources.xml +++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml @@ -61,28 +61,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <constructor-arg index="3" value="${screenshareConfSuffix}"/> </bean> - <bean id="redisStorageService" class="org.bigbluebutton.api.messaging.RedisStorageService" - init-method="start" destroy-method="stop"> - <property name="host" value="${redisHost}"/> - <property name="port" value="${redisPort}"/> - </bean> - - - <bean id="redisMessageHandler" class="org.bigbluebutton.api.messaging.ReceivedMessageHandler" - init-method="start" destroy-method="stop"> - </bean> - - - <bean id="redisMessageDistributor" class="org.bigbluebutton.api.messaging.MessageDistributor"> - <property name="messageHandler"> <ref local="redisMessageHandler"/> </property> - <property name="messageListeners"> - <set> - <ref bean="meetingService" /> - <ref bean="keepAliveService" /> - </set> - </property> - </bean> - <bean id="recordingServiceHelper" class="org.bigbluebutton.api.util.RecordingMetadataReaderHelper"> <property name="recordingServiceGW" ref="recordingServiceGW"/> </bean> @@ -154,9 +132,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. </bean> <import resource="doc-conversion.xml"/> - <import resource="bbb-redis-pool.xml"/> - <!-- <import resource="bbb-redis-messaging.xml"/> - --> <import resource="turn-stun-servers.xml"/> </beans> diff --git a/bigbluebutton-web/pres-checker/build.gradle b/bigbluebutton-web/pres-checker/build.gradle index c918e988075707c2972cfe7f36fa80d37387e134..dfb9bee22f6f85534f9c9599f99f119a7dd6fac8 100755 --- a/bigbluebutton-web/pres-checker/build.gradle +++ b/bigbluebutton-web/pres-checker/build.gradle @@ -1,15 +1,15 @@ apply plugin: 'java' -sourceCompatibility=1.8 -targetCompatibility=1.8 +sourceCompatibility = 1.8 +targetCompatibility = 1.8 version = '0.0.1' -archivesBaseName = 'bbb-pres-check' +archivesBaseName = 'bbb-pres-check' task resolveDeps(type: Copy) { - into('lib') - from configurations.default - from configurations.default.allArtifacts.file + into('lib') + from configurations.default + from configurations.default.allArtifacts.file } repositories { @@ -17,22 +17,21 @@ repositories { mavenLocal() } -dependencies { - compile 'org.apache.poi:poi:3.17@jar' - compile 'org.apache.poi:poi-ooxml:3.17@jar' - compile 'org.apache.poi:poi-ooxml-schemas:3.17@jar' - compile 'commons-io:commons-io:2.6@jar' - compile 'org.apache.commons:commons-lang3:3.7@jar' - compile 'org.apache.commons:commons-collections4:4.2@jar' - compile 'org.apache.xmlbeans:xmlbeans:3.0.0@jar' +dependencies { + compile 'org.apache.poi:poi:4.0.0@jar' + compile 'org.apache.poi:poi-ooxml:4.0.0@jar' + compile 'org.apache.poi:poi-ooxml-schemas:4.0.0@jar' + compile 'commons-io:commons-io:2.6@jar' + compile 'org.apache.commons:commons-lang3:3.8.1@jar' + compile 'org.apache.commons:commons-collections4:4.2@jar' + compile 'org.apache.xmlbeans:xmlbeans:3.0.2@jar' } jar { - manifest.mainAttributes("Permissions": "all-permissions") - manifest.mainAttributes("Codebase": "*") - manifest.mainAttributes("Application-Name": "BigBlueButton Presentation Checker") - manifest.mainAttributes("Application-Library-Allowable-Codebase": "*") - manifest.mainAttributes("Caller-Allowable-Codebase": "*") - manifest.mainAttributes("Trusted-Only": "true") + manifest.mainAttributes("Permissions": "all-permissions") + manifest.mainAttributes("Codebase": "*") + manifest.mainAttributes("Application-Name": "BigBlueButton Presentation Checker") + manifest.mainAttributes("Application-Library-Allowable-Codebase": "*") + manifest.mainAttributes("Caller-Allowable-Codebase": "*") + manifest.mainAttributes("Trusted-Only": "true") } - diff --git a/bigbluebutton-web/pres-checker/build.sh b/bigbluebutton-web/pres-checker/build.sh index 1f5048f55723f9d76bfbb4b1bcf08e307fe7069d..d2a60ea6951cb7b6607e066cc3ff1812419a0927 100755 --- a/bigbluebutton-web/pres-checker/build.sh +++ b/bigbluebutton-web/pres-checker/build.sh @@ -1,4 +1,3 @@ gradle clean gradle jar cp build/lib/*.jar lib - diff --git a/bigbluebutton-web/pres-checker/run.sh b/bigbluebutton-web/pres-checker/run.sh index 04fc97183cb1bc79fd22dc6a6f395865a4409bbe..faa48086ab4fed3f2534705e3ab0de49af682724 100755 --- a/bigbluebutton-web/pres-checker/run.sh +++ b/bigbluebutton-web/pres-checker/run.sh @@ -1,2 +1 @@ java -cp "/usr/share/prescheck/lib/*" org.bigbluebutton.prescheck.Main $@ - diff --git a/bigbluebutton-web/run.sh b/bigbluebutton-web/run.sh index b707bed78f2b5e48049e3430bfb67c6257aa8658..a9e681a95cbf97223c494f7ad14b2f170cb7eee4 100755 --- a/bigbluebutton-web/run.sh +++ b/bigbluebutton-web/run.sh @@ -1,2 +1 @@ grails -Dserver.port=8989 run-war - diff --git a/bigbluebutton-web/test/unit/org/bigbluebutton/api/messaging/NullMessagingService.java b/bigbluebutton-web/test/unit/org/bigbluebutton/api/messaging/NullMessagingService.java index 8c12f4d2d9130c88bef4b42509c1ecfbbeb75e9e..03ee0fdfa0775e25b3714557aa7fc41926babd2e 100644 --- a/bigbluebutton-web/test/unit/org/bigbluebutton/api/messaging/NullMessagingService.java +++ b/bigbluebutton-web/test/unit/org/bigbluebutton/api/messaging/NullMessagingService.java @@ -5,79 +5,65 @@ import java.util.Map; public class NullMessagingService implements MessagingService { - public void start() { - // TODO Auto-generated method stub + public void start() { + // TODO Auto-generated method stub - } + } - public void stop() { - // TODO Auto-generated method stub + public void stop() { + // TODO Auto-generated method stub - } + } - @Override - public void recordMeetingInfo(String meetingId, Map<String, String> info) { - // TODO Auto-generated method stub + @Override + public void recordMeetingInfo(String meetingId, Map<String, String> info) { + // TODO Auto-generated method stub - } + } - /*@Override - public void recordMeetingMetadata(String meetingId, - Map<String, String> metadata) { - // TODO Auto-generated method stub + /* + * @Override public void recordMeetingMetadata(String meetingId, Map<String, + * String> metadata) { // TODO Auto-generated method stub + * + * } + */ - }*/ + public void addListener(MessageListener listener) { + // TODO Auto-generated method stub - @Override - public void endMeeting(String meetingId) { - // TODO Auto-generated method stub + } - } + public void removeListener(MessageListener listener) { + // TODO Auto-generated method stub - @Override - public void send(String channel, String message) { - // TODO Auto-generated method stub + } - } + public void destroyMeeting(String meetingID) { + // TODO Auto-generated method stub - public void addListener(MessageListener listener) { - // TODO Auto-generated method stub + } - } + public void createMeeting(String meetingID, String externalMeetingID, String meetingName, Boolean recorded, + String voiceBridge, Long duration) { + // TODO Auto-generated method stub - public void removeListener(MessageListener listener) { - // TODO Auto-generated method stub + } - } + public void sendPolls(String meetingId, String title, String question, String questionType, List<String> answers) { + // TODO Auto-generated method stub - public void destroyMeeting(String meetingID) { - // TODO Auto-generated method stub - - } + } - public void createMeeting(String meetingID, String externalMeetingID, String meetingName, - Boolean recorded, String voiceBridge, Long duration) { - // TODO Auto-generated method stub - - } + @Override + public void recordBreakoutInfo(String meetingId, Map<String, String> breakoutInfo) { + // TODO Auto-generated method stub - public void sendPolls(String meetingId, String title, String question, - String questionType, List<String> answers) { - // TODO Auto-generated method stub - - } + } - @Override - public void registerUser(String meetingID, String internalUserId, - String fullname, String role, String externUserID, String authToken, String avatarURL) { - // TODO Auto-generated method stub - - } + @Override + public void addBreakoutRoom(String parentId, String breakoutId) { + // TODO Auto-generated method stub - @Override - public void sendKeepAlive(String keepAliveId) { - // TODO Auto-generated method stub - - } + } }