Merge pull request #19162 from gustavotrott/akka-setPresenterInPod

refactor: Eliminate Meteor dependency in setting up Presenter In Pod
This commit is contained in:
Anton Georgiev 2023-11-20 14:54:31 -05:00 committed by GitHub
commit 1a4c77bb8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 98 additions and 112 deletions

View File

@ -113,6 +113,12 @@ case class EjectUserFromBreakoutInternalMsg(parentId: String, breakoutId: String
*/
case class CapturePresentationReqInternalMsg(userId: String, parentMeetingId: String, filename: String, allPages: Boolean = true) extends InMessage
/**
* Sent to the same meeting to force a new presenter to the Pod
* @param presenterId
*/
case class SetPresenterInDefaultPodInternalMsg(presenterId: String) extends InMessage
/**
* Sent by breakout room to parent meeting to obtain padId
* @param breakoutId

View File

@ -11,7 +11,7 @@ class PresentationPodHdlrs(implicit val context: ActorContext)
with PresentationConversionCompletedSysPubMsgHdlr
with PdfConversionInvalidErrorSysPubMsgHdlr
with SetCurrentPagePubMsgHdlr
with SetPresenterInPodReqMsgHdlr
with SetPresenterInDefaultPodInternalMsgHdlr
with RemovePresentationPubMsgHdlr
with SetPresentationDownloadablePubMsgHdlr
with PresentationConversionUpdatePubMsgHdlr

View File

@ -0,0 +1,68 @@
package org.bigbluebutton.core.apps.presentationpod
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.api.SetPresenterInDefaultPodInternalMsg
import org.bigbluebutton.core.apps.{ RightsManagementTrait }
import org.bigbluebutton.core.bus.MessageBus
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core.models.{ PresentationPod, Users2x }
trait SetPresenterInDefaultPodInternalMsgHdlr {
this: PresentationPodHdlrs =>
def handleSetPresenterInDefaultPodInternalMsg(
msg: SetPresenterInDefaultPodInternalMsg, state: MeetingState2x,
liveMeeting: LiveMeeting, bus: MessageBus
): MeetingState2x = {
// Swith presenter as default presenter pod has changed.
log.info("Presenter pod change will trigger a presenter change")
SetPresenterInPodActionHandler.handleAction(state, liveMeeting, bus.outGW, "", PresentationPod.DEFAULT_PRESENTATION_POD, msg.presenterId)
}
}
object SetPresenterInPodActionHandler extends RightsManagementTrait {
def handleAction(
state: MeetingState2x,
liveMeeting: LiveMeeting,
outGW: OutMsgRouter,
assignedBy: String,
podId: String,
newPresenterId: String
): MeetingState2x = {
def broadcastSetPresenterInPodRespMsg(podId: String, nextPresenterId: String, requesterId: String): Unit = {
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, requesterId
)
val envelope = BbbCoreEnvelope(SetPresenterInPodRespMsg.NAME, routing)
val header = BbbClientMsgHeader(SetPresenterInPodRespMsg.NAME, liveMeeting.props.meetingProp.intId, requesterId)
val body = SetPresenterInPodRespMsgBody(podId, nextPresenterId)
val event = SetPresenterInPodRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
val newState = for {
user <- Users2x.findWithIntId(liveMeeting.users2x, newPresenterId)
pod <- PresentationPodsApp.getPresentationPod(state, podId)
} yield {
if (pod.currentPresenter != "") {
Users2x.removeUserFromPresenterGroup(liveMeeting.users2x, pod.currentPresenter)
liveMeeting.users2x.addOldPresenter(pod.currentPresenter)
}
Users2x.addUserToPresenterGroup(liveMeeting.users2x, newPresenterId)
val updatedPod = pod.setCurrentPresenter(newPresenterId)
broadcastSetPresenterInPodRespMsg(pod.id, newPresenterId, assignedBy)
val pods = state.presentationPodManager.addPod(updatedPod)
state.update(pods)
}
newState match {
case Some(ns) => ns
case None => state
}
}
}

View File

@ -1,78 +0,0 @@
package org.bigbluebutton.core.apps.presentationpod
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.users.AssignPresenterActionHandler
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
import org.bigbluebutton.core.bus.MessageBus
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core.models.{ PresentationPod, Users2x }
trait SetPresenterInPodReqMsgHdlr {
this: PresentationPodHdlrs =>
def handle(
msg: SetPresenterInPodReqMsg, state: MeetingState2x,
liveMeeting: LiveMeeting, bus: MessageBus
): MeetingState2x = {
if (msg.body.podId == PresentationPod.DEFAULT_PRESENTATION_POD) {
// Swith presenter as default presenter pod has changed.
log.info("Presenter pod change will trigger a presenter change")
AssignPresenterActionHandler.handleAction(liveMeeting, bus.outGW, msg.header.userId, msg.body.nextPresenterId)
}
SetPresenterInPodActionHandler.handleAction(state, liveMeeting, bus.outGW, msg.header.userId, msg.body.podId, msg.body.nextPresenterId)
}
}
object SetPresenterInPodActionHandler extends RightsManagementTrait {
def handleAction(
state: MeetingState2x,
liveMeeting: LiveMeeting,
outGW: OutMsgRouter,
assignedBy: String,
podId: String,
newPresenterId: String
): MeetingState2x = {
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, assignedBy)) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to set presenter in presentation pod."
PermissionCheck.ejectUserForFailedPermission(meetingId, assignedBy, reason, outGW, liveMeeting)
state
} else {
def broadcastSetPresenterInPodRespMsg(podId: String, nextPresenterId: String, requesterId: String): Unit = {
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, requesterId
)
val envelope = BbbCoreEnvelope(SetPresenterInPodRespMsg.NAME, routing)
val header = BbbClientMsgHeader(SetPresenterInPodRespMsg.NAME, liveMeeting.props.meetingProp.intId, requesterId)
val body = SetPresenterInPodRespMsgBody(podId, nextPresenterId)
val event = SetPresenterInPodRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
val newState = for {
user <- Users2x.findWithIntId(liveMeeting.users2x, newPresenterId)
pod <- PresentationPodsApp.getPresentationPod(state, podId)
} yield {
if (pod.currentPresenter != "") {
Users2x.removeUserFromPresenterGroup(liveMeeting.users2x, pod.currentPresenter)
liveMeeting.users2x.addOldPresenter(pod.currentPresenter)
}
Users2x.addUserToPresenterGroup(liveMeeting.users2x, newPresenterId)
val updatedPod = pod.setCurrentPresenter(newPresenterId)
broadcastSetPresenterInPodRespMsg(pod.id, newPresenterId, assignedBy)
val pods = state.presentationPodManager.addPod(updatedPod)
state.update(pods)
}
newState match {
case Some(ns) => ns
case None => state
}
}
}
}

View File

@ -2,12 +2,14 @@ package org.bigbluebutton.core.apps.users
import org.apache.pekko.actor.ActorContext
import org.apache.pekko.event.Logging
import org.bigbluebutton.Boot.eventBus
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.api.{SetPresenterInDefaultPodInternalMsg}
import org.bigbluebutton.core.apps.ExternalVideoModel
import org.bigbluebutton.core.bus.InternalEventBus
import org.bigbluebutton.core.bus.{BigBlueButtonEvent, InternalEventBus}
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.running.{LiveMeeting, OutMsgRouter}
import org.bigbluebutton.core2.message.senders.{MsgBuilder, Sender}
import org.bigbluebutton.core2.message.senders.{MsgBuilder}
import org.bigbluebutton.core.apps.screenshare.ScreenshareApp2x
import org.bigbluebutton.core.db.UserStateDAO
@ -67,8 +69,8 @@ object UsersApp {
moderator <- Users2x.findModerator(liveMeeting.users2x)
newPresenter <- Users2x.makePresenter(liveMeeting.users2x, moderator.intId)
} yield {
// println(s"automaticallyAssignPresenter: moderator=${moderator} newPresenter=${newPresenter.intId}");
sendPresenterAssigned(outGW, meetingId, newPresenter.intId, newPresenter.name, newPresenter.intId)
sendPresenterInPodReq(meetingId, newPresenter.intId)
}
}
@ -77,6 +79,10 @@ object UsersApp {
outGW.send(event)
}
def sendPresenterInPodReq(meetingId: String, newPresenterIntId: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingId, SetPresenterInDefaultPodInternalMsg(newPresenterIntId)))
}
def sendUserLeftMeetingToAllClients(outGW: OutMsgRouter, meetingId: String,
userId: String, eject: Boolean = false, ejectedBy: String = "", reason: String = "", reasonCode: String = ""): Unit = {
// send a user left event for the clients to update

View File

@ -346,8 +346,6 @@ class ReceivedJsonMsgHandlerActor(
routeGenericMsg[CreateNewPresentationPodPubMsg](envelope, jsonNode)
case RemovePresentationPodPubMsg.NAME =>
routeGenericMsg[RemovePresentationPodPubMsg](envelope, jsonNode)
case SetPresenterInPodReqMsg.NAME =>
routeGenericMsg[SetPresenterInPodReqMsg](envelope, jsonNode)
// Caption
case EditCaptionHistoryPubMsg.NAME =>

View File

@ -248,25 +248,26 @@ class MeetingActor(
//=============================
// 2x messages
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
// Handling RegisterUserReqMsg as it is forwarded from BBBActor and
// its type is not BbbCommonEnvCoreMsg
case m: RegisterUserReqMsg => usersApp.handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: GetRunningMeetingStateReqMsg => handleGetRunningMeetingStateReqMsg(m)
case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m)
case m: RegisterUserReqMsg => usersApp.handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: GetRunningMeetingStateReqMsg => handleGetRunningMeetingStateReqMsg(m)
case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m)
// Meeting
case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m)
case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m)
//======================================
//=======================================
// internal messages
case msg: MonitorNumberOfUsersInternalMsg => handleMonitorNumberOfUsers(msg)
case msg: MonitorNumberOfUsersInternalMsg => handleMonitorNumberOfUsers(msg)
case msg: SetPresenterInDefaultPodInternalMsg => state = presentationPodsApp.handleSetPresenterInDefaultPodInternalMsg(msg, state, liveMeeting, msgBus)
case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg)
case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg)
case msg: SendTimeRemainingAuditInternalMsg =>
if (!liveMeeting.props.meetingProp.isBreakout) {
// Update users of meeting remaining time.
@ -531,7 +532,6 @@ class MeetingActor(
case m: PresentationConversionCompletedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: PdfConversionInvalidErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: SetCurrentPagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: SetPresenterInPodReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: RemovePresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: SetPresentationDownloadablePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: PresentationConversionUpdateSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)

View File

@ -1,8 +1,8 @@
package org.bigbluebutton.core2.message.senders
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, Routing, ValidateConnAuthTokenSysRespMsg, ValidateConnAuthTokenSysRespMsgBody, NotifyAllInMeetingEvtMsg, NotifyAllInMeetingEvtMsgBody, NotifyRoleInMeetingEvtMsg, NotifyRoleInMeetingEvtMsgBody, NotifyUserInMeetingEvtMsg, NotifyUserInMeetingEvtMsgBody, _ }
import org.bigbluebutton.core.models.GuestWaiting
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, NotifyAllInMeetingEvtMsg, NotifyAllInMeetingEvtMsgBody, NotifyRoleInMeetingEvtMsg, NotifyRoleInMeetingEvtMsgBody, NotifyUserInMeetingEvtMsg, NotifyUserInMeetingEvtMsgBody, Routing, ValidateConnAuthTokenSysRespMsg, ValidateConnAuthTokenSysRespMsgBody, _ }
import org.bigbluebutton.core.models.{ GuestWaiting, PresentationPod }
object MsgBuilder {
def buildGuestPolicyChangedEvtMsg(meetingId: String, userId: String, policy: String, setBy: String): BbbCommonEnvCoreMsg = {

View File

@ -23,10 +23,6 @@ object SetCurrentPagePubMsg { val NAME = "SetCurrentPagePubMsg" }
case class SetCurrentPagePubMsg(header: BbbClientMsgHeader, body: SetCurrentPagePubMsgBody) extends StandardMsg
case class SetCurrentPagePubMsgBody(podId: String, presentationId: String, pageId: String)
object SetPresenterInPodReqMsg { val NAME = "SetPresenterInPodReqMsg" }
case class SetPresenterInPodReqMsg(header: BbbClientMsgHeader, body: SetPresenterInPodReqMsgBody) extends StandardMsg
case class SetPresenterInPodReqMsgBody(podId: String, nextPresenterId: String)
object RemovePresentationPubMsg { val NAME = "RemovePresentationPubMsg" }
case class RemovePresentationPubMsg(header: BbbClientMsgHeader, body: RemovePresentationPubMsgBody) extends StandardMsg
case class RemovePresentationPubMsgBody(podId: String, presentationId: String)

View File

@ -1,21 +1,11 @@
import Users from '/imports/api/users';
import PresentationPods from '/imports/api/presentation-pods';
import changePresenter from '/imports/api/users/server/modifiers/changePresenter';
import RedisPubSub from '/imports/startup/server/redis';
import Logger from '/imports/startup/server/logger';
function setPresenterInPodReqMsg(credentials) { // TODO-- switch to meetingId, etc
const REDIS_CONFIG = Meteor.settings.private.redis;
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
const EVENT_NAME = 'SetPresenterInPodReqMsg';
const { meetingId, requesterUserId, presenterId } = credentials;
const payload = {
podId: 'DEFAULT_PRESENTATION_POD',
nextPresenterId: presenterId,
};
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
// TODO It will be removed soon
Logger.debug(credentials);
}
export default async function handlePresenterAssigned({ body }, meetingId) {