- send create message from bbb-web

This commit is contained in:
Richard Alam 2017-05-24 15:19:03 -07:00
parent 467598ffd2
commit e56a758c5f
21 changed files with 150 additions and 49 deletions

View File

@ -45,11 +45,12 @@ libraryDependencies ++= {
"ch.qos.logback" % "logback-classic" % "1.0.13" % "runtime",
"junit" % "junit" % "4.11",
"commons-codec" % "commons-codec" % "1.10",
"org.apache.commons" % "commons-lang3" % "3.2",
"org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT"
"org.apache.commons" % "commons-lang3" % "3.2"
)
}
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" % "2.12.2"
// https://mvnrepository.com/artifact/org.scala-lang/scala-compiler

View File

@ -46,11 +46,11 @@ object Boot extends App with SystemConfiguration {
val bbbMsgBus = new BbbMsgRouterEventBus
val bbbInGW = new BigBlueButtonInGW(system, eventBus, bbbMsgBus, outGW, red5DeskShareIP, red5DeskShareApp)
val bbbInGW = new BigBlueButtonInGW(system, eventBus, bbbMsgBus, outGW)
val redisMsgReceiver = new RedisMessageReceiver(bbbInGW)
val redisMessageHandlerActor = system.actorOf(ReceivedJsonMsgHandlerActor.props(bbbMsgBus, incomingJsonMessageBus))
incomingJsonMessageBus.subscribe(redisMessageHandlerActor, "incoming-json-message")
incomingJsonMessageBus.subscribe(redisMessageHandlerActor, toAkkaAppsJsonChannel)
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(redisMsgReceiver, incomingJsonMessageBus), "redis-subscriber")

View File

@ -32,4 +32,14 @@ trait SystemConfiguration {
lazy val outMessageChannel = Try(config.getString("eventBus.outMessageChannel")).getOrElse("OutgoingMessageChannel")
lazy val incomingJsonMsgChannel = Try(config.getString("eventBus.incomingJsonMsgChannel")).getOrElse("IncomingJsonMsgChannel")
lazy val outBbbMsgMsgChannel = Try(config.getString("eventBus.outBbbMsgMsgChannel")).getOrElse("OutBbbMsgChannel")
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 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")
lazy val toClientChannel = Try(config.getString("eventBus.toClientChannel")).getOrElse("to-client-channel")
lazy val toAkkaAppsJsonChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-json-channel")
lazy val fromAkkaAppsJsonChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-json-channel")
lazy val fromAkkaAppsOldJsonChannel = Try(config.getString("eventBus.fromAkkaAppsOldChannel")).getOrElse("from-akka-apps-old-json-channel")
}

View File

@ -1,6 +1,7 @@
package org.bigbluebutton.core
import java.io.{ PrintWriter, StringWriter }
import akka.actor._
import akka.actor.ActorLogging
import akka.actor.SupervisorStrategy.Resume
@ -12,6 +13,7 @@ import org.bigbluebutton.core.api._
import org.bigbluebutton.SystemConfiguration
import java.util.concurrent.TimeUnit
import org.bigbluebutton.common2.messages.{ BbbCommonEnvCoreMsg, CreateMeetingReqMsg }
import org.bigbluebutton.core.running.RunningMeeting
object BigBlueButtonActor extends SystemConfiguration {
@ -50,6 +52,7 @@ class BigBlueButtonActor(val system: ActorSystem,
}
def receive = {
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
case msg: CreateMeeting => handleCreateMeeting(msg)
case msg: DestroyMeeting => handleDestroyMeeting(msg)
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
@ -65,6 +68,17 @@ class BigBlueButtonActor(val system: ActorSystem,
case _ => // do nothing
}
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
log.debug("****** RECEIVED BbbCommonEnvCoreMsg msg {}", msg)
msg.core match {
case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
}
}
private def handleCreateMeetingReqMsg(msg: CreateMeetingReqMsg): Unit = {
log.debug("****** RECEIVED CreateMeetingReqMsg msg {}", msg)
}
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
meetings.values.find(m => { m.mProps.voiceBridge == voiceConfId })
}

View File

