- try writing test
- start implementing meeting inactivity - updated scalariform to format scala code
This commit is contained in:
parent
08fe6cea81
commit
80213da06e
@ -25,6 +25,7 @@ resolvers ++= Seq(
|
||||
)
|
||||
|
||||
resolvers += Resolver.sonatypeRepo("releases")
|
||||
resolvers += Resolver.typesafeRepo("releases")
|
||||
|
||||
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) )
|
||||
|
||||
@ -90,9 +91,21 @@ libraryDependencies += "org.scalatest" % "scalatest_2.12" % "3.0.3" % "test"
|
||||
libraryDependencies += "org.mockito" % "mockito-core" % "2.7.22" % "test"
|
||||
|
||||
|
||||
seq(Revolver.settings: _*)
|
||||
|
||||
scalariformSettings
|
||||
|
||||
import com.typesafe.sbt.SbtScalariform
|
||||
|
||||
import scalariform.formatter.preferences._
|
||||
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
|
||||
|
||||
SbtScalariform.defaultScalariformSettings
|
||||
|
||||
ScalariformKeys.preferences := ScalariformKeys.preferences.value
|
||||
.setPreference(AlignSingleLineCaseStatements, true)
|
||||
.setPreference(DoubleIndentClassDeclaration, true)
|
||||
.setPreference(AlignParameters, true)
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------
|
||||
|
@ -1,6 +1,8 @@
|
||||
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2")
|
||||
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
|
||||
//addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
|
||||
|
||||
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
|
||||
|
||||
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0")
|
||||
|
||||
|
@ -15,7 +15,8 @@ object Boot extends App with SystemConfiguration {
|
||||
implicit val executor = system.dispatcher
|
||||
val logger = Logging(system, getClass)
|
||||
|
||||
val eventBus = new IncomingEventBus
|
||||
val eventBus = new InMsgBusGW(new IncomingEventBusImp())
|
||||
|
||||
val outgoingEventBus = new OutgoingEventBus
|
||||
val outBus2 = new OutEventBus2
|
||||
val recordingEventBus = new RecordingEventBus
|
||||
|
@ -19,16 +19,20 @@ import org.bigbluebutton.core2.RunningMeetings
|
||||
import org.bigbluebutton.core2.message.senders.MsgBuilder
|
||||
|
||||
object BigBlueButtonActor extends SystemConfiguration {
|
||||
def props(system: ActorSystem,
|
||||
eventBus: IncomingEventBus,
|
||||
def props(
|
||||
system: ActorSystem,
|
||||
eventBus: IncomingEventBus,
|
||||
bbbMsgBus: BbbMsgRouterEventBus,
|
||||
outGW: OutMessageGateway): Props =
|
||||
outGW: OutMessageGateway
|
||||
): Props =
|
||||
Props(classOf[BigBlueButtonActor], system, eventBus, bbbMsgBus, outGW)
|
||||
}
|
||||
|
||||
class BigBlueButtonActor(val system: ActorSystem,
|
||||
class BigBlueButtonActor(
|
||||
val system: ActorSystem,
|
||||
val eventBus: IncomingEventBus, val bbbMsgBus: BbbMsgRouterEventBus,
|
||||
val outGW: OutMessageGateway) extends Actor
|
||||
val outGW: OutMessageGateway
|
||||
) extends Actor
|
||||
with ActorLogging with SystemConfiguration {
|
||||
|
||||
implicit def executionContext = system.dispatcher
|
||||
@ -56,27 +60,27 @@ class BigBlueButtonActor(val system: ActorSystem,
|
||||
|
||||
def receive = {
|
||||
// 2x messages
|
||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||
|
||||
// 1x messages
|
||||
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
|
||||
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
|
||||
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
|
||||
case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg)
|
||||
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
|
||||
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
|
||||
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
|
||||
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
|
||||
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
|
||||
case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg)
|
||||
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
|
||||
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
|
||||
case msg: VoiceConfRecordingStartedMessage => handleVoiceConfRecordingStartedMessage(msg)
|
||||
case _ => // do nothing
|
||||
case _ => // do nothing
|
||||
}
|
||||
|
||||
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
||||
msg.core match {
|
||||
case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
|
||||
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
|
||||
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
|
||||
case m: PubSubPingSysReqMsg => handlePubSubPingSysReqMsg(m)
|
||||
case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
|
||||
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
|
||||
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
|
||||
case m: PubSubPingSysReqMsg => handlePubSubPingSysReqMsg(m)
|
||||
case m: DestroyMeetingSysCmdMsg => handleDestroyMeeting(m)
|
||||
case _ => log.warning("Cannot handle " + msg.envelope.name)
|
||||
case _ => log.warning("Cannot handle " + msg.envelope.name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +98,7 @@ class BigBlueButtonActor(val system: ActorSystem,
|
||||
log.debug("****** RECEIVED CreateMeetingReqMsg msg {}", msg)
|
||||
|
||||
RunningMeetings.findWithId(meetings, msg.body.props.meetingProp.intId) match {
|
||||
case None => {
|
||||
case None =>
|
||||
log.info("Create meeting request. meetingId={}", msg.body.props.meetingProp.intId)
|
||||
|
||||
val m = RunningMeeting(msg.body.props, outGW, eventBus)
|
||||
@ -115,11 +119,11 @@ class BigBlueButtonActor(val system: ActorSystem,
|
||||
// Send new 2x message
|
||||
val msgEvent = MsgBuilder.buildMeetingCreatedEvtMsg(m.props.meetingProp.intId, msg.body.props)
|
||||
outGW.send(msgEvent)
|
||||
}
|
||||
case Some(m) => {
|
||||
|
||||
case Some(m) =>
|
||||
log.info("Meeting already created. meetingID={}", msg.body.props.meetingProp.intId)
|
||||
// do nothing
|
||||
}
|
||||
// do nothing
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,10 @@ import scala.collection.JavaConverters
|
||||
|
||||
class BigBlueButtonInGW(
|
||||
val system: ActorSystem,
|
||||
eventBus: IncomingEventBus,
|
||||
bbbMsgBus: BbbMsgRouterEventBus,
|
||||
outGW: OutMessageGateway) extends IBigBlueButtonInGW with SystemConfiguration {
|
||||
eventBus: IncomingEventBus,
|
||||
bbbMsgBus: BbbMsgRouterEventBus,
|
||||
outGW: OutMessageGateway
|
||||
) extends IBigBlueButtonInGW with SystemConfiguration {
|
||||
|
||||
val log = Logging(system, getClass)
|
||||
val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, bbbMsgBus, outGW), "bigbluebutton-actor")
|
||||
@ -34,22 +35,26 @@ class BigBlueButtonInGW(
|
||||
message match {
|
||||
case msg: StartCustomPollRequestMessage => {
|
||||
eventBus.publish(
|
||||
BigBlueButtonEvent(msg.payload.meetingId,
|
||||
BigBlueButtonEvent(
|
||||
msg.payload.meetingId,
|
||||
new StartCustomPollRequest(msg.payload.meetingId, msg.payload.requesterId,
|
||||
msg.payload.pollId, msg.payload.pollType, msg.payload.answers)))
|
||||
msg.payload.pollId, msg.payload.pollType, msg.payload.answers)
|
||||
)
|
||||
)
|
||||
}
|
||||
case msg: PubSubPingMessage => {
|
||||
eventBus.publish(
|
||||
BigBlueButtonEvent("meeting-manager", new PubSubPing(msg.payload.system, msg.payload.timestamp)))
|
||||
BigBlueButtonEvent("meeting-manager", new PubSubPing(msg.payload.system, msg.payload.timestamp))
|
||||
)
|
||||
}
|
||||
|
||||
case msg: CreateMeetingRequest => {
|
||||
val policy = msg.payload.guestPolicy.toUpperCase() match {
|
||||
case "ALWAYS_ACCEPT" => GuestPolicyType.ALWAYS_ACCEPT
|
||||
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
|
||||
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
|
||||
case "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
|
||||
//default
|
||||
case undef => GuestPolicyType.ASK_MODERATOR
|
||||
case undef => GuestPolicyType.ASK_MODERATOR
|
||||
}
|
||||
/*
|
||||
val mProps = new MeetingProperties(
|
||||
@ -84,18 +89,18 @@ class BigBlueButtonInGW(
|
||||
def handleJsonMessage(json: String) {
|
||||
JsonMessageDecoder.decode(json) match {
|
||||
case Some(validMsg) => forwardMessage(validMsg)
|
||||
case None => log.error("Unhandled json message: {}", json)
|
||||
case None => log.error("Unhandled json message: {}", json)
|
||||
}
|
||||
}
|
||||
|
||||
def forwardMessage(msg: InMessage) = {
|
||||
msg match {
|
||||
case m: BreakoutRoomsListMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: CreateBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: BreakoutRoomsListMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: CreateBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: RequestBreakoutJoinURLInMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: TransferUserToMeetingRequest => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: EndAllBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case _ => log.error("Unhandled message: {}", msg)
|
||||
case m: TransferUserToMeetingRequest => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case m: EndAllBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
|
||||
case _ => log.error("Unhandled message: {}", msg)
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +110,10 @@ class BigBlueButtonInGW(
|
||||
BigBlueButtonEvent(
|
||||
"meeting-manager",
|
||||
new DestroyMeeting(
|
||||
meetingID)))
|
||||
meetingID
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
def getAllMeetings(meetingID: String) {
|
||||
@ -117,7 +125,7 @@ class BigBlueButtonInGW(
|
||||
}
|
||||
|
||||
def lockSettings(meetingID: String, locked: java.lang.Boolean,
|
||||
lockSettings: java.util.Map[String, java.lang.Boolean]) {
|
||||
lockSettings: java.util.Map[String, java.lang.Boolean]) {
|
||||
}
|
||||
|
||||
def statusMeetingAudit(meetingID: String) {
|
||||
@ -146,7 +154,7 @@ class BigBlueButtonInGW(
|
||||
}
|
||||
|
||||
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String,
|
||||
authToken: String, avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean): Unit = {
|
||||
authToken: String, avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean): Unit = {
|
||||
val userRole = if (role == "MODERATOR") Roles.MODERATOR_ROLE else Roles.VIEWER_ROLE
|
||||
eventBus.publish(BigBlueButtonEvent(meetingID, new RegisterUser(meetingID, userID, name, userRole,
|
||||
extUserID, authToken, avatarURL, guest, authed)))
|
||||
@ -166,13 +174,15 @@ class BigBlueButtonInGW(
|
||||
val lockOnJoin = s.getOrElse("lockOnJoin", false)
|
||||
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
|
||||
|
||||
val permissions = new Permissions(disableCam = disableCam,
|
||||
val permissions = new Permissions(
|
||||
disableCam = disableCam,
|
||||
disableMic = disableMic,
|
||||
disablePrivChat = disablePrivChat,
|
||||
disablePubChat = disablePubChat,
|
||||
lockedLayout = lockedLayout,
|
||||
lockOnJoin = lockOnJoin,
|
||||
lockOnJoinConfigurable = lockOnJoinConfigurable)
|
||||
lockOnJoinConfigurable = lockOnJoinConfigurable
|
||||
)
|
||||
|
||||
eventBus.publish(BigBlueButtonEvent(meetingID, new SetLockSettings(meetingID, userId, permissions)))
|
||||
}
|
||||
@ -190,13 +200,15 @@ class BigBlueButtonInGW(
|
||||
val lockedLayout = s.getOrElse("lockedLayout", false)
|
||||
val lockOnJoin = s.getOrElse("lockOnJoin", false)
|
||||
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
|
||||
val permissions = new Permissions(disableCam = disableCam,
|
||||
val permissions = new Permissions(
|
||||
disableCam = disableCam,
|
||||
disableMic = disableMic,
|
||||
disablePrivChat = disablePrivChat,
|
||||
disablePubChat = disablePubChat,
|
||||
lockedLayout = lockedLayout,
|
||||
lockOnJoin = lockOnJoin,
|
||||
lockOnJoinConfigurable = lockOnJoinConfigurable)
|
||||
lockOnJoinConfigurable = lockOnJoinConfigurable
|
||||
)
|
||||
|
||||
eventBus.publish(BigBlueButtonEvent(meetingID, new InitLockSettings(meetingID, permissions)))
|
||||
}
|
||||
@ -263,8 +275,10 @@ class BigBlueButtonInGW(
|
||||
}
|
||||
|
||||
def checkIfAllowedToShareDesktop(meetingID: String, userID: String): Unit = {
|
||||
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(meetingID: String,
|
||||
userID: String)))
|
||||
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(
|
||||
meetingID: String,
|
||||
userID: String
|
||||
)))
|
||||
}
|
||||
|
||||
def assignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String): Unit = {
|
||||
@ -300,10 +314,10 @@ class BigBlueButtonInGW(
|
||||
def setGuestPolicy(meetingId: String, guestPolicy: String, requesterId: String) {
|
||||
val policy = guestPolicy.toUpperCase() match {
|
||||
case "ALWAYS_ACCEPT" => GuestPolicyType.ALWAYS_ACCEPT
|
||||
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
|
||||
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
|
||||
case "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
|
||||
//default
|
||||
case undef => GuestPolicyType.ASK_MODERATOR
|
||||
case undef => GuestPolicyType.ASK_MODERATOR
|
||||
}
|
||||
eventBus.publish(BigBlueButtonEvent(meetingId, new SetGuestPolicy(meetingId, policy, requesterId)))
|
||||
}
|
||||
@ -442,7 +456,7 @@ class BigBlueButtonInGW(
|
||||
}
|
||||
|
||||
def voiceUserJoined(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
|
||||
callerIdNum: String, muted: java.lang.Boolean, avatarURL: String, talking: java.lang.Boolean) {
|
||||
callerIdNum: String, muted: java.lang.Boolean, avatarURL: String, talking: java.lang.Boolean) {
|
||||
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, userId, callerIdName,
|
||||
callerIdNum, muted, talking, avatarURL, false /*hardcode listenOnly to false as the message for listenOnly is ConnectedToGlobalAudio*/ )))
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ object JsonMessageDecoder {
|
||||
def decode(json: String): Option[InMessage] = {
|
||||
unmarshall(json) match {
|
||||
case Success(validMsg) => Some(validMsg)
|
||||
case Failure(ex) => None
|
||||
case Failure(ex) => None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,16 @@ class JsonMessageSenderActor(val service: MessageSender)
|
||||
def receive = {
|
||||
|
||||
// Breakout
|
||||
case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg)
|
||||
case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg)
|
||||
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg)
|
||||
case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg)
|
||||
case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg)
|
||||
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg)
|
||||
case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURL(msg)
|
||||
case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStarted(msg)
|
||||
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg)
|
||||
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg)
|
||||
case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsers(msg)
|
||||
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
|
||||
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
|
||||
|
||||
case _ => // do nothing
|
||||
case _ => // do nothing
|
||||
}
|
||||
|
||||
// Breakout
|
||||
@ -87,8 +87,10 @@ class JsonMessageSenderActor(val service: MessageSender)
|
||||
}
|
||||
|
||||
def handleBreakoutRoomJoinURL(msg: BreakoutRoomJoinURLOutMessage) {
|
||||
val payload = new BreakoutRoomJoinURLPayload(msg.parentMeetingId,
|
||||
msg.breakoutMeetingId, msg.userId, msg.redirectJoinURL, msg.noRedirectJoinURL)
|
||||
val payload = new BreakoutRoomJoinURLPayload(
|
||||
msg.parentMeetingId,
|
||||
msg.breakoutMeetingId, msg.userId, msg.redirectJoinURL, msg.noRedirectJoinURL
|
||||
)
|
||||
val request = new BreakoutRoomJoinURL(payload)
|
||||
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import org.bigbluebutton.core.api.Permissions
|
||||
case object StopMeetingActor
|
||||
|
||||
case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20,
|
||||
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
|
||||
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
|
||||
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
|
||||
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
|
||||
|
||||
class MeetingModel {
|
||||
private var audioSettingsInited = false
|
||||
|
@ -6,15 +6,19 @@ import org.bigbluebutton.core.api.IOutMessage
|
||||
import org.bigbluebutton.core.bus._
|
||||
|
||||
object OutMessageGatewayImp {
|
||||
def apply(outgoingEventBus: OutgoingEventBus,
|
||||
outBus2: OutEventBus2,
|
||||
recordBus: RecordingEventBus) =
|
||||
def apply(
|
||||
outgoingEventBus: OutgoingEventBus,
|
||||
outBus2: OutEventBus2,
|
||||
recordBus: RecordingEventBus
|
||||
) =
|
||||
new OutMessageGatewayImp(outgoingEventBus, outBus2, recordBus)
|
||||
}
|
||||
|
||||
class OutMessageGatewayImp(outgoingEventBus: OutgoingEventBus,
|
||||
outBus2: OutEventBus2,
|
||||
recordBus: RecordingEventBus) extends OutMessageGateway
|
||||
class OutMessageGatewayImp(
|
||||
outgoingEventBus: OutgoingEventBus,
|
||||
outBus2: OutEventBus2,
|
||||
recordBus: RecordingEventBus
|
||||
) extends OutMessageGateway
|
||||
with SystemConfiguration {
|
||||
|
||||
def send1(msg: IOutMessage) {
|
||||
|
@ -20,7 +20,7 @@ object UserMessagesProtocol extends DefaultJsonProtocol {
|
||||
|
||||
def read(json: JsValue): MessageType.MessageType = json match {
|
||||
case JsString(str) => MessageType.withName(str)
|
||||
case _ => throw new DeserializationException("Enum string expected")
|
||||
case _ => throw new DeserializationException("Enum string expected")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,6 @@ trait OutMessage
|
||||
case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload)
|
||||
case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload)
|
||||
case class CreateBreakoutRoomOutMsgPayload(meetingId: String, parentId: String, name: String,
|
||||
voiceConfId: String, moderatorPassword: String, viewerPassword: String,
|
||||
durationInMinutes: Int, sourcePresentationId: String, sourcePresentationSlide: Int,
|
||||
record: Boolean, sequence: Int)
|
||||
voiceConfId: String, moderatorPassword: String, viewerPassword: String,
|
||||
durationInMinutes: Int, sourcePresentationId: String, sourcePresentationSlide: Int,
|
||||
record: Boolean, sequence: Int)
|
||||
|
@ -74,9 +74,9 @@ case class GetLockSettings(meetingID: String, userId: String) extends InMessage
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case class ValidateAuthToken(meetingID: String, userId: String, token: String,
|
||||
correlationId: String, sessionId: String) extends InMessage
|
||||
correlationId: String, sessionId: String) extends InMessage
|
||||
case class RegisterUser(meetingID: String, userID: String, name: String, role: String,
|
||||
extUserID: String, authToken: String, avatarURL: String, guest: Boolean, authed: Boolean) extends InMessage
|
||||
extUserID: String, authToken: String, avatarURL: String, guest: Boolean, authed: Boolean) extends InMessage
|
||||
case class UserJoining(meetingID: String, userID: String, authToken: String) extends InMessage
|
||||
case class UserLeaving(meetingID: String, userID: String, sessionId: String) extends InMessage
|
||||
case class GetUsers(meetingID: String, requesterID: String) extends InMessage
|
||||
@ -98,9 +98,9 @@ case class LogoutEndMeeting(meetingID: String, userID: String) extends InMessage
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
|
||||
userid: String, name: String) extends InMessage
|
||||
userid: String, name: String) extends InMessage
|
||||
case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
|
||||
userid: String, name: String) extends InMessage
|
||||
userid: String, name: String) extends InMessage
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Guest support
|
||||
@ -116,7 +116,7 @@ case class RespondToGuest(meetingID: String, userId: String, response: Boolean,
|
||||
|
||||
case class GetCurrentLayoutRequest(meetingID: String, requesterID: String) extends InMessage
|
||||
case class LockLayoutRequest(meetingID: String, setById: String, lock: Boolean, viewersOnly: Boolean,
|
||||
layout: Option[String]) extends InMessage
|
||||
layout: Option[String]) extends InMessage
|
||||
case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout: String) extends InMessage
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -127,19 +127,19 @@ case class ClearPresentation(meetingID: String) extends InMessage
|
||||
case class RemovePresentation(meetingID: String, presentationID: String) extends InMessage
|
||||
case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
|
||||
case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double,
|
||||
widthRatio: Double, heightRatio: Double) extends InMessage
|
||||
widthRatio: Double, heightRatio: Double) extends InMessage
|
||||
case class GotoSlide(meetingID: String, page: String) extends InMessage
|
||||
case class SharePresentation(meetingID: String, presentationID: String, share: Boolean) extends InMessage
|
||||
case class GetSlideInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
|
||||
case class PreuploadedPresentations(meetingID: String, presentations: Seq[Presentation]) extends InMessage
|
||||
case class PresentationConversionUpdate(meetingID: String, messageKey: String, code: String,
|
||||
presentationId: String, presName: String) extends InMessage
|
||||
presentationId: String, presName: String) extends InMessage
|
||||
case class PresentationPageCountError(meetingID: String, messageKey: String, code: String, presentationId: String,
|
||||
numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage
|
||||
numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage
|
||||
case class PresentationSlideGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
|
||||
numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage
|
||||
numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage
|
||||
case class PresentationConversionCompleted(meetingID: String, messageKey: String, code: String,
|
||||
presentation: Presentation) extends InMessage
|
||||
presentation: Presentation) extends InMessage
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Polling
|
||||
@ -168,9 +168,9 @@ case class MuteUserRequest(meetingID: String, requesterID: String, userID: Strin
|
||||
case class LockUserRequest(meetingID: String, requesterID: String, userID: String, lock: Boolean) extends InMessage
|
||||
case class EjectUserFromVoiceRequest(meetingID: String, userId: String, ejectedBy: String) extends InMessage
|
||||
case class VoiceUserJoinedMessage(meetingID: String, user: String, voiceConfId: String,
|
||||
callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage
|
||||
callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage
|
||||
case class UserJoinedVoiceConfMessage(voiceConfId: String, voiceUserId: String, userId: String, externUserId: String,
|
||||
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage
|
||||
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage
|
||||
case class UserLeftVoiceConfMessage(voiceConfId: String, voiceUserId: String) extends InMessage
|
||||
case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage
|
||||
case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage
|
||||
|
@ -10,7 +10,7 @@ case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recording
|
||||
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
|
||||
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
|
||||
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
|
||||
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
|
||||
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
|
||||
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
|
||||
case class MeetingEnding(meetingID: String) extends IOutMessage
|
||||
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
|
||||
@ -30,8 +30,8 @@ case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[Breakout
|
||||
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
|
||||
case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
|
||||
case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
|
||||
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
|
||||
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
|
||||
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
|
||||
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
|
||||
case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, redirectJoinURL: String, noRedirectJoinURL: String) extends IOutMessage
|
||||
case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomInfo) extends IOutMessage
|
||||
case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUserVO]) extends IOutMessage
|
||||
@ -64,7 +64,7 @@ case class UserStatusChange(meetingID: String, recorded: Boolean, userID: String
|
||||
case class UserRoleChange(meetingID: String, recorded: Boolean, userID: String, role: String) extends IOutMessage
|
||||
case class GetUsersInVoiceConference(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
|
||||
case class MuteVoiceUser(meetingID: String, recorded: Boolean, requesterID: String,
|
||||
userId: String, voiceConfId: String, voiceUserId: String, mute: Boolean) extends IOutMessage
|
||||
userId: String, voiceConfId: String, voiceUserId: String, mute: Boolean) extends IOutMessage
|
||||
case class UserVoiceMuted(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
|
||||
case class UserVoiceTalking(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
|
||||
case class EjectVoiceUser(meetingID: String, recorded: Boolean, requesterID: String, userId: String, voiceConfId: String, voiceUserId: String) extends IOutMessage
|
||||
@ -82,30 +82,30 @@ case class StopRecording(meetingID: String, recorded: Boolean, requesterID: Stri
|
||||
|
||||
// Layout
|
||||
case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String,
|
||||
locked: Boolean, setByUserID: String) extends IOutMessage
|
||||
locked: Boolean, setByUserID: String) extends IOutMessage
|
||||
case class BroadcastLayoutEvent(meetingID: String, recorded: Boolean, requesterID: String,
|
||||
layoutID: String, locked: Boolean, setByUserID: String, applyTo: Array[UserVO]) extends IOutMessage
|
||||
layoutID: String, locked: Boolean, setByUserID: String, applyTo: Array[UserVO]) extends IOutMessage
|
||||
case class LockLayoutEvent(meetingID: String, recorded: Boolean, setById: String, locked: Boolean,
|
||||
applyTo: Array[UserVO]) extends IOutMessage
|
||||
applyTo: Array[UserVO]) extends IOutMessage
|
||||
|
||||
// Presentation
|
||||
case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
|
||||
case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage
|
||||
case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String,
|
||||
info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
|
||||
info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
|
||||
case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
|
||||
case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
|
||||
case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage
|
||||
case class GetSlideInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, page: Page, replyTo: String) extends IOutMessage
|
||||
case class GetPreuploadedPresentationsOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
|
||||
case class PresentationConversionProgress(meetingID: String, messageKey: String, code: String,
|
||||
presentationId: String, presentationName: String) extends IOutMessage
|
||||
presentationId: String, presentationName: String) extends IOutMessage
|
||||
case class PresentationConversionError(meetingID: String, messageKey: String, code: String,
|
||||
presentationId: String, numberOfPages: Int, maxNumberPages: Int, presentationName: String) extends IOutMessage
|
||||
presentationId: String, numberOfPages: Int, maxNumberPages: Int, presentationName: String) extends IOutMessage
|
||||
case class PresentationPageGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
|
||||
numberOfPages: Int, pagesCompleted: Int, presentationName: String) extends IOutMessage
|
||||
numberOfPages: Int, pagesCompleted: Int, presentationName: String) extends IOutMessage
|
||||
case class PresentationConversionDone(meetingID: String, recorded: Boolean, messageKey: String, code: String,
|
||||
presentation: Presentation) extends IOutMessage
|
||||
presentation: Presentation) extends IOutMessage
|
||||
case class PresentationChanged(meetingID: String, presentation: Presentation) extends IOutMessage
|
||||
case class GetPresentationStatusReply(meetingID: String, presentations: Seq[Presentation], current: Presentation, replyTo: String) extends IOutMessage
|
||||
case class PresentationRemoved(meetingID: String, presentationId: String) extends IOutMessage
|
||||
|
@ -35,58 +35,65 @@ object ErrorCodes {
|
||||
case class RequestResult(status: StatusCode, errors: Option[Array[ErrorCode]])
|
||||
|
||||
case class Presenter(
|
||||
presenterID: String,
|
||||
presenterID: String,
|
||||
presenterName: String,
|
||||
assignedBy: String)
|
||||
assignedBy: String
|
||||
)
|
||||
|
||||
case class User(
|
||||
id: String,
|
||||
externId: String,
|
||||
name: String,
|
||||
moderator: Boolean,
|
||||
avatarUrl: String,
|
||||
logoutUrl: String,
|
||||
presenter: Boolean,
|
||||
callerId: CallerId,
|
||||
id: String,
|
||||
externId: String,
|
||||
name: String,
|
||||
moderator: Boolean,
|
||||
avatarUrl: String,
|
||||
logoutUrl: String,
|
||||
presenter: Boolean,
|
||||
callerId: CallerId,
|
||||
phoneCaller: Boolean,
|
||||
emojiStatus: String,
|
||||
muted: Boolean,
|
||||
talking: Boolean)
|
||||
muted: Boolean,
|
||||
talking: Boolean
|
||||
)
|
||||
|
||||
case class CallerId(
|
||||
name: String,
|
||||
number: String)
|
||||
name: String,
|
||||
number: String
|
||||
)
|
||||
|
||||
case class Permissions(
|
||||
disableCam: Boolean = false,
|
||||
disableMic: Boolean = false,
|
||||
disablePrivChat: Boolean = false,
|
||||
disablePubChat: Boolean = false,
|
||||
lockedLayout: Boolean = false,
|
||||
lockOnJoin: Boolean = false,
|
||||
lockOnJoinConfigurable: Boolean = false)
|
||||
disableCam: Boolean = false,
|
||||
disableMic: Boolean = false,
|
||||
disablePrivChat: Boolean = false,
|
||||
disablePubChat: Boolean = false,
|
||||
lockedLayout: Boolean = false,
|
||||
lockOnJoin: Boolean = false,
|
||||
lockOnJoinConfigurable: Boolean = false
|
||||
)
|
||||
|
||||
case class Voice(
|
||||
id: String,
|
||||
webId: String,
|
||||
callId: CallerId,
|
||||
id: String,
|
||||
webId: String,
|
||||
callId: CallerId,
|
||||
phoningIn: Boolean,
|
||||
joined: Boolean,
|
||||
locked: Boolean,
|
||||
muted: Boolean,
|
||||
talking: Boolean)
|
||||
joined: Boolean,
|
||||
locked: Boolean,
|
||||
muted: Boolean,
|
||||
talking: Boolean
|
||||
)
|
||||
|
||||
case class MeetingConfig(name: String,
|
||||
id: MeetingID,
|
||||
passwords: MeetingPasswords,
|
||||
welcomeMsg: String,
|
||||
logoutUrl: String,
|
||||
maxUsers: Int,
|
||||
record: Boolean = false,
|
||||
duration: MeetingDuration,
|
||||
defaultAvatarURL: String,
|
||||
case class MeetingConfig(
|
||||
name: String,
|
||||
id: MeetingID,
|
||||
passwords: MeetingPasswords,
|
||||
welcomeMsg: String,
|
||||
logoutUrl: String,
|
||||
maxUsers: Int,
|
||||
record: Boolean = false,
|
||||
duration: MeetingDuration,
|
||||
defaultAvatarURL: String,
|
||||
defaultConfigToken: String,
|
||||
guestPolicy: String = GuestPolicyType.ASK_MODERATOR)
|
||||
guestPolicy: String = GuestPolicyType.ASK_MODERATOR
|
||||
)
|
||||
|
||||
case class MeetingName(name: String)
|
||||
|
||||
@ -97,11 +104,12 @@ case class VoiceConfig(telVoice: String, webVoice: String, dialNumber: String)
|
||||
case class MeetingPasswords(moderatorPass: String, viewerPass: String)
|
||||
|
||||
case class MeetingDuration(duration: Int = 0, createdTime: Long = 0,
|
||||
startTime: Long = 0, endTime: Long = 0)
|
||||
startTime: Long = 0, endTime: Long = 0)
|
||||
|
||||
case class MeetingInfo(
|
||||
meetingID: String,
|
||||
meetingID: String,
|
||||
meetingName: String,
|
||||
recorded: Boolean,
|
||||
recorded: Boolean,
|
||||
voiceBridge: String,
|
||||
duration: Long)
|
||||
duration: Long
|
||||
)
|
||||
|
@ -6,11 +6,11 @@ import org.bigbluebutton.common2.domain.PageVO
|
||||
case class CurrentPresenter(userId: String, name: String, assignedBy: String)
|
||||
case class CurrentPresentationInfo(presenter: CurrentPresenter, presentations: Seq[Presentation])
|
||||
case class Presentation(id: String, name: String, current: Boolean = false,
|
||||
pages: scala.collection.immutable.Map[String, PageVO], downloadable: Boolean)
|
||||
pages: scala.collection.immutable.Map[String, PageVO], downloadable: Boolean)
|
||||
|
||||
case class Page(id: String, num: Int, thumbUri: String = "", swfUri: String,
|
||||
txtUri: String, svgUri: String, current: Boolean = false, xOffset: Double = 0, yOffset: Double = 0,
|
||||
widthRatio: Double = 100D, heightRatio: Double = 100D)
|
||||
txtUri: String, svgUri: String, current: Boolean = false, xOffset: Double = 0, yOffset: Double = 0,
|
||||
widthRatio: Double = 100D, heightRatio: Double = 100D)
|
||||
|
||||
class PresentationModel {
|
||||
private var presentations = new scala.collection.immutable.HashMap[String, Presentation]
|
||||
@ -70,8 +70,8 @@ class PresentationModel {
|
||||
}
|
||||
|
||||
def resizePage(presentationId: String, pageId: String,
|
||||
xOffset: Double, yOffset: Double, widthRatio: Double,
|
||||
heightRatio: Double): Option[PageVO] = {
|
||||
xOffset: Double, yOffset: Double, widthRatio: Double,
|
||||
heightRatio: Double): Option[PageVO] = {
|
||||
for {
|
||||
pres <- presentations.get(presentationId)
|
||||
page <- pres.pages.get(pageId)
|
||||
|
@ -103,7 +103,7 @@ class SharedNotesModel {
|
||||
def getNoteReport(noteId: String): Option[NoteReport] = {
|
||||
notes.get(noteId) match {
|
||||
case Some(note) => Some(noteToReport(note))
|
||||
case None => None
|
||||
case None => None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,16 +218,15 @@ class WhiteboardModel {
|
||||
def cleansePointsInAnnotation(ann: AnnotationVO): AnnotationVO = {
|
||||
var updatedAnnotationInfo = ann.annotationInfo
|
||||
ann.annotationInfo.get("points").foreach(points =>
|
||||
updatedAnnotationInfo = (ann.annotationInfo + ("points" -> convertListNumbersToFloat(points.asInstanceOf[List[_]])))
|
||||
)
|
||||
updatedAnnotationInfo = (ann.annotationInfo + ("points" -> convertListNumbersToFloat(points.asInstanceOf[List[_]]))))
|
||||
ann.copy(annotationInfo = updatedAnnotationInfo)
|
||||
}
|
||||
|
||||
def convertListNumbersToFloat(list: List[_]): List[Float] = {
|
||||
list.map {
|
||||
case f: Double => f.toFloat
|
||||
case f: Float => f
|
||||
case f: Int => f.toFloat
|
||||
case f: Float => f
|
||||
case f: Int => f.toFloat
|
||||
}.asInstanceOf[List[Float]]
|
||||
}
|
||||
}
|
||||
|
@ -51,13 +51,14 @@ object BreakoutRoomsUtil {
|
||||
}
|
||||
|
||||
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String,
|
||||
password: String): (mutable.Map[String, String], mutable.Map[String, String]) = {
|
||||
password: String): (mutable.Map[String, String], mutable.Map[String, String]) = {
|
||||
val params = collection.mutable.HashMap(
|
||||
"fullName" -> urlEncode(username),
|
||||
"userID" -> urlEncode(userId),
|
||||
"isBreakout" -> urlEncode(isBreakout.toString()),
|
||||
"meetingID" -> urlEncode(breakoutMeetingId),
|
||||
"password" -> urlEncode(password))
|
||||
"password" -> urlEncode(password)
|
||||
)
|
||||
|
||||
(params += "redirect" -> urlEncode("true"), mutable.Map[String, String]() ++= params += "redirect" -> urlEncode("false"))
|
||||
}
|
||||
|
@ -61,12 +61,14 @@ trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
|
||||
}
|
||||
|
||||
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String,
|
||||
breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
|
||||
breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
|
||||
log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId)
|
||||
|
||||
def build(meetingId: String, breakout: BreakoutRoomInfo): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, "not-used")
|
||||
val routing = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, "not-used"
|
||||
)
|
||||
val envelope = BbbCoreEnvelope(BreakoutRoomStartedEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(BreakoutRoomStartedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, "not-used")
|
||||
|
||||
@ -97,7 +99,7 @@ trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
|
||||
BreakoutRoomsUtil.calculateChecksum(apiCall, noRedirectBaseString, bbbWebSharedSecret))
|
||||
} yield {
|
||||
def build(meetingId: String, breakoutMeetingId: String,
|
||||
userId: String, redirectJoinURL: String, noRedirectJoinURL: String): BbbCommonEnvCoreMsg = {
|
||||
userId: String, redirectJoinURL: String, noRedirectJoinURL: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(BreakoutRoomJoinURLEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(BreakoutRoomJoinURLEvtMsg.NAME, meetingId, "not-used")
|
||||
|
@ -14,11 +14,15 @@ trait CreateBreakoutRoomsCmdMsgHdlr {
|
||||
def handleCreateBreakoutRoomsCmdMsg(msg: CreateBreakoutRoomsCmdMsg): Unit = {
|
||||
// If breakout rooms are being created we ignore the coming message
|
||||
if (liveMeeting.breakoutRooms.pendingRoomsNumber > 0) {
|
||||
log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}",
|
||||
liveMeeting.breakoutRooms.pendingRoomsNumber, liveMeeting.props.meetingProp.intId)
|
||||
log.warning(
|
||||
"CreateBreakoutRooms event received while {} are pending to be created for meeting {}",
|
||||
liveMeeting.breakoutRooms.pendingRoomsNumber, liveMeeting.props.meetingProp.intId
|
||||
)
|
||||
} else if (BreakoutRooms.getNumberOfRooms(liveMeeting.breakoutRooms) > 0) {
|
||||
log.warning("CreateBreakoutRooms event received while {} breakout rooms running for meeting {}",
|
||||
BreakoutRooms.getNumberOfRooms(liveMeeting.breakoutRooms), liveMeeting.props.meetingProp.intId)
|
||||
log.warning(
|
||||
"CreateBreakoutRooms event received while {} breakout rooms running for meeting {}",
|
||||
BreakoutRooms.getNumberOfRooms(liveMeeting.breakoutRooms), liveMeeting.props.meetingProp.intId
|
||||
)
|
||||
} else {
|
||||
var i = 0
|
||||
// in very rare cases the presentation conversion generates an error, what should we do?
|
||||
|
@ -38,8 +38,10 @@ trait RequestBreakoutJoinURLReqMsgHdlr {
|
||||
val envelope = BbbCoreEnvelope(RequestBreakoutJoinURLRespMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(RequestBreakoutJoinURLRespMsg.NAME, props.meetingProp.intId, msg.header.userId)
|
||||
|
||||
val body = RequestBreakoutJoinURLRespMsgBody(props.meetingProp.intId,
|
||||
externalMeetingId, userId, redirectJoinURL, noRedirectJoinURL)
|
||||
val body = RequestBreakoutJoinURLRespMsgBody(
|
||||
props.meetingProp.intId,
|
||||
externalMeetingId, userId, redirectJoinURL, noRedirectJoinURL
|
||||
)
|
||||
val event = RequestBreakoutJoinURLRespMsg(header, body)
|
||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||
|
||||
|
@ -16,7 +16,9 @@ trait SendBreakoutUsersUpdateMsgHdlr {
|
||||
|
||||
val users = Users2x.findAll(liveMeeting.users2x)
|
||||
val breakoutUsers = users map { u => new BreakoutUserVO(u.extId, u.name) }
|
||||
eventBus.publish(BigBlueButtonEvent(props.breakoutProps.parentId,
|
||||
new BreakoutRoomUsersUpdate(props.breakoutProps.parentId, props.meetingProp.intId, breakoutUsers)))
|
||||
eventBus.publish(BigBlueButtonEvent(
|
||||
props.breakoutProps.parentId,
|
||||
new BreakoutRoomUsersUpdate(props.breakoutProps.parentId, props.meetingProp.intId, breakoutUsers)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,10 @@ import org.bigbluebutton.common2.msgs.TranscriptVO
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
|
||||
class CaptionApp2x(val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway)(implicit val context: ActorContext)
|
||||
class CaptionApp2x(
|
||||
val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway
|
||||
)(implicit val context: ActorContext)
|
||||
extends UserLeavingHdlr
|
||||
with EditCaptionHistoryPubMsgHdlr
|
||||
with UpdateCaptionOwnerPubMsgHdlr
|
||||
|
@ -6,8 +6,10 @@ import org.bigbluebutton.common2.msgs.TranscriptVO
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
|
||||
class ChatApp2x(val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway)(implicit val context: ActorContext)
|
||||
class ChatApp2x(
|
||||
val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway
|
||||
)(implicit val context: ActorContext)
|
||||
extends GetChatHistoryReqMsgHdlr
|
||||
with SendPublicMessagePubMsgHdlr
|
||||
with SendPrivateMessagePubMsgHdlr
|
||||
|
@ -24,7 +24,8 @@ trait BroadcastLayoutMsgHdlr {
|
||||
val body = BroadcastLayoutEvtMsgBody(
|
||||
Layouts.getCurrentLayout(),
|
||||
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
|
||||
Layouts.getLayoutSetter(), affectedUsers)
|
||||
Layouts.getLayoutSetter(), affectedUsers
|
||||
)
|
||||
val event = BroadcastLayoutEvtMsg(header, body)
|
||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||
|
||||
|
@ -20,9 +20,11 @@ trait GetCurrentLayoutReqMsgHdlr {
|
||||
val envelope = BbbCoreEnvelope(GetCurrentLayoutRespMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(GetCurrentLayoutRespMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
|
||||
|
||||
val body = GetCurrentLayoutRespMsgBody(Layouts.getCurrentLayout(),
|
||||
val body = GetCurrentLayoutRespMsgBody(
|
||||
Layouts.getCurrentLayout(),
|
||||
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
|
||||
Layouts.getLayoutSetter())
|
||||
Layouts.getLayoutSetter()
|
||||
)
|
||||
val event = GetCurrentLayoutRespMsg(header, body)
|
||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||
|
||||
|
@ -8,8 +8,10 @@ import org.bigbluebutton.core.running.LiveMeeting
|
||||
import org.bigbluebutton.common2.domain.PageVO
|
||||
import org.bigbluebutton.core.apps.Presentation
|
||||
|
||||
class PresentationApp2x(val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway)(implicit val context: ActorContext)
|
||||
class PresentationApp2x(
|
||||
val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway
|
||||
)(implicit val context: ActorContext)
|
||||
extends NewPresentationMsgHdlr
|
||||
with SetCurrentPresentationPubMsgHdlr
|
||||
with GetPresentationInfoReqMsgHdlr
|
||||
@ -54,8 +56,8 @@ class PresentationApp2x(val liveMeeting: LiveMeeting,
|
||||
}
|
||||
|
||||
def resizeAndMovePage(presentationId: String, pageId: String,
|
||||
xOffset: Double, yOffset: Double, widthRatio: Double,
|
||||
heightRatio: Double): Option[PageVO] = {
|
||||
xOffset: Double, yOffset: Double, widthRatio: Double,
|
||||
heightRatio: Double): Option[PageVO] = {
|
||||
// Force coordinate that are out-of-bounds inside valid values
|
||||
// 0.25D is 400% zoom
|
||||
// 100D-checkedWidth is the maximum the page can be moved over
|
||||
|
@ -5,8 +5,10 @@ import akka.event.Logging
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
|
||||
class ScreenshareApp2x(val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway)(implicit val context: ActorContext)
|
||||
class ScreenshareApp2x(
|
||||
val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway
|
||||
)(implicit val context: ActorContext)
|
||||
extends ScreenshareStartedVoiceConfEvtMsgHdlr
|
||||
with ScreenshareStoppedVoiceConfEvtMsgHdlr
|
||||
with ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr
|
||||
|
@ -11,13 +11,17 @@ trait ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr {
|
||||
|
||||
def handleScreenshareRtmpBroadcastStartedVoiceConfEvtMsg(msg: ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg): Unit = {
|
||||
def broadcastEvent(voiceConf: String, screenshareConf: String, stream: String, vidWidth: Int, vidHeight: Int,
|
||||
timestamp: String): BbbCommonEnvCoreMsg = {
|
||||
timestamp: String): BbbCommonEnvCoreMsg = {
|
||||
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, "not-used")
|
||||
val routing = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, "not-used"
|
||||
)
|
||||
val envelope = BbbCoreEnvelope(ScreenshareRtmpBroadcastStartedEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(ScreenshareRtmpBroadcastStartedEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, "not-used")
|
||||
val header = BbbClientMsgHeader(
|
||||
ScreenshareRtmpBroadcastStartedEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, "not-used"
|
||||
)
|
||||
|
||||
val body = ScreenshareRtmpBroadcastStartedEvtMsgBody(voiceConf, screenshareConf,
|
||||
stream, vidWidth, vidHeight, timestamp)
|
||||
|
@ -12,14 +12,18 @@ trait ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsgHdlr {
|
||||
def handleScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg(msg: ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg): Unit = {
|
||||
|
||||
def broadcastEvent(voiceConf: String, screenshareConf: String,
|
||||
stream: String, vidWidth: Int, vidHeight: Int,
|
||||
timestamp: String): BbbCommonEnvCoreMsg = {
|
||||
stream: String, vidWidth: Int, vidHeight: Int,
|
||||
timestamp: String): BbbCommonEnvCoreMsg = {
|
||||
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, "not-used")
|
||||
val routing = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, "not-used"
|
||||
)
|
||||
val envelope = BbbCoreEnvelope(ScreenshareRtmpBroadcastStoppedEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(ScreenshareRtmpBroadcastStoppedEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, "not-used")
|
||||
val header = BbbClientMsgHeader(
|
||||
ScreenshareRtmpBroadcastStoppedEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, "not-used"
|
||||
)
|
||||
|
||||
val body = ScreenshareRtmpBroadcastStoppedEvtMsgBody(voiceConf, screenshareConf,
|
||||
stream, vidWidth, vidHeight, timestamp)
|
||||
|
@ -15,8 +15,10 @@ trait ScreenshareStartedVoiceConfEvtMsgHdlr {
|
||||
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME, routing)
|
||||
val header = BbbCoreHeaderWithMeetingId(ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId)
|
||||
val header = BbbCoreHeaderWithMeetingId(
|
||||
ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId
|
||||
)
|
||||
|
||||
val body = ScreenshareStartRtmpBroadcastVoiceConfMsgBody(voiceConf: String, screenshareConf: String, url: String, timestamp: String)
|
||||
val event = ScreenshareStartRtmpBroadcastVoiceConfMsg(header, body)
|
||||
|
@ -14,8 +14,10 @@ trait ScreenshareStoppedVoiceConfEvtMsgHdlr {
|
||||
def broadcastEvent(voiceConf: String, screenshareConf: String, url: String, timestamp: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(ScreenshareStopRtmpBroadcastVoiceConfMsg.NAME, routing)
|
||||
val header = BbbCoreHeaderWithMeetingId(ScreenshareStopRtmpBroadcastVoiceConfMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId)
|
||||
val header = BbbCoreHeaderWithMeetingId(
|
||||
ScreenshareStopRtmpBroadcastVoiceConfMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId
|
||||
)
|
||||
|
||||
val body = ScreenshareStopRtmpBroadcastVoiceConfMsgBody(voiceConf, screenshareConf, url, timestamp)
|
||||
val event = ScreenshareStopRtmpBroadcastVoiceConfMsg(header, body)
|
||||
|
@ -5,8 +5,10 @@ import akka.event.Logging
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
|
||||
class SharedNotesApp2x(val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway)(implicit val context: ActorContext)
|
||||
class SharedNotesApp2x(
|
||||
val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway
|
||||
)(implicit val context: ActorContext)
|
||||
extends GetSharedNotesPubMsgHdlr
|
||||
with SyncSharedNotePubMsgHdlr
|
||||
with UpdateSharedNoteReqMsgHdlr
|
||||
|
@ -23,7 +23,7 @@ trait SyncSharedNotePubMsgHdlr {
|
||||
|
||||
liveMeeting.notesModel.getNoteReport(msg.body.noteId) match {
|
||||
case Some(noteReport) => broadcastEvent(msg, noteReport)
|
||||
case None => log.warning("Could not find note " + msg.body.noteId)
|
||||
case None => log.warning("Could not find note " + msg.body.noteId)
|
||||
}
|
||||
}
|
||||
}
|
@ -23,9 +23,9 @@ trait UpdateSharedNoteReqMsgHdlr {
|
||||
|
||||
val userId = msg.body.operation match {
|
||||
case "PATCH" => msg.header.userId
|
||||
case "UNDO" => liveMeeting.notesModel.SYSTEM_ID
|
||||
case "REDO" => liveMeeting.notesModel.SYSTEM_ID
|
||||
case _ => return
|
||||
case "UNDO" => liveMeeting.notesModel.SYSTEM_ID
|
||||
case "REDO" => liveMeeting.notesModel.SYSTEM_ID
|
||||
case _ => return
|
||||
}
|
||||
|
||||
val (patchId, patch, undo, redo) = liveMeeting.notesModel.patchNote(msg.body.noteId, msg.body.patch, msg.body.operation)
|
||||
|
@ -10,8 +10,10 @@ trait AssignPresenterReqMsgHdlr {
|
||||
|
||||
def broadcastPresenterChange(oldPres: UserState, newPres: UserState): Unit = {
|
||||
// unassign old presenter
|
||||
val routingUnassign = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
this.liveMeeting.props.meetingProp.intId, oldPres.intId)
|
||||
val routingUnassign = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
this.liveMeeting.props.meetingProp.intId, oldPres.intId
|
||||
)
|
||||
val envelopeUnassign = BbbCoreEnvelope(PresenterUnassignedEvtMsg.NAME, routingUnassign)
|
||||
val headerUnassign = BbbClientMsgHeader(PresenterUnassignedEvtMsg.NAME, this.liveMeeting.props.meetingProp.intId,
|
||||
oldPres.intId)
|
||||
@ -22,8 +24,10 @@ trait AssignPresenterReqMsgHdlr {
|
||||
outGW.send(msgEventUnassign)
|
||||
|
||||
// set new presenter
|
||||
val routingAssign = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
this.liveMeeting.props.meetingProp.intId, newPres.intId)
|
||||
val routingAssign = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
this.liveMeeting.props.meetingProp.intId, newPres.intId
|
||||
)
|
||||
val envelopeAssign = BbbCoreEnvelope(PresenterAssignedEvtMsg.NAME, routingAssign)
|
||||
val headerAssign = BbbClientMsgHeader(PresenterAssignedEvtMsg.NAME, this.liveMeeting.props.meetingProp.intId,
|
||||
newPres.intId)
|
||||
|
@ -19,8 +19,10 @@ trait EjectUserFromMeetingCmdMsgHdlr {
|
||||
RegisteredUsers.remove(msg.body.userId, liveMeeting.registeredUsers)
|
||||
|
||||
// send a message to client
|
||||
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(liveMeeting.props.meetingProp.intId,
|
||||
user.intId, msg.body.ejectedBy)
|
||||
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
user.intId, msg.body.ejectedBy
|
||||
)
|
||||
outGW.send(ejectFromMeetingClientEvent)
|
||||
log.info("Ejecting user from meeting (client msg). meetingId=" + liveMeeting.props.meetingProp.intId +
|
||||
" userId=" + msg.body.userId)
|
||||
@ -39,8 +41,10 @@ trait EjectUserFromMeetingCmdMsgHdlr {
|
||||
for {
|
||||
vu <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
|
||||
} yield {
|
||||
val ejectFromVoiceEvent = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(liveMeeting.props.meetingProp.intId,
|
||||
liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId)
|
||||
val ejectFromVoiceEvent = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId
|
||||
)
|
||||
outGW.send(ejectFromVoiceEvent)
|
||||
log.info("Ejecting user from voice. meetingId=" + liveMeeting.props.meetingProp.intId + " userId=" + vu.intId)
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.bigbluebutton.core.apps.users
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import akka.event.Logging
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
import org.bigbluebutton.core2.message.handlers.users.ValidateAuthTokenReqMsgHdlr
|
||||
|
||||
class UsersApp(
|
||||
val liveMeeting: LiveMeeting,
|
||||
val outGW: OutMessageGateway
|
||||
)(implicit val context: ActorContext)
|
||||
|
||||
extends ValidateAuthTokenReqMsgHdlr {
|
||||
|
||||
val log = Logging(context.system, getClass)
|
||||
}
|
@ -7,7 +7,6 @@ trait UsersApp2x
|
||||
extends RegisterUserReqMsgHdlr
|
||||
with ChangeUserRoleCmdMsgHdlr
|
||||
with SyncGetUsersMeetingRespMsgHdlr
|
||||
with ValidateAuthTokenReqMsgHdlr
|
||||
with UserLeaveReqMsgHdlr
|
||||
with LogoutAndEndMeetingCmdMsgHdlr
|
||||
with MeetingActivityResponseCmdMsgHdlr
|
||||
|
@ -17,11 +17,15 @@ trait UserJoinedVoiceConfEvtMsgHdlr {
|
||||
log.warning("Received user joined voice conference " + msg)
|
||||
|
||||
def broadcastEvent(voiceUserState: VoiceUserState): Unit = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, voiceUserState.intId)
|
||||
val routing = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId, voiceUserState.intId
|
||||
)
|
||||
val envelope = BbbCoreEnvelope(UserJoinedVoiceConfToClientEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(UserJoinedVoiceConfToClientEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, voiceUserState.intId)
|
||||
val header = BbbClientMsgHeader(
|
||||
UserJoinedVoiceConfToClientEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, voiceUserState.intId
|
||||
)
|
||||
|
||||
val body = UserJoinedVoiceConfToClientEvtMsgBody(intId = voiceUserState.intId, voiceUserId = voiceUserState.voiceUserId,
|
||||
callerName = voiceUserState.callerName, callerNum = voiceUserState.callerNum, muted = voiceUserState.muted,
|
||||
|
@ -46,8 +46,10 @@ trait UserLeftVoiceConfEvtMsgHdlr {
|
||||
log.info("Send STOP RECORDING voice conf. meetingId=" + liveMeeting.props.meetingProp.intId
|
||||
+ " voice conf=" + liveMeeting.props.voiceProp.voiceConf)
|
||||
|
||||
val event = buildStopRecordingVoiceConfSysMsg(liveMeeting.props.meetingProp.intId,
|
||||
liveMeeting.props.voiceProp.voiceConf, MeetingStatus2x.getVoiceRecordingFilename(liveMeeting.status))
|
||||
val event = buildStopRecordingVoiceConfSysMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
liveMeeting.props.voiceProp.voiceConf, MeetingStatus2x.getVoiceRecordingFilename(liveMeeting.status)
|
||||
)
|
||||
outGW.send(event)
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,16 @@ trait UserMutedInVoiceConfEvtMsgHdlr {
|
||||
def handleUserMutedInVoiceConfEvtMsg(msg: UserMutedInVoiceConfEvtMsg): Unit = {
|
||||
|
||||
def broadcastEvent(vu: VoiceUserState): Unit = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
val routing = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
vu.intId)
|
||||
vu.intId
|
||||
)
|
||||
val envelope = BbbCoreEnvelope(UserMutedVoiceEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(UserMutedVoiceEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, vu.intId)
|
||||
val header = BbbClientMsgHeader(
|
||||
UserMutedVoiceEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, vu.intId
|
||||
)
|
||||
|
||||
val body = UserMutedVoiceEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId, vu.muted)
|
||||
|
||||
|
@ -14,12 +14,16 @@ trait UserTalkingInVoiceConfEvtMsgHdlr {
|
||||
def handleUserTalkingInVoiceConfEvtMsg(msg: UserTalkingInVoiceConfEvtMsg): Unit = {
|
||||
|
||||
def broadcastEvent(vu: VoiceUserState): Unit = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
|
||||
val routing = Routing.addMsgToClientRouting(
|
||||
MessageTypes.BROADCAST_TO_MEETING,
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
vu.intId)
|
||||
vu.intId
|
||||
)
|
||||
val envelope = BbbCoreEnvelope(UserTalkingVoiceEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(UserTalkingVoiceEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, vu.intId)
|
||||
val header = BbbClientMsgHeader(
|
||||
UserTalkingVoiceEvtMsg.NAME,
|
||||
liveMeeting.props.meetingProp.intId, vu.intId
|
||||
)
|
||||
|
||||
val body = UserTalkingVoiceEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId, vu.talking)
|
||||
|
||||
|
16
akka-bbb-apps/src/main/scala/org/bigbluebutton/core/bus/InMsgBusGW.scala
Executable file
16
akka-bbb-apps/src/main/scala/org/bigbluebutton/core/bus/InMsgBusGW.scala
Executable file
@ -0,0 +1,16 @@
|
||||
package org.bigbluebutton.core.bus
|
||||
import akka.actor.ActorRef
|
||||
|
||||
class InMsgBusGW(bus: IncomingEventBusImp) extends IncomingEventBus {
|
||||
override def publish(event: BigBlueButtonEvent): Unit = {
|
||||
bus.publish(event)
|
||||
}
|
||||
|
||||
override def subscribe(actorRef: ActorRef, topic: String): Unit = {
|
||||
bus.subscribe(actorRef, topic)
|
||||
}
|
||||
|
||||
override def unsubscribe(actorRef: ActorRef, topic: String): Unit = {
|
||||
bus.unsubscribe(actorRef, topic)
|
||||
}
|
||||
}
|
@ -1,33 +1,14 @@
|
||||
package org.bigbluebutton.core.bus
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.event.EventBus
|
||||
import akka.event.LookupClassification
|
||||
import org.bigbluebutton.core.api.InMessage
|
||||
|
||||
case class BigBlueButtonEvent(val topic: String, val payload: InMessage)
|
||||
|
||||
class IncomingEventBus extends EventBus with LookupClassification {
|
||||
type Event = BigBlueButtonEvent
|
||||
type Classifier = String
|
||||
type Subscriber = ActorRef
|
||||
trait IncomingEventBus {
|
||||
|
||||
// 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
|
||||
def publish(event: BigBlueButtonEvent): Unit
|
||||
def subscribe(actorRef: ActorRef, topic: String)
|
||||
def unsubscribe(actorRef: ActorRef, topic: String)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
package org.bigbluebutton.core.bus
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.event.EventBus
|
||||
import akka.event.LookupClassification
|
||||
|
||||
class IncomingEventBusImp extends EventBus with LookupClassification {
|
||||
type Event = BigBlueButtonEvent
|
||||
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
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.bigbluebutton.core.domain
|
||||
|
||||
case class MeetingInactivityTracker(
|
||||
maxInactivityTimeoutMinutes: Int,
|
||||
warningMinutesBeforeMax: Int,
|
||||
lastActivityTime: Long,
|
||||
warningSent: Boolean,
|
||||
warningSentOn: Long
|
||||
)
|
||||
|
||||
case class MeetingExpiryTracker(lastUserLeftOn: Long)
|
@ -4,71 +4,80 @@ import com.softwaremill.quicklens._
|
||||
import org.bigbluebutton.core.api.Permissions
|
||||
|
||||
case class MeetingProperties(
|
||||
id: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
recorded: Boolean,
|
||||
voiceConf: String,
|
||||
duration: Int,
|
||||
autoStartRecording: Boolean,
|
||||
id: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
recorded: Boolean,
|
||||
voiceConf: String,
|
||||
duration: Int,
|
||||
autoStartRecording: Boolean,
|
||||
allowStartStopRecording: Boolean,
|
||||
moderatorPass: String,
|
||||
viewerPass: String,
|
||||
createTime: Long,
|
||||
createDate: String,
|
||||
isBreakout: Boolean)
|
||||
moderatorPass: String,
|
||||
viewerPass: String,
|
||||
createTime: Long,
|
||||
createDate: String,
|
||||
isBreakout: Boolean
|
||||
)
|
||||
|
||||
case class MeetingProperties2x(
|
||||
id: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
voiceConf: String,
|
||||
duration: Int,
|
||||
maxUsers: Int,
|
||||
id: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
voiceConf: String,
|
||||
duration: Int,
|
||||
maxUsers: Int,
|
||||
allowVoiceOnly: Boolean,
|
||||
isBreakout: Boolean,
|
||||
extensionProp: MeetingExtensionProp,
|
||||
recordingProp: MeetingRecordingProp)
|
||||
isBreakout: Boolean,
|
||||
extensionProp: MeetingExtensionProp,
|
||||
recordingProp: MeetingRecordingProp
|
||||
)
|
||||
|
||||
case class MeetingRecordingProp(
|
||||
recorded: Boolean = false,
|
||||
autoStartRecording: Boolean = false,
|
||||
allowStartStopRecording: Boolean = true)
|
||||
recorded: Boolean = false,
|
||||
autoStartRecording: Boolean = false,
|
||||
allowStartStopRecording: Boolean = true
|
||||
)
|
||||
|
||||
case class MeetingExtensionProp(
|
||||
maxExtensions: Int = 0,
|
||||
extendByMinutes: Int = 20,
|
||||
sendNotice: Boolean = true)
|
||||
maxExtensions: Int = 0,
|
||||
extendByMinutes: Int = 20,
|
||||
sendNotice: Boolean = true
|
||||
)
|
||||
|
||||
case class MeetingRecordingStatus(
|
||||
recording: Boolean = false,
|
||||
voiceRecordingFilename: String = "")
|
||||
recording: Boolean = false,
|
||||
voiceRecordingFilename: String = ""
|
||||
)
|
||||
|
||||
case class MeetingExtensionStatus(
|
||||
numExtensions: Int = 0,
|
||||
numExtensions: Int = 0,
|
||||
sent15MinNotice: Boolean = false,
|
||||
sent10MinNotice: Boolean = false,
|
||||
sent5MinNotice: Boolean = false)
|
||||
sent5MinNotice: Boolean = false
|
||||
)
|
||||
|
||||
case class Meeting3x(permissions: Permissions,
|
||||
isRecording: Boolean = false,
|
||||
muted: Boolean = false,
|
||||
ended: Boolean = false,
|
||||
hasLastWebUserLeft: Boolean = false,
|
||||
lastWebUserLeftOnTimestamp: Long = 0L,
|
||||
voiceRecordingFilename: String = "",
|
||||
startedOn: Long = 0L,
|
||||
pinNumbers: Set[String] = Set.empty,
|
||||
lastGeneratedPin: Int = 0,
|
||||
breakoutRoomsStartedOn: Long = 0L,
|
||||
breakoutRoomsDurationInMinutes: Int = 120,
|
||||
extensionStatus: MeetingExtensionStatus = new MeetingExtensionStatus,
|
||||
recordingStatus: MeetingRecordingStatus = new MeetingRecordingStatus)
|
||||
case class Meeting3x(
|
||||
permissions: Permissions,
|
||||
isRecording: Boolean = false,
|
||||
muted: Boolean = false,
|
||||
ended: Boolean = false,
|
||||
hasLastWebUserLeft: Boolean = false,
|
||||
lastWebUserLeftOnTimestamp: Long = 0L,
|
||||
voiceRecordingFilename: String = "",
|
||||
startedOn: Long = 0L,
|
||||
pinNumbers: Set[String] = Set.empty,
|
||||
lastGeneratedPin: Int = 0,
|
||||
breakoutRoomsStartedOn: Long = 0L,
|
||||
breakoutRoomsDurationInMinutes: Int = 120,
|
||||
extensionStatus: MeetingExtensionStatus = new MeetingExtensionStatus,
|
||||
recordingStatus: MeetingRecordingStatus = new MeetingRecordingStatus
|
||||
)
|
||||
|
||||
object Meeting3x {
|
||||
def isExtensionAllowed(
|
||||
extension: MeetingExtensionProp,
|
||||
status: MeetingExtensionStatus): Boolean = status.numExtensions < extension.maxExtensions
|
||||
status: MeetingExtensionStatus
|
||||
): Boolean = status.numExtensions < extension.maxExtensions
|
||||
|
||||
def incNumExtension(extension: MeetingExtensionProp, status: MeetingExtensionStatus): MeetingExtensionStatus = {
|
||||
if (status.numExtensions < extension.maxExtensions) {
|
||||
|
@ -18,8 +18,10 @@ object Util {
|
||||
header
|
||||
}
|
||||
|
||||
def buildJson(header: java.util.HashMap[String, Any],
|
||||
payload: java.util.HashMap[String, Any]): String = {
|
||||
def buildJson(
|
||||
header: java.util.HashMap[String, Any],
|
||||
payload: java.util.HashMap[String, Any]
|
||||
): String = {
|
||||
|
||||
val message = new java.util.HashMap[String, java.util.HashMap[String, Any]]()
|
||||
message.put(Constants.HEADER, header)
|
||||
|
@ -10,7 +10,7 @@ object BreakoutRooms {
|
||||
def breakoutRoomsdurationInMinutes(status: BreakoutRooms, duration: Int) = status.breakoutRoomsdurationInMinutes = duration
|
||||
|
||||
def newBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String,
|
||||
assignedUsers: Vector[String], breakoutRooms: BreakoutRooms): Option[BreakoutRoomVO] = {
|
||||
assignedUsers: Vector[String], breakoutRooms: BreakoutRooms): Option[BreakoutRoomVO] = {
|
||||
val brvo = new BreakoutRoomVO(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector())
|
||||
breakoutRooms.add(brvo)
|
||||
Some(brvo)
|
||||
|
@ -101,7 +101,7 @@ object Polls {
|
||||
}
|
||||
|
||||
def handleRespondToPollReqMsg(requesterId: String, pollId: String, questionId: Int, answerId: Int,
|
||||
lm: LiveMeeting): Option[(String, String, SimplePollResultOutVO)] = {
|
||||
lm: LiveMeeting): Option[(String, String, SimplePollResultOutVO)] = {
|
||||
|
||||
for {
|
||||
curPres <- Users2x.findPresenter(lm.users2x)
|
||||
@ -114,7 +114,7 @@ object Polls {
|
||||
}
|
||||
|
||||
def handleStartCustomPollReqMsg(requesterId: String, pollId: String, pollType: String,
|
||||
answers: Seq[String], lm: LiveMeeting): Option[SimplePollOutVO] = {
|
||||
answers: Seq[String], lm: LiveMeeting): Option[SimplePollOutVO] = {
|
||||
|
||||
def createPoll(pollId: String, numRespondents: Int): Option[Poll] = {
|
||||
for {
|
||||
@ -142,7 +142,7 @@ object Polls {
|
||||
// Helper methods:
|
||||
//
|
||||
private def handleRespondToPoll(poll: SimplePollResultOutVO, requesterId: String, pollId: String, questionId: Int,
|
||||
answerId: Int, lm: LiveMeeting): Option[SimplePollResultOutVO] = {
|
||||
answerId: Int, lm: LiveMeeting): Option[SimplePollResultOutVO] = {
|
||||
/*
|
||||
* Hardcode to zero as we are assuming the poll has only one question.
|
||||
* Our data model supports multiple question polls but for this
|
||||
|
@ -5,8 +5,8 @@ import com.softwaremill.quicklens._
|
||||
|
||||
object RegisteredUsers {
|
||||
def create(userId: String, extId: String, name: String, roles: String,
|
||||
token: String, avatar: String, guest: Boolean, authenticated: Boolean,
|
||||
waitingForAcceptance: Boolean, users: RegisteredUsers): RegisteredUser = {
|
||||
token: String, avatar: String, guest: Boolean, authenticated: Boolean,
|
||||
waitingForAcceptance: Boolean, users: RegisteredUsers): RegisteredUser = {
|
||||
val ru = new RegisteredUser(userId, extId, name, roles, token, avatar, guest, authenticated, waitingForAcceptance)
|
||||
users.save(ru)
|
||||
ru
|
||||
@ -48,7 +48,7 @@ object RegisteredUsers {
|
||||
}
|
||||
|
||||
def setWaitingForApproval(users: RegisteredUsers, user: RegisteredUser,
|
||||
waitingForApproval: Boolean): RegisteredUser = {
|
||||
waitingForApproval: Boolean): RegisteredUser = {
|
||||
val u = user.modify(_.waitingForAcceptance).setTo(waitingForApproval)
|
||||
users.save(u)
|
||||
u
|
||||
@ -74,6 +74,6 @@ class RegisteredUsers {
|
||||
}
|
||||
|
||||
case class RegisteredUser(id: String, externId: String, name: String, role: String,
|
||||
authToken: String, avatarURL: String, guest: Boolean,
|
||||
authed: Boolean, waitingForAcceptance: Boolean)
|
||||
authToken: String, avatarURL: String, guest: Boolean,
|
||||
authed: Boolean, waitingForAcceptance: Boolean)
|
||||
|
||||
|
@ -88,7 +88,7 @@ object Users2x {
|
||||
def hasPresenter(users: Users2x): Boolean = {
|
||||
findPresenter(users) match {
|
||||
case Some(p) => true
|
||||
case None => false
|
||||
case None => false
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,8 +144,8 @@ class Users2x {
|
||||
}
|
||||
|
||||
case class UserState(intId: String, extId: String, name: String, role: String,
|
||||
guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emoji: String, locked: Boolean,
|
||||
presenter: Boolean, avatar: String)
|
||||
guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emoji: String, locked: Boolean,
|
||||
presenter: Boolean, avatar: String)
|
||||
|
||||
case class UserIdAndName(id: String, name: String)
|
||||
|
||||
|
@ -5,17 +5,19 @@ case class Status(isPresenter: Boolean = false, emojiStatus: String = "none")
|
||||
case class CallerId(num: String = "", name: String = "")
|
||||
|
||||
case class Voice(
|
||||
hasJoined: Boolean = false,
|
||||
id: String = "",
|
||||
callerId: CallerId = CallerId(),
|
||||
muted: Boolean = false,
|
||||
talking: Boolean = false,
|
||||
locked: Boolean = false)
|
||||
hasJoined: Boolean = false,
|
||||
id: String = "",
|
||||
callerId: CallerId = CallerId(),
|
||||
muted: Boolean = false,
|
||||
talking: Boolean = false,
|
||||
locked: Boolean = false
|
||||
)
|
||||
|
||||
case class UserV(
|
||||
id: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
role: String = Roles.VIEWER_ROLE,
|
||||
id: String,
|
||||
extId: String,
|
||||
name: String,
|
||||
role: String = Roles.VIEWER_ROLE,
|
||||
status: Status = Status(),
|
||||
voice: Voice = Voice())
|
||||
voice: Voice = Voice()
|
||||
)
|
@ -118,8 +118,8 @@ class VoiceUsers {
|
||||
|
||||
case class VoiceUser2x(intId: String, voiceUserId: String)
|
||||
case class VoiceUserVO2x(intId: String, voiceUserId: String, callerName: String,
|
||||
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
|
||||
talking: Boolean, callingWith: String, listenOnly: Boolean)
|
||||
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
|
||||
talking: Boolean, callingWith: String, listenOnly: Boolean)
|
||||
|
||||
case class VoiceUserState(intId: String, voiceUserId: String, callingWith: String, callerName: String,
|
||||
callerNum: String, muted: Boolean, talking: Boolean, listenOnly: Boolean)
|
||||
callerNum: String, muted: Boolean, talking: Boolean, listenOnly: Boolean)
|
@ -14,8 +14,9 @@ object ReceivedJsonMsgHandlerActor {
|
||||
}
|
||||
|
||||
class ReceivedJsonMsgHandlerActor(
|
||||
val eventBus: BbbMsgRouterEventBus,
|
||||
val incomingJsonMessageBus: IncomingJsonMessageBus)
|
||||
val eventBus: BbbMsgRouterEventBus,
|
||||
val incomingJsonMessageBus: IncomingJsonMessageBus
|
||||
)
|
||||
extends Actor with ActorLogging
|
||||
with SystemConfiguration
|
||||
with ReceivedJsonMsgDeserializer
|
||||
|
@ -0,0 +1,55 @@
|
||||
package org.bigbluebutton.core.running
|
||||
|
||||
import org.bigbluebutton.common2.domain.DefaultProps
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.api.BreakoutRoomCreated
|
||||
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, IncomingEventBus }
|
||||
|
||||
trait AuditHelpers {
|
||||
|
||||
def getUsersInVoiceConf(
|
||||
props: DefaultProps,
|
||||
outGW: OutMessageGateway
|
||||
): Unit = {
|
||||
def buildGetUsersInVoiceConfSysMsg(meetingId: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(GetUsersInVoiceConfSysMsg.NAME, routing)
|
||||
val body = GetUsersInVoiceConfSysMsgBody(props.voiceProp.voiceConf)
|
||||
val header = BbbCoreHeaderWithMeetingId(GetUsersInVoiceConfSysMsg.NAME, meetingId)
|
||||
val event = GetUsersInVoiceConfSysMsg(header, body)
|
||||
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = buildGetUsersInVoiceConfSysMsg(props.meetingProp.intId)
|
||||
outGW.send(event)
|
||||
}
|
||||
|
||||
def sendBreakoutRoomCreatedToParent(
|
||||
props: DefaultProps,
|
||||
eventBus: IncomingEventBus
|
||||
): Unit = {
|
||||
eventBus.publish(BigBlueButtonEvent(
|
||||
props.breakoutProps.parentId,
|
||||
BreakoutRoomCreated(props.breakoutProps.parentId, props.meetingProp.intId)
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
|
||||
def sendMeetingIsActive(props: DefaultProps, outGW: OutMessageGateway): Unit = {
|
||||
def buildMeetingIsActiveEvtMsg(meetingId: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(MeetingIsActiveEvtMsg.NAME, routing)
|
||||
val body = MeetingIsActiveEvtMsgBody(meetingId)
|
||||
val header = BbbClientMsgHeader(MeetingIsActiveEvtMsg.NAME, meetingId, "not-used")
|
||||
val event = MeetingIsActiveEvtMsg(header, body)
|
||||
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = buildMeetingIsActiveEvtMsg(props.meetingProp.intId)
|
||||
outGW.send(event)
|
||||
}
|
||||
}
|
@ -8,26 +8,29 @@ import org.bigbluebutton.core2.MeetingStatus2x
|
||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender, UserJoinedMeetingEvtMsgBuilder }
|
||||
|
||||
trait HandlerHelpers {
|
||||
// this: BaseMeetingActor =>
|
||||
|
||||
def validateTokenFailed(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String,
|
||||
valid: Boolean, waitForApproval: Boolean): Unit = {
|
||||
val event = MsgBuilder.buildValidateAuthTokenRespMsg(meetingId,
|
||||
userId, authToken, valid, waitForApproval)
|
||||
valid: Boolean, waitForApproval: Boolean): Unit = {
|
||||
val event = MsgBuilder.buildValidateAuthTokenRespMsg(
|
||||
meetingId,
|
||||
userId, authToken, valid, waitForApproval
|
||||
)
|
||||
Sender.send(outGW, event)
|
||||
|
||||
// TODO: Should disconnect user here.
|
||||
}
|
||||
|
||||
def sendValidateAuthTokenRespMsg(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String,
|
||||
valid: Boolean, waitForApproval: Boolean): Unit = {
|
||||
val event = MsgBuilder.buildValidateAuthTokenRespMsg(meetingId,
|
||||
userId, authToken, valid, waitForApproval)
|
||||
valid: Boolean, waitForApproval: Boolean): Unit = {
|
||||
val event = MsgBuilder.buildValidateAuthTokenRespMsg(
|
||||
meetingId,
|
||||
userId, authToken, valid, waitForApproval
|
||||
)
|
||||
Sender.send(outGW, event)
|
||||
}
|
||||
|
||||
def userValidatedButNeedToWaitForApproval(outGW: OutMessageGateway, liveMeeting: LiveMeeting,
|
||||
user: RegisteredUser): Unit = {
|
||||
user: RegisteredUser): Unit = {
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
sendValidateAuthTokenRespMsg(outGW, meetingId, user.id, user.authToken, valid = true, waitForApproval = false)
|
||||
|
||||
@ -40,8 +43,11 @@ trait HandlerHelpers {
|
||||
GuestsWaiting.add(guestsWaitingList, guest)
|
||||
}
|
||||
|
||||
def userValidatedAndNoNeedToWaitForApproval(outGW: OutMessageGateway, liveMeeting: LiveMeeting,
|
||||
user: RegisteredUser): Unit = {
|
||||
def userValidatedAndNoNeedToWaitForApproval(
|
||||
outGW: OutMessageGateway,
|
||||
liveMeeting: LiveMeeting,
|
||||
user: RegisteredUser
|
||||
): Unit = {
|
||||
|
||||
println("**************** userValidatedAndNoNeedToWaitForApproval")
|
||||
|
||||
@ -95,8 +101,8 @@ trait HandlerHelpers {
|
||||
}
|
||||
|
||||
def sendAllVoiceUsersInMeeting(outGW: OutMessageGateway, requesterId: String,
|
||||
voiceUsers: VoiceUsers,
|
||||
meetingId: String): Unit = {
|
||||
voiceUsers: VoiceUsers,
|
||||
meetingId: String): Unit = {
|
||||
|
||||
val vu = VoiceUsers.findAll(voiceUsers).map { u =>
|
||||
VoiceConfUser(intId = u.intId, voiceUserId = u.voiceUserId, callingWith = u.callingWith, callerName = u.callerName,
|
||||
@ -111,7 +117,8 @@ trait HandlerHelpers {
|
||||
for {
|
||||
regUser <- RegisteredUsers.findWithToken(authToken, liveMeeting.registeredUsers)
|
||||
} yield {
|
||||
val userState = UserState(intId = regUser.id,
|
||||
val userState = UserState(
|
||||
intId = regUser.id,
|
||||
extId = regUser.externId,
|
||||
name = regUser.name,
|
||||
role = regUser.role,
|
||||
@ -121,7 +128,8 @@ trait HandlerHelpers {
|
||||
emoji = "none",
|
||||
presenter = false,
|
||||
locked = false,
|
||||
avatar = regUser.avatarURL)
|
||||
avatar = regUser.avatarURL
|
||||
)
|
||||
|
||||
Users2x.add(liveMeeting.users2x, userState)
|
||||
|
||||
|
@ -9,24 +9,26 @@ import org.bigbluebutton.core.domain.Meeting3x
|
||||
import org.bigbluebutton.core.models._
|
||||
import org.bigbluebutton.core2.MeetingStatus2x
|
||||
|
||||
class LiveMeeting(val props: DefaultProps,
|
||||
val status: MeetingStatus2x,
|
||||
class LiveMeeting(
|
||||
val props: DefaultProps,
|
||||
val status: MeetingStatus2x,
|
||||
val screenshareModel: ScreenshareModel,
|
||||
val chatModel: ChatModel,
|
||||
val layoutModel: LayoutModel,
|
||||
val layouts: Layouts,
|
||||
val registeredUsers: RegisteredUsers,
|
||||
val polls: Polls, // 2x
|
||||
val pollModel: PollModel, // 1.1x
|
||||
val wbModel: WhiteboardModel,
|
||||
val presModel: PresentationModel,
|
||||
val breakoutRooms: BreakoutRooms,
|
||||
val captionModel: CaptionModel,
|
||||
val notesModel: SharedNotesModel,
|
||||
val webcams: Webcams,
|
||||
val voiceUsers: VoiceUsers,
|
||||
val users2x: Users2x,
|
||||
val guestsWaiting: GuestsWaiting) {
|
||||
val chatModel: ChatModel,
|
||||
val layoutModel: LayoutModel,
|
||||
val layouts: Layouts,
|
||||
val registeredUsers: RegisteredUsers,
|
||||
val polls: Polls, // 2x
|
||||
val pollModel: PollModel, // 1.1x
|
||||
val wbModel: WhiteboardModel,
|
||||
val presModel: PresentationModel,
|
||||
val breakoutRooms: BreakoutRooms,
|
||||
val captionModel: CaptionModel,
|
||||
val notesModel: SharedNotesModel,
|
||||
val webcams: Webcams,
|
||||
val voiceUsers: VoiceUsers,
|
||||
val users2x: Users2x,
|
||||
val guestsWaiting: GuestsWaiting
|
||||
) {
|
||||
|
||||
def hasMeetingEnded(): Boolean = {
|
||||
MeetingStatus2x.hasMeetingEnded(status)
|
||||
|
@ -1,6 +1,9 @@
|
||||
package org.bigbluebutton.core.running
|
||||
|
||||
import java.io.{ PrintWriter, StringWriter }
|
||||
|
||||
import org.bigbluebutton.core.apps.users.UsersApp
|
||||
import org.bigbluebutton.core.domain.MeetingInactivityTracker
|
||||
//import java.util.concurrent.TimeUnit
|
||||
|
||||
import akka.actor._
|
||||
@ -33,16 +36,21 @@ import org.bigbluebutton.core.apps.layout.LayoutApp2x
|
||||
import org.bigbluebutton.core.apps.meeting.SyncGetMeetingInfoRespMsgHdlr
|
||||
|
||||
object MeetingActor {
|
||||
def props(props: DefaultProps,
|
||||
eventBus: IncomingEventBus,
|
||||
outGW: OutMessageGateway, liveMeeting: LiveMeeting): Props =
|
||||
def props(
|
||||
props: DefaultProps,
|
||||
eventBus: IncomingEventBus,
|
||||
outGW: OutMessageGateway,
|
||||
liveMeeting: LiveMeeting
|
||||
): Props =
|
||||
Props(classOf[MeetingActor], props, eventBus, outGW, liveMeeting)
|
||||
}
|
||||
|
||||
class MeetingActor(val props: DefaultProps,
|
||||
val eventBus: IncomingEventBus,
|
||||
val outGW: OutMessageGateway,
|
||||
val liveMeeting: LiveMeeting)
|
||||
class MeetingActor(
|
||||
val props: DefaultProps,
|
||||
val eventBus: IncomingEventBus,
|
||||
val outGW: OutMessageGateway,
|
||||
val liveMeeting: LiveMeeting
|
||||
)
|
||||
extends BaseMeetingActor
|
||||
with GuestsApp
|
||||
with LayoutApp2x
|
||||
@ -83,19 +91,19 @@ class MeetingActor(val props: DefaultProps,
|
||||
* Put the internal message injector into another actor so this
|
||||
* actor is easy to test.
|
||||
*/
|
||||
var actorMonitor = context.actorOf(MeetingActorInternal.props(props, eventBus, outGW),
|
||||
"actorMonitor-" + props.meetingProp.intId)
|
||||
var actorMonitor = context.actorOf(
|
||||
MeetingActorInternal.props(props, eventBus, outGW),
|
||||
"actorMonitor-" + props.meetingProp.intId
|
||||
)
|
||||
|
||||
/** Subscribe to meeting and voice events. **/
|
||||
eventBus.subscribe(actorMonitor, props.meetingProp.intId)
|
||||
eventBus.subscribe(actorMonitor, props.voiceProp.voiceConf)
|
||||
eventBus.subscribe(actorMonitor, props.screenshareProps.screenshareConf)
|
||||
val presentationApp2x = new PresentationApp2x(liveMeeting, outGW)
|
||||
val screenshareApp2x = new ScreenshareApp2x(liveMeeting, outGW)
|
||||
val captionApp2x = new CaptionApp2x(liveMeeting, outGW)
|
||||
val sharedNotesApp2x = new SharedNotesApp2x(liveMeeting, outGW)
|
||||
val chatApp2x = new ChatApp2x(liveMeeting, outGW)
|
||||
val usersApp = new UsersApp(liveMeeting, outGW)
|
||||
|
||||
val presentationApp2x = new PresentationApp2x(liveMeeting, outGW = outGW)
|
||||
val screenshareApp2x = new ScreenshareApp2x(liveMeeting, outGW = outGW)
|
||||
val captionApp2x = new CaptionApp2x(liveMeeting, outGW = outGW)
|
||||
val sharedNotesApp2x = new SharedNotesApp2x(liveMeeting, outGW = outGW)
|
||||
val chatApp2x = new ChatApp2x(liveMeeting, outGW = outGW)
|
||||
//var inactivityTracker = new MeetingInactivityTracker()
|
||||
|
||||
/*******************************************************************/
|
||||
//object FakeTestData extends FakeTestData
|
||||
@ -105,42 +113,44 @@ class MeetingActor(val props: DefaultProps,
|
||||
def receive = {
|
||||
//=============================
|
||||
// 2x messages
|
||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||
|
||||
// Handling RegisterUserReqMsg as it is forwarded from BBBActor and
|
||||
// its type is not BbbCommonEnvCoreMsg
|
||||
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
|
||||
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
|
||||
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
|
||||
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
|
||||
|
||||
// Meeting
|
||||
case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m)
|
||||
case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m)
|
||||
|
||||
//======================================
|
||||
|
||||
//=======================================
|
||||
// old messages
|
||||
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
|
||||
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
|
||||
|
||||
case msg: AllowUserToShareDesktop => handleAllowUserToShareDesktop(msg)
|
||||
case msg: InitializeMeeting => handleInitializeMeeting(msg)
|
||||
case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg)
|
||||
case msg: SendTimeRemainingUpdate => handleSendTimeRemainingUpdate(msg)
|
||||
case msg: AllowUserToShareDesktop => handleAllowUserToShareDesktop(msg)
|
||||
case msg: InitializeMeeting => handleInitializeMeeting(msg)
|
||||
case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg)
|
||||
case msg: SendTimeRemainingUpdate => handleSendTimeRemainingUpdate(msg)
|
||||
|
||||
// Screenshare
|
||||
case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg)
|
||||
|
||||
// Guest
|
||||
case msg: GetGuestPolicy => handleGetGuestPolicy(msg)
|
||||
case msg: SetGuestPolicy => handleSetGuestPolicy(msg)
|
||||
case msg: GetGuestPolicy => handleGetGuestPolicy(msg)
|
||||
case msg: SetGuestPolicy => handleSetGuestPolicy(msg)
|
||||
|
||||
case _ => // do nothing
|
||||
case _ => // do nothing
|
||||
}
|
||||
|
||||
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
||||
// TODO: Update meeting activity status here
|
||||
// updateActivityStatus(msg)
|
||||
|
||||
msg.core match {
|
||||
// Users
|
||||
case m: ValidateAuthTokenReqMsg => handleValidateAuthTokenReqMsg(m)
|
||||
case m: ValidateAuthTokenReqMsg => usersApp.handleValidateAuthTokenReqMsg(m)
|
||||
case m: UserJoinMeetingReqMsg => handleUserJoinMeetingReqMsg(m)
|
||||
case m: UserLeaveReqMsg => handleUserLeaveReqMsg(m)
|
||||
case m: UserBroadcastCamStartMsg => handleUserBroadcastCamStartMsg(m)
|
||||
@ -362,8 +372,10 @@ class MeetingActor(val props: DefaultProps,
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = buildRecordingStatusChangedEvtMsg(liveMeeting.props.meetingProp.intId,
|
||||
"system", MeetingStatus2x.isRecording(liveMeeting.status))
|
||||
val event = buildRecordingStatusChangedEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
"system", MeetingStatus2x.isRecording(liveMeeting.status)
|
||||
)
|
||||
outGW.send(event)
|
||||
|
||||
}
|
||||
@ -385,8 +397,10 @@ class MeetingActor(val props: DefaultProps,
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = buildRecordingStatusChangedEvtMsg(liveMeeting.props.meetingProp.intId,
|
||||
"system", MeetingStatus2x.isRecording(liveMeeting.status))
|
||||
val event = buildRecordingStatusChangedEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
"system", MeetingStatus2x.isRecording(liveMeeting.status)
|
||||
)
|
||||
outGW.send(event)
|
||||
|
||||
}
|
||||
|
@ -20,17 +20,21 @@ import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration.{ Deadline, FiniteDuration }
|
||||
|
||||
object MeetingActorInternal {
|
||||
def props(props: DefaultProps,
|
||||
def props(
|
||||
props: DefaultProps,
|
||||
eventBus: IncomingEventBus,
|
||||
outGW: OutMessageGateway): Props =
|
||||
outGW: OutMessageGateway
|
||||
): Props =
|
||||
Props(classOf[MeetingActorInternal], props, eventBus, outGW)
|
||||
}
|
||||
|
||||
// This actor is an internal audit actor for each meeting actor that
|
||||
// periodically sends messages to the meeting actor
|
||||
class MeetingActorInternal(val props: DefaultProps,
|
||||
val eventBus: IncomingEventBus, val outGW: OutMessageGateway)
|
||||
extends Actor with ActorLogging with SystemConfiguration {
|
||||
class MeetingActorInternal(
|
||||
val props: DefaultProps,
|
||||
val eventBus: IncomingEventBus, val outGW: OutMessageGateway
|
||||
)
|
||||
extends Actor with ActorLogging with SystemConfiguration with AuditHelpers {
|
||||
|
||||
object AuditMonitorInternalMsg
|
||||
|
||||
@ -47,7 +51,7 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
private def getInactivityDeadline(): Int = {
|
||||
val time = getMetadata(Metadata.INACTIVITY_DEADLINE, props.metadataProp.metadata) match {
|
||||
case Some(result) => result.asInstanceOf[Int]
|
||||
case None => inactivityDeadline
|
||||
case None => inactivityDeadline
|
||||
}
|
||||
log.debug("InactivityDeadline: {} seconds", time)
|
||||
time
|
||||
@ -56,7 +60,7 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
private def getInactivityTimeLeft(): Int = {
|
||||
val time = getMetadata(Metadata.INACTIVITY_TIMELEFT, props.metadataProp.metadata) match {
|
||||
case Some(result) => result.asInstanceOf[Int]
|
||||
case None => inactivityTimeLeft
|
||||
case None => inactivityTimeLeft
|
||||
}
|
||||
log.debug("InactivityTimeLeft: {} seconds", time)
|
||||
time
|
||||
@ -78,7 +82,7 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
|
||||
private val InactivityDeadline = FiniteDuration(getInactivityDeadline(), "seconds")
|
||||
private val InactivityTimeLeft = FiniteDuration(getInactivityTimeLeft(), "seconds")
|
||||
private var inactivity = InactivityDeadline.fromNow
|
||||
private var inactivityDeadlineTime = InactivityDeadline.fromNow
|
||||
private var inactivityWarning: Option[Deadline] = None
|
||||
|
||||
private val ExpireMeetingDuration = FiniteDuration(props.durationProps.duration, "minutes")
|
||||
@ -91,30 +95,17 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
context.system.scheduler.schedule(5 seconds, MonitorFrequency, self, AuditMonitorInternalMsg)
|
||||
|
||||
// Query to get voice conference users
|
||||
def buildGetUsersInVoiceConfSysMsg(meetingId: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(GetUsersInVoiceConfSysMsg.NAME, routing)
|
||||
val body = GetUsersInVoiceConfSysMsgBody(props.voiceProp.voiceConf)
|
||||
val header = BbbCoreHeaderWithMeetingId(GetUsersInVoiceConfSysMsg.NAME, meetingId)
|
||||
val event = GetUsersInVoiceConfSysMsg(header, body)
|
||||
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = buildGetUsersInVoiceConfSysMsg(props.meetingProp.intId)
|
||||
outGW.send(event)
|
||||
getUsersInVoiceConf(props, outGW)
|
||||
|
||||
if (props.meetingProp.isBreakout) {
|
||||
// This is a breakout room. Inform our parent meeting that we have been successfully created.
|
||||
eventBus.publish(BigBlueButtonEvent(
|
||||
props.breakoutProps.parentId,
|
||||
BreakoutRoomCreated(props.breakoutProps.parentId, props.meetingProp.intId)))
|
||||
sendBreakoutRoomCreatedToParent(props, eventBus)
|
||||
}
|
||||
|
||||
def receive = {
|
||||
case AuditMonitorInternalMsg => handleMonitor()
|
||||
case AuditMonitorInternalMsg => handleMonitor()
|
||||
case msg: UpdateMeetingExpireMonitor => handleUpdateMeetingExpireMonitor(msg)
|
||||
case msg: Object => handleMessage(msg)
|
||||
case msg: Object => handleMessage(msg)
|
||||
}
|
||||
|
||||
def handleMonitor() {
|
||||
@ -146,28 +137,17 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
|
||||
inactivityWarning match {
|
||||
case Some(iw) =>
|
||||
if (inactivity.isOverdue() && iw.isOverdue()) {
|
||||
if (inactivityDeadlineTime.isOverdue() && iw.isOverdue()) {
|
||||
log.info("Closing meeting {} due to inactivity for {} seconds", props.meetingProp.intId, InactivityDeadline.toSeconds)
|
||||
updateInactivityMonitors()
|
||||
pushInactivityDeadline()
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
|
||||
// Or else make sure to send only one warning message
|
||||
}
|
||||
case None =>
|
||||
if (inactivity.isOverdue()) {
|
||||
if (inactivityDeadlineTime.isOverdue()) {
|
||||
log.info("Sending inactivity warning to meeting {}", props.meetingProp.intId)
|
||||
|
||||
def build(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(MeetingInactivityWarningEvtMsg.NAME, routing)
|
||||
val body = MeetingInactivityWarningEvtMsgBody(timeLeftInSec)
|
||||
val header = BbbClientMsgHeader(MeetingInactivityWarningEvtMsg.NAME, meetingId, "not-used")
|
||||
val event = MeetingInactivityWarningEvtMsg(header, body)
|
||||
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = build(props.meetingProp.intId, InactivityTimeLeft.toSeconds)
|
||||
outGW.send(event)
|
||||
sendMeetingInactivityWarning(props, outGW, InactivityTimeLeft.toSeconds)
|
||||
|
||||
// We add 5 seconds so clients will have enough time to process the message
|
||||
inactivityWarning = Some((InactivityTimeLeft + (5 seconds)).fromNow)
|
||||
@ -198,7 +178,6 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private def handleUpdateMeetingExpireMonitor(msg: UpdateMeetingExpireMonitor) {
|
||||
@ -215,8 +194,8 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
}
|
||||
}
|
||||
|
||||
private def updateInactivityMonitors() {
|
||||
inactivity = InactivityDeadline.fromNow
|
||||
private def pushInactivityDeadline() {
|
||||
inactivityDeadlineTime = InactivityDeadline.fromNow
|
||||
inactivityWarning = None
|
||||
}
|
||||
|
||||
@ -224,38 +203,26 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
for {
|
||||
_ <- inactivityWarning
|
||||
} yield {
|
||||
val event = buildMeetingIsActiveEvtMsg(props.meetingProp.intId)
|
||||
outGW.send(event)
|
||||
sendMeetingIsActive(props, outGW)
|
||||
}
|
||||
|
||||
updateInactivityMonitors()
|
||||
}
|
||||
|
||||
def buildMeetingIsActiveEvtMsg(meetingId: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(MeetingIsActiveEvtMsg.NAME, routing)
|
||||
val body = MeetingIsActiveEvtMsgBody(meetingId)
|
||||
val header = BbbClientMsgHeader(MeetingIsActiveEvtMsg.NAME, meetingId, "not-used")
|
||||
val event = MeetingIsActiveEvtMsg(header, body)
|
||||
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
pushInactivityDeadline()
|
||||
}
|
||||
|
||||
private def handleActivityResponse(msg: ActivityResponse) {
|
||||
log.info("User endorsed that meeting {} is active", props.meetingProp.intId)
|
||||
updateInactivityMonitors()
|
||||
val event = buildMeetingIsActiveEvtMsg(props.meetingProp.intId)
|
||||
outGW.send(event)
|
||||
pushInactivityDeadline()
|
||||
sendMeetingIsActive(props, outGW)
|
||||
}
|
||||
|
||||
private def isMeetingActivity(msg: Object): Boolean = {
|
||||
// We need to avoid all internal system's messages
|
||||
msg match {
|
||||
case msg: MonitorNumberOfUsers => false
|
||||
case msg: MonitorNumberOfUsers => false
|
||||
case msg: SendTimeRemainingUpdate => false
|
||||
case msg: SendBreakoutUsersUpdate => false
|
||||
case msg: BreakoutRoomCreated => false
|
||||
case _ => true
|
||||
case msg: BreakoutRoomCreated => false
|
||||
case _ => true
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,14 +239,14 @@ class MeetingActorInternal(val props: DefaultProps,
|
||||
// Can be defined between 1 minute to 6 hours
|
||||
metadataIntegerValueOf(v, 60, 21600) match {
|
||||
case Some(r) => Some(r.asInstanceOf[Object])
|
||||
case None => None
|
||||
case None => None
|
||||
}
|
||||
|
||||
case Metadata.INACTIVITY_TIMELEFT =>
|
||||
// Can be defined between 30 seconds to 30 minutes
|
||||
metadataIntegerValueOf(v, 30, 1800) match {
|
||||
case Some(r) => Some(r.asInstanceOf[Object])
|
||||
case None => None
|
||||
case None => None
|
||||
}
|
||||
|
||||
case _ => None
|
@ -0,0 +1,71 @@
|
||||
package org.bigbluebutton.core.running
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import org.bigbluebutton.core.domain.MeetingInactivityTracker
|
||||
import com.softwaremill.quicklens._
|
||||
import org.bigbluebutton.common2.domain.DefaultProps
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
|
||||
trait MeetingInactivityTrackerHelper {
|
||||
def shouldSendInactivityWarning(now: Long, tracker: MeetingInactivityTracker): Boolean = {
|
||||
(!tracker.warningSent) &&
|
||||
(tracker.lastActivityTime + tracker.maxInactivityTimeoutMinutes) < (now + tracker.warningMinutesBeforeMax)
|
||||
}
|
||||
|
||||
def isMeetingActive(now: Long, tracker: MeetingInactivityTracker): Boolean = {
|
||||
(now - tracker.lastActivityTime) < tracker.maxInactivityTimeoutMinutes
|
||||
}
|
||||
|
||||
def isMeetingInactive(now: Long, tracker: MeetingInactivityTracker): Boolean = {
|
||||
(tracker.warningSent) && (now - tracker.lastActivityTime) > tracker.maxInactivityTimeoutMinutes
|
||||
}
|
||||
|
||||
def processMeetingInactivityAudit(tracker: MeetingInactivityTracker): MeetingInactivityTracker = {
|
||||
val now = System.currentTimeMillis()
|
||||
if (isMeetingActive(now, tracker)) {
|
||||
tracker
|
||||
} else {
|
||||
if (isMeetingInactive(now, tracker)) {
|
||||
sendMeetingInactive
|
||||
endMeeting
|
||||
} else {
|
||||
warnOfMeetingInactivity(tracker)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def timeLeftInMinutes(nowInMins: Long, ) : Int = {
|
||||
|
||||
}
|
||||
|
||||
def nowInMinutes() : Long = {
|
||||
TimeUnit.MILLISECONDS.toMinutes(System.currentTimeMillis())
|
||||
}
|
||||
|
||||
def warnOfMeetingInactivity(now: Long, tracker: MeetingInactivityTracker): MeetingInactivityTracker = {
|
||||
if (tracker.warningSent) {
|
||||
tracker
|
||||
} else {
|
||||
val timeLeftSeconds = tracker.lastActivityTime + tracker.maxInactivityTimeoutMinutes - now
|
||||
sendMeetingInactivityWarning(props, outGW, timeLeftSeconds)
|
||||
tracker.modify(_.warningSent).setTo(true).modify(_.warningSentOn).setTo(System.currentTimeMillis())
|
||||
}
|
||||
}
|
||||
|
||||
def sendMeetingInactivityWarning(props: DefaultProps, outGW: OutMessageGateway, timeLeftSeconds: Long): Unit = {
|
||||
def build(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
|
||||
val envelope = BbbCoreEnvelope(MeetingInactivityWarningEvtMsg.NAME, routing)
|
||||
val body = MeetingInactivityWarningEvtMsgBody(timeLeftInSec)
|
||||
val header = BbbClientMsgHeader(MeetingInactivityWarningEvtMsg.NAME, meetingId, "not-used")
|
||||
val event = MeetingInactivityWarningEvtMsg(header, body)
|
||||
|
||||
BbbCommonEnvCoreMsg(envelope, event)
|
||||
}
|
||||
|
||||
val event = build(props.meetingProp.intId, timeLeftSeconds)
|
||||
outGW.send(event)
|
||||
}
|
||||
}
|
@ -10,12 +10,12 @@ import org.bigbluebutton.core2.MeetingStatus2x
|
||||
|
||||
object RunningMeeting {
|
||||
def apply(props: DefaultProps, outGW: OutMessageGateway,
|
||||
eventBus: IncomingEventBus)(implicit context: ActorContext) =
|
||||
eventBus: IncomingEventBus)(implicit context: ActorContext) =
|
||||
new RunningMeeting(props, outGW, eventBus)(context)
|
||||
}
|
||||
|
||||
class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
|
||||
val eventBus: IncomingEventBus)(implicit val context: ActorContext) {
|
||||
val eventBus: IncomingEventBus)(implicit val context: ActorContext) {
|
||||
|
||||
val chatModel = new ChatModel()
|
||||
val layoutModel = new LayoutModel()
|
||||
|
@ -12,7 +12,7 @@ object Model1x2xConverter {
|
||||
}
|
||||
|
||||
def defaultUserVO(intId: String, extId: String, name: String, role: String, guest: Boolean, authed: Boolean,
|
||||
waitingForAcceptance: Boolean, lockStatus: Boolean, vu: VoiceUserVO): UserVO = {
|
||||
waitingForAcceptance: Boolean, lockStatus: Boolean, vu: VoiceUserVO): UserVO = {
|
||||
new UserVO(intId, extId, name, role, guest, authed, waitingForAcceptance = waitingForAcceptance,
|
||||
emojiStatus = "none", presenter = false,
|
||||
hasStream = false, locked = lockStatus,
|
||||
|
@ -15,7 +15,7 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender)
|
||||
|
||||
def receive = {
|
||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||
case _ => log.warning("Cannot handle message ")
|
||||
case _ => log.warning("Cannot handle message ")
|
||||
}
|
||||
|
||||
def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
||||
@ -23,8 +23,8 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender)
|
||||
|
||||
msg.envelope.name match {
|
||||
case SyncGetPresentationInfoRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||
case SyncGetMeetingInfoRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||
case SyncGetUsersMeetingRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||
case SyncGetMeetingInfoRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||
case SyncGetUsersMeetingRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json)
|
||||
|
||||
// Sent to FreeSWITCH
|
||||
case ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME =>
|
||||
|
@ -11,13 +11,15 @@ trait ChangeLockSettingsInMeetingCmdMsgHdlr {
|
||||
val outGW: OutMessageGateway
|
||||
|
||||
def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg) {
|
||||
val settings = Permissions(disableCam = msg.body.disableCam,
|
||||
val settings = Permissions(
|
||||
disableCam = msg.body.disableCam,
|
||||
disableMic = msg.body.disableMic,
|
||||
disablePrivChat = msg.body.disablePrivChat,
|
||||
disablePubChat = msg.body.disablePubChat,
|
||||
lockedLayout = msg.body.lockedLayout,
|
||||
lockOnJoin = msg.body.lockOnJoin,
|
||||
lockOnJoinConfigurable = msg.body.lockOnJoinConfigurable)
|
||||
lockOnJoinConfigurable = msg.body.lockOnJoinConfigurable
|
||||
)
|
||||
|
||||
if (!liveMeeting.permissionsEqual(settings)) {
|
||||
liveMeeting.newPermissions(settings)
|
||||
@ -25,11 +27,13 @@ trait ChangeLockSettingsInMeetingCmdMsgHdlr {
|
||||
def build(meetingId: String, userId: String, settings: Permissions, setBy: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
|
||||
val envelope = BbbCoreEnvelope(LockSettingsInMeetingChangedEvtMsg.NAME, routing)
|
||||
val body = LockSettingsInMeetingChangedEvtMsgBody(disableCam = settings.disableCam,
|
||||
val body = LockSettingsInMeetingChangedEvtMsgBody(
|
||||
disableCam = settings.disableCam,
|
||||
disableMic = settings.disableMic, disablePrivChat = settings.disablePrivChat,
|
||||
disablePubChat = settings.disablePubChat, lockedLayout = settings.lockedLayout,
|
||||
lockOnJoin = settings.lockOnJoin, lockOnJoinConfigurable = settings.lockOnJoinConfigurable,
|
||||
setBy)
|
||||
setBy
|
||||
)
|
||||
val header = BbbClientMsgHeader(LockSettingsInMeetingChangedEvtMsg.NAME, meetingId, userId)
|
||||
val event = LockSettingsInMeetingChangedEvtMsg(header, body)
|
||||
|
||||
|
@ -30,7 +30,7 @@ trait MuteAllExceptPresentersCmdMsgHdlr {
|
||||
if (!vu.listenOnly) {
|
||||
Users2x.findWithIntId(liveMeeting.users2x, vu.intId) match {
|
||||
case Some(u) => if (!u.presenter) muteUserInVoiceConf(vu)
|
||||
case None => muteUserInVoiceConf(vu)
|
||||
case None => muteUserInVoiceConf(vu)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ trait RecordingStartedVoiceConfEvtMsgHdlr {
|
||||
MeetingStatus2x.setVoiceRecordingFilename(liveMeeting.status, msg.body.stream)
|
||||
|
||||
def buildVoiceRecordingStartedEvtMsg(meetingId: String, stream: String, timestamp: String,
|
||||
voiceConf: String): BbbCommonEnvCoreMsg = {
|
||||
voiceConf: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(VoiceRecordingStartedEvtMsg.NAME, routing)
|
||||
|
||||
@ -34,7 +34,7 @@ trait RecordingStartedVoiceConfEvtMsgHdlr {
|
||||
MeetingStatus2x.setVoiceRecordingFilename(liveMeeting.status, "")
|
||||
|
||||
def buildVoiceRecordingStoppedEvtMsg(meetingId: String, stream: String, timestamp: String,
|
||||
voiceConf: String): BbbCommonEnvCoreMsg = {
|
||||
voiceConf: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
|
||||
val envelope = BbbCoreEnvelope(VoiceRecordingStoppedEvtMsg.NAME, routing)
|
||||
|
||||
|
@ -17,7 +17,8 @@ trait GetGuestsWaitingApprovalReqMsgHdlr extends HandlerHelpers {
|
||||
val event = MsgBuilder.buildGetGuestsWaitingApprovalRespMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
msg.body.requesterId,
|
||||
guests)
|
||||
guests
|
||||
)
|
||||
|
||||
Sender.send(outGW, event)
|
||||
|
||||
|
@ -30,8 +30,10 @@ trait GuestsWaitingApprovedMsgHdlr extends HandlerHelpers {
|
||||
RegisteredUsers.setWaitingForApproval(liveMeeting.registeredUsers, u, false)
|
||||
// send message to user that he has been approved
|
||||
}
|
||||
val event = MsgBuilder.buildGuestApprovedEvtMsg(liveMeeting.props.meetingProp.intId,
|
||||
g.intId, guest.approved, approvedBy)
|
||||
val event = MsgBuilder.buildGuestApprovedEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
g.intId, guest.approved, approvedBy
|
||||
)
|
||||
|
||||
Sender.send(outGW, event)
|
||||
|
||||
@ -41,8 +43,10 @@ trait GuestsWaitingApprovedMsgHdlr extends HandlerHelpers {
|
||||
def notifyModeratorsOfGuestsApproval(guests: Vector[GuestApprovedVO], approvedBy: String): Unit = {
|
||||
val mods = Users2x.findAll(liveMeeting.users2x).filter(p => p.role == Roles.MODERATOR_ROLE)
|
||||
mods foreach { m =>
|
||||
val event = MsgBuilder.buildGuestsWaitingApprovedEvtMsg(liveMeeting.props.meetingProp.intId,
|
||||
m.intId, guests, approvedBy)
|
||||
val event = MsgBuilder.buildGuestsWaitingApprovedEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
m.intId, guests, approvedBy
|
||||
)
|
||||
Sender.send(outGW, event)
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ trait SetGuestPolicyMsgHdlr {
|
||||
val policy = GuestPolicy(newPolicy, msg.body.setBy)
|
||||
GuestsWaiting.setGuestPolicy(liveMeeting.guestsWaiting, policy)
|
||||
val event = MsgBuilder.buildGuestPolicyChangedEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId, msg.header.userId, newPolicy, msg.body.setBy)
|
||||
liveMeeting.props.meetingProp.intId, msg.header.userId, newPolicy, msg.body.setBy
|
||||
)
|
||||
Sender.send(outGW, event)
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,10 @@ trait DestroyMeetingSysCmdMsgHdlr {
|
||||
log.info("Handling DestroyMeeting message for meetingId={}", msg.body.meetingId)
|
||||
|
||||
if (liveMeeting.props.meetingProp.isBreakout) {
|
||||
log.info("Informing parent meeting {} that a breakout room has been ended {}",
|
||||
liveMeeting.props.breakoutProps.parentId, liveMeeting.props.meetingProp.intId)
|
||||
log.info(
|
||||
"Informing parent meeting {} that a breakout room has been ended {}",
|
||||
liveMeeting.props.breakoutProps.parentId, liveMeeting.props.meetingProp.intId
|
||||
)
|
||||
|
||||
// send out BreakoutRoomEndedEvtMsg to inform clients the breakout has ended
|
||||
outGW.send(MsgBuilder.buildBreakoutRoomEndedEvtMsg(liveMeeting.props.meetingProp.intId, "not-used",
|
||||
@ -28,8 +30,10 @@ trait DestroyMeetingSysCmdMsgHdlr {
|
||||
outGW.send(MsgBuilder.buildEndAndKickAllSysMsg(liveMeeting.props.meetingProp.intId, "not-used"))
|
||||
|
||||
// Eject all users from the voice conference
|
||||
outGW.send(MsgBuilder.buildEjectAllFromVoiceConfMsg(liveMeeting.props.meetingProp.intId,
|
||||
liveMeeting.props.voiceProp.voiceConf))
|
||||
outGW.send(MsgBuilder.buildEjectAllFromVoiceConfMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
liveMeeting.props.voiceProp.voiceConf
|
||||
))
|
||||
|
||||
// send a system message to force disconnection
|
||||
outGW.send(MsgBuilder.buildDisconnectAllClientsSysMsg(liveMeeting.props.meetingProp.intId))
|
||||
|
@ -2,11 +2,12 @@ package org.bigbluebutton.core2.message.handlers.users
|
||||
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.OutMessageGateway
|
||||
import org.bigbluebutton.core.apps.users.UsersApp
|
||||
import org.bigbluebutton.core.models._
|
||||
import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, BaseMeetingActor }
|
||||
import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting }
|
||||
|
||||
trait ValidateAuthTokenReqMsgHdlr extends HandlerHelpers {
|
||||
this: BaseMeetingActor =>
|
||||
this: UsersApp =>
|
||||
|
||||
val liveMeeting: LiveMeeting
|
||||
val outGW: OutMessageGateway
|
||||
@ -37,33 +38,3 @@ trait ValidateAuthTokenReqMsgHdlr extends HandlerHelpers {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait FooValidateAuthTokenReqMsgHdlr extends HandlerHelpers {
|
||||
val liveMeeting: LiveMeeting
|
||||
val outGW: OutMessageGateway
|
||||
|
||||
def handleValidateAuthTokenReqMsg(msg: ValidateAuthTokenReqMsg): Unit = {
|
||||
|
||||
RegisteredUsers.getRegisteredUserWithToken(msg.body.authToken, msg.body.userId, liveMeeting.registeredUsers) match {
|
||||
case Some(u) =>
|
||||
val guestPolicyType = GuestsWaiting.getGuestPolicy(liveMeeting.guestsWaiting).policy
|
||||
if (guestPolicyType == GuestPolicyType.ALWAYS_ACCEPT) {
|
||||
userValidatedAndNoNeedToWaitForApproval(outGW, liveMeeting, u)
|
||||
} else if (guestPolicyType == GuestPolicyType.ASK_MODERATOR) {
|
||||
if (u.guest && u.waitingForAcceptance) {
|
||||
userValidatedButNeedToWaitForApproval(outGW, liveMeeting, u)
|
||||
} else {
|
||||
userValidatedAndNoNeedToWaitForApproval(outGW, liveMeeting, u)
|
||||
}
|
||||
} else {
|
||||
validateTokenFailed(outGW, meetingId = liveMeeting.props.meetingProp.intId,
|
||||
userId = msg.body.userId, authToken = msg.body.authToken, valid = false, waitForApproval = false)
|
||||
// TODO: Disconnect user
|
||||
}
|
||||
case None =>
|
||||
validateTokenFailed(outGW, meetingId = liveMeeting.props.meetingProp.intId,
|
||||
userId = msg.body.userId, authToken = msg.body.authToken, valid = false, waitForApproval = false)
|
||||
// TODO: Disconnect user
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ object MsgBuilder {
|
||||
}
|
||||
|
||||
def buildGuestsWaitingApprovedEvtMsg(meetingId: String, userId: String,
|
||||
guests: Vector[GuestApprovedVO], approvedBy: String): BbbCommonEnvCoreMsg = {
|
||||
guests: Vector[GuestApprovedVO], approvedBy: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
|
||||
val envelope = BbbCoreEnvelope(GuestsWaitingApprovedEvtMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(GuestsWaitingApprovedEvtMsg.NAME, meetingId, userId)
|
||||
@ -64,7 +64,7 @@ object MsgBuilder {
|
||||
}
|
||||
|
||||
def buildValidateAuthTokenRespMsg(meetingId: String, userId: String, authToken: String,
|
||||
valid: Boolean, waitForApproval: Boolean): BbbCommonEnvCoreMsg = {
|
||||
valid: Boolean, waitForApproval: Boolean): BbbCommonEnvCoreMsg = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
|
||||
val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(ValidateAuthTokenRespMsg.NAME, meetingId, userId)
|
||||
|
@ -6,7 +6,7 @@ import org.bigbluebutton.core.OutMessageGateway
|
||||
object ValidateAuthTokenRespMsgSender {
|
||||
|
||||
def send(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String,
|
||||
valid: Boolean, waitForApproval: Boolean): Unit = {
|
||||
valid: Boolean, waitForApproval: Boolean): Unit = {
|
||||
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
|
||||
val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing)
|
||||
val header = BbbClientMsgHeader(ValidateAuthTokenRespMsg.NAME, meetingId, userId)
|
||||
|
@ -33,7 +33,7 @@ trait FakeTestData {
|
||||
}
|
||||
|
||||
def createUserVoiceAndCam(liveMeeting: LiveMeeting, role: String, guest: Boolean, authed: Boolean, callingWith: String,
|
||||
muted: Boolean, talking: Boolean, listenOnly: Boolean): Unit = {
|
||||
muted: Boolean, talking: Boolean, listenOnly: Boolean): Unit = {
|
||||
|
||||
val ruser1 = FakeUserGenerator.createFakeRegisteredUser(liveMeeting.registeredUsers, Roles.MODERATOR_ROLE, true, false)
|
||||
|
||||
|
@ -26,8 +26,7 @@ object FakeUserGenerator {
|
||||
"Jake", "James", "Jason", "Joe", "John", "Jonathan", "Joseph", "Joshua", "Julian", "Justin", "Keith", "Kevin",
|
||||
"Leonard", "Liam", "Lucas", "Luke", "Matt", "Max", "Michael", "Nathan", "Neil", "Nicholas", "Oliver", "Owen",
|
||||
"Paul", "Peter", "Phil", "Piers", "Richard", "Robert", "Ryan", "Sam", "Sean", "Sebastian", "Simon", "Stephen",
|
||||
"Steven", "Stewart", "Thomas", "Tim", "Trevor", "Victor", "Warren", "William"
|
||||
)
|
||||
"Steven", "Stewart", "Thomas", "Tim", "Trevor", "Victor", "Warren", "William")
|
||||
|
||||
private val lastNames = Seq("Abraham", "Allan", "Alsop", "Anderson", "Arnold", "Avery", "Bailey", "Baker", "Ball", "Bell",
|
||||
"Berry", "Black", "Blake", "Bond", "Bower", "Brown", "Buckland", "Burgess", "Butler", "Cameron", "Campbell",
|
||||
@ -42,8 +41,7 @@ object FakeUserGenerator {
|
||||
"Piper", "Poole", "Powell", "Pullman", "Quinn", "Rampling", "Randall", "Rees", "Reid", "Roberts", "Robertson",
|
||||
"Ross", "Russell", "Rutherford", "Sanderson", "Scott", "Sharp", "Short", "Simpson", "Skinner", "Slater", "Smith",
|
||||
"Springer", "Stewart", "Sutherland", "Taylor", "Terry", "Thomson", "Tucker", "Turner", "Underwood", "Vance",
|
||||
"Vaughan", "Walker", "Wallace", "Walsh", "Watson", "Welch", "White", "Wilkins", "Wilson", "Wright", "Young"
|
||||
)
|
||||
"Vaughan", "Walker", "Wallace", "Walsh", "Watson", "Welch", "White", "Wilkins", "Wilson", "Wright", "Young")
|
||||
|
||||
private def getRandomElement(list: Seq[String], random: Random): String = list(random.nextInt(list.length))
|
||||
|
||||
@ -60,14 +58,14 @@ object FakeUserGenerator {
|
||||
}
|
||||
|
||||
def createFakeVoiceUser(user: RegisteredUser, callingWith: String, muted: Boolean, talking: Boolean,
|
||||
listenOnly: Boolean): VoiceUserState = {
|
||||
listenOnly: Boolean): VoiceUserState = {
|
||||
val voiceUserId = RandomStringGenerator.randomAlphanumericString(8)
|
||||
VoiceUserState(intId = user.id, voiceUserId = voiceUserId, callingWith, callerName = user.name,
|
||||
callerNum = user.name, muted, talking, listenOnly)
|
||||
}
|
||||
|
||||
def createFakeVoiceOnlyUser(callingWith: String, muted: Boolean, talking: Boolean,
|
||||
listenOnly: Boolean): VoiceUserState = {
|
||||
listenOnly: Boolean): VoiceUserState = {
|
||||
val voiceUserId = RandomStringGenerator.randomAlphanumericString(8)
|
||||
val intId = "v_" + RandomStringGenerator.randomAlphanumericString(16)
|
||||
val name = getRandomElement(firstNames, random) + " " + getRandomElement(lastNames, random)
|
||||
|
@ -28,10 +28,12 @@ object AppsRedisSubscriberActor extends SystemConfiguration {
|
||||
}
|
||||
|
||||
class AppsRedisSubscriberActor(msgReceiver: RedisMessageReceiver, 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 {
|
||||
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 => {
|
||||
|
@ -40,35 +40,35 @@ class RedisRecorderActor(val system: ActorSystem)
|
||||
def receive = {
|
||||
//case msg: SendPublicMessageEvent => handleSendPublicMessageEvent(msg)
|
||||
//case msg: ClearPublicChatHistoryReply => handleClearPublicChatHistoryReply(msg)
|
||||
case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
|
||||
case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
|
||||
case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
|
||||
case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
|
||||
case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
|
||||
case msg: EndAndKickAll => handleEndAndKickAll(msg)
|
||||
case msg: PresenterAssigned => handleAssignPresenter(msg)
|
||||
case msg: UserJoined => handleUserJoined(msg)
|
||||
case msg: UserLeft => handleUserLeft(msg)
|
||||
case msg: UserStatusChange => handleUserStatusChange(msg)
|
||||
case msg: UserVoiceMuted => handleUserVoiceMuted(msg)
|
||||
case msg: UserVoiceTalking => handleUserVoiceTalking(msg)
|
||||
case msg: UserJoinedVoice => handleUserJoinedVoice(msg)
|
||||
case msg: UserLeftVoice => handleUserLeftVoice(msg)
|
||||
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
|
||||
case msg: UserChangedEmojiStatus => handleChangedUserEmojiStatus(msg)
|
||||
case msg: UserSharedWebcam => handleUserSharedWebcam(msg)
|
||||
case msg: UserUnsharedWebcam => handleUserUnsharedWebcam(msg)
|
||||
case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
|
||||
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
|
||||
case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
|
||||
case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
|
||||
case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
|
||||
case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
|
||||
case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
|
||||
case msg: EndAndKickAll => handleEndAndKickAll(msg)
|
||||
case msg: PresenterAssigned => handleAssignPresenter(msg)
|
||||
case msg: UserJoined => handleUserJoined(msg)
|
||||
case msg: UserLeft => handleUserLeft(msg)
|
||||
case msg: UserStatusChange => handleUserStatusChange(msg)
|
||||
case msg: UserVoiceMuted => handleUserVoiceMuted(msg)
|
||||
case msg: UserVoiceTalking => handleUserVoiceTalking(msg)
|
||||
case msg: UserJoinedVoice => handleUserJoinedVoice(msg)
|
||||
case msg: UserLeftVoice => handleUserLeftVoice(msg)
|
||||
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
|
||||
case msg: UserChangedEmojiStatus => handleChangedUserEmojiStatus(msg)
|
||||
case msg: UserSharedWebcam => handleUserSharedWebcam(msg)
|
||||
case msg: UserUnsharedWebcam => handleUserUnsharedWebcam(msg)
|
||||
case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
|
||||
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
|
||||
// case msg: SendWhiteboardAnnotationEvtMsg => handleSendWhiteboardAnnotationEvent(msg)
|
||||
// case msg: CursorPositionUpdatedEvent => handleCursorPositionUpdatedEvent(msg)
|
||||
// case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg)
|
||||
// case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
|
||||
// case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg)
|
||||
case msg: DeskShareStartRTMPBroadcast => handleDeskShareStartRTMPBroadcast(msg)
|
||||
case msg: DeskShareStopRTMPBroadcast => handleDeskShareStopRTMPBroadcast(msg)
|
||||
case msg: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(msg)
|
||||
case _ => // do nothing
|
||||
case msg: DeskShareStopRTMPBroadcast => handleDeskShareStopRTMPBroadcast(msg)
|
||||
case msg: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(msg)
|
||||
case _ => // do nothing
|
||||
}
|
||||
|
||||
/* private def handleSendPublicMessageEvent(msg: SendPublicMessageEvent) {
|
||||
|
@ -76,10 +76,31 @@ trait AppsTestFixtures {
|
||||
|
||||
// meetingModel.setGuestPolicy(props.usersProp.guestPolicy)
|
||||
|
||||
// We extract the meeting handlers into this class so it is
|
||||
// easy to test.
|
||||
val liveMeeting = new LiveMeeting(defaultProps, meetingStatux2x, deskshareModel, chatModel, layoutModel, layouts,
|
||||
registeredUsers, polls2x, pollModel, wbModel, presModel, breakoutRooms, captionModel,
|
||||
notesModel, webcams, voiceUsers, users2x, guestsWaiting)
|
||||
def newLiveMeeting(): LiveMeeting = {
|
||||
val chatModel = new ChatModel()
|
||||
val layoutModel = new LayoutModel()
|
||||
val layouts = new Layouts()
|
||||
val pollModel = new PollModel()
|
||||
val wbModel = new WhiteboardModel()
|
||||
val presModel = new PresentationModel()
|
||||
val breakoutRooms = new BreakoutRooms()
|
||||
val captionModel = new CaptionModel()
|
||||
val notesModel = new SharedNotesModel()
|
||||
val registeredUsers = new RegisteredUsers
|
||||
val meetingStatux2x = new MeetingStatus2x
|
||||
val webcams = new Webcams
|
||||
val voiceUsers = new VoiceUsers
|
||||
val users2x = new Users2x
|
||||
val polls2x = new Polls
|
||||
val guestsWaiting = new GuestsWaiting
|
||||
val deskshareModel = new ScreenshareModel
|
||||
|
||||
// meetingModel.setGuestPolicy(props.usersProp.guestPolicy)
|
||||
|
||||
// We extract the meeting handlers into this class so it is
|
||||
// easy to test.
|
||||
new LiveMeeting(defaultProps, meetingStatux2x, deskshareModel, chatModel, layoutModel, layouts,
|
||||
registeredUsers, polls2x, pollModel, wbModel, presModel, breakoutRooms, captionModel,
|
||||
notesModel, webcams, voiceUsers, users2x, guestsWaiting)
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,10 @@ import org.scalatest.{ Matchers, WordSpecLike }
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class BigBlueButtonActorTestsSpec extends TestKit(ActorSystem("BigBlueButtonActorTestsSpec",
|
||||
ConfigFactory.parseString(TestKitUsageSpec.config)))
|
||||
class BigBlueButtonActorTestsSpec extends TestKit(ActorSystem(
|
||||
"BigBlueButtonActorTestsSpec",
|
||||
ConfigFactory.parseString(TestKitUsageSpec.config)
|
||||
))
|
||||
with DefaultTimeout with ImplicitSender with WordSpecLike
|
||||
with Matchers with StopSystemAfterAll with AppsTestFixtures with SystemConfiguration {
|
||||
|
||||
@ -20,12 +22,12 @@ class BigBlueButtonActorTestsSpec extends TestKit(ActorSystem("BigBlueButtonActo
|
||||
|
||||
// Setup dependencies
|
||||
val bbbMsgBus = new BbbMsgRouterEventBus
|
||||
val eventBus = new IncomingEventBus
|
||||
val eventBus = new InMsgBusGW(new IncomingEventBusImp())
|
||||
val outgoingEventBus = new OutgoingEventBus
|
||||
val outBus2 = new OutEventBus2
|
||||
val recordBus = new RecordingEventBus
|
||||
|
||||
val outGW = OutMessageGatewayImp(outgoingEventBus, outBus2, recordBus)
|
||||
//val outGW = OutMessageGatewayImp(outgoingEventBus, outBus2, recordBus)
|
||||
|
||||
// Have the build in testActor receive messages coming from class under test (BigBlueButtonActor)
|
||||
outBus2.subscribe(testActor, outBbbMsgMsgChannel)
|
||||
@ -34,22 +36,27 @@ class BigBlueButtonActorTestsSpec extends TestKit(ActorSystem("BigBlueButtonActo
|
||||
"Send a MeetingCreatedEvtMsg when receiving CreateMeetingReqMsg" in {
|
||||
within(500 millis) {
|
||||
|
||||
val outGWSeq = new OutMsgGWSeq()
|
||||
// Create BigBlueButton Actor
|
||||
val bbbActorRef = system.actorOf(BigBlueButtonActor.props(system,
|
||||
eventBus, bbbMsgBus, outGW))
|
||||
val bbbActorRef = system.actorOf(BigBlueButtonActor.props(
|
||||
system,
|
||||
eventBus, bbbMsgBus, outGWSeq
|
||||
))
|
||||
|
||||
// Send our create meeting request message
|
||||
val msg = buildCreateMeetingReqMsg(defaultProps)
|
||||
bbbActorRef ! msg
|
||||
|
||||
//assert(outGWSeq.msgs.length == 2)
|
||||
|
||||
// Expect a message from BigBlueButtonActor as a result of handling
|
||||
// the create meeting request message.
|
||||
//expectMsgClass(classOf[BbbCommonEnvCoreMsg])
|
||||
expectMsgPF() {
|
||||
case event: BbbCommonEnvCoreMsg =>
|
||||
assert(event.envelope.name == MeetingCreatedEvtMsg.NAME)
|
||||
// Can do more assertions here
|
||||
}
|
||||
// expectMsgPF() {
|
||||
// case event: BbbCommonEnvCoreMsg =>
|
||||
// assert(event.envelope.name == MeetingCreatedEvtMsg.NAME)
|
||||
// Can do more assertions here
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class JsonMessageDecoderTests extends UnitSpec with JsonMessageFixtures {
|
||||
it should "fail to decode CreateBreakoutRoomsRequestMessage" in {
|
||||
JsonMessageDecoder.decode(invalidCreateBreakoutRoomsRequestMessage) match {
|
||||
case Some(validMsg) => fail("Should have failed to decode message")
|
||||
case None => assert(true)
|
||||
case None => assert(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
15
akka-bbb-apps/src/test/scala/org/bigbluebutton/core/MockTestActor.scala
Executable file
15
akka-bbb-apps/src/test/scala/org/bigbluebutton/core/MockTestActor.scala
Executable file
@ -0,0 +1,15 @@
|
||||
package org.bigbluebutton.core
|
||||
|
||||
import akka.actor.Props
|
||||
import org.bigbluebutton.core.running.BaseMeetingActor
|
||||
|
||||
object MockTestActor {
|
||||
def props(): Props = Props(classOf[MockTestActor])
|
||||
}
|
||||
|
||||
class MockTestActor extends BaseMeetingActor {
|
||||
|
||||
def receive = {
|
||||
case _ => log.error("Shouldn't receive anything as this is just an actor stand in.")
|
||||
}
|
||||
}
|
@ -18,8 +18,10 @@ import org.scalatest.Matchers
|
||||
/**
|
||||
* a Test to show some TestKit examples
|
||||
*/
|
||||
class TestKitUsageSpec extends TestKit(ActorSystem("TestKitUsageSpec",
|
||||
ConfigFactory.parseString(TestKitUsageSpec.config)))
|
||||
class TestKitUsageSpec extends TestKit(ActorSystem(
|
||||
"TestKitUsageSpec",
|
||||
ConfigFactory.parseString(TestKitUsageSpec.config)
|
||||
))
|
||||
with DefaultTimeout with ImplicitSender with WordSpecLike
|
||||
with Matchers with BeforeAndAfterAll {
|
||||
|
||||
@ -130,7 +132,7 @@ object TestKitUsageSpec {
|
||||
class FilteringActor(next: ActorRef) extends Actor {
|
||||
def receive = {
|
||||
case msg: String => next ! msg
|
||||
case _ => None
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +143,7 @@ object TestKitUsageSpec {
|
||||
* be bothered with the rest
|
||||
*/
|
||||
class SequencingActor(next: ActorRef, head: immutable.Seq[String],
|
||||
tail: immutable.Seq[String]) extends Actor {
|
||||
tail: immutable.Seq[String]) extends Actor {
|
||||
def receive = {
|
||||
case msg => {
|
||||
head foreach { next ! _ }
|
||||
|
@ -26,7 +26,7 @@ class DirectChatModelTest extends UnitSpec {
|
||||
val dc2 = DirectChats.find(between, directChats)
|
||||
dc2 match {
|
||||
case Some(directChat) => assert(directChat.messages.length == 2)
|
||||
case None => fail("No direct chat found!")
|
||||
case None => fail("No direct chat found!")
|
||||
}
|
||||
|
||||
// Append a third message and make sure there are three messages
|
||||
@ -37,7 +37,7 @@ class DirectChatModelTest extends UnitSpec {
|
||||
val dc3 = DirectChats.find(between, directChats)
|
||||
dc3 match {
|
||||
case Some(directChat) => assert(directChat.messages.length == 3)
|
||||
case None => fail("No direct chat found!")
|
||||
case None => fail("No direct chat found!")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package org.bigbluebutton.core.running
|
||||
|
||||
import org.bigbluebutton.core.UnitSpec
|
||||
import org.bigbluebutton.core.domain.MeetingInactivityTracker
|
||||
|
||||
class MeetingInactivityTrackerHelperTests extends UnitSpec {
|
||||
|
||||
"A MeetingInactivityTrackerHelper" should "be return meeting is inactive" in {
|
||||
object Handler extends MeetingInactivityTrackerHelper
|
||||
|
||||
val tracker = new MeetingInactivityTracker(20, 5, 10, false, 0L)
|
||||
val active = Handler.isMeetingActive(40, tracker)
|
||||
assert(active == false)
|
||||
}
|
||||
|
||||
"A MeetingInactivityTrackerHelper" should "be return meeting is active" in {
|
||||
object Handler extends MeetingInactivityTrackerHelper
|
||||
|
||||
val tracker = new MeetingInactivityTracker(20, 5, 10, false, 0L)
|
||||
val active = Handler.isMeetingActive(12, tracker)
|
||||
assert(active)
|
||||
}
|
||||
|
||||
"A MeetingInactivityTrackerHelper" should "be return send warning if close to max inactivity" in {
|
||||
object Handler extends MeetingInactivityTrackerHelper
|
||||
|
||||
val tracker = new MeetingInactivityTracker(20, 5, 10, false, 0L)
|
||||
|
||||
val send = Handler.shouldSendInactivityWarning(now = 28, tracker)
|
||||
assert(send)
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +1,24 @@
|
||||
package org.bigbluebutton.core2.message.handlers
|
||||
|
||||
import akka.actor.{ ActorSystem, Props }
|
||||
import akka.actor.{ ActorContext, ActorSystem, Props }
|
||||
import akka.testkit.{ DefaultTimeout, ImplicitSender, TestKit }
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import org.bigbluebutton.SystemConfiguration
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core._
|
||||
import org.bigbluebutton.core.apps.users.UsersApp
|
||||
import org.bigbluebutton.core.bus._
|
||||
import org.bigbluebutton.core.models._
|
||||
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
|
||||
import org.bigbluebutton.core2.message.handlers.users.{ FooValidateAuthTokenReqMsgHdlr, ValidateAuthTokenReqMsgHdlr }
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
import org.bigbluebutton.core2.testdata.TestDataGen
|
||||
import org.scalatest.{ Matchers, WordSpecLike }
|
||||
|
||||
import akka.testkit.TestActorRef
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("ValidateAuthTokenReqMsgHdlrTestsSpec",
|
||||
ConfigFactory.parseString(TestKitUsageSpec.config)))
|
||||
class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem(
|
||||
"ValidateAuthTokenReqMsgHdlrTestsSpec",
|
||||
ConfigFactory.parseString(TestKitUsageSpec.config)
|
||||
))
|
||||
with DefaultTimeout with ImplicitSender with WordSpecLike
|
||||
with Matchers with StopSystemAfterAll with AppsTestFixtures with SystemConfiguration {
|
||||
|
||||
@ -26,37 +28,29 @@ class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("Validate
|
||||
val outBus2 = new OutEventBus2
|
||||
val recordBus = new RecordingEventBus
|
||||
|
||||
val outGW = OutMessageGatewayImp(outgoingEventBus, outBus2, recordBus)
|
||||
|
||||
// Have the build in testActor receive messages coming from class under test
|
||||
outBus2.subscribe(testActor, outBbbMsgMsgChannel)
|
||||
|
||||
"A MeetingActor" should {
|
||||
"Reject an invalid authToken because there is no registered users in the meeting" in {
|
||||
within(500 millis) {
|
||||
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = system.actorOf(ValidateAuthTokenRespMsgTestActor.props(outGW, liveMeeting))
|
||||
val state = newLiveMeeting()
|
||||
val outGW = new OutMsgGWSeq()
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps")
|
||||
val envelope = BbbCoreEnvelope(CreateMeetingReqMsg.NAME, routing)
|
||||
val req = ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
BbbCommonEnvCoreMsg(envelope, req)
|
||||
// Need to get an ActorContext
|
||||
val actorRef = TestActorRef[MockTestActor]
|
||||
val actor = actorRef.underlyingActor
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = new UsersApp(state, outGW)(actor.context)
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): ValidateAuthTokenReqMsg = {
|
||||
ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
}
|
||||
|
||||
// Send our message
|
||||
val msg = build(liveMeeting.props.meetingProp.intId, "unknown user", "fake auth token")
|
||||
meetingActorRef ! msg
|
||||
val msg = build(state.props.meetingProp.intId, "unknown user", "fake auth token")
|
||||
meetingActorRef.handleValidateAuthTokenReqMsg(msg)
|
||||
|
||||
// Handle message expectations
|
||||
expectMsgPF() {
|
||||
case event: BbbCommonEnvCoreMsg =>
|
||||
assert(event.envelope.name == ValidateAuthTokenRespMsg.NAME)
|
||||
val outMsg = event.core.asInstanceOf[ValidateAuthTokenRespMsg]
|
||||
assert(outMsg.body.valid == false)
|
||||
// Can do more assertions here
|
||||
}
|
||||
assert(outGW.msgs.length == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -65,31 +59,27 @@ class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("Validate
|
||||
"Reject an invalid authToken for a registered users in the meeting" in {
|
||||
within(500 millis) {
|
||||
|
||||
val richard = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
val state = newLiveMeeting()
|
||||
val outGW = new OutMsgGWSeq()
|
||||
val richard = TestDataGen.createRegisteredUser(state.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
|
||||
// Need to get an ActorContext
|
||||
val actorRef = TestActorRef[MockTestActor]
|
||||
val actor = actorRef.underlyingActor
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = system.actorOf(ValidateAuthTokenRespMsgTestActor.props(outGW, liveMeeting))
|
||||
val meetingActorRef = new UsersApp(state, outGW)(actor.context)
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps")
|
||||
val envelope = BbbCoreEnvelope(CreateMeetingReqMsg.NAME, routing)
|
||||
val req = ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
BbbCommonEnvCoreMsg(envelope, req)
|
||||
def build(meetingId: String, userId: String, authToken: String): ValidateAuthTokenReqMsg = {
|
||||
ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
}
|
||||
|
||||
// Send our message
|
||||
val msg = build(liveMeeting.props.meetingProp.intId, richard.id, "wrong token")
|
||||
meetingActorRef ! msg
|
||||
val msg = build(state.props.meetingProp.intId, richard.id, "wrong token")
|
||||
meetingActorRef.handleValidateAuthTokenReqMsg(msg)
|
||||
|
||||
// Handle message expectations
|
||||
expectMsgPF() {
|
||||
case event: BbbCommonEnvCoreMsg =>
|
||||
assert(event.envelope.name == ValidateAuthTokenRespMsg.NAME)
|
||||
val outMsg = event.core.asInstanceOf[ValidateAuthTokenRespMsg]
|
||||
assert(outMsg.body.valid == false)
|
||||
// Can do more assertions here
|
||||
}
|
||||
assert(outGW.msgs.length == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,32 +87,28 @@ class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("Validate
|
||||
"A MeetingActor" should {
|
||||
"Accept a valid authToken for a registered users in the meeting" in {
|
||||
within(500 millis) {
|
||||
val state = newLiveMeeting()
|
||||
val outGW = new OutMsgGWSeq()
|
||||
|
||||
val richard = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
val richard = TestDataGen.createRegisteredUser(state.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
|
||||
// Need to get an ActorContext
|
||||
val actorRef = TestActorRef[MockTestActor]
|
||||
val actor = actorRef.underlyingActor
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = system.actorOf(ValidateAuthTokenRespMsgTestActor.props(outGW, liveMeeting))
|
||||
val meetingActorRef = new UsersApp(state, outGW)(actor.context)
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps")
|
||||
val envelope = BbbCoreEnvelope(CreateMeetingReqMsg.NAME, routing)
|
||||
val req = ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
BbbCommonEnvCoreMsg(envelope, req)
|
||||
def build(meetingId: String, userId: String, authToken: String): ValidateAuthTokenReqMsg = {
|
||||
ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
}
|
||||
|
||||
// Send our message
|
||||
val msg = build(liveMeeting.props.meetingProp.intId, richard.id, richard.authToken)
|
||||
meetingActorRef ! msg
|
||||
val msg = build(state.props.meetingProp.intId, richard.id, richard.authToken)
|
||||
meetingActorRef.handleValidateAuthTokenReqMsg(msg)
|
||||
|
||||
// Handle message expectations
|
||||
expectMsgPF() {
|
||||
case event: BbbCommonEnvCoreMsg =>
|
||||
assert(event.envelope.name == ValidateAuthTokenRespMsg.NAME)
|
||||
val outMsg = event.core.asInstanceOf[ValidateAuthTokenRespMsg]
|
||||
assert(outMsg.body.valid == true)
|
||||
// Can do more assertions here
|
||||
}
|
||||
assert(outGW.msgs.length == 6)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,37 +116,33 @@ class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("Validate
|
||||
"A MeetingActor" should {
|
||||
"Accept a valid authToken for a registered users in the meeting and not wait for approval for none guests" in {
|
||||
within(500 millis) {
|
||||
val state = newLiveMeeting()
|
||||
val outGW = new OutMsgGWSeq()
|
||||
|
||||
// Set the guest policy to ask moderator
|
||||
GuestsWaiting.setGuestPolicy(liveMeeting.guestsWaiting, GuestPolicy(GuestPolicyType.ASK_MODERATOR, "SYSTEM"))
|
||||
GuestsWaiting.setGuestPolicy(state.guestsWaiting, GuestPolicy(GuestPolicyType.ASK_MODERATOR, "SYSTEM"))
|
||||
|
||||
// Register a user that is not a guest
|
||||
val richard = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
val richard = TestDataGen.createRegisteredUser(state.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
|
||||
// Need to get an ActorContext
|
||||
val actorRef = TestActorRef[MockTestActor]
|
||||
val actor = actorRef.underlyingActor
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = system.actorOf(ValidateAuthTokenRespMsgTestActor.props(outGW, liveMeeting))
|
||||
val meetingActorRef = new UsersApp(state, outGW)(actor.context)
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps")
|
||||
val envelope = BbbCoreEnvelope(CreateMeetingReqMsg.NAME, routing)
|
||||
val req = ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
BbbCommonEnvCoreMsg(envelope, req)
|
||||
def build(meetingId: String, userId: String, authToken: String): ValidateAuthTokenReqMsg = {
|
||||
ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
}
|
||||
|
||||
// Send our message
|
||||
val msg = build(liveMeeting.props.meetingProp.intId, richard.id, richard.authToken)
|
||||
meetingActorRef ! msg
|
||||
val msg = build(state.props.meetingProp.intId, richard.id, richard.authToken)
|
||||
meetingActorRef.handleValidateAuthTokenReqMsg(msg)
|
||||
|
||||
// Handle message expectations
|
||||
expectMsgPF() {
|
||||
case event: BbbCommonEnvCoreMsg =>
|
||||
assert(event.envelope.name == ValidateAuthTokenRespMsg.NAME)
|
||||
val outMsg = event.core.asInstanceOf[ValidateAuthTokenRespMsg]
|
||||
assert(outMsg.body.valid == true)
|
||||
assert(outMsg.body.waitForApproval == false)
|
||||
// Can do more assertions here
|
||||
}
|
||||
// Handle message expectations
|
||||
assert(outGW.msgs.length == 6)
|
||||
|
||||
}
|
||||
}
|
||||
@ -168,108 +150,51 @@ class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("Validate
|
||||
|
||||
"A MeetingActor" should {
|
||||
"Accept a valid authToken for a registered users in the meeting and wait for approval for guests" in {
|
||||
within(500 millis) {
|
||||
|
||||
// Set the guest policy to ask moderator
|
||||
GuestsWaiting.setGuestPolicy(liveMeeting.guestsWaiting, GuestPolicy(GuestPolicyType.ASK_MODERATOR, "SYSTEM"))
|
||||
|
||||
// Register a user that is not a guest
|
||||
val richard = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
val fred = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Fred", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
val anton = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Anton", Roles.VIEWER_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
|
||||
val richardUser = TestDataGen.createUserFor(liveMeeting, richard, presenter = false)
|
||||
val fredUser = TestDataGen.createUserFor(liveMeeting, fred, presenter = false)
|
||||
val antonUser = TestDataGen.createUserFor(liveMeeting, anton, presenter = false)
|
||||
|
||||
val chad = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Chad", Roles.VIEWER_ROLE,
|
||||
guest = true, authed = false, waitForApproval = true)
|
||||
|
||||
val outGWSeq = new OutMsgGWSeq()
|
||||
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = system.actorOf(ValidateAuthTokenRespMsgTestActor.props(outGWSeq, liveMeeting))
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps")
|
||||
val envelope = BbbCoreEnvelope(ValidateAuthTokenReqMsg.NAME, routing)
|
||||
val req = ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
BbbCommonEnvCoreMsg(envelope, req)
|
||||
}
|
||||
|
||||
println("****** Sending validate msg test")
|
||||
// Send our message
|
||||
val msg = build(liveMeeting.props.meetingProp.intId, chad.id, chad.authToken)
|
||||
meetingActorRef ! msg
|
||||
|
||||
/**
|
||||
* // Handle message expectations
|
||||
* expectMsgPF() {
|
||||
* case event: BbbCommonEnvCoreMsg =>
|
||||
* assert(event.envelope.name == ValidateAuthTokenRespMsg.NAME)
|
||||
* val outMsg = event.core.asInstanceOf[ValidateAuthTokenRespMsg]
|
||||
* assert(outMsg.body.valid == true)
|
||||
* assert(outMsg.body.waitForApproval == false)
|
||||
* // Can do more assertions here
|
||||
* }
|
||||
*/
|
||||
println("******* Asserting message length ")
|
||||
assert(outGWSeq.msgs.length == 6)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"A MeetingActor" should {
|
||||
"Accept a valid authToken for a registered users in the meeting and wait for approval for guests 2" in {
|
||||
within(500 millis) {
|
||||
|
||||
val registeredUsers = new RegisteredUsers
|
||||
val users2x = new Users2x
|
||||
val liveMeeting = new LiveMeeting(defaultProps, meetingStatux2x, deskshareModel, chatModel, layoutModel, layouts,
|
||||
val state = new LiveMeeting(defaultProps, meetingStatux2x, deskshareModel, chatModel, layoutModel, layouts,
|
||||
registeredUsers, polls2x, pollModel, wbModel, presModel, breakoutRooms, captionModel,
|
||||
notesModel, webcams, voiceUsers, users2x, guestsWaiting)
|
||||
|
||||
// Set the guest policy to ask moderator
|
||||
GuestsWaiting.setGuestPolicy(liveMeeting.guestsWaiting, GuestPolicy(GuestPolicyType.ASK_MODERATOR, "SYSTEM"))
|
||||
GuestsWaiting.setGuestPolicy(state.guestsWaiting, GuestPolicy(GuestPolicyType.ASK_MODERATOR, "SYSTEM"))
|
||||
|
||||
// Register a user that is not a guest
|
||||
val richard = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
val richard = TestDataGen.createRegisteredUser(state.registeredUsers, "Richard", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
val fred = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Fred", Roles.MODERATOR_ROLE,
|
||||
val fred = TestDataGen.createRegisteredUser(state.registeredUsers, "Fred", Roles.MODERATOR_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
val anton = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Anton", Roles.VIEWER_ROLE,
|
||||
val anton = TestDataGen.createRegisteredUser(state.registeredUsers, "Anton", Roles.VIEWER_ROLE,
|
||||
guest = false, authed = false, waitForApproval = false)
|
||||
|
||||
val richardUser = TestDataGen.createUserFor(liveMeeting, richard, presenter = false)
|
||||
val fredUser = TestDataGen.createUserFor(liveMeeting, fred, presenter = false)
|
||||
val antonUser = TestDataGen.createUserFor(liveMeeting, anton, presenter = false)
|
||||
val richardUser = TestDataGen.createUserFor(state, richard, presenter = false)
|
||||
val fredUser = TestDataGen.createUserFor(state, fred, presenter = false)
|
||||
val antonUser = TestDataGen.createUserFor(state, anton, presenter = false)
|
||||
|
||||
val chad = TestDataGen.createRegisteredUser(liveMeeting.registeredUsers, "Chad", Roles.VIEWER_ROLE,
|
||||
val chad = TestDataGen.createRegisteredUser(state.registeredUsers, "Chad", Roles.VIEWER_ROLE,
|
||||
guest = true, authed = false, waitForApproval = true)
|
||||
|
||||
val outGWSeq = new OutMsgGWSeq()
|
||||
val outGW = new OutMsgGWSeq()
|
||||
|
||||
// Need to get an ActorContext
|
||||
val actorRef = TestActorRef[MockTestActor]
|
||||
val actor = actorRef.underlyingActor
|
||||
// Create actor under test Actor
|
||||
val meetingActorRef = new FooMeeting(outGWSeq, liveMeeting)
|
||||
val meetingActorRef = new UsersApp(state, outGW)(actor.context)
|
||||
|
||||
def build(meetingId: String, userId: String, authToken: String): BbbCommonEnvCoreMsg = {
|
||||
val routing = collection.immutable.HashMap("sender" -> "bbb-apps")
|
||||
val envelope = BbbCoreEnvelope(ValidateAuthTokenReqMsg.NAME, routing)
|
||||
val req = ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
BbbCommonEnvCoreMsg(envelope, req)
|
||||
def build(meetingId: String, userId: String, authToken: String): ValidateAuthTokenReqMsg = {
|
||||
ValidateAuthTokenReqMsg(meetingId, userId, authToken)
|
||||
}
|
||||
|
||||
println("****** Sending validate msg test")
|
||||
|
||||
val msg = build(liveMeeting.props.meetingProp.intId, chad.id, chad.authToken)
|
||||
meetingActorRef.handleValidateAuthTokenReqMsg(msg.core.asInstanceOf[ValidateAuthTokenReqMsg])
|
||||
val msg = build(state.props.meetingProp.intId, chad.id, chad.authToken)
|
||||
meetingActorRef.handleValidateAuthTokenReqMsg(msg)
|
||||
|
||||
println("******* Asserting message length ")
|
||||
assert(outGWSeq.msgs.length == 6)
|
||||
assert(outGW.msgs.length == 3)
|
||||
|
||||
}
|
||||
}
|
||||
@ -290,27 +215,3 @@ class ValidateAuthTokenReqMsgHdlrTestsSpec extends TestKit(ActorSystem("Validate
|
||||
}
|
||||
}
|
||||
|
||||
class FooMeeting(val outGW: OutMessageGateway,
|
||||
val liveMeeting: LiveMeeting) extends FooValidateAuthTokenReqMsgHdlr {
|
||||
|
||||
}
|
||||
|
||||
class ValidateAuthTokenRespMsgTestActor(val outGW: OutMessageGateway,
|
||||
val liveMeeting: LiveMeeting)
|
||||
extends BaseMeetingActor with ValidateAuthTokenReqMsgHdlr {
|
||||
|
||||
def receive = {
|
||||
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
|
||||
}
|
||||
|
||||
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
|
||||
msg.core match {
|
||||
case m: ValidateAuthTokenReqMsg => handleValidateAuthTokenReqMsg(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ValidateAuthTokenRespMsgTestActor {
|
||||
def props(outGW: OutMessageGateway, liveMeeting: LiveMeeting): Props =
|
||||
Props(classOf[ValidateAuthTokenRespMsgTestActor], outGW, liveMeeting)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import org.bigbluebutton.core.util.RandomStringGenerator
|
||||
|
||||
object TestDataGen {
|
||||
def createRegisteredUser(users: RegisteredUsers, name: String, role: String,
|
||||
guest: Boolean, authed: Boolean, waitForApproval: Boolean): RegisteredUser = {
|
||||
guest: Boolean, authed: Boolean, waitForApproval: Boolean): RegisteredUser = {
|
||||
val id = "w_" + RandomStringGenerator.randomAlphanumericString(16)
|
||||
val extId = RandomStringGenerator.randomAlphanumericString(16)
|
||||
val authToken = RandomStringGenerator.randomAlphanumericString(16)
|
||||
@ -18,14 +18,14 @@ object TestDataGen {
|
||||
}
|
||||
|
||||
def createVoiceUserForUser(user: RegisteredUser, callingWith: String, muted: Boolean, talking: Boolean,
|
||||
listenOnly: Boolean): VoiceUserState = {
|
||||
listenOnly: Boolean): VoiceUserState = {
|
||||
val voiceUserId = RandomStringGenerator.randomAlphanumericString(8)
|
||||
VoiceUserState(intId = user.id, voiceUserId = voiceUserId, callingWith, callerName = user.name,
|
||||
callerNum = user.name, muted, talking, listenOnly)
|
||||
}
|
||||
|
||||
def createFakeVoiceOnlyUser(callingWith: String, muted: Boolean, talking: Boolean,
|
||||
listenOnly: Boolean, name: String): VoiceUserState = {
|
||||
listenOnly: Boolean, name: String): VoiceUserState = {
|
||||
val voiceUserId = RandomStringGenerator.randomAlphanumericString(8)
|
||||
val intId = "v_" + RandomStringGenerator.randomAlphanumericString(16)
|
||||
VoiceUserState(intId, voiceUserId = voiceUserId, callingWith, callerName = name,
|
||||
|
Loading…
Reference in New Issue
Block a user