Merge branch 'bbb-2x-mconf' into userlist-2x-design

This commit is contained in:
Oswaldo Acauan 2017-08-01 14:29:12 -03:00
commit df35a22676
727 changed files with 10202 additions and 17756 deletions

View File

@ -1,6 +1,5 @@
package org.bigbluebutton.core.api;
import java.util.Map;
import org.bigbluebutton.common.messages.*;
public interface IBigBlueButtonInGW {
@ -14,36 +13,11 @@ public interface IBigBlueButtonInGW {
void destroyMeeting(String meetingID);
void getAllMeetings(String meetingID);
void lockSettings(String meetingID, Boolean locked, Map<String, Boolean> lockSettigs);
void activityResponse(String meetingID);
// Lock
void initLockSettings(String meetingID, Map<String, Boolean> settings);
void sendLockSettings(String meetingID, String userId, Map<String, Boolean> settings);
void getLockSettings(String meetingId, String userId);
// Users
void validateAuthToken(String meetingId, String userId, String token, String correlationId, String sessionId);
void registerUser(String roomName, String userid, String username, String role, String externUserID,
String authToken, String avatarURL, Boolean guest, Boolean authed);
void userEmojiStatus(String meetingId, String userId, String emojiStatus);
void shareWebcam(String meetingId, String userId, String stream);
void unshareWebcam(String meetingId, String userId, String stream);
void setUserStatus(String meetingID, String userID, String status, Object value);
void setUserRole(String meetingID, String userID, String role);
void getUsers(String meetingID, String requesterID);
void userLeft(String meetingID, String userID, String sessionId);
void userJoin(String meetingID, String userID, String authToken);
void getCurrentPresenter(String meetingID, String requesterID);
void checkIfAllowedToShareDesktop(String meetingID, String userID);
void assignPresenter(String meetingID, String newPresenterID, String newPresenterName, String assignedBy);
void setRecordingStatus(String meetingId, String userId, Boolean recording);
void getRecordingStatus(String meetingId, String userId);
void getGuestPolicy(String meetingID, String userID);
void setGuestPolicy(String meetingID, String guestPolicy, String setBy);
void responseToGuest(String meetingID, String userID, Boolean response, String requesterID);
void logoutEndMeeting(String meetingID, String userID);
// DeskShare
void deskShareStarted(String confId, String callerId, String callerIdName);
void deskShareStopped(String conferenceName, String callerId, String callerIdName);

View File

@ -1,44 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.GetLockSettingsMessage;
import org.bigbluebutton.common.messages.LockUserMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.SendLockSettingsMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
public class LockMessageReceiver implements MessageHandler {
private IBigBlueButtonInGW bbbGW;
public LockMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_MEETING_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (GetLockSettingsMessage.GET_LOCK_SETTINGS.equals(messageName)) {
GetLockSettingsMessage msg = GetLockSettingsMessage.fromJson(message);
bbbGW.getLockSettings(msg.meetingId, msg.userId);
} else if(LockUserMessage.LOCK_USER.equals(messageName)) {
LockUserMessage msg = LockUserMessage.fromJson(message);
} else if(SendLockSettingsMessage.SEND_LOCK_SETTINGS.equals(messageName)) {
SendLockSettingsMessage msg = SendLockSettingsMessage.fromJson(message);
bbbGW.sendLockSettings(msg.meetingId, msg.userId, msg.newSettings);
}
}
}
}
}
}

View File

@ -13,10 +13,8 @@ import org.bigbluebutton.common.messages.MessageFromJsonConverter;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.PubSubPingMessage;
import org.bigbluebutton.common.messages.ValidateAuthTokenMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import org.bigbluebutton.messages.CreateMeetingRequest;
import org.bigbluebutton.messages.RegisterUserMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -47,12 +45,6 @@ public class MeetingMessageReceiver implements MessageHandler {
Gson gson = new Gson();
CreateMeetingRequest msg = gson.fromJson(message, CreateMeetingRequest.class);
bbbGW.handleBigBlueButtonMessage(msg);
} else if (RegisterUserMessage.NAME.equals(messageName)) {
Gson gson = new Gson();
RegisterUserMessage msg = gson.fromJson(message, RegisterUserMessage.class);
bbbGW.registerUser(msg.payload.meetingId, msg.payload.userId, msg.payload.name, msg.payload.role,
msg.payload.extUserId, msg.payload.authToken, msg.payload.avatarUrl, msg.payload.guest,
msg.payload.authed);
}
}
}
@ -66,11 +58,6 @@ public class MeetingMessageReceiver implements MessageHandler {
} else if (msg instanceof DestroyMeetingMessage) {
DestroyMeetingMessage dmm = (DestroyMeetingMessage) msg;
bbbGW.destroyMeeting(dmm.meetingId);
} else if (msg instanceof ValidateAuthTokenMessage) {
ValidateAuthTokenMessage vam = (ValidateAuthTokenMessage) msg;
String sessionId = "tobeimplemented";
bbbGW.validateAuthToken(vam.meetingId, vam.userId, vam.token, vam.replyTo, sessionId);
} else if (msg instanceof GetAllMeetingsRequest) {
GetAllMeetingsRequest gamr = (GetAllMeetingsRequest) msg;
bbbGW.getAllMeetings("no_need_of_a_meeting_id");
} else if (msg instanceof ActivityResponseMessage) {

View File

@ -31,9 +31,6 @@ public class RedisMessageReceiver {
}
private void setupReceivers() {
LockMessageReceiver lockRx = new LockMessageReceiver(bbbGW);
receivers.add(lockRx);
UsersMessageReceiver usersRx = new UsersMessageReceiver(bbbGW);
receivers.add(usersRx);

View File

@ -30,109 +30,18 @@ public class UsersMessageReceiver implements MessageHandler{
if (header.has("name")) {
String messageName = header.get("name").getAsString();
switch (messageName) {
case UserLeavingMessage.USER_LEAVING:
processUserLeavingMessage(message);
break;
case AllowUserToShareDesktopRequest.NAME:
processAllowUserToShareDesktopRequest(message);
break;
case AssignPresenterRequestMessage.ASSIGN_PRESENTER_REQUEST:
processAssignPresenterRequestMessage(message);
break;
case UserEmojiStatusMessage.USER_EMOJI_STATUS:
processUserEmojiStatusMessage(message);
break;
case UserShareWebcamRequestMessage.USER_SHARE_WEBCAM_REQUEST:
processUserShareWebcamRequestMessage(message);
break;
case UserUnshareWebcamRequestMessage.USER_UNSHARE_WEBCAM_REQUEST:
processUserUnshareWebcamRequestMessage(message);
break;
case SetUserStatusRequestMessage.SET_USER_STATUS_REQUEST:
processSetUserStatusRequestMessage(message);
break;
case SetRecordingStatusRequestMessage.SET_RECORDING_STATUS_REQUEST:
processSetRecordingStatusRequestMessage(message);
break;
case GetRecordingStatusRequestMessage.GET_RECORDING_STATUS_REQUEST:
processGetRecordingStatusRequestMessage(message);
break;
case GetUsersRequestMessage.GET_USERS_REQUEST:
processGetUsersRequestMessage(message);
break;
case InitPermissionsSettingMessage.INIT_PERMISSIONS_SETTING:
processInitPermissionsSettingMessage(message);
break;
case ChangeUserRoleMessage.CHANGE_USER_ROLE:
processChangeUserRoleMessage(message);
break;
case GetGuestPolicyMessage.GET_GUEST_POLICY:
processGetGuestPolicyMessage(message);
break;
case SetGuestPolicyMessage.SET_GUEST_POLICY:
processSetGuestPolicyMessage(message);
break;
case RespondToGuestMessage.RESPOND_TO_GUEST:
processRespondToGuestMessage(message);
break;
case LogoutEndMeetingRequestMessage.LOGOUT_END_MEETING_REQUEST_MESSAGE:
processLogoutEndMeetingRequestMessage(message);
break;
}
}
}
}
}
private void processUserLeavingMessage(String message) {
UserLeavingMessage ulm = UserLeavingMessage.fromJson(message);
if (ulm != null) {
bbbInGW.userLeft(ulm.meetingId, ulm.userId, ulm.meetingId);
}
}
private void processAllowUserToShareDesktopRequest(String message) {
AllowUserToShareDesktopRequest msg = AllowUserToShareDesktopRequest.fromJson(message);
if (msg != null) {
bbbInGW.checkIfAllowedToShareDesktop(msg.meetingId, msg.userId);
}
}
private void processAssignPresenterRequestMessage(String message) {
AssignPresenterRequestMessage apm = AssignPresenterRequestMessage.fromJson(message);
if (apm != null) {
bbbInGW.assignPresenter(apm.meetingId, apm.newPresenterId, apm.newPresenterName, apm.assignedBy);
}
}
private void processUserEmojiStatusMessage(String message) {
UserEmojiStatusMessage uesm = UserEmojiStatusMessage.fromJson(message);
if (uesm != null) {
bbbInGW.userEmojiStatus(uesm.meetingId, uesm.userId, uesm.emojiStatus);
}
}
private void processUserShareWebcamRequestMessage(String message) {
UserShareWebcamRequestMessage msg = UserShareWebcamRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.shareWebcam(msg.meetingId, msg.userId, msg.stream);
}
}
private void processUserUnshareWebcamRequestMessage(String message) {
UserUnshareWebcamRequestMessage msg = UserUnshareWebcamRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.unshareWebcam(msg.meetingId, msg.userId, msg.stream);
}
}
private void processSetUserStatusRequestMessage(String message) {
SetUserStatusRequestMessage msg = SetUserStatusRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.setUserStatus(msg.meetingId, msg.userId, msg.status, msg.value);
}
}
private void processSetRecordingStatusRequestMessage(String message) {
SetRecordingStatusRequestMessage msg = SetRecordingStatusRequestMessage.fromJson(message);
if (msg != null) {
@ -146,53 +55,4 @@ public class UsersMessageReceiver implements MessageHandler{
bbbInGW.getRecordingStatus(msg.meetingId, msg.userId);
}
}
private void processGetUsersRequestMessage(String message) {
GetUsersRequestMessage msg = GetUsersRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.getUsers(msg.meetingId, msg.requesterId);
}
}
private void processInitPermissionsSettingMessage(String message) {
InitPermissionsSettingMessage msg = InitPermissionsSettingMessage.fromJson(message);
if (msg != null) {
bbbInGW.initLockSettings(msg.meetingId, msg.permissions);
}
}
private void processChangeUserRoleMessage(String message) {
ChangeUserRoleMessage msg = ChangeUserRoleMessage.fromJson(message);
if (msg != null) {
bbbInGW.setUserRole(msg.meetingId, msg.userId, msg.role);
}
}
private void processGetGuestPolicyMessage(String message) {
GetGuestPolicyMessage msg = GetGuestPolicyMessage.fromJson(message);
if (msg != null) {
bbbInGW.getGuestPolicy(msg.meetingId, msg.requesterId);
}
}
private void processSetGuestPolicyMessage(String message) {
SetGuestPolicyMessage msg = SetGuestPolicyMessage.fromJson(message);
if (msg != null) {
bbbInGW.setGuestPolicy(msg.meetingId, msg.guestPolicy, msg.setBy);
}
}
private void processRespondToGuestMessage(String message) {
RespondToGuestMessage msg = RespondToGuestMessage.fromJson(message);
if (msg != null) {
bbbInGW.responseToGuest(msg.meetingId, msg.userId, msg.response, msg.requesterId);
}
}
private void processLogoutEndMeetingRequestMessage(String message) {
LogoutEndMeetingRequestMessage lemm = LogoutEndMeetingRequestMessage.fromJson(message);
if (lemm != null) {
bbbInGW.logoutEndMeeting(lemm.meetingId, lemm.userId);
}
}
}

View File