@ -2,6 +2,7 @@ package org.bigbluebutton.core
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._
import scala.collection.JavaConversions._
import org.bigbluebutton.core.apps.Page
import org.bigbluebutton.core.apps.Presentation
@ -12,18 +13,20 @@ import org.bigbluebutton.common.messages.StartCustomPollRequestMessage
import org.bigbluebutton.common.messages.PubSubPingMessage
import org.bigbluebutton.messages._
import akka.event.Logging
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.core.models.Roles
class BigBlueButtonInGW(
val system: ActorSystem,
eventBus: IncomingEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway,
val red5DeskShareIP: String,
val red5DeskShareApp: String) extends IBigBlueButtonInGW {
outGW: OutMessageGateway) extends IBigBlueButtonInGW with SystemConfiguration {
val log = Logging(system, getClass)
val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, bbbMsgBus, outGW), "bigbluebutton-actor")
eventBus.subscribe(bbbActor, meetingManagerChannel)
/** For OLD Messaged **/
eventBus.subscribe(bbbActor, "meeting-manager")
def handleBigBlueButtonMessage(message: IBigBlueButtonMessage) {

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.messages.BbbMsg
import org.bigbluebutton.common2.messages.{ BbbCommonEnvJsNodeMsg }
import org.bigbluebutton.core.bus.{ BbbOutMessage, BigBlueButtonOutMessage, OutEventBus2, OutgoingEventBus }
import org.bigbluebutton.core.api.IOutMessage
@ -16,7 +16,7 @@ class OutMessageGateway(outgoingEventBus: OutgoingEventBus, outBus2: OutEventBus
outgoingEventBus.publish(BigBlueButtonOutMessage(outMessageChannel, msg))
}
def send(msg: BbbMsg): Unit = {
def send(msg: BbbCommonEnvJsNodeMsg): Unit = {
outBus2.publish(BbbOutMessage(outBbbMsgMsgChannel, msg))
}
}

View File

@ -2,9 +2,9 @@ package org.bigbluebutton.core.bus
import akka.actor.ActorRef
import akka.event.{ EventBus, LookupClassification }
import org.bigbluebutton.common2.messages.BbbMsg
import org.bigbluebutton.common2.messages.BbbCommonEnvCoreMsg
case class BbbMsgEvent(val topic: String, val payload: BbbMsg)
case class BbbMsgEvent(val topic: String, val payload: BbbCommonEnvCoreMsg)
class BbbMsgRouterEventBus extends EventBus with LookupClassification {
type Event = BbbMsgEvent

View File

@ -3,7 +3,7 @@ package org.bigbluebutton.core.bus
import akka.actor.ActorRef
import akka.event.{ EventBus, LookupClassification }
case class ReceivedJsonMessage(name: String, data: String)
case class ReceivedJsonMessage(channel: String, data: String)
case class IncomingJsonMessage(val topic: String, val payload: ReceivedJsonMessage)
class IncomingJsonMessageBus extends EventBus with LookupClassification {

View File

@ -2,9 +2,9 @@ package org.bigbluebutton.core.bus
import akka.actor.ActorRef
import akka.event.{ EventBus, LookupClassification }
import org.bigbluebutton.common2.messages.BbbMsg
import org.bigbluebutton.common2.messages.{ BbbCommonEnvJsNodeMsg }
case class BbbOutMessage(val topic: String, val payload: BbbMsg)
case class BbbOutMessage(val topic: String, val payload: BbbCommonEnvJsNodeMsg)
class OutEventBus2 extends EventBus with LookupClassification {
type Event = BbbOutMessage

View File

@ -1,7 +1,9 @@
package org.bigbluebutton.core.pubsub.senders
import akka.actor.{ Actor, ActorLogging, Props }
import org.bigbluebutton.common2.messages.CreateMeetingReq
import com.fasterxml.jackson.databind.JsonNode
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.messages.{ BbbCommonEnvCoreMsg, BbbCommonEnvJsNodeMsg, BbbCoreEnvelope, CreateMeetingReqMsg }
import org.bigbluebutton.common2.util.JsonUtil
import org.bigbluebutton.core.bus._
@ -13,31 +15,26 @@ object ReceivedJsonMsgHandlerActor {
class ReceivedJsonMsgHandlerActor(
val eventBus: BbbMsgRouterEventBus,
val incomingJsonMessageBus: IncomingJsonMessageBus)
extends Actor with ActorLogging {
extends Actor with ActorLogging with SystemConfiguration {
def receive = {
case msg: ReceivedJsonMessage =>
val map = JsonUtil.toMap[Map[String, Any]](msg.data)
val map = JsonUtil.fromJson[BbbCommonEnvJsNodeMsg](msg.data)
println(map)
for {
header <- map.get("header")
name <- header.get("name")
} yield {
println(s"***** msg name = ${name}")
decode(name.toString, msg.data)
}
decode(map.envelope, map.jsonNode)
case _ => // do nothing
}
def decode(name: String, json: String): Unit = {
name match {
case "CreateMeetingReq" =>
val cmr = JsonUtil.fromJson[CreateMeetingReq](json)
val msg = BbbMsgEvent("to-meeting-manager", cmr)
eventBus.publish(msg)
println("CMR= " + cmr)
def decode(envelope: BbbCoreEnvelope, jsonNode: JsonNode): Unit = {
envelope.name match {
case CreateMeetingReqMsg.NAME =>
val body = JsonUtil.toJson(jsonNode)
log.debug("CreateMeetingReqMsg toJson " + body)
val cmr = JsonUtil.fromJson[CreateMeetingReqMsg](body)
log.debug("CreateMeetingReqMsg fromJson " + cmr)
val event = BbbMsgEvent(meetingManagerChannel, BbbCommonEnvCoreMsg(envelope, cmr))
eventBus.publish(event)
case _ => // do nothing
}
}

View File

@ -18,7 +18,7 @@ import redis.api.servers.ClientSetname
object AppsRedisSubscriberActor extends SystemConfiguration {
val TO_AKKA_APPS = "bbb:to-akka-apps"
val channels = Seq("time", TO_AKKA_APPS)
val channels = Seq("time", toAkkaAppsRedisChannel)
val patterns = Seq("bigbluebutton:to-bbb-apps:*", "bigbluebutton:from-voice-conf:*")
def props(msgReceiver: RedisMessageReceiver, jsonMsgBus: IncomingJsonMessageBus): Props =
@ -31,7 +31,7 @@ class AppsRedisSubscriberActor(msgReceiver: RedisMessageReceiver, jsonMsgBus: In
redisPort: Int,
channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
extends RedisSubscriberActor(new InetSocketAddress(redisHost, redisPort),
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) {
channels, patterns, onConnectStatus = connected => { println(s"connected: $connected") }) with SystemConfiguration {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
@ -43,18 +43,16 @@ class AppsRedisSubscriberActor(msgReceiver: RedisMessageReceiver, jsonMsgBus: In
}
}
val TO_AKKA_APPS = "bbb:to-akka-apps"
// 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) {
//log.error(s"SHOULD NOT BE RECEIVING: $message")
if (message.channel == TO_AKKA_APPS) {
if (message.channel == toAkkaAppsRedisChannel) {
val receivedJsonMessage = new ReceivedJsonMessage(message.channel, message.data.utf8String)
println(receivedJsonMessage.data)
jsonMsgBus.publish(IncomingJsonMessage("incoming-json-message", receivedJsonMessage))
log.debug(s"RECEIVED:\n [${receivedJsonMessage.channel}] \n ${receivedJsonMessage.data} \n")
jsonMsgBus.publish(IncomingJsonMessage(toAkkaAppsJsonChannel, receivedJsonMessage))
}
}

View File

@ -18,8 +18,11 @@ case class VoiceProp(telVoice: String, webVoice: String, dialNumber: String)
case class UsersProp(maxUsers: Int, webcamsOnlyForModerator: Boolean, guestPolicy: String)
case class MetadataProp(metadata: collection.immutable.Map[String, String])
case class DefaultProps(meetingProp: MeetingProp, durationProps: DurationProps, password: PasswordProp,
recordProp: RecordProp, welcomeProp: WelcomeProp, voiceProp: VoiceProp, usersProp: UsersProp)
recordProp: RecordProp, welcomeProp: WelcomeProp, voiceProp: VoiceProp,
usersProp: UsersProp, metadataProp: MetadataProp)
case class StartEndTimeStatus(startTime: Long, endTime: Long)

View File

@ -61,6 +61,7 @@ import org.bigbluebutton.api.messaging.messages.UserSharedWebcam;
import org.bigbluebutton.api.messaging.messages.UserStatusChanged;
import org.bigbluebutton.api.messaging.messages.UserUnsharedWebcam;
import org.bigbluebutton.api.pub.IPublisherService;
import org.bigbluebutton.api2.IBbbWebApiGWApp;
import org.bigbluebutton.presentation.PresentationUrlDownloadService;
import org.bigbluebutton.api.messaging.messages.StunTurnInfoRequested;
import org.bigbluebutton.web.services.RegisteredUserCleanupTimerTask;
@ -97,6 +98,8 @@ public class MeetingService implements MessageListener {
private ParamsProcessorUtil paramsProcessorUtil;
private PresentationUrlDownloadService presDownloadService;
private IBbbWebApiGWApp gw;
public MeetingService() {
meetings = new ConcurrentHashMap<String, Meeting>(8, 0.9f, 1);
sessions = new ConcurrentHashMap<String, UserSession>(8, 0.9f, 1);
@ -272,6 +275,15 @@ public class MeetingService implements MessageListener {
m.getCreateTime(), formatPrettyDate(m.getCreateTime()),
m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy());
gw.createMeeting(m.getInternalId(), m.getExternalId(),
m.getParentMeetingId(), m.getName(), m.isRecord(),
m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(),
m.getAllowStartStopRecording(), m.getWebcamsOnlyForModerator(),
m.getModeratorPassword(), m.getViewerPassword(),
m.getCreateTime(), formatPrettyDate(m.getCreateTime()),
m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy(), m.getWelcomeMessageTemplate(),
m.getWelcomeMessage(), m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers());
}
private String formatPrettyDate(Long timestamp) {
@ -916,6 +928,10 @@ public class MeetingService implements MessageListener {
messagingService = mess;
}
public void setGw(IBbbWebApiGWApp gw) {
this.gw = gw;
}
public void setRegisteredUserCleanupTimerTask(
RegisteredUserCleanupTimerTask c) {

View File

@ -1,6 +1,16 @@
package org.bigbluebutton.api2;
import java.util.Map;
public interface IBbbWebApiGWApp {
void send(String channel, String message);
void createMeeting(String meetingID, String externalMeetingID,
String parentMeetingID, String meetingName, Boolean recorded,
String voiceBridge, Integer duration, Boolean autoStartRecording,
Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator,
String moderatorPass, String viewerPass, Long createTime,
String createDate, Boolean isBreakout, Integer sequence, Map<String, String> metadata,
String guestPolicy, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage,
String dialNumber, Integer maxUsers);
}

View File

@ -1,9 +1,13 @@
package org.bigbluebutton.api2
import java.util
import java.util.Map
import scala.collection.JavaConverters._
import akka.actor.ActorSystem
import org.bigbluebutton.api2.bus._
import org.bigbluebutton.api2.endpoint.redis.{AppsRedisSubscriberActor, MessageSender, RedisPublisher}
import org.bigbluebutton.api2.meeting.MeetingsManagerActor
import org.bigbluebutton.api2.meeting.{CreateMeetingMsg, MeetingsManagerActor}
import org.bigbluebutton.common2.domain._
import scala.concurrent.duration._
@ -53,4 +57,33 @@ class BbbWebApiGWApp(val oldMessageReceivedGW: OldMessageReceivedGW) extends IBb
def send(channel: String, json: String): Unit = {
jsonMsgToAkkaAppsBus.publish(JsonMsgToAkkaAppsBusMsg(toAkkaAppsJsonChannel, new JsonMsgToSendToAkkaApps(channel, json)))
}
def createMeeting(meetingId: String, extMeetingId: String, parentMeetingId: String, meetingName: String,
recorded: java.lang.Boolean, voiceBridge: String, duration: java.lang.Integer,
autoStartRecording: java.lang.Boolean,
allowStartStopRecording: java.lang.Boolean, webcamsOnlyForModerator: java.lang.Boolean, moderatorPass: String,
viewerPass: String, createTime: java.lang.Long, createDate: String, isBreakout: java.lang.Boolean,
sequence: java.lang.Integer,
metadata: java.util.Map[String, String], guestPolicy: String,
welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String,
dialNumber: String, maxUsers: java.lang.Integer): Unit = {
val meetingProp = MeetingProp(name = meetingName, extId = extMeetingId, intId = meetingId,
isBreakout = isBreakout.booleanValue())
val durationProps = DurationProps(duration = duration, createdTime = createTime)
val password = PasswordProp(moderatorPass = moderatorPass, viewerPass = viewerPass)
val recordProp = RecordProp(record = recorded, autoStartRecording = autoStartRecording,
allowStartStopRecording = allowStartStopRecording)
val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg,
modOnlyMessage = modOnlyMessage)
val voiceProp = VoiceProp(telVoice = voiceBridge, webVoice = voiceBridge, dialNumber = dialNumber)
val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator,
guestPolicy = guestPolicy)
val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap)
val defaultProps = DefaultProps(meetingProp, durationProps, password, recordProp, welcomeProp, voiceProp,
usersProp, metadataProp)
meetingManagerActorRef ! new CreateMeetingMsg(defaultProps)
}
}

View File

@ -14,7 +14,7 @@ class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
redis.clientSetname("BbbWebPub")
def publish(channel: String, data: String) {
//println("PUBLISH TO [" + channel + "]: \n [" + data + "]")
println("PUBLISH TO \n[" + channel + "]: \n " + data + "\n")
redis.publish(channel, ByteString(data))
}

View File

@ -1,8 +1,16 @@
package org.bigbluebutton.api2.meeting
import org.bigbluebutton.common2.domain.DefaultProps
object MeetingsManager {
def create(mgr: MeetingsManager, defaultProps: DefaultProps): RunningMeeting = {
val rm = RunningMeeting(defaultProps.meetingProp.intId, defaultProps)
mgr.save(rm)
rm
}
def findWithId(mgr: MeetingsManager, id: String): Option[RunningMeeting] = {
mgr.toVector.find(m => m.meetingId == id)
}

View File

@ -67,7 +67,7 @@ class MeetingsManagerActor(val msgToAkkaAppsEventBus: MsgToAkkaAppsEventBus)
} yield {
MeetingsManager.findMeetingThatStartsWith(manager, mid) match {
case Some(m) => replyWithDuplicateMeeting()
case None => createNewMeeting()
case None => createNewMeeting(msg)
sendCreateMeetingRequestToAkkaApps(msg.defaultProps)
replyWithCreatedMeeting()
}
@ -80,8 +80,8 @@ class MeetingsManagerActor(val msgToAkkaAppsEventBus: MsgToAkkaAppsEventBus)
}
def createNewMeeting(): Unit = {
def createNewMeeting(msg: CreateMeetingMsg): RunningMeeting = {
MeetingsManager.create(manager, msg.defaultProps)
}
def replyWithCreatedMeeting(): Unit = {

View File

@ -1,12 +1,13 @@
package org.bigbluebutton.api2.meeting
import org.bigbluebutton.api2.domain.{RegisteredUsers, Users, UsersCustomData}
import org.bigbluebutton.common2.domain.DefaultProps
object RunningMeeting {
def apply(meetingId: String, defaultProps: DefaultProps) = new RunningMeeting(meetingId, defaultProps)
}
class RunningMeeting(val meetingId: String) {
class RunningMeeting(val meetingId: String, val defaultProps: DefaultProps) {
private val users = new Users
private val registeredUsers = new RegisteredUsers
private val usersCustomData = new UsersCustomData

View File

@ -1,13 +1,18 @@
package org.bigbluebutton.api2.meeting
import org.bigbluebutton.api2.bus.MsgToAkkaAppsEventBus
import org.bigbluebutton.api2.SystemConfiguration
import org.bigbluebutton.api2.bus.{MsgToAkkaApps, MsgToAkkaAppsEventBus}
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.messages._
trait ToAkkaAppsSendersTrait {
trait ToAkkaAppsSendersTrait extends SystemConfiguration{
val msgToAkkaAppsEventBus: MsgToAkkaAppsEventBus
def sendToBus(msg: BbbCommonEnvCoreMsg): Unit = {
msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, msg))
}
def sendCreateMeetingRequestToAkkaApps(props: DefaultProps): Unit = {
val routing = collection.immutable.HashMap("sender" -> "bbb-web")
val envelope = BbbCoreEnvelope(CreateMeetingReqMsg.NAME, routing)
@ -15,5 +20,6 @@ trait ToAkkaAppsSendersTrait {
val body = CreateMeetingReqMsgBody(props)
val req = CreateMeetingReqMsg(header, body)
val msg = BbbCommonEnvCoreMsg(envelope, req)
sendToBus(msg)
}
}

View File

@ -50,6 +50,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<property name="paramsProcessorUtil" ref="paramsProcessorUtil"/>
<property name="stunTurnService" ref="stunTurnService"/>
<property name="registeredUserCleanupTimerTask" ref="registeredUserCleanupTimerTask"/>
<property name="gw" ref="bbbWebApiGWApp" />
</bean>
<bean id="oldMessageReceivedGW" class="org.bigbluebutton.api2.bus.OldMessageReceivedGW">