@ -17,22 +17,17 @@ object Boot extends App with SystemConfiguration {
val eventBus = new InMsgBusGW(new IncomingEventBusImp())
val outgoingEventBus = new OutgoingEventBus
val outBus2 = new OutEventBus2
val recordingEventBus = new RecordingEventBus
val outGW = new OutMessageGatewayImp(outgoingEventBus, outBus2, recordingEventBus)
val outGW = new OutMessageGatewayImp(outBus2)
val redisPublisher = new RedisPublisher(system)
val msgSender = new MessageSender(redisPublisher)
val redisRecorderActor = system.actorOf(RedisRecorderActor.props(system), "redisRecorderActor")
val messageSenderActor = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor")
outgoingEventBus.subscribe(messageSenderActor, outMessageChannel)
outgoingEventBus.subscribe(redisRecorderActor, outMessageChannel)
recordingEventBus.subscribe(redisRecorderActor, outMessageChannel)
val incomingJsonMessageBus = new IncomingJsonMessageBus
val bbbMsgBus = new BbbMsgRouterEventBus

View File

@ -21,7 +21,7 @@ import org.bigbluebutton.core2.message.senders.MsgBuilder
object BigBlueButtonActor extends SystemConfiguration {
def props(
system: ActorSystem,
eventBus: IncomingEventBus,
eventBus: InternalEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway
): Props =
@ -30,7 +30,7 @@ object BigBlueButtonActor extends SystemConfiguration {
class BigBlueButtonActor(
val system: ActorSystem,
val eventBus: IncomingEventBus, val bbbMsgBus: BbbMsgRouterEventBus,
val eventBus: InternalEventBus, val bbbMsgBus: BbbMsgRouterEventBus,
val outGW: OutMessageGateway
) extends Actor
with ActorLogging with SystemConfiguration {
@ -59,21 +59,21 @@ class BigBlueButtonActor(
}
def receive = {
// 2x messages
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
// Internal messages
case msg: DestroyMeetingInternalMsg => handleDestroyMeeting(msg)
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
case _ => // do nothing
// 2x messages
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
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: DestroyMeetingSysCmdMsg => handleDestroyMeeting(m)
case _ => log.warning("Cannot handle " + msg.envelope.name)
case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: PubSubPingSysReqMsg => handlePubSubPingSysReqMsg(m)
case _ => log.warning("Cannot handle " + msg.envelope.name)
}
}
@ -109,7 +109,7 @@ class BigBlueButtonActor(
// Send new 2x message
val msgEvent = MsgBuilder.buildMeetingCreatedEvtMsg(m.props.meetingProp.intId, msg.body.props)
outGW.send(msgEvent)
m.outMsgRouter.send(msgEvent)
case Some(m) =>
log.info("Meeting already created. meetingID={}", msg.body.props.meetingProp.intId)
@ -125,67 +125,40 @@ class BigBlueButtonActor(
})
}
private def handleValidateAuthToken(msg: ValidateAuthToken) {
for {
m <- RunningMeetings.findWithId(meetings, msg.meetingID)
} yield {
m.actorRef forward (msg)
}
//meetings.get(msg.meetingID) foreach { m =>
// m.actorRef ! msg
// val future = m.actorRef.ask(msg)(5 seconds)
// future onComplete {
// case Success(result) => {
// log.info("Validate auth token response. meetingId=" + msg.meetingID + " userId=" + msg.userId + " token=" + msg.token)
// /**
// * Received a reply from MeetingActor which means hasn't hung!
// * Sometimes, the actor seems to hang and doesn't anymore accept messages. This is a simple
// * audit to check whether the actor is still alive. (ralam feb 25, 2015)
// */
// }
// case Failure(failure) => {
// log.warning("Validate auth token timeout. meetingId=" + msg.meetingID + " userId=" + msg.userId + " token=" + msg.token)
// outGW.send(new ValidateAuthTokenTimedOut(msg.meetingID, msg.userId, msg.token, false, msg.correlationId))
// }
// }
//}
}
private def handlePubSubPingSysReqMsg(msg: PubSubPingSysReqMsg): Unit = {
val event = MsgBuilder.buildPubSubPongSysRespMsg(msg.body.system, msg.body.timestamp)
outGW.send(event)
}
private def handleDestroyMeeting(msg: DestroyMeetingSysCmdMsg): Unit = {
private def handleDestroyMeeting(msg: DestroyMeetingInternalMsg): Unit = {
for {
m <- RunningMeetings.findWithId(meetings, msg.body.meetingId)
m2 <- RunningMeetings.remove(meetings, msg.body.meetingId)
m <- RunningMeetings.findWithId(meetings, msg.meetingId)
m2 <- RunningMeetings.remove(meetings, msg.meetingId)
} yield {
// send the message for MeetingActor to handle too
m.actorRef ! msg
/** Unsubscribe to meeting and voice events. **/
eventBus.unsubscribe(m.actorRef, m.props.meetingProp.intId)
eventBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf)
eventBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
// Delay sending DisconnectAllUsers because of RTMPT connection being dropped before UserEject message arrives to the client
bbbMsgBus.unsubscribe(m.actorRef, m.props.meetingProp.intId)
bbbMsgBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf)
bbbMsgBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
// Delay sending DisconnectAllUsers to allow messages to reach the client
// before the connections are closed.
context.system.scheduler.scheduleOnce(Duration.create(2500, TimeUnit.MILLISECONDS)) {
// Disconnect all clients
val disconnectEvnt = MsgBuilder.buildDisconnectAllClientsSysMsg(msg.body.meetingId)
outGW.send(disconnectEvnt)
val disconnectEvnt = MsgBuilder.buildDisconnectAllClientsSysMsg(msg.meetingId)
m2.outMsgRouter.send(disconnectEvnt)
log.info("Destroyed meetingId={}", msg.body.meetingId)
val destroyedEvent = MsgBuilder.buildMeetingDestroyedEvtMsg(msg.body.meetingId)
outGW.send(destroyedEvent)
val stopTranscodersCmd = MsgBuilder.buildStopMeetingTranscodersSysCmdMsg(msg.meetingId)
m2.outMsgRouter.send(stopTranscodersCmd)
/** Unsubscribe to meeting and voice events. **/
eventBus.unsubscribe(m.actorRef, m.props.meetingProp.intId)
eventBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf)
eventBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
bbbMsgBus.unsubscribe(m.actorRef, m.props.meetingProp.intId)
bbbMsgBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf)
bbbMsgBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
log.info("Destroyed meetingId={}", msg.meetingId)
val destroyedEvent = MsgBuilder.buildMeetingDestroyedEvtMsg(msg.meetingId)
m2.outMsgRouter.send(destroyedEvent)
// Stop the meeting actor.
context.stop(m.actorRef)

View File

@ -10,13 +10,12 @@ import org.bigbluebutton.common.messages.PubSubPingMessage
import org.bigbluebutton.messages._
import akka.event.Logging
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.core.models.{ GuestPolicyType, Roles }
import scala.collection.JavaConverters
class BigBlueButtonInGW(
val system: ActorSystem,
eventBus: IncomingEventBus,
eventBus: InternalEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway
) extends IBigBlueButtonInGW with SystemConfiguration {
@ -37,13 +36,13 @@ class BigBlueButtonInGW(
}
case msg: CreateMeetingRequest => {
val policy = msg.payload.guestPolicy.toUpperCase() match {
/*val policy = msg.payload.guestPolicy.toUpperCase() match {
case "ALWAYS_ACCEPT" => GuestPolicyType.ALWAYS_ACCEPT
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
case "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
//default
case undef => GuestPolicyType.ASK_MODERATOR
}
}*/
/*
val mProps = new MeetingProperties(
msg.payload.id,
@ -78,7 +77,7 @@ class BigBlueButtonInGW(
eventBus.publish(
BigBlueButtonEvent(
"meeting-manager",
new DestroyMeeting(
new DestroyMeetingInternalMsg(
meetingID
)
)
@ -93,10 +92,6 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent("meeting-manager", new KeepAliveMessage(aliveId)))
}
def lockSettings(meetingID: String, locked: java.lang.Boolean,
lockSettings: java.util.Map[String, java.lang.Boolean]) {
}
def statusMeetingAudit(meetingID: String) {
}
@ -118,73 +113,6 @@ class BigBlueButtonInGW(
* Message Interface for Users
* ***********************************************************
*/
def validateAuthToken(meetingId: String, userId: String, token: String, correlationId: String, sessionId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new ValidateAuthToken(meetingId, userId, token, correlationId, sessionId)))
}
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 = {
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)))
}
def sendLockSettings(meetingID: String, userId: String, settings: java.util.Map[String, java.lang.Boolean]) {
// Convert java.util.Map to scala.collection.immutable.Map
// settings.mapValues -> convaert java Map to scala mutable Map
// v => v.booleanValue() -> convert java Boolean to Scala Boolean
// toMap -> converts from scala mutable map to scala immutable map
val s = settings.mapValues(v => v.booleanValue() /* convert java Boolean to Scala Boolean */ ).toMap
val disableCam = s.getOrElse("disableCam", false)
val disableMic = s.getOrElse("disableMic", false)
val disablePrivChat = s.getOrElse("disablePrivateChat", false)
val disablePubChat = s.getOrElse("disablePublicChat", false)
val lockedLayout = s.getOrElse("lockedLayout", false)
val lockOnJoin = s.getOrElse("lockOnJoin", false)
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
val permissions = new Permissions(
disableCam = disableCam,
disableMic = disableMic,
disablePrivChat = disablePrivChat,
disablePubChat = disablePubChat,
lockedLayout = lockedLayout,
lockOnJoin = lockOnJoin,
lockOnJoinConfigurable = lockOnJoinConfigurable
)
eventBus.publish(BigBlueButtonEvent(meetingID, new SetLockSettings(meetingID, userId, permissions)))
}
def initLockSettings(meetingID: String, settings: java.util.Map[String, java.lang.Boolean]) {
// Convert java.util.Map to scala.collection.immutable.Map
// settings.mapValues -> convert java Map to scala mutable Map
// v => v.booleanValue() -> convert java Boolean to Scala Boolean
// toMap -> converts from scala mutable map to scala immutable map
val s = settings.mapValues(v => v.booleanValue() /* convert java Boolean to Scala Boolean */ ).toMap
val disableCam = s.getOrElse("disableCam", false)
val disableMic = s.getOrElse("disableMic", false)
val disablePrivChat = s.getOrElse("disablePrivateChat", false)
val disablePubChat = s.getOrElse("disablePublicChat", false)
val lockedLayout = s.getOrElse("lockedLayout", false)
val lockOnJoin = s.getOrElse("lockOnJoin", false)
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
val permissions = new Permissions(
disableCam = disableCam,
disableMic = disableMic,
disablePrivChat = disablePrivChat,
disablePubChat = disablePubChat,
lockedLayout = lockedLayout,
lockOnJoin = lockOnJoin,
lockOnJoinConfigurable = lockOnJoinConfigurable
)
eventBus.publish(BigBlueButtonEvent(meetingID, new InitLockSettings(meetingID, permissions)))
}
def getLockSettings(meetingId: String, userId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new GetLockSettings(meetingId, userId)))
}
def setRecordingStatus(meetingId: String, userId: String, recording: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingId, new SetRecordingStatus(meetingId, userId, recording.booleanValue())))
@ -194,87 +122,6 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent(meetingId, new GetRecordingStatus(meetingId, userId)))
}
// Users
def userEmojiStatus(meetingId: String, userId: String, emojiStatus: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new UserEmojiStatus(meetingId, userId, emojiStatus)))
}
def ejectUserFromMeeting(meetingId: String, userId: String, ejectedBy: String) {
}
def logoutEndMeeting(meetingId: String, userId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new LogoutEndMeeting(meetingId, userId)))
}
def shareWebcam(meetingId: String, userId: String, stream: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new UserShareWebcam(meetingId, userId, stream)))
}
def unshareWebcam(meetingId: String, userId: String, stream: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new UserUnshareWebcam(meetingId, userId, stream)))
}
def setUserStatus(meetingID: String, userID: String, status: String, value: Object) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ChangeUserStatus(meetingID, userID, status, value)))
}
def setUserRole(meetingID: String, userID: String, role: String) {
}
def getUsers(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetUsers(meetingID, requesterID)))
}
def userLeft(meetingID: String, userID: String, sessionId: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new UserLeaving(meetingID, userID, sessionId)))
}
def userJoin(meetingID: String, userID: String, authToken: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new UserJoining(meetingID, userID, authToken)))
}
def checkIfAllowedToShareDesktop(meetingID: String, userID: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(
meetingID: String,
userID: String
)))
}
def assignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new AssignPresenter(meetingID, newPresenterID, newPresenterName, assignedBy)))
}
def getCurrentPresenter(meetingID: String, requesterID: String): Unit = {
// do nothing
}
/**
* ***********************************************************************
* Message Interface for Guest
* *******************************************************************
*/
def getGuestPolicy(meetingId: String, requesterId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new GetGuestPolicy(meetingId, requesterId)))
}
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 "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
//default
case undef => GuestPolicyType.ASK_MODERATOR
}
eventBus.publish(BigBlueButtonEvent(meetingId, new SetGuestPolicy(meetingId, policy, requesterId)))
}
def responseToGuest(meetingId: String, userId: String, response: java.lang.Boolean, requesterId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new RespondToGuest(meetingId, userId, response, requesterId)))
}
/**
* *******************************************************************
* Message Interface for DeskShare

View File

@ -13,7 +13,6 @@ class MeetingModel {
private var permissionsInited = false
private var permissions = new Permissions()
private var recording = false
private var broadcastingRTMP = false
private var muted = false
private var meetingEnded = false
private var meetingMuted = false
@ -23,70 +22,11 @@ class MeetingModel {
private var lastWebUserLeftOnTimestamp: Long = 0
private var voiceRecordingFilename: String = ""
private var rtmpBroadcastingUrl: String = ""
private var deskShareStarted = false
private var desktopShareVideoWidth = 0
private var desktopShareVideoHeight = 0
private var extension = new MeetingExtensionProp
/*
val startedOn = timeNowInSeconds;
var breakoutRoomsStartedOn: Long = 0
var breakoutRoomsdurationInMinutes: Int = 0
def resetDesktopSharingParams() = {
broadcastingRTMP = false
deskShareStarted = false
rtmpBroadcastingUrl = ""
desktopShareVideoWidth = 0
desktopShareVideoHeight = 0
}
def getDeskShareStarted(): Boolean = {
return deskShareStarted
}
def setDeskShareStarted(b: Boolean) {
deskShareStarted = b
}
def setDesktopShareVideoWidth(videoWidth: Int) {
desktopShareVideoWidth = videoWidth
}
def setDesktopShareVideoHeight(videoHeight: Int) {
desktopShareVideoHeight = videoHeight
}
def getDesktopShareVideoWidth(): Int = {
desktopShareVideoWidth
}
def getDesktopShareVideoHeight(): Int = {
desktopShareVideoHeight
}
def broadcastingRTMPStarted() {
broadcastingRTMP = true
}
def isBroadcastingRTMP(): Boolean = {
broadcastingRTMP
}
def broadcastingRTMPStopped() {
broadcastingRTMP = false
}
def setRTMPBroadcastingUrl(path: String) {
rtmpBroadcastingUrl = path
}
def getRTMPBroadcastingUrl(): String = {
rtmpBroadcastingUrl
}
def isExtensionAllowed(): Boolean = extension.numExtensions < extension.maxExtensions
def incNumExtension(): Int = {
if (extension.numExtensions < extension.maxExtensions) {

View File

@ -1,11 +0,0 @@
package org.bigbluebutton.core
import org.bigbluebutton.common2.msgs.BbbCoreMsg
object MessageRecorder {
def record(outGW: OutMessageGateway, record: Boolean, msg: BbbCoreMsg): Unit = {
if (record) {
outGW.record(msg)
}
}
}

View File

@ -9,13 +9,10 @@ import java.io.{ PrintWriter, StringWriter }
import org.bigbluebutton.core.api._
import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.core.pubsub.senders.MeetingMessageToJsonConverter
import org.bigbluebutton.common.messages.AllowUserToShareDesktopReply
import scala.collection.JavaConversions._
import scala.concurrent.duration._
import org.bigbluebutton.core.pubsub.senders.UsersMessageToJsonConverter
import org.bigbluebutton.common.messages.UserEjectedFromMeetingMessage
import org.bigbluebutton.common.converters.ToJsonEncoder
import org.bigbluebutton.common.messages.StopMeetingTranscodersMessage
import scala.collection.JavaConverters
object MessageSenderActor {
@ -38,51 +35,23 @@ class MessageSenderActor(val service: MessageSender)
val encoder = new ToJsonEncoder()
def receive = {
case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg)
case msg: MeetingCreated => handleMeetingCreated(msg)
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
case msg: GetRecordingStatusReply => handleGetRecordingStatusReply(msg)
case msg: MeetingEnding => handleMeetingEnding(msg)
case msg: MeetingEnded => handleMeetingEnded(msg)
case msg: MeetingHasEnded => handleMeetingHasEnded(msg)
case msg: MeetingDestroyed => handleMeetingDestroyed(msg)
case msg: KeepAliveMessageReply => handleKeepAliveMessageReply(msg)
case msg: PubSubPong => handlePubSubPong(msg)
case msg: InactivityWarning => handleInactivityWarning(msg)
case msg: MeetingIsActive => handleMeetingIsActive(msg)
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
case msg: MeetingMuted => handleMeetingMuted(msg)
case msg: MeetingState => handleMeetingState(msg)
case msg: DisconnectAllUsers => handleDisconnectAllUsers(msg)
case msg: AllowUserToShareDesktopOut => handleAllowUserToShareDesktopOut(msg)
case msg: DisconnectUser => handleDisconnectUser(msg)
case msg: PermissionsSettingInitialized => handlePermissionsSettingInitialized(msg)
case msg: NewPermissionsSetting => handleNewPermissionsSetting(msg)
case msg: UserLocked => handleUserLocked(msg)
case msg: GetPermissionsSettingReply => handleGetPermissionsSettingReply(msg)
case msg: UserRegistered => handleUserRegistered(msg)
case msg: UserLeft => handleUserLeft(msg)
case msg: PresenterAssigned => handlePresenterAssigned(msg)
case msg: EndAndKickAll => handleEndAndKickAll(msg)
case msg: GetUsersReply => handleGetUsersReply(msg)
case msg: ValidateAuthTokenReply => handleValidateAuthTokenReply(msg)
case msg: ValidateAuthTokenTimedOut => handleValidateAuthTokenTimedOut(msg)
case msg: UserJoined => handleUserJoined(msg)
case msg: UserChangedEmojiStatus => handleChangedUserEmojiStatus(msg)
case msg: UserSharedWebcam => handleUserSharedWebcam(msg)
case msg: UserUnsharedWebcam => handleUserUnsharedWebcam(msg)
case msg: UserStatusChange => handleUserStatusChange(msg)
case msg: UserRoleChange => handleUserRoleChange(msg)
case msg: GetGuestPolicyReply => handleGetGuestPolicyReply(msg)
case msg: GuestPolicyChanged => handleGuestPolicyChanged(msg)
case msg: GuestAccessDenied => handleGuestAccessDenied(msg)
case _ => // do nothing
}
private def handleUserEjectedFromMeeting(msg: UserEjectedFromMeeting) {
val m = new UserEjectedFromMeetingMessage(msg.meetingID, msg.userId, msg.ejectedBy)
service.send(MessagingConstants.FROM_USERS_CHANNEL, m.toJson)
case msg: MeetingCreated => handleMeetingCreated(msg)
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
case msg: GetRecordingStatusReply => handleGetRecordingStatusReply(msg)
case msg: MeetingEnding => handleMeetingEnding(msg)
case msg: MeetingEnded => handleMeetingEnded(msg)
case msg: MeetingHasEnded => handleMeetingHasEnded(msg)
case msg: MeetingDestroyed => handleMeetingDestroyed(msg)
case msg: KeepAliveMessageReply => handleKeepAliveMessageReply(msg)
case msg: PubSubPong => handlePubSubPong(msg)
case msg: InactivityWarning => handleInactivityWarning(msg)
case msg: MeetingIsActive => handleMeetingIsActive(msg)
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
case msg: MeetingMuted => handleMeetingMuted(msg)
case msg: MeetingState => handleMeetingState(msg)
case msg: DisconnectAllUsers => handleDisconnectAllUsers(msg)
case msg: DisconnectUser => handleDisconnectUser(msg)
case _ => // do nothing
}
private def handleMeetingDestroyed(msg: MeetingDestroyed) {
@ -176,127 +145,4 @@ class MessageSenderActor(val service: MessageSender)
val json = UsersMessageToJsonConverter.disconnectUserToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleAllowUserToShareDesktopOut(msg: AllowUserToShareDesktopOut): Unit = {
val obj = new AllowUserToShareDesktopReply(msg.meetingID, msg.userID, msg.allowed,
TimestampGenerator.generateTimestamp)
val json = obj.toJson()
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handlePermissionsSettingInitialized(msg: PermissionsSettingInitialized) {
val json = UsersMessageToJsonConverter.permissionsSettingInitializedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleNewPermissionsSetting(msg: NewPermissionsSetting) {
val json = UsersMessageToJsonConverter.newPermissionsSettingToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleUserLocked(msg: UserLocked) {
val json = UsersMessageToJsonConverter.userLockedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleGetPermissionsSettingReply(msg: GetPermissionsSettingReply) {
val json = UsersMessageToJsonConverter.getPermissionsSettingReplyToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleUserRegistered(msg: UserRegistered) {
val json = UsersMessageToJsonConverter.userRegisteredToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
handleRegisteredUser(msg);
}
private def handleUserStatusChange(msg: UserStatusChange) {
val json = UsersMessageToJsonConverter.userStatusChangeToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserRoleChange(msg: UserRoleChange) {
val json = UsersMessageToJsonConverter.userRoleChangeToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleChangedUserEmojiStatus(msg: UserChangedEmojiStatus) {
val json = UsersMessageToJsonConverter.userChangedEmojiStatusToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserSharedWebcam(msg: UserSharedWebcam) {
val json = UsersMessageToJsonConverter.userSharedWebcamToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserUnsharedWebcam(msg: UserUnsharedWebcam) {
val json = UsersMessageToJsonConverter.userUnsharedWebcamToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleGetUsersReply(msg: GetUsersReply) {
val json = UsersMessageToJsonConverter.getUsersReplyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleValidateAuthTokenReply(msg: ValidateAuthTokenReply) {
println("**** handleValidateAuthTokenReply *****")
val json = UsersMessageToJsonConverter.validateAuthTokenReplyToJson(msg)
//println("************** Publishing [" + json + "] *******************")
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleValidateAuthTokenTimedOut(msg: ValidateAuthTokenTimedOut) {
println("**** handleValidateAuthTokenTimedOut *****")
val json = UsersMessageToJsonConverter.validateAuthTokenTimeoutToJson(msg)
//println("************** Publishing [" + json + "] *******************")
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserJoined(msg: UserJoined) {
val json = UsersMessageToJsonConverter.userJoinedToJson(msg)
//println("************** Publishing [" + json + "] *******************")
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleRegisteredUser(msg: UserRegistered) {
val json = UsersMessageToJsonConverter.userRegisteredToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserLeft(msg: UserLeft) {
val json = UsersMessageToJsonConverter.userLeftToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handlePresenterAssigned(msg: PresenterAssigned) {
val json = UsersMessageToJsonConverter.presenterAssignedToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleEndAndKickAll(msg: EndAndKickAll) {
val json = UsersMessageToJsonConverter.endAndKickAllToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleStopMeetingTranscoders(msg: StopMeetingTranscoders) {
val smt = new StopMeetingTranscodersMessage(msg.meetingID)
service.send(MessagingConstants.TO_BBB_TRANSCODE_SYSTEM_CHAN, smt.toJson())
}
private def handleGetGuestPolicyReply(msg: GetGuestPolicyReply) {
val json = UsersMessageToJsonConverter.getGuestPolicyReplyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleGuestPolicyChanged(msg: GuestPolicyChanged) {
val json = UsersMessageToJsonConverter.guestPolicyChangedToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleGuestAccessDenied(msg: GuestAccessDenied) {
val json = UsersMessageToJsonConverter.guestAccessDeniedToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
}

View File

@ -1,13 +1,10 @@
package org.bigbluebutton.core
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreMsg }
import org.bigbluebutton.core.api.IOutMessage
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg }
trait OutMessageGateway {
def send1(msg: IOutMessage)
def send(msg: BbbCommonEnvCoreMsg): Unit
def record(msg: BbbCoreMsg): Unit
def record(msg: BbbCommonEnvCoreMsg): Unit
}

View File

@ -7,29 +7,21 @@ import org.bigbluebutton.core.bus._
object OutMessageGatewayImp {
def apply(
outgoingEventBus: OutgoingEventBus,
outBus2: OutEventBus2,
recordBus: RecordingEventBus
outBus2: OutEventBus2
) =
new OutMessageGatewayImp(outgoingEventBus, outBus2, recordBus)
new OutMessageGatewayImp(outBus2)
}
class OutMessageGatewayImp(
outgoingEventBus: OutgoingEventBus,
outBus2: OutEventBus2,
recordBus: RecordingEventBus
outBus2: OutEventBus2
) extends OutMessageGateway
with SystemConfiguration {
def send1(msg: IOutMessage) {
outgoingEventBus.publish(BigBlueButtonOutMessage(outMessageChannel, msg))
}
def send(msg: BbbCommonEnvCoreMsg): Unit = {
outBus2.publish(BbbOutMessage(outBbbMsgMsgChannel, msg))
}
def record(msg: BbbCoreMsg): Unit = {
recordBus.publish(BbbRecordMessage(recordServiceMessageChannel, msg))
def record(msg: BbbCommonEnvCoreMsg): Unit = {
outBus2.publish(BbbOutMessage(recordServiceMessageChannel, msg))
}
}

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core.api
import org.bigbluebutton.common2.msgs.BreakoutUserVO
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.domain.BreakoutUser
import spray.json.JsObject
case class InMessageHeader(name: String)
case class InHeaderAndJsonPayload(header: InMessageHeader, payload: JsObject)
@ -18,58 +18,70 @@ case class IsMeetingActorAliveMessage(meetingId: String) extends InMessage
case class KeepAliveMessage(aliveID: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////
// Meeting
// Internal Messages
/////////////////////////////////////////////////////////////////////////////
case class MonitorNumberOfUsers(meetingID: String) extends InMessage
case class SendTimeRemainingUpdate(meetingId: String) extends InMessage
case class MonitorNumberOfUsersInternalMsg(meetingID: String) extends InMessage
/**
* Audit message sent to meeting to trigger updating clients of meeting time remaining.
* @param meetingId
*/
case class SendTimeRemainingAuditInternalMsg(meetingId: String) extends InMessage
case class ExtendMeetingDuration(meetingId: String, userId: String) extends InMessage
case class DestroyMeeting(meetingID: String) extends InMessage
case class DestroyMeetingInternalMsg(meetingId: String) extends InMessage
/**
* Sent by breakout room to parent meeting the breakout had ended.
* @param meetingId
*/
case class BreakoutRoomEndedInternalMsg(meetingId: String) extends InMessage
/**
* Sent by breakout room to parent meeting that breakout room has been created.
* @param parentId
* @param breakoutId
*/
case class BreakoutRoomCreatedInternalMsg(parentId: String, breakoutId: String) extends InMessage
/**
* Audit message to trigger breakout room to update parent meeting of list of users.
* @param parentId
* @param breakoutId
*/
case class SendBreakoutUsersAuditInternalMsg(parentId: String, breakoutId: String) extends InMessage
/**
* Send by breakout room to parent meeting with list of users in breakout room.
* @param parentId
* @param breakoutId
* @param users
*/
case class BreakoutRoomUsersUpdateInternalMsg(parentId: String, breakoutId: String, users: Vector[BreakoutUser]) extends InMessage
/**
* Sent by parent meeting to breakout room to end breakout room.
* @param parentId
* @param breakoutId
*/
case class EndBreakoutRoomInternalMsg(parentId: String, breakoutId: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////
// Meeting
/////////////////////////////////////////////////////////////////////////////
case class StartMeeting(meetingID: String) extends InMessage
case class EndMeeting(meetingId: String) extends InMessage
case class LockSetting(meetingID: String, locked: Boolean, settings: Map[String, Boolean]) extends InMessage
case class UpdateMeetingExpireMonitor(meetingID: String, hasUser: Boolean) extends InMessage
////////////////////////////////////////////////////////////////////////////////////
// Lock
///////////////////////////////////////////////////////////////////////////////////
case class LockUser(meetingID: String, userId: String, lock: Boolean) extends InMessage
case class InitLockSettings(meetingID: String, settings: Permissions) extends InMessage
case class SetLockSettings(meetingID: String, setByUser: String, settings: Permissions) extends InMessage
case class GetLockSettings(meetingID: String, userId: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////
// Users
/////////////////////////////////////////////////////////////////////////////////
case class ValidateAuthToken(meetingID: String, userId: String, token: String,
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
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
case class UserEmojiStatus(meetingID: String, userId: String, emojiStatus: String) extends InMessage
case class UserShareWebcam(meetingID: String, userId: String, stream: String) extends InMessage
case class UserUnshareWebcam(meetingID: String, userId: String, stream: String) extends InMessage
case class ChangeUserStatus(meetingID: String, userID: String, status: String, value: Object) extends InMessage
case class AssignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String) extends InMessage
case class SetRecordingStatus(meetingID: String, userId: String, recording: Boolean) extends InMessage
case class GetRecordingStatus(meetingID: String, userId: String) extends InMessage
case class AllowUserToShareDesktop(meetingID: String, userID: String) extends InMessage
case class ActivityResponse(meetingID: String) extends InMessage
case class LogoutEndMeeting(meetingID: String, userID: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////////
// Guest support
///////////////////////////////////////////////////////////////////////////////////////
case class GetGuestPolicy(meetingID: String, requesterID: String) extends InMessage
case class SetGuestPolicy(meetingID: String, policy: String, setBy: String) extends InMessage
case class RespondToGuest(meetingID: String, userId: String, response: Boolean, requesterID: String) extends InMessage
// No idea what part this is for
case class GetAllMeetingsRequest(meetingID: String /** Not used. Just to satisfy trait **/ ) extends InMessage

View File

@ -2,8 +2,6 @@ package org.bigbluebutton.core.api
import org.bigbluebutton.core.apps._
import org.bigbluebutton.core.models._
import org.bigbluebutton.common2.domain.UserVO
import org.bigbluebutton.common2.msgs.{ BreakoutRoomInfo, BreakoutUserVO }
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
@ -23,31 +21,6 @@ case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
case object IsAliveMessage extends IOutMessage
// Permissions
case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class NewPermissionsSetting(meetingID: String, setByUser: String, permissions: Permissions, applyTo: Vector[UserState]) extends IOutMessage
case class UserLocked(meetingID: String, userId: String, lock: Boolean) extends IOutMessage
case class GetPermissionsSettingReply(meetingID: String, userId: String) extends IOutMessage
// Users
case class UserRegistered(meetingID: String, recorded: Boolean, user: RegisteredUser) extends IOutMessage
case class UserLeft(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserEjectedFromMeeting(meetingID: String, recorded: Boolean, userId: String, ejectedBy: String) extends IOutMessage
case class PresenterAssigned(meetingID: String, recorded: Boolean, presenter: Presenter) extends IOutMessage
case class EjectAllVoiceUsers(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class EndAndKickAll(meetingID: String, recorded: Boolean) extends IOutMessage
case class GetUsersReply(meetingID: String, requesterID: String, users: Array[UserVO]) extends IOutMessage
case class ValidateAuthTokenTimedOut(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class ValidateAuthTokenReply(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class UserJoined(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserChangedEmojiStatus(meetingID: String, recorded: Boolean, emojiStatus: String, userID: String) extends IOutMessage
case class UserSharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserUnsharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserStatusChange(meetingID: String, recorded: Boolean, userID: String, status: String, value: Object) extends IOutMessage
case class UserRoleChange(meetingID: String, recorded: Boolean, userID: String, role: String) extends IOutMessage
case class TransferUserToMeeting(voiceConfId: String, targetVoiceConfId: String, userId: String) extends IOutMessage
case class AllowUserToShareDesktopOut(meetingID: String, userID: String, allowed: Boolean) extends IOutMessage
// No idea what part this is for
case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage
@ -58,11 +31,6 @@ case class DeskShareNotifyViewersRTMP(meetingID: String, streamPath: String, vid
case class DeskShareNotifyASingleViewer(meetingID: String, userID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareHangUp(meetingID: String, fsConferenceName: String) extends IOutMessage
// Guest
case class GetGuestPolicyReply(meetingID: String, recorded: Boolean, requesterID: String, policy: String) extends IOutMessage
case class GuestPolicyChanged(meetingID: String, recorded: Boolean, policy: String) extends IOutMessage
case class GuestAccessDenied(meetingID: String, recorded: Boolean, userId: String) extends IOutMessage
//Transcode
case class StopMeetingTranscoders(meetingID: String) extends IOutMessage

View File

@ -0,0 +1,77 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.domain.{ BreakoutRoom2x, BreakoutUser }
object BreakoutModel {
def create(
parentId: String,
id: String,
externalId: String,
name: String,
sequence: Integer,
voiceConf: String,
assignedUsers: Vector[String]
): BreakoutRoom2x = {
new BreakoutRoom2x(id, externalId, name, parentId, sequence, voiceConf, assignedUsers, Vector(), None, false)
}
}
case class BreakoutModel(
startedOn: Option[Long],
durationInMinutes: Int,
rooms: Map[String, BreakoutRoom2x]
) {
def find(id: String): Option[BreakoutRoom2x] = {
rooms.get(id)
}
def findWithExternalId(externalId: String): Option[BreakoutRoom2x] = {
rooms.values find (r => r.externalId == externalId)
}
def getRooms(): Vector[BreakoutRoom2x] = {
rooms.values.toVector
}
def getNumberOfRooms(): Int = {
rooms.size
}
def started(room: BreakoutRoom2x, startedOnInMillis: Long): BreakoutRoom2x = {
room.copy(started = true, startedOn = Some(startedOnInMillis))
}
def hasAllStarted(): Boolean = {
rooms.values.filter(r => r.started).size == rooms.values.size
}
def update(room: BreakoutRoom2x): BreakoutModel = {
copy(rooms = rooms + (room.id -> room))
}
def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = {
for {
room <- rooms.get(breakoutMeetingId)
} yield room.assignedUsers
}
def updateBreakoutUsers(breakoutMeetingId: String, users: Vector[BreakoutUser]): BreakoutModel = {
val model = for {
room <- rooms.get(breakoutMeetingId)
} yield {
val newRoom = room.copy(users = users)
copy(rooms = rooms + (newRoom.id -> newRoom))
}
model match {
case Some(m) => m
case None => copy()
}
}
def removeRoom(id: String): BreakoutModel = {
copy(rooms = rooms - id)
}
}

View File

@ -1,11 +1,12 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.message.handlers.guests.{ GetGuestsWaitingApprovalReqMsgHdlr, GuestsWaitingApprovedMsgHdlr, SetGuestPolicyMsgHdlr }
import org.bigbluebutton.core2.message.handlers.guests.{ GetGuestPolicyReqMsgHdlr, GetGuestsWaitingApprovalReqMsgHdlr, GuestsWaitingApprovedMsgHdlr, SetGuestPolicyMsgHdlr }
trait GuestsApp extends GetGuestsWaitingApprovalReqMsgHdlr
with GuestsWaitingApprovedMsgHdlr
with SetGuestPolicyMsgHdlr {
with SetGuestPolicyMsgHdlr
with GetGuestPolicyReqMsgHdlr {
this: MeetingActor =>

View File

@ -7,6 +7,9 @@ object ScreenshareModel {
status.rtmpBroadcastingUrl = ""
status.screenshareVideoWidth = 0
status.screenshareVideoHeight = 0
status.voiceConf = ""
status.screenshareConf = ""
status.timestamp = ""
}
def getScreenshareStarted(status: ScreenshareModel): Boolean = {
@ -52,6 +55,30 @@ object ScreenshareModel {
def getRTMPBroadcastingUrl(status: ScreenshareModel): String = {
status.rtmpBroadcastingUrl
}
def setVoiceConf(status: ScreenshareModel, voiceConf: String): Unit = {
status.voiceConf = voiceConf
}
def getVoiceConf(status: ScreenshareModel): String = {
status.voiceConf
}
def setScreenshareConf(status: ScreenshareModel, screenshareConf: String): Unit = {
status.screenshareConf = screenshareConf
}
def getScreenshareConf(status: ScreenshareModel): String = {
status.screenshareConf
}
def setTimestamp(status: ScreenshareModel, timestamp: String): Unit = {
status.timestamp = timestamp
}
def getTimestamp(status: ScreenshareModel): String = {
status.timestamp
}
}
class ScreenshareModel {
@ -60,56 +87,7 @@ class ScreenshareModel {
private var screenshareVideoWidth = 0
private var screenshareVideoHeight = 0
private var broadcastingRTMP = false
private def resetDesktopSharingParams() = {
broadcastingRTMP = false
screenshareStarted = false
rtmpBroadcastingUrl = ""
screenshareVideoWidth = 0
screenshareVideoHeight = 0
}
private def getScreenshareStarted(): Boolean = {
return screenshareStarted
}
private def setScreenshareStarted(b: Boolean) {
screenshareStarted = b
}
private def setScreenshareVideoWidth(videoWidth: Int) {
screenshareVideoWidth = videoWidth
}
private def setScreenshareVideoHeight(videoHeight: Int) {
screenshareVideoHeight = videoHeight
}
private def getScreenshareVideoWidth(): Int = {
screenshareVideoWidth
}
private def getScreenshareVideoHeight(): Int = {
screenshareVideoHeight
}
private def broadcastingRTMPStarted() {
broadcastingRTMP = true
}
private def isBroadcastingRTMP(): Boolean = {
broadcastingRTMP
}
private def broadcastingRTMPStopped() {
broadcastingRTMP = false
}
private def setRTMPBroadcastingUrl(path: String) {
rtmpBroadcastingUrl = path
}
private def getRTMPBroadcastingUrl(): String = {
rtmpBroadcastingUrl
}
private var voiceConf: String = ""
private var screenshareConf: String = ""
private var timestamp: String = ""
}

View File

@ -2,20 +2,19 @@ package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.core.running.MeetingActor
import java.net.URLEncoder
import scala.collection.SortedSet
import scala.collection.mutable
import org.apache.commons.codec.digest.DigestUtils
trait BreakoutApp2x extends BreakoutRoomCreatedMsgHdlr
with BreakoutRoomEndedMsgHdlr
with BreakoutRoomsListMsgHdlr
with BreakoutRoomUsersUpdateMsgHdlr
with CreateBreakoutRoomsCmdMsgHdlr
with EndAllBreakoutRoomsMsgHdlr
with RequestBreakoutJoinURLReqMsgHdlr
with SendBreakoutUsersUpdateMsgHdlr
with TransferUserToMeetingRequestHdlr {
with TransferUserToMeetingRequestHdlr
with EndBreakoutRoomInternalMsgHdlr
with BreakoutRoomEndedInternalMsgHdlr {
this: MeetingActor =>
@ -51,8 +50,8 @@ object BreakoutRoomsUtil {
}
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String,
password: String): (mutable.Map[String, String], mutable.Map[String, String]) = {
val params = collection.mutable.HashMap(
password: String): (collection.immutable.Map[String, String], collection.immutable.Map[String, String]) = {
val params = collection.immutable.HashMap(
"fullName" -> urlEncode(username),
"userID" -> urlEncode(userId),
"isBreakout" -> urlEncode(isBreakout.toString()),
@ -60,16 +59,16 @@ object BreakoutRoomsUtil {
"password" -> urlEncode(password)
)
(params += "redirect" -> urlEncode("true"), mutable.Map[String, String]() ++= params += "redirect" -> urlEncode("false"))
(params + ("redirect" -> urlEncode("true")), params + ("redirect" -> urlEncode("false")))
}
def sortParams(params: mutable.Map[String, String]): SortedSet[String] = {
def sortParams(params: collection.immutable.Map[String, String]): SortedSet[String] = {
collection.immutable.SortedSet[String]() ++ params.keySet
}
//From the list of parameters we want to pass. Creates a base string with parameters
//sorted in alphabetical order for us to sign.
def createBaseString(params: mutable.Map[String, String]): String = {
def createBaseString(params: collection.immutable.Map[String, String]): String = {
val csbuf = new StringBuffer()
val keys = sortParams(params)

View File

@ -0,0 +1,50 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait BreakoutHdlrHelpers extends SystemConfiguration {
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
def sendJoinURL(userId: String, externalMeetingId: String, roomSequence: String, breakoutId: String) {
for {
user <- Users2x.findWithIntId(liveMeeting.users2x, userId)
apiCall = "join"
(redirectParams, noRedirectParams) = BreakoutRoomsUtil.joinParams(user.name, userId + "-" + roomSequence, true,
externalMeetingId, liveMeeting.props.password.moderatorPass)
// We generate a first url with redirect -> true
redirectBaseString = BreakoutRoomsUtil.createBaseString(redirectParams)
redirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, redirectBaseString,
BreakoutRoomsUtil.calculateChecksum(apiCall, redirectBaseString, bbbWebSharedSecret))
// We generate a second url with redirect -> false
noRedirectBaseString = BreakoutRoomsUtil.createBaseString(noRedirectParams)
noRedirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, noRedirectBaseString,
BreakoutRoomsUtil.calculateChecksum(apiCall, noRedirectBaseString, bbbWebSharedSecret))
} yield {
sendJoinURLMsg(liveMeeting.props.meetingProp.intId, breakoutId, externalMeetingId,
userId, redirectJoinURL, noRedirectJoinURL)
}
}
def sendJoinURLMsg(meetingId: String, breakoutId: String, externalId: String,
userId: String, redirectJoinURL: String, noRedirectJoinURL: String): Unit = {
def build(meetingId: String, breakoutId: String,
userId: String, redirectJoinURL: String, noRedirectJoinURL: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
val envelope = BbbCoreEnvelope(BreakoutRoomJoinURLEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(BreakoutRoomJoinURLEvtMsg.NAME, meetingId, userId)
val body = BreakoutRoomJoinURLEvtMsgBody(meetingId, breakoutId, externalId,
userId, redirectJoinURL, noRedirectJoinURL)
val event = BreakoutRoomJoinURLEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val msgEvent = build(meetingId, breakoutId, userId, redirectJoinURL, noRedirectJoinURL)
outGW.send(msgEvent)
}
}

View File

@ -1,39 +1,51 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ BreakoutRooms, Users2x }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, MeetingActor }
import org.bigbluebutton.core.api.BreakoutRoomCreatedInternalMsg
import org.bigbluebutton.core.apps.BreakoutModel
import org.bigbluebutton.core.domain.{ BreakoutRoom2x, MeetingState2x }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter }
trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
trait BreakoutRoomCreatedMsgHdlr extends BreakoutHdlrHelpers {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleBreakoutRoomCreatedMsg(msg: BreakoutRoomCreatedMsg): Unit = {
def handleBreakoutRoomCreatedInternalMsg(msg: BreakoutRoomCreatedInternalMsg, state: MeetingState2x): MeetingState2x = {
liveMeeting.breakoutRooms.pendingRoomsNumber -= 1
val room = BreakoutRooms.getBreakoutRoom(liveMeeting.breakoutRooms, msg.body.breakoutRoomId)
room foreach { room =>
sendBreakoutRoomStarted(room.parentRoomId, room.name, room.externalMeetingId, room.id, room.sequence, room.voiceConfId)
}
// We postpone sending invitation until all breakout rooms have been created
if (liveMeeting.breakoutRooms.pendingRoomsNumber == 0) {
log.info("All breakout rooms created for meetingId={}", liveMeeting.props.meetingProp.intId)
BreakoutRooms.getRooms(liveMeeting.breakoutRooms).foreach { room =>
BreakoutRooms.getAssignedUsers(liveMeeting.breakoutRooms, room.id) foreach { users =>
users.foreach { u =>
log.debug("Sending Join URL for users")
sendJoinURL(u, room.externalMeetingId, room.sequence.toString())
}
}
val updatedModel = for {
breakoutModel <- state.breakout
room <- breakoutModel.find(msg.breakoutId)
startedRoom = breakoutModel.started(room, System.currentTimeMillis())
} yield {
val updatedRoom = sendBreakoutRoomStarted(startedRoom)
var updatedModel = breakoutModel.update(updatedRoom)
// We postpone sending invitation until all breakout rooms have been created
if (updatedModel.hasAllStarted()) {
updatedModel = updatedModel.copy(startedOn = Some(System.currentTimeMillis()))
updatedModel = sendBreakoutRoomsList(updatedModel)
updatedModel = sendBreakoutInvitations(updatedModel)
}
sendBreakoutRoomsList()
updatedModel
}
updatedModel match {
case Some(model) => state.update(Some(model))
case None => state
}
}
def sendBreakoutInvitations(breakoutModel: BreakoutModel): BreakoutModel = {
log.debug("Sending breakout invitations")
breakoutModel.rooms.values.foreach { room =>
log.debug("Sending invitations for room {} with num users {}", room.name, room.assignedUsers.toVector.length)
room.assignedUsers.foreach { user =>
sendJoinURL(user, room.externalId, room.sequence.toString(), room.id)
}
}
breakoutModel
}
def buildBreakoutRoomsListEvtMsg(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean): BbbCommonEnvCoreMsg = {
@ -47,22 +59,21 @@ trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
}
def sendBreakoutRoomsList(): Unit = {
val breakoutRooms = BreakoutRooms.getRooms(liveMeeting.breakoutRooms).toVector map { r =>
new BreakoutRoomInfo(r.name, r.externalMeetingId, r.id, r.sequence)
def sendBreakoutRoomsList(breakoutModel: BreakoutModel): BreakoutModel = {
val breakoutRooms = breakoutModel.rooms.values.toVector map { r =>
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence)
}
val roomsReady = liveMeeting.breakoutRooms.pendingRoomsNumber == 0 && breakoutRooms.length > 0
log.info("Sending breakout rooms list to {} with containing {} room(s)", liveMeeting.props.meetingProp.intId, breakoutRooms.length)
val msgEvent = buildBreakoutRoomsListEvtMsg(liveMeeting.props.meetingProp.intId, breakoutRooms, roomsReady)
val msgEvent = buildBreakoutRoomsListEvtMsg(liveMeeting.props.meetingProp.intId, breakoutRooms, true)
outGW.send(msgEvent)
breakoutModel
}
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String,
breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId)
def sendBreakoutRoomStarted(room: BreakoutRoom2x): BreakoutRoom2x = {
log.info("Sending breakout room started {} for parent meeting {} ", room.id, room.parentId)
def build(meetingId: String, breakout: BreakoutRoomInfo): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(
@ -77,42 +88,11 @@ trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
BbbCommonEnvCoreMsg(envelope, event)
}
val breakoutInfo = BreakoutRoomInfo(breakoutName, externalMeetingId, meetingId, sequence)
val event = build(meetingId, breakoutInfo)
val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence)
val event = build(liveMeeting.props.meetingProp.intId, breakoutInfo)
outGW.send(event)
room
}
def sendJoinURL(userId: String, externalMeetingId: String, roomSequence: String) {
log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId)
for {
user <- Users2x.findWithIntId(liveMeeting.users2x, userId)
apiCall = "join"
params = BreakoutRoomsUtil.joinParams(user.name, userId + "-" + roomSequence, true,
externalMeetingId, liveMeeting.props.password.moderatorPass)
// We generate a first url with redirect -> true
redirectBaseString = BreakoutRoomsUtil.createBaseString(params._1)
redirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, redirectBaseString,
BreakoutRoomsUtil.calculateChecksum(apiCall, redirectBaseString, bbbWebSharedSecret))
// We generate a second url with redirect -> false
noRedirectBaseString = BreakoutRoomsUtil.createBaseString(params._2)
noRedirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, noRedirectBaseString,
BreakoutRoomsUtil.calculateChecksum(apiCall, noRedirectBaseString, bbbWebSharedSecret))
} yield {
def build(meetingId: String, breakoutMeetingId: String,
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")
val body = BreakoutRoomJoinURLEvtMsgBody(meetingId, breakoutMeetingId,
userId, redirectJoinURL, noRedirectJoinURL)
val event = BreakoutRoomJoinURLEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val msgEvent = build(liveMeeting.props.meetingProp.intId, externalMeetingId, userId,
redirectJoinURL, noRedirectJoinURL)
outGW.send(msgEvent)
}
}
}

View File

@ -0,0 +1,27 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.core.api.BreakoutRoomEndedInternalMsg
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait BreakoutRoomEndedInternalMsgHdlr {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleBreakoutRoomEndedInternalMsg(msg: BreakoutRoomEndedInternalMsg, state: MeetingState2x): MeetingState2x = {
// send out BreakoutRoomEndedEvtMsg to inform clients the breakout has ended
outGW.send(MsgBuilder.buildBreakoutRoomEndedEvtMsg(liveMeeting.props.meetingProp.intId, "not-used",
msg.meetingId))
val updatedModel = for {
breakoutModel <- state.breakout
} yield {
breakoutModel.removeRoom(msg.meetingId)
}
state.update(updatedModel)
}
}

View File

@ -1,22 +0,0 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.BreakoutRooms
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait BreakoutRoomEndedMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleBreakoutRoomEndedMsg(msg: BreakoutRoomEndedMsg): Unit = {
// send out BreakoutRoomEndedEvtMsg to inform clients the breakout has ended
outGW.send(MsgBuilder.buildBreakoutRoomEndedEvtMsg(liveMeeting.props.meetingProp.intId, msg.header.userId,
msg.body.breakoutRoomId))
BreakoutRooms.removeRoom(liveMeeting.breakoutRooms, msg.body.breakoutRoomId)
}
}

View File

@ -1,31 +1,42 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.BreakoutRooms
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.api.BreakoutRoomUsersUpdateInternalMsg
import org.bigbluebutton.core.domain.{ BreakoutRoom2x, MeetingState2x }
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait BreakoutRoomUsersUpdateMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleBreakoutRoomUsersUpdateMsg(msg: BreakoutRoomUsersUpdateMsg): Unit = {
def handleBreakoutRoomUsersUpdateInternalMsg(msg: BreakoutRoomUsersUpdateInternalMsg, state: MeetingState2x): MeetingState2x = {
def broadcastEvent(msg: BreakoutRoomUsersUpdateMsg): Unit = {
BreakoutRooms.updateBreakoutUsers(liveMeeting.breakoutRooms, msg.body.breakoutMeetingId, msg.body.users) foreach { room =>
def broadcastEvent(room: BreakoutRoom2x): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, "not-used")
val envelope = BbbCoreEnvelope(UpdateBreakoutUsersEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UpdateBreakoutUsersEvtMsg.NAME, props.meetingProp.intId, "not-used")
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(UpdateBreakoutUsersEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UpdateBreakoutUsersEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = UpdateBreakoutUsersEvtMsgBody(props.meetingProp.intId, msg.body.breakoutMeetingId, room.users)
val event = UpdateBreakoutUsersEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
val users = room.users.map(u => BreakoutUserVO(u.id, u.name))
val body = UpdateBreakoutUsersEvtMsgBody(props.meetingProp.intId, msg.breakoutId, users)
val event = UpdateBreakoutUsersEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val breakoutModel = for {
model <- state.breakout
room <- model.find(msg.breakoutId)
} yield {
val updatedRoom = room.copy(users = msg.users)
val msgEvent = broadcastEvent(updatedRoom)
outGW.send(msgEvent)
model.update(updatedRoom)
}
breakoutModel match {
case Some(model) => state.update(Some(model))
case None => state
}
broadcastEvent(msg)
}
}

View File

@ -1,33 +1,39 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.BreakoutRooms
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait BreakoutRoomsListMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleBreakoutRoomsListMsg(msg: BreakoutRoomsListMsg): Unit = {
def handleBreakoutRoomsListMsg(msg: BreakoutRoomsListMsg, state: MeetingState2x): MeetingState2x = {
def broadcastEvent(msg: BreakoutRoomsListMsg): Unit = {
val breakoutRooms = BreakoutRooms.getRooms(liveMeeting.breakoutRooms).toVector map { r => new BreakoutRoomInfo(r.name, r.externalMeetingId, r.id, r.sequence) }
val roomsReady = liveMeeting.breakoutRooms.pendingRoomsNumber == 0 && breakoutRooms.length > 0
log.info("Sending breakout rooms list to {} with containing {} room(s)", props.meetingProp.intId, breakoutRooms.length)
def broadcastEvent(rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean): Unit = {
log.info("Sending breakout rooms list to {} with containing {} room(s)", props.meetingProp.intId, rooms.length)
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(BreakoutRoomsListEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(BreakoutRoomsListEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = BreakoutRoomsListEvtMsgBody(msg.body.meetingId, breakoutRooms, roomsReady)
val body = BreakoutRoomsListEvtMsgBody(msg.body.meetingId, rooms, roomsReady)
val event = BreakoutRoomsListEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
broadcastEvent(msg)
for {
breakoutModel <- state.breakout
} yield {
val rooms = breakoutModel.rooms.values.toVector map { r =>
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence)
}
val ready = breakoutModel.hasAllStarted()
broadcastEvent(rooms, ready)
}
state
}
}

View File

@ -1,64 +1,82 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.BreakoutRooms
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core.apps.BreakoutModel
import org.bigbluebutton.core.domain.{ BreakoutRoom2x, MeetingState2x }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter }
trait CreateBreakoutRoomsCmdMsgHdlr {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
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
)
} 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
)
} else {
var i = 0
// in very rare cases the presentation conversion generates an error, what should we do?
// those cases where default.pdf is deleted from the whiteboard
val sourcePresentationId = if (!liveMeeting.presModel.getCurrentPresentation().isEmpty) liveMeeting.presModel.getCurrentPresentation().get.id else "blank"
val sourcePresentationSlide = if (!liveMeeting.presModel.getCurrentPage().isEmpty) liveMeeting.presModel.getCurrentPage().get.num else 0
liveMeeting.breakoutRooms.pendingRoomsNumber = msg.body.rooms.length
for (room <- msg.body.rooms) {
i += 1
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(liveMeeting.props.meetingProp.intId, i)
val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(liveMeeting.props.voiceProp.voiceConf, i)
for {
r <- BreakoutRooms.newBreakoutRoom(liveMeeting.props.meetingProp.intId, breakoutMeetingId._1, breakoutMeetingId._2, room.name,
room.sequence, voiceConfId, room.users, liveMeeting.breakoutRooms)
} yield {
val roomDetail = new BreakoutRoomDetail(r.id, r.name, liveMeeting.props.meetingProp.intId, r.sequence,
r.voiceConfId, msg.body.durationInMinutes, liveMeeting.props.password.moderatorPass, liveMeeting.props.password.viewerPass,
sourcePresentationId, sourcePresentationSlide, msg.body.record)
def build(meetingId: String, breakout: BreakoutRoomDetail): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(CreateBreakoutRoomSysCmdMsg.NAME, routing)
val header = BbbCoreBaseHeader(CreateBreakoutRoomSysCmdMsg.NAME)
val body = CreateBreakoutRoomSysCmdMsgBody(meetingId, breakout)
val event = CreateBreakoutRoomSysCmdMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val event = build(liveMeeting.props.meetingProp.intId, roomDetail)
outGW.send(event)
}
}
def handleCreateBreakoutRoomsCmdMsg(msg: CreateBreakoutRoomsCmdMsg, state: MeetingState2x): MeetingState2x = {
state.breakout match {
case Some(breakout) =>
log.warning(
"CreateBreakoutRooms event received while breakout created for meeting {}", liveMeeting.props.meetingProp.intId
)
state
case None =>
processRequest(msg, state)
}
}
def processRequest(msg: CreateBreakoutRoomsCmdMsg, state: MeetingState2x): MeetingState2x = {
val presId = getPresentationId
val presSlide = getPresentationSlide
val parentId = liveMeeting.props.meetingProp.intId
var rooms = new collection.immutable.HashMap[String, BreakoutRoom2x]
var i = 0
for (room <- msg.body.rooms) {
i += 1
val (internalId, externalId) = BreakoutRoomsUtil.createMeetingIds(liveMeeting.props.meetingProp.intId, i)
val voiceConf = BreakoutRoomsUtil.createVoiceConfId(liveMeeting.props.voiceProp.voiceConf, i)
val breakout = BreakoutModel.create(parentId, internalId, externalId, room.name, room.sequence, voiceConf, room.users)
rooms = rooms + (breakout.id -> breakout)
}
for (breakout <- rooms.values.toVector) {
val roomDetail = new BreakoutRoomDetail(
breakout.id, breakout.name,
liveMeeting.props.meetingProp.intId,
breakout.sequence,
breakout.voiceConf,
msg.body.durationInMinutes,
liveMeeting.props.password.moderatorPass,
liveMeeting.props.password.viewerPass,
presId, presSlide, msg.body.record
)
val event = buildCreateBreakoutRoomSysCmdMsg(liveMeeting.props.meetingProp.intId, roomDetail)
outGW.send(event)
}
val breakoutModel = new BreakoutModel(None, msg.body.durationInMinutes, rooms)
state.update(Some(breakoutModel))
}
def buildCreateBreakoutRoomSysCmdMsg(meetingId: String, breakout: BreakoutRoomDetail): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(CreateBreakoutRoomSysCmdMsg.NAME, routing)
val header = BbbCoreBaseHeader(CreateBreakoutRoomSysCmdMsg.NAME)
val body = CreateBreakoutRoomSysCmdMsgBody(meetingId, breakout)
val event = CreateBreakoutRoomSysCmdMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
def getPresentationId: String = {
// in very rare cases the presentation conversion generates an error, what should we do?
// those cases where default.pdf is deleted from the whiteboard
if (!liveMeeting.presModel.getCurrentPresentation().isEmpty) liveMeeting.presModel.getCurrentPresentation().get.id else "blank"
}
def getPresentationSlide: Int = {
if (!liveMeeting.presModel.getCurrentPage().isEmpty) liveMeeting.presModel.getCurrentPage().get.num else 0
}
}

View File

@ -1,33 +1,26 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.BreakoutRooms
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.api.EndBreakoutRoomInternalMsg
import org.bigbluebutton.core.bus.BigBlueButtonEvent
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait EndAllBreakoutRoomsMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleEndAllBreakoutRoomsMsg(msg: EndAllBreakoutRoomsMsg): Unit = {
def handleEndAllBreakoutRoomsMsg(msg: EndAllBreakoutRoomsMsg, state: MeetingState2x): MeetingState2x = {
def broadcastEvent(msg: EndAllBreakoutRoomsMsg): Unit = {
log.info("EndAllBreakoutRooms event received for meetingId={}", props.meetingProp.intId)
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(EndBreakoutRoomEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(EndBreakoutRoomEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
BreakoutRooms.getRooms(liveMeeting.breakoutRooms).foreach { room =>
val body = EndBreakoutRoomEvtMsgBody(room.id)
val event = EndBreakoutRoomEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
for {
model <- state.breakout
} yield {
model.rooms.values.foreach { room =>
eventBus.publish(BigBlueButtonEvent(room.id, EndBreakoutRoomInternalMsg(props.breakoutProps.parentId, room.id)))
}
}
broadcastEvent(msg)
state.update(None)
}
}

View File

@ -0,0 +1,19 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.core.api.EndBreakoutRoomInternalMsg
import org.bigbluebutton.core.bus.{ InternalEventBus }
import org.bigbluebutton.core.domain.MeetingEndReason
import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter }
trait EndBreakoutRoomInternalMsgHdlr extends HandlerHelpers {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
val eventBus: InternalEventBus
def handleEndBreakoutRoomInternalMsg(msg: EndBreakoutRoomInternalMsg): Unit = {
log.info("Breakout room {} ended by parent meeting {}.", msg.breakoutId, msg.parentId)
sendEndMeetingDueToExpiry(MeetingEndReason.ENDED_BY_PARENT, eventBus, outGW, liveMeeting)
}
}

View File

@ -1,54 +1,23 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ BreakoutRooms, Users2x }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait RequestBreakoutJoinURLReqMsgHdlr {
trait RequestBreakoutJoinURLReqMsgHdlr extends BreakoutHdlrHelpers {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleRequestBreakoutJoinURLReqMsg(msg: RequestBreakoutJoinURLReqMsg): Unit = {
def handleRequestBreakoutJoinURLReqMsg(msg: RequestBreakoutJoinURLReqMsg, state: MeetingState2x): MeetingState2x = {
def broadcastEvent(msg: RequestBreakoutJoinURLReqMsg): Unit = {
for {
breakoutRoom <- BreakoutRooms.getRoomWithExternalId(liveMeeting.breakoutRooms, msg.body.breakoutMeetingId)
} yield sendJoinURL(msg.body.userId, msg.body.breakoutMeetingId, breakoutRoom.sequence.toString())
for {
model <- state.breakout
room <- model.find(msg.body.breakoutId)
} yield {
sendJoinURL(msg.body.userId, room.externalId, room.sequence.toString(), room.id)
}
def sendJoinURL(userId: String, externalMeetingId: String, roomSequence: String) {
log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId)
for {
user <- Users2x.findWithIntId(liveMeeting.users2x, userId)
apiCall = "join"
params = BreakoutRoomsUtil.joinParams(user.name, userId + "-" + roomSequence, true,
externalMeetingId, props.password.moderatorPass)
// We generate a first url with redirect -> true
redirectBaseString = BreakoutRoomsUtil.createBaseString(params._1)
redirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, redirectBaseString,
BreakoutRoomsUtil.calculateChecksum(apiCall, redirectBaseString, bbbWebSharedSecret))
// We generate a second url with redirect -> false
noRedirectBaseString = BreakoutRoomsUtil.createBaseString(params._2)
noRedirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, noRedirectBaseString,
BreakoutRoomsUtil.calculateChecksum(apiCall, noRedirectBaseString, bbbWebSharedSecret))
} yield {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, props.meetingProp.intId, msg.header.userId)
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 event = RequestBreakoutJoinURLRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
}
broadcastEvent(msg)
state
}
}

View File

@ -1,22 +1,24 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs.{ BreakoutUserVO, SendBreakoutUsersUpdateMsg }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ BreakoutRoomUsersUpdateInternalMsg, SendBreakoutUsersAuditInternalMsg }
import org.bigbluebutton.core.bus.BigBlueButtonEvent
import org.bigbluebutton.core.domain.BreakoutUser
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait SendBreakoutUsersUpdateMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSendBreakoutUsersUpdateMsg(msg: SendBreakoutUsersUpdateMsg): Unit = {
def handleSendBreakoutUsersUpdateInternalMsg(msg: SendBreakoutUsersAuditInternalMsg): Unit = {
val users = Users2x.findAll(liveMeeting.users2x)
val breakoutUsers = users map { u => new BreakoutUserVO(u.extId, u.name) }
/** TODO Need to figure out how to do this in a 2.0 way */
log.error("**** SendBreakoutUsersUpdateMsgHdlr isn't finished and needs a new part *****")
//eventBus.publish(BigBlueButtonEvent(props.breakoutProps.parentId,
// new BreakoutRoomUsersUpdate(props.breakoutProps.parentId, props.meetingProp.intId, breakoutUsers)))
val breakoutUsers = users map { u => new BreakoutUser(u.extId, u.name) }
eventBus.publish(BigBlueButtonEvent(
props.breakoutProps.parentId,
new BreakoutRoomUsersUpdateInternalMsg(props.breakoutProps.parentId, props.meetingProp.intId, breakoutUsers)
))
}
}

View File

@ -1,50 +1,48 @@
package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ BreakoutRooms, Users2x, VoiceUser2x, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.apps.BreakoutModel
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.models.{ VoiceUsers }
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait TransferUserToMeetingRequestHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleTransferUserToMeetingRequestMsg(msg: TransferUserToMeetingRequestMsg): Unit = {
def handleTransferUserToMeetingRequestMsg(msg: TransferUserToMeetingRequestMsg, state: MeetingState2x): MeetingState2x = {
def broadcastEvent(msg: TransferUserToMeetingRequestMsg): Unit = {
var targetVoiceBridge: String = msg.body.targetMeetingId
// If the current room is a parent room we fetch the voice bridge from the breakout room
if (!props.meetingProp.isBreakout) {
BreakoutRooms.getBreakoutRoom(liveMeeting.breakoutRooms, msg.body.targetMeetingId) match {
case Some(b) => {
targetVoiceBridge = b.voiceConfId;
}
case None => // do nothing
}
} // if it is a breakout room, the target voice bridge is the same after removing the last digit
else {
targetVoiceBridge = props.voiceProp.voiceConf.dropRight(1)
}
// We check the user from the mode
VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId) match {
case Some(u) =>
log.info("Transferring user userId=" + u.intId + " from voiceBridge=" + props.voiceProp.voiceConf + " to targetVoiceConf=" + targetVoiceBridge)
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(TransferUserToMeetingEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(TransferUserToMeetingEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = TransferUserToMeetingEvtMsgBody(props.voiceProp.voiceConf, targetVoiceBridge, u.voiceUserId)
val event = TransferUserToMeetingEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
case None => // do nothing
}
for {
model <- state.breakout
to <- getVoiceConf(msg.body.toMeetingId, model)
from <- getVoiceConf(msg.body.fromMeetingId, model)
voiceUser <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
} yield {
val event = buildTransferUserToVoiceConfSysMsg(from, to, voiceUser.voiceUserId)
outGW.send(event)
}
broadcastEvent(msg)
state
}
def buildTransferUserToVoiceConfSysMsg(fromVoiceConf: String, toVoiceConf: String, voiceUserId: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(TransferUserToVoiceConfSysMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(TransferUserToVoiceConfSysMsg.NAME, props.meetingProp.intId)
val body = TransferUserToVoiceConfSysMsgBody(fromVoiceConf, toVoiceConf, voiceUserId)
val event = TransferUserToVoiceConfSysMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
def getVoiceConf(meetingId: String, breakoutModel: BreakoutModel): Option[String] = {
if (meetingId == liveMeeting.props.meetingProp.intId) {
Some(liveMeeting.props.voiceProp.voiceConf)
} else {
for {
room <- breakoutModel.find(meetingId)
} yield room.voiceConf
}
}
}

View File

@ -3,12 +3,11 @@ package org.bigbluebutton.core.apps.caption
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.common2.msgs.TranscriptVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
class CaptionApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
val outGW: OutMsgRouter
)(implicit val context: ActorContext)
extends UserLeavingHdlr
with EditCaptionHistoryPubMsgHdlr

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait EditCaptionHistoryPubMsgHdlr {
this: CaptionApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleEditCaptionHistoryPubMsg(msg: EditCaptionHistoryPubMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait SendCaptionHistoryReqMsgHdlr {
this: CaptionApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSendCaptionHistoryReqMsg(msg: SendCaptionHistoryReqMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait UpdateCaptionOwnerPubMsgHdlr {
this: CaptionApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUpdateCaptionOwnerPubMsg(msg: UpdateCaptionOwnerPubMsg): Unit = {
updateCaptionOwner(msg.body.locale, msg.body.localeCode, msg.body.ownerId).foreach(f => {

View File

@ -1,12 +1,11 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ OutMsgRouter }
trait UserLeavingHdlr {
this: CaptionApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUserLeavingMsg(userId: String): Unit = {
for {

View File

@ -2,13 +2,11 @@ package org.bigbluebutton.core.apps.chat
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.common2.msgs.TranscriptVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
class ChatApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
val outGW: OutMsgRouter
)(implicit val context: ActorContext)
extends GetChatHistoryReqMsgHdlr
with SendPublicMessagePubMsgHdlr

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.chat
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ChatModel
import org.bigbluebutton.core.running.OutMsgRouter
trait ClearPublicChatHistoryPubMsgHdlr {
this: ChatApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleClearPublicChatHistoryPubMsg(msg: ClearPublicChatHistoryPubMsg): Unit = {
def broadcastEvent(msg: ClearPublicChatHistoryPubMsg): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.chat
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ChatModel
import org.bigbluebutton.core.running.OutMsgRouter
trait GetChatHistoryReqMsgHdlr {
this: ChatApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetChatHistoryReqMsg(msg: GetChatHistoryReqMsg): Unit = {
def broadcastEvent(msg: GetChatHistoryReqMsg, history: Array[ChatMessageVO]): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.chat
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait SendPrivateMessagePubMsgHdlr {
this: ChatApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSendPrivateMessagePubMsg(msg: SendPrivateMessagePubMsg): Unit = {
def broadcastEvent(message: ChatMessageVO, userId: String): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.chat
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ChatModel
import org.bigbluebutton.core.running.OutMsgRouter
trait SendPublicMessagePubMsgHdlr {
this: ChatApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSendPublicMessagePubMsg(msg: SendPublicMessagePubMsg): Unit = {
def broadcastEvent(msg: SendPublicMessagePubMsg, message: ChatMessageVO): Unit = {

View File

@ -1,14 +1,14 @@
package org.bigbluebutton.core.apps.layout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Layouts
import org.bigbluebutton.core.running.OutMsgRouter
import org.bigbluebutton.core2.MeetingStatus2x
trait BroadcastLayoutMsgHdlr {
this: LayoutApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleBroadcastLayoutMsg(msg: BroadcastLayoutMsg): Unit = {
Layouts.setCurrentLayout(msg.body.layout)

View File

@ -2,15 +2,14 @@ package org.bigbluebutton.core.apps.layout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Layouts
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait GetCurrentLayoutReqMsgHdlr {
this: LayoutApp2x =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetCurrentLayoutReqMsg(msg: GetCurrentLayoutReqMsg): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.layout
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Layouts
import org.bigbluebutton.core.running.OutMsgRouter
trait LockLayoutMsgHdlr {
this: LayoutApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleLockLayoutMsg(msg: LockLayoutMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.meeting
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait SyncGetMeetingInfoRespMsgHdlr {
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSyncGetMeetingInfoRespMsg(props: DefaultProps): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, props.meetingProp.intId, "nodeJSapp")

View File

@ -2,14 +2,13 @@ package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.domain.PollVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait GetCurrentPollReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetCurrentPollReqMsg(msgIn: GetCurrentPollReqMsg): Unit = {

View File

@ -1,14 +1,13 @@
package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait HidePollResultReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleHidePollResultReqMsg(msg: HidePollResultReqMsg): Unit = {

View File

@ -2,14 +2,13 @@ package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.domain.SimplePollResultOutVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait RespondToPollReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleRespondToPollReqMsg(msg: RespondToPollReqMsg): Unit = {
log.debug("Received RespondToPollReqMsg {}", RespondToPollReqMsg)

View File

@ -2,14 +2,13 @@ package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.domain.SimplePollResultOutVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait ShowPollResultReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleShowPollResultReqMsg(msg: ShowPollResultReqMsg): Unit = {

View File

@ -2,14 +2,13 @@ package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.domain.SimplePollOutVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait StartCustomPollReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleStartCustomPollReqMsg(msg: StartCustomPollReqMsg): Unit = {

View File

@ -2,14 +2,13 @@ package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.domain.SimplePollOutVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait StartPollReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleStartPollReqMsg(msg: StartPollReqMsg): Unit = {

View File

@ -1,14 +1,13 @@
package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait StopPollReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def broadcastEvent(requesterId: String, stoppedPollId: String): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, requesterId)

View File

@ -1,14 +1,14 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.running.OutMsgRouter
trait GetPresentationInfoReqMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetPresentationInfoReqMsg(msg: GetPresentationInfoReqMsg): Unit = {
log.debug("Received GetPresentationInfoReqMsg")

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.core.running.OutMsgRouter
trait NewPresentationMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def broadcastNewPresentationEvent(userId: String, presentation: PresentationVO): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, userId)

View File

@ -2,15 +2,13 @@ package org.bigbluebutton.core.apps.presentation
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.apps.Presentation
class PresentationApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
val outGW: OutMsgRouter
)(implicit val context: ActorContext)
extends NewPresentationMsgHdlr
with SetCurrentPresentationPubMsgHdlr
@ -63,8 +61,8 @@ class PresentationApp2x(
// 100D-checkedWidth is the maximum the page can be moved over
val checkedWidth = Math.min(Math.max(widthRatio, 25D), 100D) //if (widthRatio <= 100D) widthRatio else 100D
val checkedHeight = Math.min(Math.max(heightRatio, 25D), 100D)
val checkedXOffset = Math.min(Math.max(xOffset, 0D), 100D - checkedWidth)
val checkedYOffset = Math.min(Math.max(yOffset, 0D), 100D - checkedHeight)
val checkedXOffset = Math.min(xOffset, 0D)
val checkedYOffset = Math.min(yOffset, 0D)
liveMeeting.presModel.resizePage(presentationId, pageId, checkedXOffset, checkedYOffset, checkedWidth, checkedHeight);
}

View File

@ -2,17 +2,15 @@ package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.running.OutMsgRouter
trait PresentationConversionCompletedPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handlePresentationConversionCompletedPubMsg(msg: PresentationConversionCompletedSysPubMsg): Unit = {
log.debug("**************** !!!!!PresentationConversionCompletedPubMsg ")
def broadcastEvent(msg: PresentationConversionCompletedSysPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(PresentationConversionCompletedEvtMsg.NAME, routing)

View File

@ -1,15 +1,15 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.OutMsgRouter
trait PresentationConversionUpdatePubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handlePresentationConversionUpdatePubMsg(msg: PresentationConversionUpdateSysPubMsg): Unit = {
log.debug("**************** !!!!!PresentationConversionUpdateSysPubMsg " + msg.body.messageKey)
def broadcastEvent(msg: PresentationConversionUpdateSysPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(PresentationConversionUpdateEvtMsg.NAME, routing)

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait PresentationPageCountErrorPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handlePresentationPageCountErrorPubMsg(msg: PresentationPageCountErrorSysPubMsg): Unit = {

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait PresentationPageGeneratedPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handlePresentationPageGeneratedPubMsg(msg: PresentationPageGeneratedSysPubMsg): Unit = {
log.debug("**************** !!!!!PresentationPageGeneratedSysPubMsg " + msg.body.messageKey)
def broadcastEvent(msg: PresentationPageGeneratedSysPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)

View File

@ -2,13 +2,13 @@ package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.common2.msgs.PreuploadedPresentationsSysPubMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.running.OutMsgRouter
trait PreuploadedPresentationsPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handlePreuploadedPresentationsPubMsg(msg: PreuploadedPresentationsSysPubMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.OutMsgRouter
trait RemovePresentationPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleRemovePresentationPubMsg(msg: RemovePresentationPubMsg): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.running.OutMsgRouter
trait ResizeAndMovePagePubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleResizeAndMovePagePubMsg(msg: ResizeAndMovePagePubMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait SetCurrentPagePubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSetCurrentPagePubMsg(msg: SetCurrentPagePubMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait SetCurrentPresentationPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSetCurrentPresentationPubMsg(msg: SetCurrentPresentationPubMsg): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.core.running.OutMsgRouter
trait SyncGetPresentationInfoRespMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSyncGetPresentationInfoRespMsg(): Unit = {
log.debug("Handling SyncGetPresentationInfo")

View File

@ -0,0 +1,48 @@
package org.bigbluebutton.core.apps.screenshare
import org.bigbluebutton.core.running.OutMsgRouter
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ScreenshareModel
trait GetScreenshareStatusReqMsgHdlr {
this: ScreenshareApp2x =>
// val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
def handleGetScreenshareStatusReqMsg(msg: GetScreenshareStatusReqMsg) {
def broadcastEvent(meetingId: String, userId: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
val envelope = BbbCoreEnvelope(ScreenshareRtmpBroadcastStartedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(
ScreenshareRtmpBroadcastStartedEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, "not-used"
)
val voiceConf = ScreenshareModel.getVoiceConf(liveMeeting.screenshareModel)
val screenshareConf = ScreenshareModel.getScreenshareConf(liveMeeting.screenshareModel)
val stream = ScreenshareModel.getRTMPBroadcastingUrl(liveMeeting.screenshareModel)
val vidWidth = ScreenshareModel.getScreenshareVideoWidth(liveMeeting.screenshareModel)
val vidHeight = ScreenshareModel.getScreenshareVideoHeight(liveMeeting.screenshareModel)
val timestamp = ScreenshareModel.getTimestamp(liveMeeting.screenshareModel)
val body = ScreenshareRtmpBroadcastStartedEvtMsgBody(voiceConf, screenshareConf,
stream, vidWidth, vidHeight, timestamp)
val event = ScreenshareRtmpBroadcastStartedEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
log.info("handleGetScreenshareStatusReqMsg: isBroadcastingRTMP=" +
ScreenshareModel.isBroadcastingRTMP(liveMeeting.screenshareModel) +
" URL:" + ScreenshareModel.getRTMPBroadcastingUrl(liveMeeting.screenshareModel))
// only reply if there is an ongoing stream
if (ScreenshareModel.isBroadcastingRTMP(liveMeeting.screenshareModel)) {
val msgEvent = broadcastEvent(liveMeeting.props.meetingProp.intId, msg.body.requestedBy)
outGW.send(msgEvent)
}
}
}

View File

@ -2,15 +2,15 @@ package org.bigbluebutton.core.apps.screenshare
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
class ScreenshareApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
val outGW: OutMsgRouter
)(implicit val context: ActorContext)
extends ScreenshareStartedVoiceConfEvtMsgHdlr
with ScreenshareStoppedVoiceConfEvtMsgHdlr
with GetScreenshareStatusReqMsgHdlr
with ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr
with ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsgHdlr {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.screenshare
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ScreenshareModel
import org.bigbluebutton.core.running.OutMsgRouter
trait ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr {
this: ScreenshareApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleScreenshareRtmpBroadcastStartedVoiceConfEvtMsg(msg: ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg): Unit = {
def broadcastEvent(voiceConf: String, screenshareConf: String, stream: String, vidWidth: Int, vidHeight: Int,
@ -39,6 +39,10 @@ trait ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr {
ScreenshareModel.broadcastingRTMPStarted(liveMeeting.screenshareModel)
ScreenshareModel.setScreenshareVideoWidth(liveMeeting.screenshareModel, msg.body.vidWidth)
ScreenshareModel.setScreenshareVideoHeight(liveMeeting.screenshareModel, msg.body.vidHeight)
ScreenshareModel.setVoiceConf(liveMeeting.screenshareModel, msg.body.voiceConf)
ScreenshareModel.setScreenshareConf(liveMeeting.screenshareModel, msg.body.screenshareConf)
ScreenshareModel.setTimestamp(liveMeeting.screenshareModel, msg.body.timestamp)
log.info("START broadcast ALLOWED when isBroadcastingRTMP=false")
// Notify viewers in the meeting that there's an rtmp stream to view

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.screenshare
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ScreenshareModel
import org.bigbluebutton.core.running.OutMsgRouter
trait ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsgHdlr {
this: ScreenshareApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg(msg: ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.screenshare
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ScreenshareModel
import org.bigbluebutton.core.running.OutMsgRouter
trait ScreenshareStartedVoiceConfEvtMsgHdlr {
this: ScreenshareApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleScreenshareStartedVoiceConfEvtMsg(msg: ScreenshareStartedVoiceConfEvtMsg): Unit = {

View File

@ -1,13 +1,13 @@
package org.bigbluebutton.core.apps.screenshare
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.ScreenshareModel
import org.bigbluebutton.core.running.OutMsgRouter
trait ScreenshareStoppedVoiceConfEvtMsgHdlr {
this: ScreenshareApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleScreenshareStoppedVoiceConfEvtMsg(msg: ScreenshareStoppedVoiceConfEvtMsg): Unit = {

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.sharednotes
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait CreateSharedNoteReqMsgHdlr {
this: SharedNotesApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleCreateSharedNoteReqMsg(msg: CreateSharedNoteReqMsg): Unit = {
@ -24,4 +24,4 @@ trait CreateSharedNoteReqMsgHdlr {
val noteId = liveMeeting.notesModel.createNote(msg.body.noteName)
broadcastEvent(msg, noteId)
}
}
}

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.sharednotes
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait DestroySharedNoteReqMsgHdlr {
this: SharedNotesApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleDestroySharedNoteReqMsg(msg: DestroySharedNoteReqMsg): Unit = {
@ -24,4 +24,4 @@ trait DestroySharedNoteReqMsgHdlr {
liveMeeting.notesModel.destroyNote(msg.body.noteId)
broadcastEvent(msg)
}
}
}

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.sharednotes
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait GetSharedNotesPubMsgHdlr {
this: SharedNotesApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetSharedNotesPubMsg(msg: GetSharedNotesPubMsg): Unit = {
@ -24,4 +24,4 @@ trait GetSharedNotesPubMsgHdlr {
val notesReport = liveMeeting.notesModel.notesReport.toMap
broadcastEvent(msg, notesReport)
}
}
}

View File

@ -2,12 +2,11 @@ package org.bigbluebutton.core.apps.sharednotes
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
class SharedNotesApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
val outGW: OutMsgRouter
)(implicit val context: ActorContext)
extends GetSharedNotesPubMsgHdlr
with SyncSharedNotePubMsgHdlr
@ -16,4 +15,4 @@ class SharedNotesApp2x(
with DestroySharedNoteReqMsgHdlr {
val log = Logging(context.system, getClass)
}
}

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.sharednotes
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait SyncSharedNotePubMsgHdlr {
this: SharedNotesApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSyncSharedNotePubMsg(msg: SyncSharedNotePubMsg): Unit = {
@ -26,4 +26,4 @@ trait SyncSharedNotePubMsgHdlr {
case None => log.warning("Could not find note " + msg.body.noteId)
}
}
}
}

View File

@ -1,12 +1,12 @@
package org.bigbluebutton.core.apps.sharednotes
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.OutMsgRouter
trait UpdateSharedNoteReqMsgHdlr {
this: SharedNotesApp2x =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUpdateSharedNoteReqMsg(msg: UpdateSharedNoteReqMsg): Unit = {
@ -36,4 +36,4 @@ trait UpdateSharedNoteReqMsgHdlr {
log.warning("Could not patch note " + msg.body.noteId)
}
}
}
}

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ UserState, Users2x }
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait AssignPresenterReqMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleAssignPresenterReqMsg(msg: AssignPresenterReqMsg) {

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, MeetingActor }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter }
trait ChangeUserEmojiCmdMsgHdlr {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleChangeUserEmojiCmdMsg(msg: ChangeUserEmojiCmdMsg) {
log.debug("handling " + msg)
@ -20,7 +19,7 @@ trait ChangeUserEmojiCmdMsgHdlr {
}
}
def sendUserEmojiChangedEvtMsg(outGW: OutMessageGateway, meetingId: String, userId: String, emoji: String): Unit = {
def sendUserEmojiChangedEvtMsg(outGW: OutMsgRouter, meetingId: String, userId: String, emoji: String): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
val envelope = BbbCoreEnvelope(UserEmojiChangedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserEmojiChangedEvtMsg.NAME, meetingId, userId)

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ Roles, Users2x }
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait ChangeUserRoleCmdMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleChangeUserRoleCmdMsg(msg: ChangeUserRoleCmdMsg) {
for {

View File

@ -1,16 +1,15 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait EjectUserFromMeetingCmdMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleEjectUserFromMeetingCmdMsg(msg: EjectUserFromMeetingCmdMsg) {
for {

View File

@ -0,0 +1,34 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.api.Permissions
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core2.MeetingStatus2x
trait GetLockSettingsReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleGetLockSettingsReqMsg(msg: GetLockSettingsReqMsg): Unit = {
def build(meetingId: String, requestedBy: String, settings: Permissions): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, requestedBy)
val envelope = BbbCoreEnvelope(GetLockSettingsRespMsg.NAME, routing)
val body = GetLockSettingsRespMsgBody(
disableCam = settings.disableCam,
disableMic = settings.disableMic, disablePrivChat = settings.disablePrivChat,
disablePubChat = settings.disablePubChat, lockedLayout = settings.lockedLayout,
lockOnJoin = settings.lockOnJoin, lockOnJoinConfigurable = settings.lockOnJoinConfigurable
)
val header = BbbClientMsgHeader(GetLockSettingsRespMsg.NAME, meetingId, requestedBy)
val event = GetLockSettingsRespMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val settings = MeetingStatus2x.getPermissions(liveMeeting.status)
val event = build(props.meetingProp.intId, msg.body.requesterId, settings)
outGW.send(event)
}
}

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.MeetingStatus2x
trait GetRecordingStatusReqMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetRecordingStatusReqMsg(msg: GetRecordingStatusReqMsg) {

View File

@ -1,18 +1,17 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs.GetUsersMeetingReqMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting }
import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, OutMsgRouter }
trait GetUsersMeetingReqMsgHdlr extends HandlerHelpers {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleGetUsersMeetingReqMsg(msg: GetUsersMeetingReqMsg): Unit = {
sendAllUsersInMeeting(outGW, msg.body.userId, liveMeeting)
sendAllVoiceUsersInMeeting(outGW, msg.body.userId, liveMeeting.voiceUsers, liveMeeting.props.meetingProp.intId)
sendAllUsersInMeeting(msg.body.userId)
sendAllVoiceUsersInMeeting(msg.body.userId, liveMeeting.voiceUsers, liveMeeting.props.meetingProp.intId)
sendAllWebcamStreams(outGW, msg.body.userId, liveMeeting.webcams, liveMeeting.props.meetingProp.intId)
}
}

View File

@ -1,16 +1,15 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait LockUserInMeetingCmdMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handle(msg: LockUserInMeetingCmdMsg) {
def handleLockUserInMeetingCmdMsg(msg: LockUserInMeetingCmdMsg) {
def build(meetingId: String, userId: String, lockedBy: String, locked: Boolean): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)

View File

@ -0,0 +1,36 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait LockUsersInMeetingCmdMsgHdlr {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleLockUsersInMeetingCmdMsg(msg: LockUsersInMeetingCmdMsg) {
def build(meetingId: String, userId: String, lockedBy: String, locked: Boolean): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
val envelope = BbbCoreEnvelope(UserLockedInMeetingEvtMsg.NAME, routing)
val body = UserLockedInMeetingEvtMsgBody(userId, locked, lockedBy)
val header = BbbClientMsgHeader(UserLockedInMeetingEvtMsg.NAME, meetingId, userId)
val event = UserLockedInMeetingEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val usersToLock = Users2x.findAll(liveMeeting.users2x).filter(u => !msg.body.except.toSet(u))
usersToLock foreach { utl =>
for {
uvo <- Users2x.setUserLocked(liveMeeting.users2x, utl.intId, msg.body.lock)
} yield {
log.info("Lock user. meetingId=" + props.meetingProp.intId + " userId=" + uvo.intId + " locked=" + uvo.locked)
val event = build(props.meetingProp.intId, uvo.intId, msg.body.lockedBy, uvo.locked)
outGW.send(event)
}
}
}
}

View File

@ -1,57 +1,27 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ EndMeeting, LogoutEndMeeting }
import org.bigbluebutton.core.bus.InternalEventBus
import org.bigbluebutton.core.domain.MeetingEndReason
import org.bigbluebutton.core.models.{ Roles, Users2x }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait LogoutAndEndMeetingCmdMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
val eventBus: InternalEventBus
def handleLogoutAndEndMeetingCmdMsg(msg: LogoutAndEndMeetingCmdMsg) {
for {
u <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId)
} yield {
if (u.role == Roles.MODERATOR_ROLE) {
endMeeting()
log.info("Meeting {} ended by user [{}, {}} when logging out.", liveMeeting.props.meetingProp.intId,
u.intId, u.name)
sendEndMeetingDueToExpiry(MeetingEndReason.ENDED_AFTER_USER_LOGGED_OUT, eventBus, outGW, liveMeeting)
}
}
def endMeeting(): Unit = {
def buildMeetingEndingEvtMsg(meetingId: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
val envelope = BbbCoreEnvelope(MeetingEndingEvtMsg.NAME, routing)
val body = MeetingEndingEvtMsgBody(meetingId)
val header = BbbClientMsgHeader(MeetingEndingEvtMsg.NAME, meetingId, "not-used")
val event = MeetingEndingEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val endingEvent = buildMeetingEndingEvtMsg(liveMeeting.props.meetingProp.intId)
// Broadcast users the meeting will end
outGW.send(endingEvent)
MeetingStatus2x.meetingHasEnded(liveMeeting.status)
def buildMeetingEndedEvtMsg(meetingId: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(MeetingEndedEvtMsg.NAME, routing)
val body = MeetingEndedEvtMsgBody(meetingId)
val header = BbbCoreBaseHeader(MeetingEndedEvtMsg.NAME)
val event = MeetingEndedEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val endedEvnt = buildMeetingEndedEvtMsg(liveMeeting.props.meetingProp.intId)
outGW.send(endedEvnt)
}
}
}

View File

@ -1,25 +1,43 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.domain.MeetingInactivityTracker
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, MeetingInactivityTrackerHelper }
import org.bigbluebutton.core.domain.{ MeetingInactivityTracker, MeetingState2x }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait MeetingActivityResponseCmdMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleMeetingActivityResponseCmdMsg(
msg: MeetingActivityResponseCmdMsg,
tracker: MeetingInactivityTracker
): MeetingInactivityTracker = {
MeetingInactivityTrackerHelper.processMeetingActivityResponse(
props = liveMeeting.props,
outGW,
msg,
tracker
)
msg: MeetingActivityResponseCmdMsg,
state: MeetingState2x
): MeetingState2x = {
processMeetingActivityResponse(liveMeeting.props, outGW, msg)
val tracker = state.inactivityTracker.resetWarningSentAndTimestamp()
state.update(tracker)
}
def processMeetingActivityResponse(
props: DefaultProps,
outGW: OutMsgRouter,
msg: MeetingActivityResponseCmdMsg
): 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)
}
}

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs.MuteUserCmdMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.VoiceUsers
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait MuteUserCmdMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleMuteUserCmdMsg(msg: MuteUserCmdMsg) {
log.info("Received mute user request. meetingId=" + props.meetingProp.intId + " userId="

View File

@ -1,34 +1,17 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.RegisteredUsers
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait RegisterUserReqMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleRegisterUserReqMsg(msg: RegisterUserReqMsg): Unit = {
log.debug("****** RECEIVED RegisterUserReqMsg msg {}", msg)
if (MeetingStatus2x.hasMeetingEnded(liveMeeting.status)) {
// Check first if the meeting has ended and the user refreshed the client to re-connect.
log.info("Register user failed. Mmeeting has ended. meetingId=" + liveMeeting.props.meetingProp.intId +
" userId=" + msg.body.intUserId)
} else {
val regUser = RegisteredUsers.create(msg.body.intUserId, msg.body.extUserId,
msg.body.name, msg.body.role, msg.body.authToken,
msg.body.avatarURL, msg.body.guest, msg.body.authed, msg.body.guest, liveMeeting.registeredUsers)
log.info("Register user success. meetingId=" + liveMeeting.props.meetingProp.intId
+ " userId=" + msg.body.extUserId + " user=" + regUser)
val event = buildUserRegisteredRespMsg(liveMeeting.props.meetingProp.intId, regUser.id, regUser.name, regUser.role)
outGW.send(event)
}
log.debug("RECEIVED RegisterUserReqMsg msg {}", msg)
def buildUserRegisteredRespMsg(meetingId: String, userId: String, name: String, role: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
@ -38,5 +21,18 @@ trait RegisterUserReqMsgHdlr {
val event = UserRegisteredRespMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val regUser = RegisteredUsers.create(msg.body.intUserId, msg.body.extUserId,
msg.body.name, msg.body.role, msg.body.authToken,
msg.body.avatarURL, msg.body.guest, msg.body.authed, msg.body.guest)
RegisteredUsers.add(liveMeeting.registeredUsers, regUser)
log.info("Register user success. meetingId=" + liveMeeting.props.meetingProp.intId
+ " userId=" + msg.body.extUserId + " user=" + regUser)
val event = buildUserRegisteredRespMsg(liveMeeting.props.meetingProp.intId, regUser.id, regUser.name, regUser.role)
outGW.send(event)
}
}

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.MeetingStatus2x
trait SetRecordingStatusCmdMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSetRecordingStatusCmdMsg(msg: SetRecordingStatusCmdMsg) {
log.info("Change recording status. meetingId=" + liveMeeting.props.meetingProp.intId + " recording=" + msg.body.recording)

View File

@ -1,15 +1,14 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
trait SyncGetUsersMeetingRespMsgHdlr {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleSyncGetUsersMeetingRespMsg(): Unit = {
log.debug("Handling SyncGetUsersMeetingRespMsg")

View File

@ -1,14 +1,13 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ MediaStream, WebcamStream, Webcams }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait UserBroadcastCamStartMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUserBroadcastCamStartMsg(msg: UserBroadcastCamStartMsg): Unit = {
@ -21,8 +20,6 @@ trait UserBroadcastCamStartMsgHdlr {
val event = UserBroadcastCamStartedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
val stream = new MediaStream(msg.body.stream, msg.body.stream, msg.header.userId, Map.empty, Set.empty)

View File

@ -1,14 +1,13 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Webcams
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait UserBroadcastCamStopMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUserBroadcastCamStopMsg(msg: UserBroadcastCamStopMsg): Unit = {
@ -21,8 +20,6 @@ trait UserBroadcastCamStopMsgHdlr {
val event = UserBroadcastCamStoppedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
for {

View File

@ -1,14 +1,13 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ Users2x, VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait UserConnectedToGlobalAudioMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUserConnectedToGlobalAudioMsg(msg: UserConnectedToGlobalAudioMsg) {
log.info("Handling UserConnectedToGlobalAudio: meetingId=" + props.meetingProp.intId + " userId=" + msg.body.userId)
@ -25,8 +24,6 @@ trait UserConnectedToGlobalAudioMsgHdlr {
val event = UserJoinedVoiceConfToClientEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
for {

View File

@ -1,14 +1,13 @@
package org.bigbluebutton.core2.message.handlers.users
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
trait UserDisconnectedFromGlobalAudioMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUserDisconnectedFromGlobalAudioMsg(msg: UserDisconnectedFromGlobalAudioMsg) {
log.info("Handling UserDisconnectedToGlobalAudio: meetingId=" + props.meetingProp.intId + " userId=" + msg.body.userId)
@ -24,8 +23,6 @@ trait UserDisconnectedFromGlobalAudioMsgHdlr {
val event = UserLeftVoiceConfToClientEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
for {

View File

@ -0,0 +1,18 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs.UserJoinMeetingReqMsg
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter }
trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers {
this: BaseMeetingActor =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
def handleUserJoinMeetingReqMsg(msg: UserJoinMeetingReqMsg, state: MeetingState2x): MeetingState2x = {
userJoinMeeting(outGW, msg.body.authToken, liveMeeting, state)
}
}

View File

@ -1,30 +1,41 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.domain.{ MeetingExpiryTracker, MeetingState2x }
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter }
import org.bigbluebutton.core.util.TimeUtil
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait UserLeaveReqMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
val outGW: OutMsgRouter
def handleUserLeaveReqMsg(msg: UserLeaveReqMsg): Unit = {
def handleUserLeaveReqMsg(msg: UserLeaveReqMsg, state: MeetingState2x): MeetingState2x = {
for {
u <- Users2x.remove(liveMeeting.users2x, msg.body.userId)
} yield {
log.info("User left meeting. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
captionApp2x.handleUserLeavingMsg(msg.body.userId)
liveMeeting.startCheckingIfWeNeedToEndVoiceConf()
stopAutoStartedRecording()
// send a user left event for the clients to update
val userLeftMeetingEvent = MsgBuilder.buildUserLeftMeetingEvtMsg(liveMeeting.props.meetingProp.intId, u.intId)
outGW.send(userLeftMeetingEvent)
log.info("User left meetingId=" + liveMeeting.props.meetingProp.intId + " userId=" + msg.body.userId)
if (u.presenter) {
automaticallyAssignPresenter(outGW, liveMeeting)
}
}
if (Users2x.numUsers(liveMeeting.users2x) == 0) {
val tracker = state.expiryTracker.setLastUserLeftOn(TimeUtil.timeNowInMs())
state.update(tracker)
} else {
state
}
}

View File

@ -2,13 +2,13 @@ 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
import org.bigbluebutton.core.bus.InternalEventBus
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
class UsersApp(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
val outGW: OutMsgRouter,
val eventBus: InternalEventBus
)(implicit val context: ActorContext)
extends ValidateAuthTokenReqMsgHdlr

View File

@ -1,11 +1,12 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.message.handlers.users.{ ChangeUserEmojiCmdMsgHdlr, ValidateAuthTokenReqMsgHdlr }
trait UsersApp2x
extends UserLeaveReqMsgHdlr
with LockUserInMeetingCmdMsgHdlr
with LockUsersInMeetingCmdMsgHdlr
with GetLockSettingsReqMsgHdlr
with ChangeUserEmojiCmdMsgHdlr {
this: MeetingActor =>

Some files were not shown because too many files have changed in this diff Show More