Merge branch 'bbb-2x-mconf' into html5-2x-polls-messages

This commit is contained in:
Klauswk 2017-07-17 16:54:37 -03:00 committed by GitHub
commit 7173c0e20c
333 changed files with 2328 additions and 11462 deletions

View File

@ -2,7 +2,7 @@ BigBlueButton
=============
BigBlueButton is an open source web conferencing system.
BigBlueButton supports real-time sharing of audio, video, slides (with witeboard controls), chat, and the screen. Instructors can engage remote students with polling, emojis, and breakout rooms. BigBlueButton can record and playback all content shared in a session.
BigBlueButton supports real-time sharing of audio, video, slides (with whiteboard controls), chat, and the screen. Instructors can engage remote students with polling, emojis, and breakout rooms. BigBlueButton can record and playback all content shared in a session.
We designed BigBlueButton for online learning (though it can be used for many [other applications](http://www.c4isrnet.com/story/military-tech/disa/2015/02/11/disa-to-save-12m-defense-collaboration-services/23238997/)). The educational use cases for BigBlueButton are
@ -10,7 +10,7 @@ We designed BigBlueButton for online learning (though it can be used for many [o
* Small group collaboration
* On-line classes
BigBlueButton runs on a Ubuntu 16.04 64-bit server. If you follow the [installation instructions](http://docs.bigbluebutton.org/install/install.html), we gaurantee you will have BigBlueButton installed and running within 30 minutes (or your money back :-).
BigBlueButton runs on a Ubuntu 16.04 64-bit server. If you follow the [installation instructions](http://docs.bigbluebutton.org/install/install.html), we guarantee you will have BigBlueButton installed and running within 30 minutes (or your money back :-).
For full technical documentation BigBlueButton -- including architecture, features, API, and GreenLight (the default front-end) -- see [http://docs.bigbluebutton.org/](http://docs.bigbluebutton.org/).

View File

@ -25,6 +25,7 @@ resolvers ++= Seq(
)
resolvers += Resolver.sonatypeRepo("releases")
resolvers += Resolver.typesafeRepo("releases")
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) )
@ -90,9 +91,21 @@ libraryDependencies += "org.scalatest" % "scalatest_2.12" % "3.0.3" % "test"
libraryDependencies += "org.mockito" % "mockito-core" % "2.7.22" % "test"
seq(Revolver.settings: _*)
scalariformSettings
import com.typesafe.sbt.SbtScalariform
import scalariform.formatter.preferences._
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
SbtScalariform.defaultScalariformSettings
ScalariformKeys.preferences := ScalariformKeys.preferences.value
.setPreference(AlignSingleLineCaseStatements, true)
.setPreference(DoubleIndentClassDeclaration, true)
.setPreference(AlignParameters, true)
//-----------

View File

@ -1,6 +1,8 @@
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
//addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0")

View File

@ -5,7 +5,6 @@ import org.bigbluebutton.common.messages.*;
public interface IBigBlueButtonInGW {
void handleJsonMessage(String json);
void handleBigBlueButtonMessage(IBigBlueButtonMessage message);
void isAliveAudit(String aliveID);
@ -18,17 +17,10 @@ public interface IBigBlueButtonInGW {
void lockSettings(String meetingID, Boolean locked, Map<String, Boolean> lockSettigs);
void activityResponse(String meetingID);
// Polling
void votePoll(String meetingId, String userId, String pollId, Integer questionId, Integer answerId);
void startPoll(String meetingId, String requesterId, String pollId, String pollType);
void stopPoll(String meetingId, String userId, String pollId);
void showPollResult(String meetingId, String requesterId, String pollId, Boolean show);
// 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);
void lockUser(String meetingId, String requesterID, boolean lock, String internalUserID);
// Users
void validateAuthToken(String meetingId, String userId, String token, String correlationId, String sessionId);
@ -47,61 +39,11 @@ public interface IBigBlueButtonInGW {
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 userConnectedToGlobalAudio(String voiceConf, String userid, String name);
void userDisconnectedFromGlobalAudio(String voiceConf, String userid, String name);
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);
// Voice
void initAudioSettings(String meetingID, String requesterID, Boolean muted);
void muteAllExceptPresenter(String meetingID, String requesterID, Boolean mute);
void muteAllUsers(String meetingID, String requesterID, Boolean mute);
void isMeetingMuted(String meetingID, String requesterID);
void muteUser(String meetingID, String requesterID, String userID, Boolean mute);
void lockMuteUser(String meetingID, String requesterID, String userID, Boolean lock);
void ejectUserFromVoice(String meetingID, String userId, String ejectedBy);
void ejectUserFromMeeting(String meetingId, String userId, String ejectedBy);
void voiceUserJoined(String voiceConfId, String voiceUserId, String userId, String callerIdName,
String callerIdNum, Boolean muted, String avatarURL, Boolean talking);
void voiceUserLeft(String meetingId, String userId);
void voiceUserLocked(String meetingId, String userId, Boolean locked);
void voiceUserMuted(String meetingId, String userId, Boolean muted);
void voiceUserTalking(String meetingId, String userId, Boolean talking);
void voiceRecording(String meetingId, String recordingFile,
String timestamp, Boolean recording);
// Presentation
void clear(String meetingID);
void removePresentation(String meetingID, String presentationID);
void getPresentationInfo(String meetingID, String requesterID, String replyTo);
void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio);
void gotoSlide(String meetingID, String page);
void sharePresentation(String meetingID, String presentationID, boolean share);
void getSlideInfo(String meetingID, String requesterID, String replyTo);
void sendConversionUpdate(String messageKey, String meetingId,
String code, String presId, String presName);
void sendPageCountError(String messageKey, String meetingId,
String code, String presId, int numberOfPages,
int maxNumberPages, String presName);
void sendSlideGenerated(String messageKey, String meetingId,
String code, String presId, int numberOfPages,
int pagesCompleted, String presName);
void sendConversionCompleted(String messageKey, String meetingId,
String code, String presId, int numPages, String presName, String presBaseUrl, boolean downloadable);
// Layout
void getCurrentLayout(String meetingID, String requesterID);
void broadcastLayout(String meetingID, String requesterID, String layout);
void lockLayout(String meetingID, String setById,
boolean lock, boolean viewersOnly,
String layout);
// DeskShare
void deskShareStarted(String confId, String callerId, String callerIdName);
void deskShareStopped(String conferenceName, String callerId, String callerIdName);

View File

@ -1,61 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class ConversionUpdatesProcessor {
private IBigBlueButtonInGW bbbInGW;
public ConversionUpdatesProcessor(IBigBlueButtonInGW bbbInGW) {
this.bbbInGW = bbbInGW;
}
public void sendConversionUpdate(String messageKey, String conference,
String code, String presId, String presName) {
bbbInGW.sendConversionUpdate(messageKey, conference,
code, presId, presName);
}
public void sendPageCountError(String messageKey, String conference,
String code, String presId, int numberOfPages,
int maxNumberPages, String presName) {
bbbInGW.sendPageCountError(messageKey, conference, code, presId, numberOfPages,
maxNumberPages, presName);
}
public void sendSlideGenerated(String messageKey, String conference,
String code, String presId, int numberOfPages,
int pagesCompleted, String presName) {
bbbInGW.sendSlideGenerated(messageKey, conference,
code, presId, numberOfPages, pagesCompleted, presName);
}
public void sendConversionCompleted(String messageKey, String conference,
String code, String presId, Integer numberOfPages, String presName,
String presBaseUrl, Boolean downloadable) {
bbbInGW.sendConversionCompleted(messageKey, conference,
code, presId, numberOfPages, presName, presBaseUrl, downloadable);
}
public void setBigBlueButtonInGW(IBigBlueButtonInGW inGW) {
bbbInGW = inGW;
}
}

View File

@ -33,7 +33,6 @@ public class LockMessageReceiver implements MessageHandler {
bbbGW.getLockSettings(msg.meetingId, msg.userId);
} else if(LockUserMessage.LOCK_USER.equals(messageName)) {
LockUserMessage msg = LockUserMessage.fromJson(message);
bbbGW.lockUser(msg.meetingId, msg.requesterId, msg.lock, msg.internalUserId);
} else if(SendLockSettingsMessage.SEND_LOCK_SETTINGS.equals(messageName)) {
SendLockSettingsMessage msg = SendLockSettingsMessage.fromJson(message);
bbbGW.sendLockSettings(msg.meetingId, msg.userId, msg.newSettings);

View File

@ -13,8 +13,6 @@ import org.bigbluebutton.common.messages.MessageFromJsonConverter;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.PubSubPingMessage;
import org.bigbluebutton.common.messages.UserConnectedToGlobalAudio;
import org.bigbluebutton.common.messages.UserDisconnectedFromGlobalAudio;
import org.bigbluebutton.common.messages.ValidateAuthTokenMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import org.bigbluebutton.messages.CreateMeetingRequest;
@ -72,40 +70,7 @@ public class MeetingMessageReceiver implements MessageHandler {
ValidateAuthTokenMessage vam = (ValidateAuthTokenMessage) msg;
String sessionId = "tobeimplemented";
bbbGW.validateAuthToken(vam.meetingId, vam.userId, vam.token, vam.replyTo, sessionId);
} else if (msg instanceof UserConnectedToGlobalAudio) {
UserConnectedToGlobalAudio ustga = (UserConnectedToGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", ustga.voiceConf);
logData.put("userId", ustga.userid);
logData.put("username", ustga.name);
logData.put("event", "user_connected_to_global_audio");
logData.put("description", "User connected to global audio.");
/*
Gson gson = new Gson();
String logStr = gson.toJson(logData);
System.out.println("User connected to global audio: data={}", logStr);
*/
bbbGW.userConnectedToGlobalAudio(ustga.voiceConf, ustga.userid, ustga.name);
} else if (msg instanceof UserDisconnectedFromGlobalAudio) {
UserDisconnectedFromGlobalAudio udfga = (UserDisconnectedFromGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", udfga.voiceConf);
logData.put("userId", udfga.userid);
logData.put("username", udfga.name);
logData.put("event", "user_disconnected_from_global_audio");
logData.put("description", "User disconnected from global audio.");
/*
Gson gson = new Gson();
String logStr = gson.toJson(logData);
System.out.println("User disconnected from global audio: data={}", logStr);
*/
bbbGW.userDisconnectedFromGlobalAudio(udfga.voiceConf, udfga.userid, udfga.name);
}
else if (msg instanceof GetAllMeetingsRequest) {
} else if (msg instanceof GetAllMeetingsRequest) {
GetAllMeetingsRequest gamr = (GetAllMeetingsRequest) msg;
bbbGW.getAllMeetings("no_need_of_a_meeting_id");
} else if (msg instanceof ActivityResponseMessage) {

View File

@ -1,53 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.*;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PollingMessageReceiver implements MessageHandler{
private static final Logger log = LoggerFactory.getLogger(PollingMessageReceiver.class);
private IBigBlueButtonInGW bbbGW;
public PollingMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_POLLING_CHANNEL)) {
log.debug("Polling message: " + channel + " " + message);
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 (VotePollUserRequestMessage.VOTE_POLL_REQUEST.equals(messageName)) {
VotePollUserRequestMessage msg = VotePollUserRequestMessage.fromJson(message);
bbbGW.votePoll(msg.meetingId, msg.userId, msg.pollId, msg.questionId, msg.answerId);
} else if (StartPollRequestMessage.START_POLL_REQUEST.equals(messageName)){
log.debug("Received StartPollRequest message");
StartPollRequestMessage msg = StartPollRequestMessage.fromJson(message);
bbbGW.startPoll(msg.meetingId, msg.requesterId, msg.pollId, msg.pollType);
} else if (StopPollRequestMessage.STOP_POLL_REQUEST.equals(messageName)){
StopPollRequestMessage msg = StopPollRequestMessage.fromJson(message);
bbbGW.stopPoll(msg.meetingId, msg.requesterId, msg.pollId);
} else if (ShowPollResultRequestMessage.SHOW_POLL_RESULT_REQUEST.equals(messageName)){
ShowPollResultRequestMessage msg = ShowPollResultRequestMessage.fromJson(message);
bbbGW.showPollResult(msg.meetingId, msg.requesterId, msg.pollId, msg.show);
} else if (StartCustomPollRequestMessage.START_CUSTOM_POLL_REQUEST.equals(messageName)){
Gson gson = new Gson();
StartCustomPollRequestMessage msg = gson.fromJson(message, StartCustomPollRequestMessage.class);
bbbGW.handleBigBlueButtonMessage(msg);
}
}
}
}
}
}

View File

@ -1,179 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import java.util.HashMap;
import org.bigbluebutton.common.messages.GetPresentationInfoMessage;
import org.bigbluebutton.common.messages.GetSlideInfoMessage;
import org.bigbluebutton.common.messages.GoToSlideMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.RemovePresentationMessage;
import org.bigbluebutton.common.messages.ResizeAndMoveSlideMessage;
import org.bigbluebutton.common.messages.SendConversionCompletedMessage;
import org.bigbluebutton.common.messages.SendConversionUpdateMessage;
import org.bigbluebutton.common.messages.SendPageCountErrorMessage;
import org.bigbluebutton.common.messages.SendSlideGeneratedMessage;
import org.bigbluebutton.common.messages.SharePresentationMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
public class PresentationMessageListener implements MessageHandler {
public static final String OFFICE_DOC_CONVERSION_SUCCESS_KEY = "OFFICE_DOC_CONVERSION_SUCCESS";
public static final String OFFICE_DOC_CONVERSION_FAILED_KEY = "OFFICE_DOC_CONVERSION_FAILED";
public static final String OFFICE_DOC_CONVERSION_INVALID_KEY = "OFFICE_DOC_CONVERSION_INVALID";
public static final String SUPPORTED_DOCUMENT_KEY = "SUPPORTED_DOCUMENT";
public static final String UNSUPPORTED_DOCUMENT_KEY = "UNSUPPORTED_DOCUMENT";
public static final String PAGE_COUNT_FAILED_KEY = "PAGE_COUNT_FAILED";
public static final String PAGE_COUNT_EXCEEDED_KEY = "PAGE_COUNT_EXCEEDED";
public static final String GENERATED_SLIDE_KEY = "GENERATED_SLIDE";
public static final String GENERATING_THUMBNAIL_KEY = "GENERATING_THUMBNAIL";
public static final String GENERATED_THUMBNAIL_KEY = "GENERATED_THUMBNAIL";
public static final String CONVERSION_COMPLETED_KEY = "CONVERSION_COMPLETED";
private ConversionUpdatesProcessor conversionUpdatesProcessor;
private IBigBlueButtonInGW bbbInGW;
public PresentationMessageListener(IBigBlueButtonInGW inGW) {
bbbInGW = inGW;
conversionUpdatesProcessor = new ConversionUpdatesProcessor(bbbInGW);
}
private void sendConversionUpdate(String messageKey, String conference,
String code, String presId, String filename) {
conversionUpdatesProcessor.sendConversionUpdate(messageKey, conference,
code, presId, filename);
}
public void sendPageCountError(String messageKey, String conference,
String code, String presId, Integer numberOfPages,
Integer maxNumberPages, String filename) {
conversionUpdatesProcessor.sendPageCountError(messageKey, conference,
code, presId, numberOfPages,
maxNumberPages, filename);
}
private void sendSlideGenerated(String messageKey, String conference,
String code, String presId, Integer numberOfPages,
Integer pagesCompleted, String filename) {
conversionUpdatesProcessor.sendSlideGenerated(messageKey, conference,
code, presId, numberOfPages,
pagesCompleted, filename);
}
private void sendConversionCompleted(String messageKey, String conference,
String code, String presId, Integer numberOfPages,
String filename, String presBaseUrl, Boolean downloadable) {
conversionUpdatesProcessor.sendConversionCompleted(messageKey, conference,
code, presId, numberOfPages, filename, presBaseUrl, downloadable);
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_PRESENTATION_CHANNEL)) {
System.out.println("Presentation message: " + channel + " " + message);
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 (SendConversionUpdateMessage.SEND_CONVERSION_UPDATE.equals(messageName)) {
SendConversionUpdateMessage msg = SendConversionUpdateMessage.fromJson(message);
// sendConversionUpdate(msg.messageKey, msg.meetingId, msg.code,
// msg.presId, msg.presName);
bbbInGW.sendConversionUpdate(msg.messageKey, msg.meetingId,
msg.code, msg.presId, msg.presName);
} else if (ResizeAndMoveSlideMessage.RESIZE_AND_MOVE_SLIDE.equals(messageName)) {
ResizeAndMoveSlideMessage msg = ResizeAndMoveSlideMessage.fromJson(message);
bbbInGW.resizeAndMoveSlide(msg.meetingId, msg.xOffset, msg.yOffset,
msg.widthRatio, msg.heightRatio);
} else if (GetPresentationInfoMessage.GET_PRESENTATION_INFO.equals(messageName)) {
GetPresentationInfoMessage msg = GetPresentationInfoMessage.fromJson(message);
bbbInGW.getPresentationInfo(msg.meetingId, msg.requesterId, msg.replyTo);
} else if (SendConversionCompletedMessage.SEND_CONVERSION_COMPLETED.equals(messageName)) {
SendConversionCompletedMessage msg = SendConversionCompletedMessage.fromJson(message);
// sendConversionCompleted(msg.messageKey, msg.meetingId, msg.code,
// msg.presId, msg.numPages, msg.presName, msg.presBaseUrl);
bbbInGW.sendConversionCompleted(msg.messageKey, msg.meetingId, msg.code,
msg.presId, msg.numPages, msg.presName, msg.presBaseUrl, msg.downloadable);
} else if (SendPageCountErrorMessage.SEND_PAGE_COUNT_ERROR.equals(messageName)) {
SendPageCountErrorMessage msg = SendPageCountErrorMessage.fromJson(message);
// sendPageCountError(msg.messageKey, msg.meetingId, msg.code,
// msg.presId, msg.numberOfPages, msg.maxNumberPages, msg.presName);
bbbInGW.sendPageCountError(msg.messageKey, msg.meetingId, msg.code,
msg.presId, msg.numberOfPages, msg.maxNumberPages, msg.presName);
} else if (GoToSlideMessage.GO_TO_SLIDE.equals(messageName)) {
GoToSlideMessage msg = GoToSlideMessage.fromJson(message);
bbbInGW.gotoSlide(msg.meetingId, msg.page);
} else if (RemovePresentationMessage.REMOVE_PRESENTATION.equals(messageName)) {
RemovePresentationMessage msg = RemovePresentationMessage.fromJson(message);
bbbInGW.removePresentation(msg.meetingId, msg.presentationId);
} else if (SharePresentationMessage.SHARE_PRESENTATION.equals(messageName)) {
SharePresentationMessage msg = SharePresentationMessage.fromJson(message);
bbbInGW.sharePresentation(msg.meetingId, msg.presentationId, msg.share);
} else if (GetSlideInfoMessage.GET_SLIDE_INFO.equals(messageName)) {
GetSlideInfoMessage msg = GetSlideInfoMessage.fromJson(message);
bbbInGW.getSlideInfo(msg.meetingId, msg.requesterId, msg.replyTo);
} else if (SendSlideGeneratedMessage.SEND_SLIDE_GENERATED.equals(messageName)) {
SendSlideGeneratedMessage msg = SendSlideGeneratedMessage.fromJson(message);
bbbInGW.sendSlideGenerated(msg.messageKey, msg.meetingId, msg.code,
msg.presId, msg.numberOfPages, msg.pagesCompleted, msg.presName);
}
}
}
else {
HashMap<String,String> map = new Gson().fromJson(message, new TypeToken<HashMap<String, String>>() {}.getType());
String code = (String) map.get("returnCode");
String presId = (String) map.get("presentationId");
String filename = (String) map.get("filename");
String conference = (String) map.get("conference");
String messageKey = (String) map.get("messageKey");
if (messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_SUCCESS_KEY) ||
messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_FAILED_KEY) ||
messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_INVALID_KEY) ||
messageKey.equalsIgnoreCase(SUPPORTED_DOCUMENT_KEY) ||
messageKey.equalsIgnoreCase(UNSUPPORTED_DOCUMENT_KEY) ||
messageKey.equalsIgnoreCase(GENERATING_THUMBNAIL_KEY) ||
messageKey.equalsIgnoreCase(GENERATED_THUMBNAIL_KEY) ||
messageKey.equalsIgnoreCase(PAGE_COUNT_FAILED_KEY)){
sendConversionUpdate(messageKey, conference, code, presId, filename);
} else if(messageKey.equalsIgnoreCase(PAGE_COUNT_EXCEEDED_KEY)){
Integer numberOfPages = new Integer((String) map.get("numberOfPages"));
Integer maxNumberPages = new Integer((String) map.get("maxNumberPages"));
sendPageCountError(messageKey, conference, code,
presId, numberOfPages, maxNumberPages, filename);
} else if(messageKey.equalsIgnoreCase(GENERATED_SLIDE_KEY)){
Integer numberOfPages = new Integer((String) map.get("numberOfPages"));
Integer pagesCompleted = new Integer((String) map.get("pagesCompleted"));
sendSlideGenerated(messageKey, conference, code,
presId, numberOfPages, pagesCompleted, filename);
} else if(messageKey.equalsIgnoreCase(CONVERSION_COMPLETED_KEY)){
Integer numberOfPages = new Integer((String) map.get("numberOfPages"));
String presBaseUrl = (String) map.get("presentationBaseUrl");
Boolean downloadable = new Boolean((String) map.get("downloadable"));
sendConversionCompleted(messageKey, conference, code,
presId, numberOfPages, filename, presBaseUrl, downloadable);
}
}
}
}
}

View File

@ -1,12 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
public class PreuploadedPresentation {
public final String id;
public final int numPages;
public PreuploadedPresentation(String id, int numPages) {
this.id = id;
this.numPages = numPages;
}
}

View File

@ -34,15 +34,9 @@ public class RedisMessageReceiver {
LockMessageReceiver lockRx = new LockMessageReceiver(bbbGW);
receivers.add(lockRx);
PresentationMessageListener presRx = new PresentationMessageListener(bbbGW);
receivers.add(presRx);
UsersMessageReceiver usersRx = new UsersMessageReceiver(bbbGW);
receivers.add(usersRx);
PollingMessageReceiver pollRx = new PollingMessageReceiver(bbbGW);
receivers.add(pollRx);
MeetingMessageReceiver meetingRx = new MeetingMessageReceiver(bbbGW);
receivers.add(meetingRx);
}

View File

@ -42,9 +42,6 @@ public class UsersMessageReceiver implements MessageHandler{
case UserEmojiStatusMessage.USER_EMOJI_STATUS:
processUserEmojiStatusMessage(message);
break;
case EjectUserFromMeetingRequestMessage.EJECT_USER_FROM_MEETING_REQUEST:
processEjectUserFromMeetingRequestMessage(message);
break;
case UserShareWebcamRequestMessage.USER_SHARE_WEBCAM_REQUEST:
processUserShareWebcamRequestMessage(message);
break;
@ -66,51 +63,6 @@ public class UsersMessageReceiver implements MessageHandler{
case InitPermissionsSettingMessage.INIT_PERMISSIONS_SETTING:
processInitPermissionsSettingMessage(message);
break;
case InitAudioSettingsMessage.INIT_AUDIO_SETTING:
processInitAudioSettingsMessage(message);
break;
case BroadcastLayoutRequestMessage.BROADCAST_LAYOUT_REQUEST:
processBroadcastLayoutRequestMessage(message);
break;
case LockLayoutRequestMessage.LOCK_LAYOUT_REQUEST:
processLockLayoutRequestMessage(message);
break;
case GetCurrentLayoutRequestMessage.GET_CURRENT_LAYOUT_REQUEST:
processGetCurrentLayoutRequestMessage(message);
break;
case MuteAllExceptPresenterRequestMessage.MUTE_ALL_EXCEPT_PRESENTER_REQUEST:
processMuteAllExceptPresenterRequestMessage(message);
break;
case MuteAllRequestMessage.MUTE_ALL_REQUEST:
processMuteAllRequestMessage(message);
break;
case IsMeetingMutedRequestMessage.IS_MEETING_MUTED_REQUEST:
processIsMeetingMutedRequestMessage(message);
break;
case MuteUserRequestMessage.MUTE_USER_REQUEST:
processMuteUserRequestMessage(message);
break;
case LockMuteUserRequestMessage.LOCK_MUTE_USER_REQUEST:
processLockMuteUserRequestMessage(message);
break;
case EjectUserFromVoiceRequestMessage.EJECT_USER_FROM_VOICE_REQUEST:
processEjectUserFromVoiceRequestMessage(message);
break;
case GetBreakoutRoomsList.NAME:
bbbInGW.handleJsonMessage(message);
break;
case CreateBreakoutRoomsRequest.NAME:
bbbInGW.handleJsonMessage(message);
break;
case ListenInOnBreakout.NAME:
bbbInGW.handleJsonMessage(message);
break;
case RequestBreakoutJoinURL.NAME:
bbbInGW.handleJsonMessage(message);
break;
case EndAllBreakoutRoomsRequest.NAME:
bbbInGW.handleJsonMessage(message);
break;
case ChangeUserRoleMessage.CHANGE_USER_ROLE:
processChangeUserRoleMessage(message);
break;
@ -129,79 +81,6 @@ public class UsersMessageReceiver implements MessageHandler{
}
}
}
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN)) {
//System.out.println("Voice message: " + channel + " " + message);
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();
switch (messageName) {
case UserJoinedVoiceConfMessage.USER_JOINED_VOICE_CONF:
processUserJoinedVoiceConfMessage(message);
break;
case UserLeftVoiceConfMessage.USER_LEFT_VOICE_CONF:
processUserLeftVoiceConfMessage(message);
break;
case UserLockedInVoiceConfMessage.USER_LOCKED_IN_VOICE_CONF:
processUserLockedInVoiceConfMessage(message);
break;
case UserMutedInVoiceConfMessage.USER_MUTED_IN_VOICE_CONF:
processUserMutedInVoiceConfMessage(message);
break;
case UserTalkingInVoiceConfMessage.USER_TALKING_IN_VOICE_CONF:
processUserTalkingInVoiceConfMessage(message);
break;
case VoiceConfRecordingStartedMessage.VOICE_CONF_RECORDING_STARTED:
processVoiceConfRecordingStartedMessage(message);
break;
}
}
}
}
}
private void processUserJoinedVoiceConfMessage(String json) {
UserJoinedVoiceConfMessage msg = UserJoinedVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserJoined(msg.voiceConfId, msg.voiceUserId, msg.userId, msg.callerIdName, msg.callerIdNum, msg.muted, msg.avatarURL, msg.talking);
}
}
private void processUserLeftVoiceConfMessage(String json) {
UserLeftVoiceConfMessage msg = UserLeftVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserLeft(msg.voiceConfId, msg.voiceUserId);
}
}
private void processUserLockedInVoiceConfMessage(String json) {
UserLockedInVoiceConfMessage msg = UserLockedInVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserLocked(msg.voiceConfId, msg.voiceUserId, msg.locked);
}
}
private void processUserMutedInVoiceConfMessage(String json) {
UserMutedInVoiceConfMessage msg = UserMutedInVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserMuted(msg.voiceConfId, msg.voiceUserId, msg.muted);
}
}
private void processUserTalkingInVoiceConfMessage(String json) {
UserTalkingInVoiceConfMessage msg = UserTalkingInVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserTalking(msg.voiceConfId, msg.voiceUserId, msg.talking);
}
}
private void processVoiceConfRecordingStartedMessage(String json) {
VoiceConfRecordingStartedMessage msg = VoiceConfRecordingStartedMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceRecording(msg.voiceConfId, msg.recordStream, msg.timestamp, msg.recording);
}
}
@ -233,13 +112,6 @@ public class UsersMessageReceiver implements MessageHandler{
}
}
private void processEjectUserFromMeetingRequestMessage(String message) {
EjectUserFromMeetingRequestMessage eufm = EjectUserFromMeetingRequestMessage.fromJson(message);
if (eufm != null) {
bbbInGW.ejectUserFromMeeting(eufm.meetingId, eufm.userId, eufm.ejectedBy);
}
}
private void processUserShareWebcamRequestMessage(String message) {
UserShareWebcamRequestMessage msg = UserShareWebcamRequestMessage.fromJson(message);
if (msg != null) {
@ -288,76 +160,6 @@ public class UsersMessageReceiver implements MessageHandler{
bbbInGW.initLockSettings(msg.meetingId, msg.permissions);
}
}
private void processInitAudioSettingsMessage(String message) {
InitAudioSettingsMessage msg = InitAudioSettingsMessage.fromJson(message);
if (msg != null) {
bbbInGW.initAudioSettings(msg.meetingId, msg.userId, msg.muted);
}
}
private void processBroadcastLayoutRequestMessage(String message) {
BroadcastLayoutRequestMessage msg = BroadcastLayoutRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.broadcastLayout(msg.meetingId, msg.userId, msg.layout);
}
}
private void processLockLayoutRequestMessage(String message) {
LockLayoutRequestMessage msg = LockLayoutRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.lockLayout(msg.meetingId, msg.userId, msg.lock, msg.viewersOnly, msg.layout);
}
}
private void processGetCurrentLayoutRequestMessage(String message) {
GetCurrentLayoutRequestMessage msg = GetCurrentLayoutRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.getCurrentLayout(msg.meetingId, msg.userId);
}
}
private void processMuteAllExceptPresenterRequestMessage(String message) {
MuteAllExceptPresenterRequestMessage msg = MuteAllExceptPresenterRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.muteAllExceptPresenter(msg.meetingId, msg.requesterId, msg.mute);
}
}
private void processMuteAllRequestMessage(String message) {
MuteAllRequestMessage msg = MuteAllRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.muteAllUsers(msg.meetingId, msg.requesterId, msg.mute);
}
}
private void processIsMeetingMutedRequestMessage(String message) {
IsMeetingMutedRequestMessage msg = IsMeetingMutedRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.isMeetingMuted(msg.meetingId, msg.requesterId);
}
}
private void processMuteUserRequestMessage(String message) {
MuteUserRequestMessage msg = MuteUserRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.muteUser(msg.meetingId, msg.requesterId, msg.userId, msg.mute);
}
}
private void processLockMuteUserRequestMessage(String message) {
LockMuteUserRequestMessage msg = LockMuteUserRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.lockMuteUser(msg.meetingId, msg.requesterId, msg.userId, msg.lock);
}
}
private void processEjectUserFromVoiceRequestMessage(String message) {
EjectUserFromVoiceRequestMessage msg = EjectUserFromVoiceRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.ejectUserFromVoice(msg.meetingId, msg.userId, msg.requesterId);
}
}
private void processChangeUserRoleMessage(String message) {
ChangeUserRoleMessage msg = ChangeUserRoleMessage.fromJson(message);

View File

@ -3,13 +3,9 @@ package org.bigbluebutton
import akka.event.Logging
import akka.actor.ActorSystem
import org.bigbluebutton.endpoint.redis.{ AppsRedisSubscriberActor, KeepAliveRedisPublisher, RedisPublisher, RedisRecorderActor }
import org.bigbluebutton.core.BigBlueButtonInGW
import org.bigbluebutton.core.MessageSender
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.MessageSenderActor
import org.bigbluebutton.core._
import org.bigbluebutton.core.pubsub.receivers.RedisMessageReceiver
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.JsonMessageSenderActor
import org.bigbluebutton.core.pubsub.senders.ReceivedJsonMsgHandlerActor
import org.bigbluebutton.core2.FromAkkaAppsMsgSenderActor
@ -19,11 +15,13 @@ object Boot extends App with SystemConfiguration {
implicit val executor = system.dispatcher
val logger = Logging(system, getClass)
val eventBus = new IncomingEventBus
val eventBus = new InMsgBusGW(new IncomingEventBusImp())
val outgoingEventBus = new OutgoingEventBus
val outBus2 = new OutEventBus2
val recordingEventBus = new RecordingEventBus
val outGW = new OutMessageGateway(outgoingEventBus, outBus2, recordingEventBus)
val outGW = new OutMessageGatewayImp(outgoingEventBus, outBus2, recordingEventBus)
val redisPublisher = new RedisPublisher(system)
val msgSender = new MessageSender(redisPublisher)
@ -31,12 +29,10 @@ object Boot extends App with SystemConfiguration {
val redisRecorderActor = system.actorOf(RedisRecorderActor.props(system), "redisRecorderActor")
val messageSenderActor = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor")
val newMessageSenderActor = system.actorOf(JsonMessageSenderActor.props(msgSender), "newMessageSenderActor")
outgoingEventBus.subscribe(messageSenderActor, outMessageChannel)
outgoingEventBus.subscribe(redisRecorderActor, outMessageChannel)
outgoingEventBus.subscribe(newMessageSenderActor, outMessageChannel)
val incomingJsonMessageBus = new IncomingJsonMessageBus
val bbbMsgBus = new BbbMsgRouterEventBus

View File

@ -19,16 +19,20 @@ import org.bigbluebutton.core2.RunningMeetings
import org.bigbluebutton.core2.message.senders.MsgBuilder
object BigBlueButtonActor extends SystemConfiguration {
def props(system: ActorSystem,
eventBus: IncomingEventBus,
def props(
system: ActorSystem,
eventBus: IncomingEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway): Props =
outGW: OutMessageGateway
): Props =
Props(classOf[BigBlueButtonActor], system, eventBus, bbbMsgBus, outGW)
}
class BigBlueButtonActor(val system: ActorSystem,
class BigBlueButtonActor(
val system: ActorSystem,
val eventBus: IncomingEventBus, val bbbMsgBus: BbbMsgRouterEventBus,
val outGW: OutMessageGateway) extends Actor
val outGW: OutMessageGateway
) extends Actor
with ActorLogging with SystemConfiguration {
implicit def executionContext = system.dispatcher
@ -58,25 +62,18 @@ class BigBlueButtonActor(val system: ActorSystem,
// 2x messages
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
// 1x messages
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg)
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
case msg: VoiceConfRecordingStartedMessage => handleVoiceConfRecordingStartedMessage(msg)
case _ => // do nothing
case msg: ValidateAuthToken => handleValidateAuthToken(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: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: PubSubPingSysReqMsg => handlePubSubPingSysReqMsg(m)
case m: DestroyMeetingSysCmdMsg => handleDestroyMeeting(m)
case _ => log.warning("Cannot handle " + msg.envelope.name)
case _ => log.warning("Cannot handle " + msg.envelope.name)
}
}
@ -94,7 +91,7 @@ class BigBlueButtonActor(val system: ActorSystem,
log.debug("****** RECEIVED CreateMeetingReqMsg msg {}", msg)
RunningMeetings.findWithId(meetings, msg.body.props.meetingProp.intId) match {
case None => {
case None =>
log.info("Create meeting request. meetingId={}", msg.body.props.meetingProp.intId)
val m = RunningMeeting(msg.body.props, outGW, eventBus)
@ -110,16 +107,14 @@ class BigBlueButtonActor(val system: ActorSystem,
RunningMeetings.add(meetings, m)
m.actorRef ! new InitializeMeeting(m.props.meetingProp.intId, m.props.recordProp.record)
// Send new 2x message
val msgEvent = MsgBuilder.buildMeetingCreatedEvtMsg(m.props.meetingProp.intId, msg.body.props)
outGW.send(msgEvent)
}
case Some(m) => {
case Some(m) =>
log.info("Meeting already created. meetingID={}", msg.body.props.meetingProp.intId)
// do nothing
}
// do nothing
}
}
@ -130,45 +125,6 @@ class BigBlueButtonActor(val system: ActorSystem,
})
}
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
RunningMeetings.findMeetingWithVoiceConfId(meetings, voiceConfId)
}
private def handleUserJoinedVoiceConfMessage(msg: UserJoinedVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m => m.actorRef ! msg }
}
private def handleUserLeftVoiceConfMessage(msg: UserLeftVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleUserLockedInVoiceConfMessage(msg: UserLockedInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleUserMutedInVoiceConfMessage(msg: UserMutedInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleVoiceConfRecordingStartedMessage(msg: VoiceConfRecordingStartedMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleUserTalkingInVoiceConfMessage(msg: UserTalkingInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleValidateAuthToken(msg: ValidateAuthToken) {
for {
m <- RunningMeetings.findWithId(meetings, msg.meetingID)

View File

@ -4,24 +4,22 @@ import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._
import scala.collection.JavaConversions._
import org.bigbluebutton.core.apps.{ Presentation }
import akka.actor.ActorSystem
import org.bigbluebutton.common.messages.IBigBlueButtonMessage
import org.bigbluebutton.common.messages.StartCustomPollRequestMessage
import org.bigbluebutton.common.messages.PubSubPingMessage
import org.bigbluebutton.messages._
import akka.event.Logging
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.models.{ GuestPolicyType, Roles }
import scala.collection.JavaConverters
class BigBlueButtonInGW(
val system: ActorSystem,
eventBus: IncomingEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway) extends IBigBlueButtonInGW with SystemConfiguration {
eventBus: IncomingEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway
) extends IBigBlueButtonInGW with SystemConfiguration {
val log = Logging(system, getClass)
val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, bbbMsgBus, outGW), "bigbluebutton-actor")
@ -32,24 +30,19 @@ class BigBlueButtonInGW(
def handleBigBlueButtonMessage(message: IBigBlueButtonMessage) {
message match {
case msg: StartCustomPollRequestMessage => {
eventBus.publish(
BigBlueButtonEvent(msg.payload.meetingId,
new StartCustomPollRequest(msg.payload.meetingId, msg.payload.requesterId,
msg.payload.pollId, msg.payload.pollType, msg.payload.answers)))
}
case msg: PubSubPingMessage => {
eventBus.publish(
BigBlueButtonEvent("meeting-manager", new PubSubPing(msg.payload.system, msg.payload.timestamp)))
BigBlueButtonEvent("meeting-manager", new PubSubPing(msg.payload.system, msg.payload.timestamp))
)
}
case msg: CreateMeetingRequest => {
val policy = msg.payload.guestPolicy.toUpperCase() match {
case "ALWAYS_ACCEPT" => GuestPolicyType.ALWAYS_ACCEPT
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
case "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
//default
case undef => GuestPolicyType.ASK_MODERATOR
case undef => GuestPolicyType.ASK_MODERATOR
}
/*
val mProps = new MeetingProperties(
@ -81,31 +74,15 @@ class BigBlueButtonInGW(
}
}
def handleJsonMessage(json: String) {
JsonMessageDecoder.decode(json) match {
case Some(validMsg) => forwardMessage(validMsg)
case None => log.error("Unhandled json message: {}", json)
}
}
def forwardMessage(msg: InMessage) = {
msg match {
case m: BreakoutRoomsListMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: CreateBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: RequestBreakoutJoinURLInMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: TransferUserToMeetingRequest => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: EndAllBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case _ => log.error("Unhandled message: {}", msg)
}
}
def destroyMeeting(meetingID: String) {
forwardMessage(new EndAllBreakoutRooms(meetingID))
eventBus.publish(
BigBlueButtonEvent(
"meeting-manager",
new DestroyMeeting(
meetingID)))
meetingID
)
)
)
}
def getAllMeetings(meetingID: String) {
@ -117,7 +94,7 @@ class BigBlueButtonInGW(
}
def lockSettings(meetingID: String, locked: java.lang.Boolean,
lockSettings: java.util.Map[String, java.lang.Boolean]) {
lockSettings: java.util.Map[String, java.lang.Boolean]) {
}
def statusMeetingAudit(meetingID: String) {
@ -146,7 +123,7 @@ class BigBlueButtonInGW(
}
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String,
authToken: String, avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean): Unit = {
authToken: String, avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean): Unit = {
val userRole = if (role == "MODERATOR") Roles.MODERATOR_ROLE else Roles.VIEWER_ROLE
eventBus.publish(BigBlueButtonEvent(meetingID, new RegisterUser(meetingID, userID, name, userRole,
extUserID, authToken, avatarURL, guest, authed)))
@ -166,13 +143,15 @@ class BigBlueButtonInGW(
val lockOnJoin = s.getOrElse("lockOnJoin", false)
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
val permissions = new Permissions(disableCam = disableCam,
val permissions = new Permissions(
disableCam = disableCam,
disableMic = disableMic,
disablePrivChat = disablePrivChat,
disablePubChat = disablePubChat,
lockedLayout = lockedLayout,
lockOnJoin = lockOnJoin,
lockOnJoinConfigurable = lockOnJoinConfigurable)
lockOnJoinConfigurable = lockOnJoinConfigurable
)
eventBus.publish(BigBlueButtonEvent(meetingID, new SetLockSettings(meetingID, userId, permissions)))
}
@ -190,29 +169,23 @@ class BigBlueButtonInGW(
val lockedLayout = s.getOrElse("lockedLayout", false)
val lockOnJoin = s.getOrElse("lockOnJoin", false)
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
val permissions = new Permissions(disableCam = disableCam,
val permissions = new Permissions(
disableCam = disableCam,
disableMic = disableMic,
disablePrivChat = disablePrivChat,
disablePubChat = disablePubChat,
lockedLayout = lockedLayout,
lockOnJoin = lockOnJoin,
lockOnJoinConfigurable = lockOnJoinConfigurable)
lockOnJoinConfigurable = lockOnJoinConfigurable
)
eventBus.publish(BigBlueButtonEvent(meetingID, new InitLockSettings(meetingID, permissions)))
}
def initAudioSettings(meetingID: String, requesterID: String, muted: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new InitAudioSettings(meetingID, requesterID, muted.booleanValue())))
}
def getLockSettings(meetingId: String, userId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new GetLockSettings(meetingId, userId)))
}
def lockUser(meetingId: String, requesterID: String, lock: Boolean, userId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new LockUserRequest(meetingId, requesterID, userId, lock)))
}
def setRecordingStatus(meetingId: String, userId: String, recording: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingId, new SetRecordingStatus(meetingId, userId, recording.booleanValue())))
}
@ -263,8 +236,10 @@ class BigBlueButtonInGW(
}
def checkIfAllowedToShareDesktop(meetingID: String, userID: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(meetingID: String,
userID: String)))
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(
meetingID: String,
userID: String
)))
}
def assignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String): Unit = {
@ -275,18 +250,6 @@ class BigBlueButtonInGW(
// do nothing
}
def userConnectedToGlobalAudio(voiceConf: String, userid: String, name: String) {
// we are required to pass the meeting_id as first parameter (just to satisfy trait)
// but it's not used anywhere. That's why we pass voiceConf twice instead
eventBus.publish(BigBlueButtonEvent(voiceConf, new UserConnectedToGlobalAudio(voiceConf, voiceConf, userid, name)))
}
def userDisconnectedFromGlobalAudio(voiceConf: String, userid: String, name: String) {
// we are required to pass the meeting_id as first parameter (just to satisfy trait)
// but it's not used anywhere. That's why we pass voiceConf twice instead
eventBus.publish(BigBlueButtonEvent(voiceConf, new UserDisconnectedFromGlobalAudio(voiceConf, voiceConf, userid, name)))
}
/**
* ***********************************************************************
* Message Interface for Guest
@ -300,10 +263,10 @@ class BigBlueButtonInGW(
def setGuestPolicy(meetingId: String, guestPolicy: String, requesterId: String) {
val policy = guestPolicy.toUpperCase() match {
case "ALWAYS_ACCEPT" => GuestPolicyType.ALWAYS_ACCEPT
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
case "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
//default
case undef => GuestPolicyType.ASK_MODERATOR
case undef => GuestPolicyType.ASK_MODERATOR
}
eventBus.publish(BigBlueButtonEvent(meetingId, new SetGuestPolicy(meetingId, policy, requesterId)))
}
@ -312,161 +275,6 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent(meetingId, new RespondToGuest(meetingId, userId, response, requesterId)))
}
/**
* ************************************************************************************
* Message Interface for Presentation
* ************************************************************************************
*/
def clear(meetingID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ClearPresentation(meetingID)))
}
def sendConversionUpdate(messageKey: String, meetingId: String, code: String, presentationId: String, presName: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationConversionUpdate(meetingId, messageKey, code, presentationId, presName)))
}
def sendPageCountError(messageKey: String, meetingId: String, code: String, presentationId: String, numberOfPages: Int, maxNumberPages: Int, presName: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationPageCountError(meetingId, messageKey, code, presentationId, numberOfPages, maxNumberPages, presName)))
}
def sendSlideGenerated(messageKey: String, meetingId: String, code: String, presentationId: String, numberOfPages: Int, pagesCompleted: Int, presName: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationSlideGenerated(meetingId, messageKey, code, presentationId, numberOfPages, pagesCompleted, presName)))
}
def generatePresentationPages(presId: String, numPages: Int, presBaseUrl: String): scala.collection.immutable.Map[String, PageVO] = {
var pages = new scala.collection.mutable.HashMap[String, PageVO]
for (i <- 1 to numPages) {
val id = presId + "/" + i
val num = i;
val current = if (i == 1) true else false
val thumbnail = presBaseUrl + "/thumbnail/" + i
val swfUri = presBaseUrl + "/slide/" + i
val txtUri = presBaseUrl + "/textfiles/" + i
val svgUri = presBaseUrl + "/svg/" + i
val p = new PageVO(id = id, num = num, thumbUri = thumbnail, swfUri = swfUri,
txtUri = txtUri, svgUri = svgUri,
current = current)
pages += p.id -> p
}
pages.toMap
}
def sendConversionCompleted(messageKey: String, meetingId: String, code: String, presentationId: String, numPages: Int, presName: String, presBaseUrl: String, downloadable: Boolean) {
val pages = generatePresentationPages(presentationId, numPages, presBaseUrl)
val presentation = new Presentation(id = presentationId, name = presName, current = true, pages = pages, downloadable = downloadable)
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationConversionCompleted(meetingId, messageKey, code, presentation)))
}
def removePresentation(meetingID: String, presentationID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new RemovePresentation(meetingID, presentationID)))
}
def getPresentationInfo(meetingID: String, requesterID: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetPresentationInfo(meetingID, requesterID, replyTo)))
}
def resizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ResizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio)))
}
def gotoSlide(meetingID: String, pageId: String) {
// println("**** Forwarding GotoSlide for meeting[" + meetingID + "] ****")
eventBus.publish(BigBlueButtonEvent(meetingID, new GotoSlide(meetingID, pageId)))
}
def sharePresentation(meetingID: String, presentationID: String, share: Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new SharePresentation(meetingID, presentationID, share)))
}
def getSlideInfo(meetingID: String, requesterID: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetSlideInfo(meetingID, requesterID, replyTo)))
}
/**
* ***********************************************************************
* Message Interface for Layout
* *******************************************************************
*/
def getCurrentLayout(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetCurrentLayoutRequest(meetingID, requesterID)))
}
def broadcastLayout(meetingID: String, requesterID: String, layout: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new BroadcastLayoutRequest(meetingID, requesterID, layout)))
}
def lockLayout(meetingId: String, setById: String, lock: Boolean, viewersOnly: Boolean, layout: String) {
if (layout != null) {
eventBus.publish(BigBlueButtonEvent(meetingId, new LockLayoutRequest(meetingId, setById, lock, viewersOnly, Some(layout))))
} else {
eventBus.publish(BigBlueButtonEvent(meetingId, new LockLayoutRequest(meetingId, setById, lock, viewersOnly, None)))
}
}
/**
* *******************************************************************
* Message Interface for Voice
* *****************************************************************
*/
def muteAllExceptPresenter(meetingID: String, requesterID: String, mute: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new MuteAllExceptPresenterRequest(meetingID, requesterID, mute)))
}
def muteAllUsers(meetingID: String, requesterID: String, mute: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new MuteMeetingRequest(meetingID, requesterID, mute)))
}
def isMeetingMuted(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new IsMeetingMutedRequest(meetingID, requesterID)))
}
def muteUser(meetingID: String, requesterID: String, userID: String, mute: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new MuteUserRequest(meetingID, requesterID, userID, mute)))
}
def lockMuteUser(meetingID: String, requesterID: String, userID: String, lock: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new LockUserRequest(meetingID, requesterID, userID, lock)))
}
def ejectUserFromVoice(meetingId: String, userId: String, ejectedBy: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new EjectUserFromVoiceRequest(meetingId, userId, ejectedBy)))
}
def voiceUserJoined(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
callerIdNum: String, muted: java.lang.Boolean, avatarURL: String, talking: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, userId, callerIdName,
callerIdNum, muted, talking, avatarURL, false /*hardcode listenOnly to false as the message for listenOnly is ConnectedToGlobalAudio*/ )))
}
def voiceUserLeft(voiceConfId: String, voiceUserId: String) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserLeftVoiceConfMessage(voiceConfId, voiceUserId)))
}
def voiceUserLocked(voiceConfId: String, voiceUserId: String, locked: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserLockedInVoiceConfMessage(voiceConfId, voiceUserId, locked)))
}
def voiceUserMuted(voiceConfId: String, voiceUserId: String, muted: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserMutedInVoiceConfMessage(voiceConfId, voiceUserId, muted)))
}
def voiceUserTalking(voiceConfId: String, voiceUserId: String, talking: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserTalkingInVoiceConfMessage(voiceConfId, voiceUserId, talking)))
}
def voiceRecording(voiceConfId: String, recordingFile: String, timestamp: String, recording: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new VoiceConfRecordingStartedMessage(voiceConfId, recordingFile, recording, timestamp)))
}
/**
* *******************************************************************
* Message Interface for DeskShare
@ -494,25 +302,4 @@ class BigBlueButtonInGW(
def deskShareGetInfoRequest(meetingId: String, requesterId: String, replyTo: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingId, new DeskShareGetDeskShareInfoRequest(meetingId, requesterId, replyTo)))
}
// Polling
def votePoll(meetingId: String, userId: String, pollId: String, questionId: Integer, answerId: Integer) {
eventBus.publish(BigBlueButtonEvent(meetingId, new RespondToPollRequest(meetingId, userId, pollId, questionId, answerId)))
}
def startPoll(meetingId: String, requesterId: String, pollId: String, pollType: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new StartPollRequest(meetingId, requesterId, pollId, pollType)))
}
def stopPoll(meetingId: String, userId: String, pollId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new StopPollRequest(meetingId, userId)))
}
def showPollResult(meetingId: String, requesterId: String, pollId: String, show: java.lang.Boolean) {
if (show) {
eventBus.publish(BigBlueButtonEvent(meetingId, new ShowPollResultRequest(meetingId, requesterId, pollId)))
} else {
eventBus.publish(BigBlueButtonEvent(meetingId, new HidePollResultRequest(meetingId, requesterId, pollId)))
}
}
}

View File

@ -1,77 +0,0 @@
package org.bigbluebutton.core
import scala.util.{ Try, Success, Failure }
import org.parboiled.errors.ParsingException
import org.bigbluebutton.core.api._
import org.bigbluebutton.messages._
object JsonMessageDecoder {
import org.bigbluebutton.core.UserMessagesProtocol._
import spray.json._
def header(msg: JsObject): InMessageHeader = {
msg.fields.get("header") match {
case Some(header) =>
header.convertTo[InMessageHeader]
case None =>
throw MessageProcessException("Cannot get payload information: [" + msg + "]")
}
}
def payload(msg: JsObject): JsObject = {
msg.fields.get("payload") match {
case Some(payload) =>
payload.asJsObject
case None =>
throw MessageProcessException("Cannot get payload information: [" + msg + "]")
}
}
def toJsObject(msg: String): JsObject = {
try {
JsonParser(msg).asJsObject
} catch {
case e: ParsingException => {
throw MessageProcessException("Cannot parse JSON message: [" + msg + "]")
}
}
}
def unmarshall(jsonMsg: String): Try[InMessage] = {
for {
jsonObj <- Try(toJsObject(jsonMsg))
header <- Try(header(jsonObj))
payload <- Try(payload(jsonObj))
msg = InHeaderAndJsonPayload(header, payload)
inmsg <- Try(convertMessage(msg))
} yield inmsg
}
def decode(json: String): Option[InMessage] = {
unmarshall(json) match {
case Success(validMsg) => Some(validMsg)
case Failure(ex) => None
}
}
def convertMessage(msg: InHeaderAndJsonPayload): InMessage = {
msg.header.name match {
case GetBreakoutRoomsList.NAME => {
msg.payload.convertTo[BreakoutRoomsListMessage]
}
case CreateBreakoutRoomsRequest.NAME => {
msg.payload.convertTo[CreateBreakoutRooms]
}
case RequestBreakoutJoinURL.NAME => {
msg.payload.convertTo[RequestBreakoutJoinURLInMessage]
}
case ListenInOnBreakout.NAME => {
msg.payload.convertTo[TransferUserToMeetingRequest]
}
case EndAllBreakoutRoomsRequest.NAME => {
msg.payload.convertTo[EndAllBreakoutRooms]
}
case _ => throw MessageProcessException("Cannot parse JSON message: [" + msg + "]")
}
}
}

View File

@ -1,95 +0,0 @@
package org.bigbluebutton.core
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import org.bigbluebutton.core.api._
import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.messages.payload._
import org.bigbluebutton.messages._
object JsonMessageSenderActor {
def props(msgSender: MessageSender): Props =
Props(classOf[JsonMessageSenderActor], msgSender)
}
class JsonMessageSenderActor(val service: MessageSender)
extends Actor with ActorLogging {
def receive = {
// Breakout
case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg)
case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg)
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg)
case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURL(msg)
case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStarted(msg)
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg)
case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsers(msg)
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
case _ => // do nothing
}
// Breakout
private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) {
val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.externalMeetingId, msg.breakout.name, msg.breakout.sequence)
val request = new BreakoutRoomStarted(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
private def handleBreakoutRoomEnded(msg: BreakoutRoomEndedOutMessage) {
val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "", "", 0)
val request = new BreakoutRoomClosed(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
private def handleUpdateBreakoutUsers(msg: UpdateBreakoutUsersOutMessage) {
val users = new java.util.ArrayList[BreakoutUserPayload]()
msg.users.foreach(x => users.add(new BreakoutUserPayload(x.id, x.name)))
val payload = new UpdateBreakoutUsersPayload(msg.parentMeetingId, msg.breakoutMeetingId, users)
val request = new UpdateBreakoutUsers(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleMeetingTimeRemainingUpdate(msg: MeetingTimeRemainingUpdate) {
val payload = new MeetingTimeRemainingPayload(msg.meetingId, msg.timeRemaining)
val request = new TimeRemainingUpdate(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleMeetingTimeRemainingUpdate(msg: BreakoutRoomsTimeRemainingUpdateOutMessage) {
val payload = new BreakoutRoomsTimeRemainingPayload(msg.meetingId, msg.timeRemaining)
val request = new BreakoutRoomsTimeRemainingUpdate(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleBreakoutRoomsList(msg: BreakoutRoomsListOutMessage) {
val rooms = new java.util.ArrayList[BreakoutRoomPayload]()
msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.meetingId, r.externalMeetingId, r.name, r.sequence)))
val payload = new BreakoutRoomsListPayload(msg.meetingId, rooms, msg.roomsReady)
val request = new BreakoutRoomsList(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleCreateBreakoutRoom(msg: CreateBreakoutRoom) {
val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutMeetingId, msg.room.parentId, msg.room.name,
msg.room.sequence, msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword,
msg.room.durationInMinutes, msg.room.sourcePresentationId, msg.room.sourcePresentationSlide, msg.room.record)
val request = new CreateBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleEndBreakoutRoom(msg: EndBreakoutRoom) {
val payload = new EndBreakoutRoomRequestPayload(msg.breakoutMeetingId)
val request = new EndBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
def handleBreakoutRoomJoinURL(msg: BreakoutRoomJoinURLOutMessage) {
val payload = new BreakoutRoomJoinURLPayload(msg.parentMeetingId,
msg.breakoutMeetingId, msg.userId, msg.redirectJoinURL, msg.noRedirectJoinURL)
val request = new BreakoutRoomJoinURL(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
}

View File

@ -5,8 +5,8 @@ import org.bigbluebutton.core.api.Permissions
case object StopMeetingActor
case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20,
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
class MeetingModel {
private var audioSettingsInited = false

View File

@ -8,28 +8,13 @@ import akka.actor.SupervisorStrategy.Resume
import java.io.{ PrintWriter, StringWriter }
import org.bigbluebutton.core.api._
import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.common.messages.StartRecordingVoiceConfRequestMessage
import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage
import org.bigbluebutton.core.pubsub.senders.MeetingMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.PesentationMessageToJsonConverter
import org.bigbluebutton.common.messages.GetPresentationInfoReplyMessage
import org.bigbluebutton.common.messages.PresentationRemovedMessage
import org.bigbluebutton.common.messages.AllowUserToShareDesktopReply
import org.bigbluebutton.core.apps.Page
import scala.collection.JavaConversions._
import scala.concurrent.duration._
import org.bigbluebutton.core.apps.SimplePollResultOutVO
import org.bigbluebutton.core.apps.SimplePollOutVO
import org.bigbluebutton.core.pubsub.senders.UsersMessageToJsonConverter
import org.bigbluebutton.common.messages.GetUsersFromVoiceConfRequestMessage
import org.bigbluebutton.common.messages.MuteUserInVoiceConfRequestMessage
import org.bigbluebutton.common.messages.EjectUserFromVoiceConfRequestMessage
import org.bigbluebutton.common.messages.GetCurrentLayoutReplyMessage
import org.bigbluebutton.common.messages.BroadcastLayoutMessage
import org.bigbluebutton.common.messages.UserEjectedFromMeetingMessage
import org.bigbluebutton.common.messages.LockLayoutMessage
import org.bigbluebutton.common.converters.ToJsonEncoder
import org.bigbluebutton.common.messages.TransferUserToVoiceConfRequestMessage
import scala.collection.JavaConverters
object MessageSenderActor {
@ -52,89 +37,46 @@ class MessageSenderActor(val service: MessageSender)
val encoder = new ToJsonEncoder()
def receive = {
case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg)
case msg: MeetingCreated => handleMeetingCreated(msg)
case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(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: StartRecording => handleStartRecording(msg)
case msg: StopRecording => handleStopRecording(msg)
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
case msg: StartRecordingVoiceConf => handleStartRecordingVoiceConf(msg)
case msg: StopRecordingVoiceConf => handleStopRecordingVoiceConf(msg)
case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
case msg: GetPresentationInfoOutMsg => handleGetPresentationInfoOutMsg(msg)
case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
case msg: GetSlideInfoOutMsg => handleGetSlideInfoOutMsg(msg)
case msg: PresentationConversionProgress => handlePresentationConversionProgress(msg)
case msg: PresentationConversionError => handlePresentationConversionError(msg)
case msg: PresentationPageGenerated => handlePresentationPageGenerated(msg)
case msg: PresentationConversionDone => handlePresentationConversionDone(msg)
case msg: PollStartedMessage => handlePollStartedMessage(msg)
case msg: PollStoppedMessage => handlePollStoppedMessage(msg)
case msg: PollShowResultMessage => handlePollShowResultMessage(msg)
case msg: PollHideResultMessage => handlePollHideResultMessage(msg)
case msg: UserRespondedToPollMessage => handleUserRespondedToPollMessage(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: 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: UserVoiceMuted => handleUserVoiceMuted(msg)
case msg: UserVoiceTalking => handleUserVoiceTalking(msg)
case msg: MuteVoiceUser => handleMuteVoiceUser(msg)
case msg: EjectVoiceUser => handleEjectVoiceUser(msg)
case msg: TransferUserToMeeting => handleTransferUserToMeeting(msg)
case msg: GetUsersInVoiceConference => handleGetUsersFromVoiceConference(msg)
case msg: UserJoinedVoice => handleUserJoinedVoice(msg)
case msg: UserLeftVoice => handleUserLeftVoice(msg)
case msg: IsMeetingMutedReply => handleIsMeetingMutedReply(msg)
case msg: UserListeningOnly => handleUserListeningOnly(msg)
case msg: GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
case msg: BroadcastLayoutEvent => handleBroadcastLayoutEvent(msg)
case msg: LockLayoutEvent => handleLockLayoutEvent(msg)
// breakout room cases
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsListOutMessage(msg)
case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStartedOutMessage(msg)
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEndedOutMessage(msg)
case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURLOutMessage(msg)
case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsersOutMessage(msg)
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
case msg: BreakoutRoomsTimeRemainingUpdateOutMessage => handleBreakoutRoomsTimeRemainingUpdate(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
case msg: GetGuestPolicyReply => handleGetGuestPolicyReply(msg)
case msg: GuestPolicyChanged => handleGuestPolicyChanged(msg)
case msg: GuestAccessDenied => handleGuestAccessDenied(msg)
case _ => // do nothing
}
private def handleUserEjectedFromMeeting(msg: UserEjectedFromMeeting) {
@ -142,16 +84,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_USERS_CHANNEL, m.toJson)
}
private def handleStartRecordingVoiceConf(msg: StartRecordingVoiceConf) {
val m = new StartRecordingVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleStopRecordingVoiceConf(msg: StopRecordingVoiceConf) {
val m = new StopRecordingVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId, msg.recordedStream)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleMeetingDestroyed(msg: MeetingDestroyed) {
val json = MeetingMessageToJsonConverter.meetingDestroyedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
@ -185,26 +117,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleStartRecording(msg: StartRecording) {
val json = MeetingMessageToJsonConverter.startRecordingToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleStopRecording(msg: StopRecording) {
val json = MeetingMessageToJsonConverter.stopRecordingToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleVoiceRecordingStarted(msg: VoiceRecordingStarted) {
val json = MeetingMessageToJsonConverter.voiceRecordingStartedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleVoiceRecordingStopped(msg: VoiceRecordingStopped) {
val json = MeetingMessageToJsonConverter.voiceRecordingStoppedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleRecordingStatusChanged(msg: RecordingStatusChanged) {
val json = MeetingMessageToJsonConverter.recordingStatusChangedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
@ -244,200 +156,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleClearPresentationOutMsg(msg: ClearPresentationOutMsg) {
val json = PesentationMessageToJsonConverter.clearPresentationOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleRemovePresentationOutMsg(msg: RemovePresentationOutMsg) {
val m = new PresentationRemovedMessage(msg.meetingID, msg.presentationID)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, m.toJson())
}
private def handleGetPresentationInfoOutMsg(msg: GetPresentationInfoOutMsg) {
}
private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) {
val json = PesentationMessageToJsonConverter.resizeAndMoveSlideOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGotoSlideOutMsg(msg: GotoSlideOutMsg) {
val json = PesentationMessageToJsonConverter.gotoSlideOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleSharePresentationOutMsg(msg: SharePresentationOutMsg) {
val json = PesentationMessageToJsonConverter.sharePresentationOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGetSlideInfoOutMsg(msg: GetSlideInfoOutMsg) {
val json = PesentationMessageToJsonConverter.getSlideInfoOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGetPreuploadedPresentationsOutMsg(msg: GetPreuploadedPresentationsOutMsg) {
val json = PesentationMessageToJsonConverter.getPreuploadedPresentationsOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationConversionProgress(msg: PresentationConversionProgress) {
val json = PesentationMessageToJsonConverter.presentationConversionProgressToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationConversionError(msg: PresentationConversionError) {
val json = PesentationMessageToJsonConverter.presentationConversionErrorToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationPageGenerated(msg: PresentationPageGenerated) {
val json = PesentationMessageToJsonConverter.presentationPageGenerated(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationConversionDone(msg: PresentationConversionDone) {
val json = PesentationMessageToJsonConverter.presentationConversionDoneToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationChanged(msg: PresentationChanged) {
val json = PesentationMessageToJsonConverter.presentationChangedToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGetPresentationStatusReply(msg: GetPresentationStatusReply) {
val json = PesentationMessageToJsonConverter.getPresentationStatusReplyToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationRemoved(msg: PresentationRemoved) {
val json = PesentationMessageToJsonConverter.presentationRemovedToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePageChanged(msg: PageChanged) {
val json = PesentationMessageToJsonConverter.pageChangedToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePollStartedMessage(msg: PollStartedMessage) {
val json = pollStartedMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollStoppedMessage(msg: PollStoppedMessage) {
val json = pollStoppedMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollShowResultMessage(msg: PollShowResultMessage) {
val json = pollShowResultMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollHideResultMessage(msg: PollHideResultMessage) {
val json = pollHideResultMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handleUserRespondedToPollMessage(msg: UserRespondedToPollMessage) {
val json = UserRespondedToPollMessageTpJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def pollVOtoMap(msg: SimplePollOutVO): java.util.HashMap[String, Object] = {
val pollVO = new java.util.HashMap[String, Object]()
pollVO.put("id", msg.id)
val answers = new java.util.ArrayList[java.util.Map[String, Any]];
msg.answers.foreach(ans => {
val amap = new java.util.HashMap[String, Any]()
amap.put("id", ans.id)
amap.put("key", ans.key)
answers.add(amap)
})
pollVO.put("answers", answers)
pollVO
}
private def pollStartedMessageToJson(msg: PollStartedMessage): String = {
val pollVO = pollVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.PollStartedMessage(msg.meetingID, msg.requesterId, pollVO)
psm.toJson
}
private def pollStoppedMessageToJson(msg: PollStoppedMessage): String = {
val psm = new org.bigbluebutton.common.messages.PollStoppedMessage(msg.meetingID, msg.requesterId, msg.pollId)
psm.toJson
}
private def pollResultVOtoMap(msg: SimplePollResultOutVO): java.util.HashMap[String, Object] = {
val pollVO = new java.util.HashMap[String, Object]()
pollVO.put("id", msg.id)
pollVO.put("num_respondents", msg.numRespondents: java.lang.Integer)
pollVO.put("num_responders", msg.numResponders: java.lang.Integer)
val answers = new java.util.ArrayList[java.util.Map[String, Any]];
msg.answers.foreach(ans => {
val amap = new java.util.HashMap[String, Any]()
amap.put("id", ans.id)
amap.put("key", ans.key)
amap.put("num_votes", ans.numVotes)
answers.add(amap)
})
pollVO.put("answers", answers)
pollVO
}
private def pollShowResultMessageToJson(msg: PollShowResultMessage): String = {
val pollResultVO = pollResultVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.PollShowResultMessage(msg.meetingID, pollResultVO)
psm.toJson
}
private def pollHideResultMessageToJson(msg: PollHideResultMessage): String = {
val psm = new org.bigbluebutton.common.messages.PollHideResultMessage(msg.meetingID, msg.pollId)
psm.toJson
}
private def UserRespondedToPollMessageTpJson(msg: UserRespondedToPollMessage): String = {
val pollResultVO = pollResultVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.UserVotedPollMessage(msg.meetingID, msg.presenterId, pollResultVO)
psm.toJson
}
private def handleLockLayoutEvent(msg: LockLayoutEvent) {
val users = new java.util.ArrayList[String];
msg.applyTo.foreach(uvo => {
users.add(uvo.id)
})
val evt = new LockLayoutMessage(msg.meetingID, msg.setById, msg.locked, users)
service.send(MessagingConstants.FROM_USERS_CHANNEL, evt.toJson())
}
private def handleBroadcastLayoutEvent(msg: BroadcastLayoutEvent) {
val users = new java.util.ArrayList[String];
msg.applyTo.foreach(uvo => {
users.add(uvo.id)
})
val evt = new BroadcastLayoutMessage(msg.meetingID, msg.setByUserID, msg.layoutID, msg.locked, users)
service.send(MessagingConstants.FROM_USERS_CHANNEL, evt.toJson())
}
private def handleGetCurrentLayoutReply(msg: GetCurrentLayoutReply) {
val reply = new GetCurrentLayoutReplyMessage(msg.meetingID, msg.requesterID, msg.setByUserID, msg.layoutID, msg.locked)
service.send(MessagingConstants.FROM_USERS_CHANNEL, reply.toJson())
}
private def handleMeetingState(msg: MeetingState) {
val json = UsersMessageToJsonConverter.meetingState(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
@ -521,51 +239,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserJoinedVoice(msg: UserJoinedVoice) {
val json = UsersMessageToJsonConverter.userJoinedVoice(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserVoiceMuted(msg: UserVoiceMuted) {
val json = UsersMessageToJsonConverter.userVoiceMuted(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserVoiceTalking(msg: UserVoiceTalking) {
val json = UsersMessageToJsonConverter.userVoiceTalking(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleMuteVoiceUser(msg: MuteVoiceUser) {
val m = new MuteUserInVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId, msg.voiceUserId, msg.mute)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleGetUsersFromVoiceConference(msg: GetUsersInVoiceConference) {
val m = new GetUsersFromVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleEjectVoiceUser(msg: EjectVoiceUser) {
val m = new EjectUserFromVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId, msg.voiceUserId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleTransferUserToMeeting(msg: TransferUserToMeeting) {
val m = new TransferUserToVoiceConfRequestMessage(msg.voiceConfId, msg.targetVoiceConfId, msg.userId);
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleUserLeftVoice(msg: UserLeftVoice) {
val json = UsersMessageToJsonConverter.userLeftVoiceToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleIsMeetingMutedReply(msg: IsMeetingMutedReply) {
val json = UsersMessageToJsonConverter.isMeetingMutedReplyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleValidateAuthTokenReply(msg: ValidateAuthTokenReply) {
println("**** handleValidateAuthTokenReply *****")
val json = UsersMessageToJsonConverter.validateAuthTokenReplyToJson(msg)
@ -606,46 +279,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserListeningOnly(msg: UserListeningOnly) {
val json = UsersMessageToJsonConverter.userListeningOnlyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomsListOutMessage(msg: BreakoutRoomsListOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomsListOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomStartedOutMessage(msg: BreakoutRoomStartedOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomStartedOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomEndedOutMessage(msg: BreakoutRoomEndedOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomEndedOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomJoinURLOutMessage(msg: BreakoutRoomJoinURLOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomJoinURLOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUpdateBreakoutUsersOutMessage(msg: UpdateBreakoutUsersOutMessage) {
val json = MeetingMessageToJsonConverter.updateBreakoutUsersOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleMeetingTimeRemainingUpdate(msg: MeetingTimeRemainingUpdate) {
val json = MeetingMessageToJsonConverter.meetingTimeRemainingUpdateToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomsTimeRemainingUpdate(msg: BreakoutRoomsTimeRemainingUpdateOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomsTimeRemainingUpdateToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleGetGuestPolicyReply(msg: GetGuestPolicyReply) {
val json = UsersMessageToJsonConverter.getGuestPolicyReplyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)

View File

@ -1,30 +1,13 @@
package org.bigbluebutton.core
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreMsg }
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api.IOutMessage
object OutMessageGateway {
def apply(outgoingEventBus: OutgoingEventBus,
outBus2: OutEventBus2,
recordBus: RecordingEventBus) =
new OutMessageGateway(outgoingEventBus, outBus2, recordBus)
}
class OutMessageGateway(outgoingEventBus: OutgoingEventBus,
outBus2: OutEventBus2,
recordBus: RecordingEventBus) extends 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))
}
trait OutMessageGateway {
def send1(msg: IOutMessage)
def send(msg: BbbCommonEnvCoreMsg): Unit
def record(msg: BbbCoreMsg): Unit
}

View File

@ -0,0 +1,35 @@
package org.bigbluebutton.core
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreMsg }
import org.bigbluebutton.core.api.IOutMessage
import org.bigbluebutton.core.bus._
object OutMessageGatewayImp {
def apply(
outgoingEventBus: OutgoingEventBus,
outBus2: OutEventBus2,
recordBus: RecordingEventBus
) =
new OutMessageGatewayImp(outgoingEventBus, outBus2, recordBus)
}
class OutMessageGatewayImp(
outgoingEventBus: OutgoingEventBus,
outBus2: OutEventBus2,
recordBus: RecordingEventBus
) 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))
}
}

View File

@ -1,39 +0,0 @@
package org.bigbluebutton.core
import spray.json.{ DefaultJsonProtocol, JsValue, JsString, DeserializationException, JsonFormat }
import org.bigbluebutton.core.api._
object UserMessagesProtocol extends DefaultJsonProtocol {
/*
implicit object RoleJsonFormat extends JsonFormat[Role.RoleType] {
def write(obj: Role.RoleType): JsValue = JsString(obj.toString)
def read(json: JsValue): Role.RoleType = json match {
case JsString(str) => Role.withName(str)
case _ => throw new DeserializationException("Enum string expected")
}
}
*/
implicit object MessageTypeFormat extends JsonFormat[MessageType.MessageType] {
def write(obj: MessageType.MessageType): JsValue = JsString(obj.toString)
def read(json: JsValue): MessageType.MessageType = json match {
case JsString(str) => MessageType.withName(str)
case _ => throw new DeserializationException("Enum string expected")
}
}
implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload)
implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms)
implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage)
implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat3(RequestBreakoutJoinURLInMessage)
implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest)
implicit val endBreakoutRoomsFormat = jsonFormat1(EndAllBreakoutRooms)
implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader)
implicit val outMsgHeaderFormat = jsonFormat1(OutMsgHeader)
implicit val outMsgEnvelopeHeaderFormat = jsonFormat2(OutMsgEnvelopeHeader)
implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat11(CreateBreakoutRoomOutMsgPayload)
implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload)
implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope)
}

View File

@ -1,13 +0,0 @@
package org.bigbluebutton.core
case class OutMsgHeader(name: String)
case class OutMsgEnvelopeHeader(`type`: MessageType.MessageType, address: String)
trait OutMessage
case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload)
case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload)
case class CreateBreakoutRoomOutMsgPayload(meetingId: String, parentId: String, name: String,
voiceConfId: String, moderatorPassword: String, viewerPassword: String,
durationInMinutes: Int, sourcePresentationId: String, sourcePresentationSlide: Int,
record: Boolean, sequence: Int)

View File

@ -9,11 +9,6 @@ case class MessageProcessException(message: String) extends Exception(message)
trait InMessage
//////////////////////////////////////////////
//
//////////////////////////////////////////////
case class SendDirectChatMsgCmd() extends InMessage
//////////////////////////////////////////////////////////////////////////////
// System
/////////////////////////////////////////////////////////////////////////////
@ -29,37 +24,12 @@ case class KeepAliveMessage(aliveID: String) extends InMessage
case class MonitorNumberOfUsers(meetingID: String) extends InMessage
case class SendTimeRemainingUpdate(meetingId: String) extends InMessage
case class ExtendMeetingDuration(meetingId: String, userId: String) extends InMessage
case class InitializeMeeting(meetingID: String, recorded: Boolean) extends InMessage
case class DestroyMeeting(meetingID: String) extends InMessage
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
//////////////////////////////////////////////////////////////////////////////////////
// Breakout room
/////////////////////////////////////////////////////////////////////////////////////
// Sent by user to request the breakout rooms list of a room
case class BreakoutRoomsListMessage(meetingId: String) extends InMessage
// Sent by user to request creation of breakout rooms
case class CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean, rooms: Vector[BreakoutRoomInPayload]) extends InMessage
case class BreakoutRoomInPayload(name: String, sequence: Int, users: Vector[String])
// Sent by user to request for a join URL in order to be able to join a breakout room
case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutMeetingId: String, userId: String) extends InMessage
// Sent by breakout actor to tell meeting actor that breakout room has been created.
case class BreakoutRoomCreated(meetingId: String, breakoutRoomId: String) extends InMessage
// Sent by breakout actor to tell meeting actor the list of users in the breakout room.
case class BreakoutRoomUsersUpdate(meetingId: String, breakoutMeetingId: String, users: Vector[BreakoutUserVO]) extends InMessage
// Send by internal actor to tell the breakout actor to send it's list of users to the main meeting actor.
case class SendBreakoutUsersUpdate(meetingId: String) extends InMessage
// Sent by user to request ending all the breakout rooms
case class EndAllBreakoutRooms(meetingId: String) extends InMessage
// Sent by breakout actor to tell meeting actor that breakout room has been ended
case class BreakoutRoomEnded(meetingId: String, breakoutRoomId: String) extends InMessage
// Sent by user actor to ask for voice conference transfer
case class TransferUserToMeetingRequest(meetingId: String, targetMeetingId: String, userId: String) extends InMessage
////////////////////////////////////////////////////////////////////////////////////
// Lock
///////////////////////////////////////////////////////////////////////////////////
@ -74,9 +44,9 @@ case class GetLockSettings(meetingID: String, userId: String) extends InMessage
/////////////////////////////////////////////////////////////////////////////////
case class ValidateAuthToken(meetingID: String, userId: String, token: String,
correlationId: String, sessionId: String) extends InMessage
correlationId: String, sessionId: String) extends InMessage
case class RegisterUser(meetingID: String, userID: String, name: String, role: String,
extUserID: String, authToken: String, avatarURL: String, guest: Boolean, authed: Boolean) extends InMessage
extUserID: String, authToken: String, avatarURL: String, guest: Boolean, authed: Boolean) extends InMessage
case class UserJoining(meetingID: String, userID: String, authToken: String) extends InMessage
case class UserLeaving(meetingID: String, userID: String, sessionId: String) extends InMessage
case class GetUsers(meetingID: String, requesterID: String) extends InMessage
@ -93,15 +63,6 @@ case class AllowUserToShareDesktop(meetingID: String, userID: String) extends In
case class ActivityResponse(meetingID: String) extends InMessage
case class LogoutEndMeeting(meetingID: String, userID: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////
// Global Audio
/////////////////////////////////////////////////////////////////////////////////
case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage
case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////////
// Guest support
///////////////////////////////////////////////////////////////////////////////////////
@ -110,73 +71,6 @@ case class GetGuestPolicy(meetingID: String, requesterID: String) extends InMess
case class SetGuestPolicy(meetingID: String, policy: String, setBy: String) extends InMessage
case class RespondToGuest(meetingID: String, userId: String, response: Boolean, requesterID: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////////
// Layout
//////////////////////////////////////////////////////////////////////////////////////
case class GetCurrentLayoutRequest(meetingID: String, requesterID: String) extends InMessage
case class LockLayoutRequest(meetingID: String, setById: String, lock: Boolean, viewersOnly: Boolean,
layout: Option[String]) extends InMessage
case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////////
// Presentation
/////////////////////////////////////////////////////////////////////////////////////
case class ClearPresentation(meetingID: String) extends InMessage
case class RemovePresentation(meetingID: String, presentationID: String) extends InMessage
case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double,
widthRatio: Double, heightRatio: Double) extends InMessage
case class GotoSlide(meetingID: String, page: String) extends InMessage
case class SharePresentation(meetingID: String, presentationID: String, share: Boolean) extends InMessage
case class GetSlideInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class PreuploadedPresentations(meetingID: String, presentations: Seq[Presentation]) extends InMessage
case class PresentationConversionUpdate(meetingID: String, messageKey: String, code: String,
presentationId: String, presName: String) extends InMessage
case class PresentationPageCountError(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage
case class PresentationSlideGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage
case class PresentationConversionCompleted(meetingID: String, messageKey: String, code: String,
presentation: Presentation) extends InMessage
/////////////////////////////////////////////////////////////////////////////////////
// Polling
////////////////////////////////////////////////////////////////////////////////////
//case class CreatePollRequest(meetingID: String, requesterId: String, pollId: String, pollType: String) extends InMessage
case class StartCustomPollRequest(meetingID: String, requesterId: String, pollId: String, pollType: String, answers: Seq[String]) extends InMessage
case class StartPollRequest(meetingID: String, requesterId: String, pollId: String, pollType: String) extends InMessage
case class StopPollRequest(meetingID: String, requesterId: String) extends InMessage
case class ShowPollResultRequest(meetingID: String, requesterId: String, pollId: String) extends InMessage
case class HidePollResultRequest(meetingID: String, requesterId: String, pollId: String) extends InMessage
case class RespondToPollRequest(meetingID: String, requesterId: String, pollId: String, questionId: Int, answerId: Int) extends InMessage
case class GetPollRequest(meetingID: String, requesterId: String, pollId: String) extends InMessage
case class GetCurrentPollRequest(meetingID: String, requesterId: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////
// Voice
///////////////////////////////////////////////////////////////////////////////////
case class InitAudioSettings(meetingID: String, requesterID: String, muted: Boolean) extends InMessage
case class SendVoiceUsersRequest(meetingID: String, requesterID: String) extends InMessage
case class MuteAllExceptPresenterRequest(meetingID: String, requesterID: String, mute: Boolean) extends InMessage
case class MuteMeetingRequest(meetingID: String, requesterID: String, mute: Boolean) extends InMessage
case class IsMeetingMutedRequest(meetingID: String, requesterID: String) extends InMessage
case class MuteUserRequest(meetingID: String, requesterID: String, userID: String, mute: Boolean) extends InMessage
case class LockUserRequest(meetingID: String, requesterID: String, userID: String, lock: Boolean) extends InMessage
case class EjectUserFromVoiceRequest(meetingID: String, userId: String, ejectedBy: String) extends InMessage
case class VoiceUserJoinedMessage(meetingID: String, user: String, voiceConfId: String,
callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage
case class UserJoinedVoiceConfMessage(voiceConfId: String, voiceUserId: String, userId: String, externUserId: String,
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage
case class UserLeftVoiceConfMessage(voiceConfId: String, voiceUserId: String) extends InMessage
case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage
case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage
case class UserTalkingInVoiceConfMessage(voiceConfId: String, voiceUserId: String, talking: Boolean) extends InMessage
case class VoiceConfRecordingStartedMessage(voiceConfId: String, recordStream: String, recording: Boolean, timestamp: 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

@ -5,12 +5,10 @@ import org.bigbluebutton.core.models._
import org.bigbluebutton.common2.domain.UserVO
import org.bigbluebutton.common2.msgs.{ BreakoutRoomInfo, BreakoutUserVO }
case class VoiceRecordingStarted(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnding(meetingID: String) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
@ -25,20 +23,6 @@ case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
case object IsAliveMessage extends IOutMessage
// Breakout Rooms
case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean) extends IOutMessage
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, redirectJoinURL: String, noRedirectJoinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomInfo) extends IOutMessage
case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUserVO]) extends IOutMessage
case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) 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
@ -57,75 +41,13 @@ case class ValidateAuthTokenTimedOut(meetingID: String, requesterId: String, tok
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 UserListeningOnly(meetingID: String, recorded: Boolean, userID: String, listenOnly: Boolean) 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 GetUsersInVoiceConference(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class MuteVoiceUser(meetingID: String, recorded: Boolean, requesterID: String,
userId: String, voiceConfId: String, voiceUserId: String, mute: Boolean) extends IOutMessage
case class UserVoiceMuted(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserVoiceTalking(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class EjectVoiceUser(meetingID: String, recorded: Boolean, requesterID: String, userId: String, voiceConfId: String, voiceUserId: String) extends IOutMessage
case class TransferUserToMeeting(voiceConfId: String, targetVoiceConfId: String, userId: String) extends IOutMessage
case class UserJoinedVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserLeftVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class AllowUserToShareDesktopOut(meetingID: String, userID: String, allowed: Boolean) extends IOutMessage
// Voice
case class IsMeetingMutedReply(meetingID: String, recorded: Boolean, requesterID: String, meetingMuted: Boolean) extends IOutMessage
case class StartRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
case class StartRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class StopRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String, recordedStream: String) extends IOutMessage
case class StopRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
// Layout
case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String,
locked: Boolean, setByUserID: String) extends IOutMessage
case class BroadcastLayoutEvent(meetingID: String, recorded: Boolean, requesterID: String,
layoutID: String, locked: Boolean, setByUserID: String, applyTo: Array[UserVO]) extends IOutMessage
case class LockLayoutEvent(meetingID: String, recorded: Boolean, setById: String, locked: Boolean,
applyTo: Array[UserVO]) extends IOutMessage
// Presentation
case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage
case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String,
info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage
case class GetSlideInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, page: Page, replyTo: String) extends IOutMessage
case class GetPreuploadedPresentationsOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class PresentationConversionProgress(meetingID: String, messageKey: String, code: String,
presentationId: String, presentationName: String) extends IOutMessage
case class PresentationConversionError(meetingID: String, messageKey: String, code: String,
presentationId: String, numberOfPages: Int, maxNumberPages: Int, presentationName: String) extends IOutMessage
case class PresentationPageGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presentationName: String) extends IOutMessage
case class PresentationConversionDone(meetingID: String, recorded: Boolean, messageKey: String, code: String,
presentation: Presentation) extends IOutMessage
case class PresentationChanged(meetingID: String, presentation: Presentation) extends IOutMessage
case class GetPresentationStatusReply(meetingID: String, presentations: Seq[Presentation], current: Presentation, replyTo: String) extends IOutMessage
case class PresentationRemoved(meetingID: String, presentationId: String) extends IOutMessage
case class PageChanged(meetingID: String, page: Page) extends IOutMessage
// Polling
//case class PollCreatedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: PollVO) extends IOutMessage
//case class CreatePollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String, pollType: String) extends IOutMessage
case class PollStartedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollOutVO) extends IOutMessage
case class StartPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollStoppedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class StopPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String) extends IOutMessage
case class PollShowResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class ShowPollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollHideResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class HidePollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class UserRespondedToPollMessage(meetingID: String, recorded: Boolean, presenterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class RespondToPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requesterId: String, hasPoll: Boolean, poll: Option[PollVO]) extends IOutMessage
// No idea what part this is for
case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage

View File

@ -35,58 +35,65 @@ object ErrorCodes {
case class RequestResult(status: StatusCode, errors: Option[Array[ErrorCode]])
case class Presenter(
presenterID: String,
presenterID: String,
presenterName: String,
assignedBy: String)
assignedBy: String
)
case class User(
id: String,
externId: String,
name: String,
moderator: Boolean,
avatarUrl: String,
logoutUrl: String,
presenter: Boolean,
callerId: CallerId,
id: String,
externId: String,
name: String,
moderator: Boolean,
avatarUrl: String,
logoutUrl: String,
presenter: Boolean,
callerId: CallerId,
phoneCaller: Boolean,
emojiStatus: String,
muted: Boolean,
talking: Boolean)
muted: Boolean,
talking: Boolean
)
case class CallerId(
name: String,
number: String)
name: String,
number: String
)
case class Permissions(
disableCam: Boolean = false,
disableMic: Boolean = false,
disablePrivChat: Boolean = false,
disablePubChat: Boolean = false,
lockedLayout: Boolean = false,
lockOnJoin: Boolean = false,
lockOnJoinConfigurable: Boolean = false)
disableCam: Boolean = false,
disableMic: Boolean = false,
disablePrivChat: Boolean = false,
disablePubChat: Boolean = false,
lockedLayout: Boolean = false,
lockOnJoin: Boolean = false,
lockOnJoinConfigurable: Boolean = false
)
case class Voice(
id: String,
webId: String,
callId: CallerId,
id: String,
webId: String,
callId: CallerId,
phoningIn: Boolean,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean)
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean
)
case class MeetingConfig(name: String,
id: MeetingID,
passwords: MeetingPasswords,
welcomeMsg: String,
logoutUrl: String,
maxUsers: Int,
record: Boolean = false,
duration: MeetingDuration,
defaultAvatarURL: String,
case class MeetingConfig(
name: String,
id: MeetingID,
passwords: MeetingPasswords,
welcomeMsg: String,
logoutUrl: String,
maxUsers: Int,
record: Boolean = false,
duration: MeetingDuration,
defaultAvatarURL: String,
defaultConfigToken: String,
guestPolicy: String = GuestPolicyType.ASK_MODERATOR)
guestPolicy: String = GuestPolicyType.ASK_MODERATOR
)
case class MeetingName(name: String)
@ -97,11 +104,12 @@ case class VoiceConfig(telVoice: String, webVoice: String, dialNumber: String)
case class MeetingPasswords(moderatorPass: String, viewerPass: String)
case class MeetingDuration(duration: Int = 0, createdTime: Long = 0,
startTime: Long = 0, endTime: Long = 0)
startTime: Long = 0, endTime: Long = 0)
case class MeetingInfo(
meetingID: String,
meetingID: String,
meetingName: String,
recorded: Boolean,
recorded: Boolean,
voiceBridge: String,
duration: Long)
duration: Long
)

View File

@ -1,280 +0,0 @@
package org.bigbluebutton.core.apps
import scala.collection.mutable.ArrayBuffer
object PollType {
val YesNoPollType = "YN"
val TrueFalsePollType = "TF"
val CustomPollType = "CUSTOM"
val LetterPollType = "A-"
val NumberPollType = "1-"
}
object PollFactory {
val LetterArray = Array("A", "B", "C", "D", "E", "F")
val NumberArray = Array("1", "2", "3", "4", "5", "6")
private def processYesNoPollType(qType: String): Question = {
val answers = new Array[Answer](2)
answers(0) = new Answer(0, "Yes", Some("Yes"))
answers(1) = new Answer(1, "No", Some("No"))
new Question(0, PollType.YesNoPollType, false, None, answers)
}
private def processTrueFalsePollType(qType: String): Question = {
val answers = new Array[Answer](2)
answers(0) = new Answer(0, "True", Some("True"))
answers(1) = new Answer(1, "False", Some("False"))
new Question(0, PollType.TrueFalsePollType, false, None, answers)
}
private def processLetterPollType(qType: String, multiResponse: Boolean): Option[Question] = {
val q = qType.split('-')
val numQs = q(1).toInt
var questionOption: Option[Question] = None
if (numQs > 0 && numQs <= 6) {
val answers = new Array[Answer](numQs)
for (i <- 0 until numQs) {
answers(i) = new Answer(i, LetterArray(i), Some(LetterArray(i)))
val question = new Question(0, PollType.LetterPollType, multiResponse, None, answers)
questionOption = Some(question)
}
}
questionOption
}
private def processNumberPollType(qType: String, multiResponse: Boolean): Option[Question] = {
val q = qType.split('-')
val numQs = q(1).toInt
var questionOption: Option[Question] = None
if (numQs > 0 && numQs <= 6) {
val answers = new Array[Answer](numQs)
var i = 0
for (i <- 0 until numQs) {
answers(i) = new Answer(i, NumberArray(i), Some(NumberArray(i)))
val question = new Question(0, PollType.NumberPollType, multiResponse, None, answers)
questionOption = Some(question)
}
}
questionOption
}
private def buildAnswers(answers: Seq[String]): Array[Answer] = {
val ans = new Array[Answer](answers.length)
for (i <- 0 until answers.length) {
ans(i) = new Answer(i, answers(i), Some(answers(i)))
}
ans
}
private def processCustomPollType(qType: String, multiResponse: Boolean, answers: Option[Seq[String]]): Option[Question] = {
var questionOption: Option[Question] = None
answers.foreach { ans =>
val someAnswers = buildAnswers(ans)
val question = new Question(0, PollType.CustomPollType, multiResponse, None, someAnswers)
questionOption = Some(question)
}
questionOption
}
private def createQuestion(qType: String, answers: Option[Seq[String]]): Option[Question] = {
println("**** Creating quesion")
val qt = qType.toUpperCase()
var questionOption: Option[Question] = None
if (qt.matches(PollType.YesNoPollType)) {
questionOption = Some(processYesNoPollType(qt))
} else if (qt.matches(PollType.TrueFalsePollType)) {
questionOption = Some(processTrueFalsePollType(qt))
} else if (qt.matches(PollType.CustomPollType)) {
questionOption = processCustomPollType(qt, false, answers)
} else if (qt.startsWith(PollType.LetterPollType)) {
questionOption = processLetterPollType(qt, false)
} else if (qt.startsWith(PollType.NumberPollType)) {
questionOption = processNumberPollType(qt, false)
}
questionOption
}
def createPoll(id: String, pollType: String, numRespondents: Int, answers: Option[Seq[String]]): Option[Poll] = {
var poll: Option[Poll] = None
createQuestion(pollType, answers) match {
case Some(question) => {
poll = Some(new Poll(id, Array(question), numRespondents, None))
}
case None => poll = None
}
poll
}
}
case class QuestionResponsesVO(val questionID: String, val responseIDs: Array[String])
case class PollResponseVO(val pollID: String, val responses: Array[QuestionResponsesVO])
case class ResponderVO(responseID: String, user: Responder)
case class AnswerVO(val id: Int, val key: String, val text: Option[String], val responders: Option[Array[Responder]])
case class QuestionVO(val id: Int, val questionType: String, val multiResponse: Boolean, val questionText: Option[String], val answers: Option[Array[AnswerVO]])
case class PollVO(val id: String, val questions: Array[QuestionVO], val title: Option[String], val started: Boolean, val stopped: Boolean, val showResult: Boolean)
case class Responder(val userId: String, name: String)
case class ResponseOutVO(id: String, text: String, responders: Array[Responder] = Array[Responder]())
case class QuestionOutVO(id: String, multiResponse: Boolean, question: String, responses: Array[ResponseOutVO])
case class SimpleAnswerOutVO(id: Int, key: String)
case class SimplePollOutVO(id: String, answers: Array[SimpleAnswerOutVO])
case class SimpleVoteOutVO(id: Int, key: String, numVotes: Int)
case class SimplePollResultOutVO(id: String, answers: Array[SimpleVoteOutVO], numRespondents: Int, numResponders: Int)
class Poll(val id: String, val questions: Array[Question], val numRespondents: Int, val title: Option[String]) {
private var _started: Boolean = false
private var _stopped: Boolean = false
private var _showResult: Boolean = false
private var _numResponders: Int = 0
def showingResult() { _showResult = true }
def hideResult() { _showResult = false }
def showResult(): Boolean = { _showResult }
def start() { _started = true }
def stop() { _stopped = true }
def isStarted(): Boolean = { return _started }
def isStopped(): Boolean = { return _stopped }
def isRunning(): Boolean = { return isStarted() && !isStopped() }
def clear() {
questions.foreach(q => { q.clear })
_started = false
_stopped = false
}
def hasResponses(): Boolean = {
questions.foreach(q => {
if (q.hasResponders) return true
})
return false
}
def respondToQuestion(questionID: Int, responseID: Int, responder: Responder) {
questions.foreach(q => {
if (q.id == questionID) {
q.respondToQuestion(responseID, responder)
_numResponders += 1
}
})
}
def toPollVO(): PollVO = {
val qvos = new ArrayBuffer[QuestionVO]
questions.foreach(q => {
qvos += q.toQuestionVO
})
new PollVO(id, qvos.toArray, title, _started, _stopped, _showResult)
}
def toSimplePollOutVO(): SimplePollOutVO = {
new SimplePollOutVO(id, questions(0).toSimpleAnswerOutVO())
}
def toSimplePollResultOutVO(): SimplePollResultOutVO = {
new SimplePollResultOutVO(id, questions(0).toSimpleVotesOutVO(), numRespondents, _numResponders)
}
}
class Question(val id: Int, val questionType: String, val multiResponse: Boolean, val text: Option[String], val answers: Array[Answer]) {
def clear() {
answers.foreach(r => r.clear)
}
def hasResponders(): Boolean = {
answers.foreach(r => {
if (r.numResponders > 0) return true
})
return false
}
def respondToQuestion(id: Int, responder: Responder) {
answers.foreach(r => {
if (r.id == id) r.addResponder(responder)
})
}
def toQuestionVO(): QuestionVO = {
val rvos = new ArrayBuffer[AnswerVO]
answers.foreach(answer => {
val r = new AnswerVO(answer.id, answer.key, answer.text, Some(answer.getResponders))
rvos += r
})
new QuestionVO(id, questionType, multiResponse, text, Some(rvos.toArray))
}
def toSimpleAnswerOutVO(): Array[SimpleAnswerOutVO] = {
val rvos = new ArrayBuffer[SimpleAnswerOutVO]
answers.foreach(answer => {
rvos += answer.toSimpleAnswerOutVO()
})
rvos.toArray
}
def toSimpleVotesOutVO(): Array[SimpleVoteOutVO] = {
val rvos = new ArrayBuffer[SimpleVoteOutVO]
answers.foreach(answer => {
rvos += answer.toSimpleVoteOutVO()
})
rvos.toArray
}
}
class Answer(val id: Int, val key: String, val text: Option[String]) {
val responders = new ArrayBuffer[Responder]()
def clear() {
responders.clear
}
def addResponder(responder: Responder) {
responders += responder
}
def numResponders(): Int = {
responders.length;
}
def getResponders(): Array[Responder] = {
var r = new Array[Responder](responders.length)
responders.copyToArray(r)
return r
}
def toSimpleAnswerOutVO(): SimpleAnswerOutVO = {
new SimpleAnswerOutVO(id, key)
}
def toSimpleVoteOutVO(): SimpleVoteOutVO = {
new SimpleVoteOutVO(id, key, numResponders)
}
}

View File

@ -1,132 +0,0 @@
package org.bigbluebutton.core.apps
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.HashMap
object PollModel {
def getRunningPollThatStartsWith(pollId: String, model: PollModel): Option[PollVO] = {
for {
poll <- model.polls.values find { poll => poll.id.startsWith(pollId) && poll.isRunning() }
} yield poll.toPollVO()
}
def numPolls(model: PollModel): Int = {
model.polls.size
}
def addPoll(poll: Poll, model: PollModel) {
model.polls += poll.id -> poll
}
def hasCurrentPoll(model: PollModel): Boolean = {
model.currentPoll != None
}
def getCurrentPoll(model: PollModel): Option[PollVO] = {
model.currentPoll
}
def getPolls(model: PollModel): Array[PollVO] = {
val poll = new ArrayBuffer[PollVO]
model.polls.values.foreach(p => {
poll += p.toPollVO
})
poll.toArray
}
def clearPoll(pollID: String, model: PollModel): Boolean = {
var success = false
model.polls.get(pollID) match {
case Some(p) => {
p.clear
success = true
}
case None => success = false
}
success
}
def startPoll(pollId: String, model: PollModel) {
model.polls.get(pollId) foreach {
p =>
p.start()
model.currentPoll = Some(p.toPollVO())
}
}
def removePoll(pollID: String, model: PollModel): Boolean = {
var success = false
model.polls.get(pollID) match {
case Some(p) => {
model.polls -= p.id
success = true
}
case None => success = false
}
success
}
def stopPoll(pollId: String, model: PollModel) {
model.polls.get(pollId) foreach (p => p.stop())
}
def hasPoll(pollId: String, model: PollModel): Boolean = {
model.polls.get(pollId) != None
}
def getSimplePoll(pollId: String, model: PollModel): Option[SimplePollOutVO] = {
var pvo: Option[SimplePollOutVO] = None
model.polls.get(pollId) foreach (p => pvo = Some(p.toSimplePollOutVO()))
pvo
}
def getSimplePollResult(pollId: String, model: PollModel): Option[SimplePollResultOutVO] = {
var pvo: Option[SimplePollResultOutVO] = None
model.polls.get(pollId) foreach (p => pvo = Some(p.toSimplePollResultOutVO()))
pvo
}
def getPoll(pollId: String, model: PollModel): Option[PollVO] = {
var pvo: Option[PollVO] = None
model.polls.get(pollId) foreach (p => pvo = Some(p.toPollVO()))
pvo
}
def hidePollResult(pollId: String, model: PollModel) {
model.polls.get(pollId) foreach {
p =>
p.hideResult()
model.currentPoll = None
}
}
def showPollResult(pollId: String, model: PollModel) {
model.polls.get(pollId) foreach {
p =>
p.showResult
model.currentPoll = Some(p.toPollVO())
}
}
def respondToQuestion(pollId: String, questionID: Int, responseID: Int, responder: Responder, model: PollModel) {
model.polls.get(pollId) match {
case Some(p) => {
p.respondToQuestion(questionID, responseID, responder)
}
case None =>
}
}
}
class PollModel {
private val polls = new HashMap[String, Poll]()
private var currentPoll: Option[PollVO] = None
}

View File

@ -1,143 +0,0 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait PresentationApp {
this: MeetingActor =>
val outGW: OutMessageGateway
def handlePreuploadedPresentations(msg: PreuploadedPresentations) {
// val pres = msg.presentations
//
// msg.presentations.foreach(presentation => {
// liveMeeting.presModel.addPresentation(presentation)
//
// sharePresentation(presentation.id, true)
// })
}
def handleInitializeMeeting(msg: InitializeMeeting) {
}
def handleClearPresentation(msg: ClearPresentation) {
// outGW.send(new ClearPresentationOutMsg(props.meetingProp.intId, props.recordProp.record))
}
def handlePresentationConversionUpdate(msg: PresentationConversionUpdate) {
// outGW.send(new PresentationConversionProgress(props.meetingProp.intId, msg.messageKey,
// msg.code, msg.presentationId, msg.presName))
}
def handlePresentationPageCountError(msg: PresentationPageCountError) {
// outGW.send(new PresentationConversionError(props.meetingProp.intId, msg.messageKey,
// msg.code, msg.presentationId,
// msg.numberOfPages,
// msg.maxNumberPages, msg.presName))
}
def handlePresentationSlideGenerated(msg: PresentationSlideGenerated) {
// outGW.send(new PresentationPageGenerated(props.meetingProp.intId, msg.messageKey,
// msg.code, msg.presentationId,
// msg.numberOfPages,
// msg.pagesCompleted, msg.presName))
}
def handlePresentationConversionCompleted(msg: PresentationConversionCompleted) {
liveMeeting.presModel.addPresentation(msg.presentation)
//
// outGW.send(new PresentationConversionDone(props.meetingProp.intId, props.recordProp.record, msg.messageKey,
// msg.code, msg.presentation))
//
// sharePresentation(msg.presentation.id, true)
}
def handleRemovePresentation(msg: RemovePresentation) {
// val curPres = liveMeeting.presModel.getCurrentPresentation
//
// val removedPresentation = liveMeeting.presModel.remove(msg.presentationID)
//
// curPres foreach (cp => {
// if (cp.id == msg.presentationID) {
// sharePresentation(msg.presentationID, false);
// }
// })
//
// outGW.send(new RemovePresentationOutMsg(msg.meetingID, props.recordProp.record, msg.presentationID))
}
def handleGetPresentationInfo(msg: GetPresentationInfo) {
// val curPresenter = MeetingStatus2x.getCurrentPresenterInfo(liveMeeting.status)
// val presenter = new CurrentPresenter(curPresenter.presenterID, curPresenter.presenterName, curPresenter.assignedBy)
// val presentations = liveMeeting.presModel.getPresentations
// val presentationInfo = new CurrentPresentationInfo(presenter, presentations)
// outGW.send(new GetPresentationInfoOutMsg(props.meetingProp.intId, props.recordProp.record, msg.requesterID, presentationInfo, msg.replyTo))
}
def handleResizeAndMoveSlide(msg: ResizeAndMoveSlide) {
// // Force coordinate that are out-of-bounds inside valid values
// val xOffset = if (msg.xOffset <= 0) msg.xOffset else 0
// val yOffset = if (msg.yOffset <= 0) msg.yOffset else 0
// val width = if (msg.widthRatio <= 100) msg.widthRatio else 100
// val height = if (msg.heightRatio <= 100) msg.heightRatio else 100
//
// val page = liveMeeting.presModel.resizePage(xOffset, yOffset, width, height);
// page foreach (p => outGW.send(new ResizeAndMoveSlideOutMsg(props.meetingProp.intId, props.recordProp.record, p)))
}
def handleGotoSlide(msg: GotoSlide) {
// liveMeeting.presModel.changePage(msg.page) foreach { page =>
// log.debug("Switching page for meeting=[{}] page=[{}]", msg.meetingID, page.num);
// outGW.send(new GotoSlideOutMsg(props.meetingProp.intId, props.recordProp.record, page))
// }
//
// Users.getCurrentPresenter(liveMeeting.users) foreach { pres =>
// handleStopPollRequest(StopPollRequest(props.meetingProp.intId, pres.id))
// }
}
def handleSharePresentation(msg: SharePresentation) {
sharePresentation(msg.presentationID, msg.share)
}
def sharePresentation(presentationID: String, share: Boolean) {
/*
val pres = liveMeeting.presModel.sharePresentation(presentationID)
pres foreach { p =>
outGW.send(new SharePresentationOutMsg(props.meetingProp.intId, props.recordProp.record, p))
liveMeeting.presModel.getCurrentPage(p) foreach { page =>
outGW.send(new GotoSlideOutMsg(props.meetingProp.intId, props.recordProp.record, page))
}
}
*/
}
def handleGetSlideInfo(msg: GetSlideInfo) {
// liveMeeting.presModel.getCurrentPresentation foreach { pres =>
// liveMeeting.presModel.getCurrentPage(pres) foreach { page =>
// outGW.send(new GetSlideInfoOutMsg(props.meetingProp.intId, props.recordProp.record, msg.requesterID, page, msg.replyTo))
// }
// }
}
def printPresentations() {
liveMeeting.presModel.getPresentations foreach { pres =>
println("presentation id=[" + pres.id + "] current=[" + pres.current + "]")
pres.pages.values foreach { page =>
println("page id=[" + page.id + "] current=[" + page.current + "]")
}
}
}
}

View File

@ -6,11 +6,11 @@ import org.bigbluebutton.common2.domain.PageVO
case class CurrentPresenter(userId: String, name: String, assignedBy: String)
case class CurrentPresentationInfo(presenter: CurrentPresenter, presentations: Seq[Presentation])
case class Presentation(id: String, name: String, current: Boolean = false,
pages: scala.collection.immutable.Map[String, PageVO], downloadable: Boolean)
pages: scala.collection.immutable.Map[String, PageVO], downloadable: Boolean)
case class Page(id: String, num: Int, thumbUri: String = "", swfUri: String,
txtUri: String, svgUri: String, current: Boolean = false, xOffset: Double = 0, yOffset: Double = 0,
widthRatio: Double = 100D, heightRatio: Double = 100D)
txtUri: String, svgUri: String, current: Boolean = false, xOffset: Double = 0, yOffset: Double = 0,
widthRatio: Double = 100D, heightRatio: Double = 100D)
class PresentationModel {
private var presentations = new scala.collection.immutable.HashMap[String, Presentation]
@ -70,8 +70,8 @@ class PresentationModel {
}
def resizePage(presentationId: String, pageId: String,
xOffset: Double, yOffset: Double, widthRatio: Double,
heightRatio: Double): Option[PageVO] = {
xOffset: Double, yOffset: Double, widthRatio: Double,
heightRatio: Double): Option[PageVO] = {
for {
pres <- presentations.get(presentationId)
page <- pres.pages.get(pageId)

View File

@ -103,7 +103,7 @@ class SharedNotesModel {
def getNoteReport(noteId: String): Option[NoteReport] = {
notes.get(noteId) match {
case Some(note) => Some(noteToReport(note))
case None => None
case None => None
}
}

View File

@ -5,7 +5,8 @@ import org.bigbluebutton.core.util.jhotdraw.BezierWrapper
import scala.collection.immutable.List
import scala.collection.immutable.HashMap
import scala.collection.JavaConverters._
import org.bigbluebutton.common2.domain.AnnotationVO
import org.bigbluebutton.common2.msgs.AnnotationVO
import org.bigbluebutton.core.apps.whiteboard.Whiteboard
class WhiteboardModel {
private var _whiteboards = new HashMap[String, Whiteboard]()
@ -218,16 +219,15 @@ class WhiteboardModel {
def cleansePointsInAnnotation(ann: AnnotationVO): AnnotationVO = {
var updatedAnnotationInfo = ann.annotationInfo
ann.annotationInfo.get("points").foreach(points =>
updatedAnnotationInfo = (ann.annotationInfo + ("points" -> convertListNumbersToFloat(points.asInstanceOf[List[_]])))
)
updatedAnnotationInfo = (ann.annotationInfo + ("points" -> convertListNumbersToFloat(points.asInstanceOf[List[_]]))))
ann.copy(annotationInfo = updatedAnnotationInfo)
}
def convertListNumbersToFloat(list: List[_]): List[Float] = {
list.map {
case f: Double => f.toFloat
case f: Float => f
case f: Int => f.toFloat
case f: Float => f
case f: Int => f.toFloat
}.asInstanceOf[List[Float]]
}
}

View File

@ -51,13 +51,14 @@ object BreakoutRoomsUtil {
}
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String,
password: String): (mutable.Map[String, String], mutable.Map[String, String]) = {
password: String): (mutable.Map[String, String], mutable.Map[String, String]) = {
val params = collection.mutable.HashMap(
"fullName" -> urlEncode(username),
"userID" -> urlEncode(userId),
"isBreakout" -> urlEncode(isBreakout.toString()),
"meetingID" -> urlEncode(breakoutMeetingId),
"password" -> urlEncode(password))
"password" -> urlEncode(password)
)
(params += "redirect" -> urlEncode("true"), mutable.Map[String, String]() ++= params += "redirect" -> urlEncode("false"))
}

View File

@ -61,12 +61,14 @@ trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
}
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String,
breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId)
def build(meetingId: String, breakout: BreakoutRoomInfo): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, "not-used")
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, "not-used"
)
val envelope = BbbCoreEnvelope(BreakoutRoomStartedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(BreakoutRoomStartedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, "not-used")
@ -97,7 +99,7 @@ trait BreakoutRoomCreatedMsgHdlr extends SystemConfiguration {
BreakoutRoomsUtil.calculateChecksum(apiCall, noRedirectBaseString, bbbWebSharedSecret))
} yield {
def build(meetingId: String, breakoutMeetingId: String,
userId: String, redirectJoinURL: String, noRedirectJoinURL: String): BbbCommonEnvCoreMsg = {
userId: String, redirectJoinURL: String, noRedirectJoinURL: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
val envelope = BbbCoreEnvelope(BreakoutRoomJoinURLEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(BreakoutRoomJoinURLEvtMsg.NAME, meetingId, "not-used")

View File

@ -14,11 +14,15 @@ trait CreateBreakoutRoomsCmdMsgHdlr {
def handleCreateBreakoutRoomsCmdMsg(msg: CreateBreakoutRoomsCmdMsg): Unit = {
// If breakout rooms are being created we ignore the coming message
if (liveMeeting.breakoutRooms.pendingRoomsNumber > 0) {
log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}",
liveMeeting.breakoutRooms.pendingRoomsNumber, liveMeeting.props.meetingProp.intId)
log.warning(
"CreateBreakoutRooms event received while {} are pending to be created for meeting {}",
liveMeeting.breakoutRooms.pendingRoomsNumber, liveMeeting.props.meetingProp.intId
)
} else if (BreakoutRooms.getNumberOfRooms(liveMeeting.breakoutRooms) > 0) {
log.warning("CreateBreakoutRooms event received while {} breakout rooms running for meeting {}",
BreakoutRooms.getNumberOfRooms(liveMeeting.breakoutRooms), liveMeeting.props.meetingProp.intId)
log.warning(
"CreateBreakoutRooms event received while {} breakout rooms running for meeting {}",
BreakoutRooms.getNumberOfRooms(liveMeeting.breakoutRooms), liveMeeting.props.meetingProp.intId
)
} else {
var i = 0
// in very rare cases the presentation conversion generates an error, what should we do?

View File

@ -38,8 +38,10 @@ trait RequestBreakoutJoinURLReqMsgHdlr {
val envelope = BbbCoreEnvelope(RequestBreakoutJoinURLRespMsg.NAME, routing)
val header = BbbClientMsgHeader(RequestBreakoutJoinURLRespMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = RequestBreakoutJoinURLRespMsgBody(props.meetingProp.intId,
externalMeetingId, userId, redirectJoinURL, noRedirectJoinURL)
val body = RequestBreakoutJoinURLRespMsgBody(
props.meetingProp.intId,
externalMeetingId, userId, redirectJoinURL, noRedirectJoinURL
)
val event = RequestBreakoutJoinURLRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)

View File

@ -2,9 +2,7 @@ package org.bigbluebutton.core.apps.breakout
import org.bigbluebutton.common2.msgs.{ BreakoutUserVO, SendBreakoutUsersUpdateMsg }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.BreakoutRoomUsersUpdate
import org.bigbluebutton.core.bus.BigBlueButtonEvent
import org.bigbluebutton.core.models.{ Users2x }
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.MeetingActor
trait SendBreakoutUsersUpdateMsgHdlr {
@ -16,7 +14,9 @@ trait SendBreakoutUsersUpdateMsgHdlr {
val users = Users2x.findAll(liveMeeting.users2x)
val breakoutUsers = users map { u => new BreakoutUserVO(u.extId, u.name) }
eventBus.publish(BigBlueButtonEvent(props.breakoutProps.parentId,
new BreakoutRoomUsersUpdate(props.breakoutProps.parentId, props.meetingProp.intId, breakoutUsers)))
/** 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)))
}
}

View File

@ -6,8 +6,10 @@ import org.bigbluebutton.common2.msgs.TranscriptVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
class CaptionApp2x(val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway)(implicit val context: ActorContext)
class CaptionApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
)(implicit val context: ActorContext)
extends UserLeavingHdlr
with EditCaptionHistoryPubMsgHdlr
with UpdateCaptionOwnerPubMsgHdlr

View File

@ -6,8 +6,10 @@ import org.bigbluebutton.common2.msgs.TranscriptVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
class ChatApp2x(val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway)(implicit val context: ActorContext)
class ChatApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
)(implicit val context: ActorContext)
extends GetChatHistoryReqMsgHdlr
with SendPublicMessagePubMsgHdlr
with SendPrivateMessagePubMsgHdlr

View File

@ -24,7 +24,8 @@ trait BroadcastLayoutMsgHdlr {
val body = BroadcastLayoutEvtMsgBody(
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter(), affectedUsers)
Layouts.getLayoutSetter(), affectedUsers
)
val event = BroadcastLayoutEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)

View File

@ -20,9 +20,11 @@ trait GetCurrentLayoutReqMsgHdlr {
val envelope = BbbCoreEnvelope(GetCurrentLayoutRespMsg.NAME, routing)
val header = BbbClientMsgHeader(GetCurrentLayoutRespMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = GetCurrentLayoutRespMsgBody(Layouts.getCurrentLayout(),
val body = GetCurrentLayoutRespMsgBody(
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter())
Layouts.getLayoutSetter()
)
val event = GetCurrentLayoutRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)

View File

@ -1,6 +1,6 @@
package org.bigbluebutton.core.apps.polls
import org.bigbluebutton.common2.domain.{ AnnotationVO, SimplePollResultOutVO }
import org.bigbluebutton.common2.domain.SimplePollResultOutVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls

View File

@ -8,8 +8,10 @@ import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.apps.Presentation
class PresentationApp2x(val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway)(implicit val context: ActorContext)
class PresentationApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
)(implicit val context: ActorContext)
extends NewPresentationMsgHdlr
with SetCurrentPresentationPubMsgHdlr
with GetPresentationInfoReqMsgHdlr
@ -54,8 +56,8 @@ class PresentationApp2x(val liveMeeting: LiveMeeting,
}
def resizeAndMovePage(presentationId: String, pageId: String,
xOffset: Double, yOffset: Double, widthRatio: Double,
heightRatio: Double): Option[PageVO] = {
xOffset: Double, yOffset: Double, widthRatio: Double,
heightRatio: Double): Option[PageVO] = {
// Force coordinate that are out-of-bounds inside valid values
// 0.25D is 400% zoom
// 100D-checkedWidth is the maximum the page can be moved over

View File

@ -5,8 +5,10 @@ import akka.event.Logging
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
class ScreenshareApp2x(val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway)(implicit val context: ActorContext)
class ScreenshareApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
)(implicit val context: ActorContext)
extends ScreenshareStartedVoiceConfEvtMsgHdlr
with ScreenshareStoppedVoiceConfEvtMsgHdlr
with ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr

View File

@ -11,13 +11,17 @@ trait ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr {
def handleScreenshareRtmpBroadcastStartedVoiceConfEvtMsg(msg: ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg): Unit = {
def broadcastEvent(voiceConf: String, screenshareConf: String, stream: String, vidWidth: Int, vidHeight: Int,
timestamp: String): BbbCommonEnvCoreMsg = {
timestamp: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, "not-used")
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, "not-used"
)
val envelope = BbbCoreEnvelope(ScreenshareRtmpBroadcastStartedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(ScreenshareRtmpBroadcastStartedEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, "not-used")
val header = BbbClientMsgHeader(
ScreenshareRtmpBroadcastStartedEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, "not-used"
)
val body = ScreenshareRtmpBroadcastStartedEvtMsgBody(voiceConf, screenshareConf,
stream, vidWidth, vidHeight, timestamp)

View File

@ -12,14 +12,18 @@ trait ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsgHdlr {
def handleScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg(msg: ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg): Unit = {
def broadcastEvent(voiceConf: String, screenshareConf: String,
stream: String, vidWidth: Int, vidHeight: Int,
timestamp: String): BbbCommonEnvCoreMsg = {
stream: String, vidWidth: Int, vidHeight: Int,
timestamp: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, "not-used")
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, "not-used"
)
val envelope = BbbCoreEnvelope(ScreenshareRtmpBroadcastStoppedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(ScreenshareRtmpBroadcastStoppedEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, "not-used")
val header = BbbClientMsgHeader(
ScreenshareRtmpBroadcastStoppedEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, "not-used"
)
val body = ScreenshareRtmpBroadcastStoppedEvtMsgBody(voiceConf, screenshareConf,
stream, vidWidth, vidHeight, timestamp)

View File

@ -15,8 +15,10 @@ trait ScreenshareStartedVoiceConfEvtMsgHdlr {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME,
liveMeeting.props.meetingProp.intId)
val header = BbbCoreHeaderWithMeetingId(
ScreenshareStartRtmpBroadcastVoiceConfMsg.NAME,
liveMeeting.props.meetingProp.intId
)
val body = ScreenshareStartRtmpBroadcastVoiceConfMsgBody(voiceConf: String, screenshareConf: String, url: String, timestamp: String)
val event = ScreenshareStartRtmpBroadcastVoiceConfMsg(header, body)

View File

@ -14,8 +14,10 @@ trait ScreenshareStoppedVoiceConfEvtMsgHdlr {
def broadcastEvent(voiceConf: String, screenshareConf: String, url: String, timestamp: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(ScreenshareStopRtmpBroadcastVoiceConfMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(ScreenshareStopRtmpBroadcastVoiceConfMsg.NAME,
liveMeeting.props.meetingProp.intId)
val header = BbbCoreHeaderWithMeetingId(
ScreenshareStopRtmpBroadcastVoiceConfMsg.NAME,
liveMeeting.props.meetingProp.intId
)
val body = ScreenshareStopRtmpBroadcastVoiceConfMsgBody(voiceConf, screenshareConf, url, timestamp)
val event = ScreenshareStopRtmpBroadcastVoiceConfMsg(header, body)

View File

@ -5,8 +5,10 @@ import akka.event.Logging
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
class SharedNotesApp2x(val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway)(implicit val context: ActorContext)
class SharedNotesApp2x(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
)(implicit val context: ActorContext)
extends GetSharedNotesPubMsgHdlr
with SyncSharedNotePubMsgHdlr
with UpdateSharedNoteReqMsgHdlr

View File

@ -23,7 +23,7 @@ trait SyncSharedNotePubMsgHdlr {
liveMeeting.notesModel.getNoteReport(msg.body.noteId) match {
case Some(noteReport) => broadcastEvent(msg, noteReport)
case None => log.warning("Could not find note " + msg.body.noteId)
case None => log.warning("Could not find note " + msg.body.noteId)
}
}
}

View File

@ -23,9 +23,9 @@ trait UpdateSharedNoteReqMsgHdlr {
val userId = msg.body.operation match {
case "PATCH" => msg.header.userId
case "UNDO" => liveMeeting.notesModel.SYSTEM_ID
case "REDO" => liveMeeting.notesModel.SYSTEM_ID
case _ => return
case "UNDO" => liveMeeting.notesModel.SYSTEM_ID
case "REDO" => liveMeeting.notesModel.SYSTEM_ID
case _ => return
}
val (patchId, patch, undo, redo) = liveMeeting.notesModel.patchNote(msg.body.noteId, msg.body.patch, msg.body.operation)

View File

@ -1,17 +1,24 @@
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
trait AssignPresenterReqMsgHdlr {
this: UsersApp2x =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
def handleAssignPresenterReqMsg(msg: AssignPresenterReqMsg) {
def broadcastPresenterChange(oldPres: UserState, newPres: UserState): Unit = {
// unassign old presenter
val routingUnassign = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
this.liveMeeting.props.meetingProp.intId, oldPres.intId)
val routingUnassign = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
this.liveMeeting.props.meetingProp.intId, oldPres.intId
)
val envelopeUnassign = BbbCoreEnvelope(PresenterUnassignedEvtMsg.NAME, routingUnassign)
val headerUnassign = BbbClientMsgHeader(PresenterUnassignedEvtMsg.NAME, this.liveMeeting.props.meetingProp.intId,
oldPres.intId)
@ -22,8 +29,10 @@ trait AssignPresenterReqMsgHdlr {
outGW.send(msgEventUnassign)
// set new presenter
val routingAssign = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
this.liveMeeting.props.meetingProp.intId, newPres.intId)
val routingAssign = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
this.liveMeeting.props.meetingProp.intId, newPres.intId
)
val envelopeAssign = BbbCoreEnvelope(PresenterAssignedEvtMsg.NAME, routingAssign)
val headerAssign = BbbClientMsgHeader(PresenterAssignedEvtMsg.NAME, this.liveMeeting.props.meetingProp.intId,
newPres.intId)

View File

@ -1,10 +1,15 @@
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
trait ChangeUserRoleCmdMsgHdlr {
this: UsersApp2x =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
def handleChangeUserRoleCmdMsg(msg: ChangeUserRoleCmdMsg) {
for {

View File

@ -7,7 +7,7 @@ import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait EjectUserFromMeetingCmdMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
@ -19,8 +19,10 @@ trait EjectUserFromMeetingCmdMsgHdlr {
RegisteredUsers.remove(msg.body.userId, liveMeeting.registeredUsers)
// send a message to client
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(liveMeeting.props.meetingProp.intId,
user.intId, msg.body.ejectedBy)
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(
liveMeeting.props.meetingProp.intId,
user.intId, msg.body.ejectedBy
)
outGW.send(ejectFromMeetingClientEvent)
log.info("Ejecting user from meeting (client msg). meetingId=" + liveMeeting.props.meetingProp.intId +
" userId=" + msg.body.userId)
@ -39,8 +41,10 @@ trait EjectUserFromMeetingCmdMsgHdlr {
for {
vu <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
} yield {
val ejectFromVoiceEvent = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(liveMeeting.props.meetingProp.intId,
liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId)
val ejectFromVoiceEvent = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(
liveMeeting.props.meetingProp.intId,
liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId
)
outGW.send(ejectFromVoiceEvent)
log.info("Ejecting user from voice. meetingId=" + liveMeeting.props.meetingProp.intId + " userId=" + vu.intId)
}

View File

@ -6,7 +6,7 @@ import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.MeetingStatus2x
trait GetRecordingStatusReqMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway

View File

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

View File

@ -8,7 +8,7 @@ import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.MeetingStatus2x
trait LogoutAndEndMeetingCmdMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway

View File

@ -2,27 +2,24 @@ 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.domain.MeetingInactivityTracker
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, MeetingInactivityTrackerHelper }
trait MeetingActivityResponseCmdMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway
def handleMeetingActivityResponseCmdMsg(msg: MeetingActivityResponseCmdMsg) {
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)
}
log.info("User endorsed that meeting {} is active", liveMeeting.props.meetingProp.intId)
val event = buildMeetingIsActiveEvtMsg(liveMeeting.props.meetingProp.intId)
outGW.send(event)
def handleMeetingActivityResponseCmdMsg(
msg: MeetingActivityResponseCmdMsg,
tracker: MeetingInactivityTracker
): MeetingInactivityTracker = {
MeetingInactivityTrackerHelper.processMeetingActivityResponse(
props = liveMeeting.props,
outGW,
msg,
tracker
)
}
}

View File

@ -7,7 +7,7 @@ import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.MeetingStatus2x
trait RegisterUserReqMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway

View File

@ -6,7 +6,7 @@ import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
import org.bigbluebutton.core2.MeetingStatus2x
trait SetRecordingStatusCmdMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway

View File

@ -6,7 +6,7 @@ import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting }
trait SyncGetUsersMeetingRespMsgHdlr {
this: BaseMeetingActor =>
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMessageGateway

View File

@ -0,0 +1,27 @@
package org.bigbluebutton.core.apps.users
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core2.message.handlers.users.ValidateAuthTokenReqMsgHdlr
class UsersApp(
val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway
)(implicit val context: ActorContext)
extends ValidateAuthTokenReqMsgHdlr
with GetUsersMeetingReqMsgHdlr
with RegisterUserReqMsgHdlr
with ChangeUserRoleCmdMsgHdlr
with SyncGetUsersMeetingRespMsgHdlr
with LogoutAndEndMeetingCmdMsgHdlr
with MeetingActivityResponseCmdMsgHdlr
with SetRecordingStatusCmdMsgHdlr
with GetRecordingStatusReqMsgHdlr
with AssignPresenterReqMsgHdlr
with EjectUserFromMeetingCmdMsgHdlr {
val log = Logging(context.system, getClass)
}

View File

@ -4,17 +4,8 @@ import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.message.handlers.users.{ ChangeUserEmojiCmdMsgHdlr, ValidateAuthTokenReqMsgHdlr }
trait UsersApp2x
extends RegisterUserReqMsgHdlr
with ChangeUserRoleCmdMsgHdlr
with SyncGetUsersMeetingRespMsgHdlr
with ValidateAuthTokenReqMsgHdlr
with UserLeaveReqMsgHdlr
with LogoutAndEndMeetingCmdMsgHdlr
with MeetingActivityResponseCmdMsgHdlr
with SetRecordingStatusCmdMsgHdlr
with GetRecordingStatusReqMsgHdlr
with AssignPresenterReqMsgHdlr
with EjectUserFromMeetingCmdMsgHdlr
extends UserLeaveReqMsgHdlr
with ChangeUserEmojiCmdMsgHdlr {
this: MeetingActor =>

View File

@ -2,7 +2,6 @@ package org.bigbluebutton.core.apps.voice
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.StartRecordingVoiceConf
import org.bigbluebutton.core.models.{ VoiceUser2x, VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, MeetingActor }
import org.bigbluebutton.core2.MeetingStatus2x
@ -17,11 +16,15 @@ trait UserJoinedVoiceConfEvtMsgHdlr {
log.warning("Received user joined voice conference " + msg)
def broadcastEvent(voiceUserState: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, voiceUserState.intId)
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, voiceUserState.intId
)
val envelope = BbbCoreEnvelope(UserJoinedVoiceConfToClientEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserJoinedVoiceConfToClientEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, voiceUserState.intId)
val header = BbbClientMsgHeader(
UserJoinedVoiceConfToClientEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, voiceUserState.intId
)
val body = UserJoinedVoiceConfToClientEvtMsgBody(intId = voiceUserState.intId, voiceUserId = voiceUserState.voiceUserId,
callerName = voiceUserState.callerName, callerNum = voiceUserState.callerNum, muted = voiceUserState.muted,

View File

@ -46,8 +46,10 @@ trait UserLeftVoiceConfEvtMsgHdlr {
log.info("Send STOP RECORDING voice conf. meetingId=" + liveMeeting.props.meetingProp.intId
+ " voice conf=" + liveMeeting.props.voiceProp.voiceConf)
val event = buildStopRecordingVoiceConfSysMsg(liveMeeting.props.meetingProp.intId,
liveMeeting.props.voiceProp.voiceConf, MeetingStatus2x.getVoiceRecordingFilename(liveMeeting.status))
val event = buildStopRecordingVoiceConfSysMsg(
liveMeeting.props.meetingProp.intId,
liveMeeting.props.voiceProp.voiceConf, MeetingStatus2x.getVoiceRecordingFilename(liveMeeting.status)
)
outGW.send(event)
}
}

View File

@ -14,12 +14,16 @@ trait UserMutedInVoiceConfEvtMsgHdlr {
def handleUserMutedInVoiceConfEvtMsg(msg: UserMutedInVoiceConfEvtMsg): Unit = {
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId,
vu.intId)
vu.intId
)
val envelope = BbbCoreEnvelope(UserMutedVoiceEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserMutedVoiceEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, vu.intId)
val header = BbbClientMsgHeader(
UserMutedVoiceEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, vu.intId
)
val body = UserMutedVoiceEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId, vu.muted)

View File

@ -14,12 +14,16 @@ trait UserTalkingInVoiceConfEvtMsgHdlr {
def handleUserTalkingInVoiceConfEvtMsg(msg: UserTalkingInVoiceConfEvtMsg): Unit = {
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING,
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId,
vu.intId)
vu.intId
)
val envelope = BbbCoreEnvelope(UserTalkingVoiceEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserTalkingVoiceEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, vu.intId)
val header = BbbClientMsgHeader(
UserTalkingVoiceEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, vu.intId
)
val body = UserTalkingVoiceEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId, vu.talking)

View File

@ -1,8 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.MeetingActor
trait ClearWhiteboardPubMsgHdlr {
this: MeetingActor =>

View File

@ -1,8 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.MeetingActor
trait GetWhiteboardAccessReqMsgHdlr {
this: MeetingActor =>

View File

@ -1,9 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.domain.AnnotationVO
import org.bigbluebutton.core.running.MeetingActor
trait GetWhiteboardAnnotationsReqMsgHdlr {
this: MeetingActor =>

View File

@ -1,8 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.MeetingActor
trait ModifyWhiteboardAccessPubMsgHdlr {
this: MeetingActor =>

View File

@ -1,8 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.MeetingActor
trait SendCursorPositionPubMsgHdlr {
this: MeetingActor =>

View File

@ -1,9 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.common2.domain.AnnotationVO
import org.bigbluebutton.core.running.MeetingActor
trait SendWhiteboardAnnotationPubMsgHdlr {
this: MeetingActor =>

View File

@ -1,8 +1,9 @@
package org.bigbluebutton.core2.message.handlers.whiteboard
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.MeetingActor
trait UndoWhiteboardPubMsgHdlr {
this: MeetingActor =>

View File

@ -1,20 +1,14 @@
package org.bigbluebutton.core.apps
package org.bigbluebutton.core.apps.whiteboard
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.{ MeetingActor }
import org.bigbluebutton.core2.message.handlers.whiteboard.SendCursorPositionPubMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.ClearWhiteboardPubMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.UndoWhiteboardPubMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.ModifyWhiteboardAccessPubMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.GetWhiteboardAccessReqMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.SendWhiteboardAnnotationPubMsgHdlr
import org.bigbluebutton.common2.domain.AnnotationVO
import org.bigbluebutton.core2.message.handlers.whiteboard.GetWhiteboardAnnotationsReqMsgHdlr
import org.bigbluebutton.common2.msgs.AnnotationVO
import org.bigbluebutton.core.apps.WhiteboardKeyUtil
case class Whiteboard(id: String, annotationCount: Int, annotationsMap: scala.collection.immutable.Map[String, scala.collection.immutable.List[AnnotationVO]])
trait WhiteboardApp
trait WhiteboardApp2x
extends SendCursorPositionPubMsgHdlr
with ClearWhiteboardPubMsgHdlr
with UndoWhiteboardPubMsgHdlr

View File

@ -0,0 +1,16 @@
package org.bigbluebutton.core.bus
import akka.actor.ActorRef
class InMsgBusGW(bus: IncomingEventBusImp) extends IncomingEventBus {
override def publish(event: BigBlueButtonEvent): Unit = {
bus.publish(event)
}
override def subscribe(actorRef: ActorRef, topic: String): Unit = {
bus.subscribe(actorRef, topic)
}
override def unsubscribe(actorRef: ActorRef, topic: String): Unit = {
bus.unsubscribe(actorRef, topic)
}
}

View File

@ -1,33 +1,14 @@
package org.bigbluebutton.core.bus
import akka.actor.ActorRef
import akka.event.EventBus
import akka.event.LookupClassification
import org.bigbluebutton.core.api.InMessage
case class BigBlueButtonEvent(val topic: String, val payload: InMessage)
class IncomingEventBus extends EventBus with LookupClassification {
type Event = BigBlueButtonEvent
type Classifier = String
type Subscriber = ActorRef
trait IncomingEventBus {
// is used for extracting the classifier from the incoming events
override protected def classify(event: Event): Classifier = event.topic
// will be invoked for each event for all subscribers which registered themselves
// for the events classifier
override protected def publish(event: Event, subscriber: Subscriber): Unit = {
subscriber ! event.payload
}
// must define a full order over the subscribers, expressed as expected from
// `java.lang.Comparable.compare`
override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
a.compareTo(b)
// determines the initial size of the index data structure
// used internally (i.e. the expected number of different classifiers)
override protected def mapSize: Int = 128
def publish(event: BigBlueButtonEvent): Unit
def subscribe(actorRef: ActorRef, topic: String)
def unsubscribe(actorRef: ActorRef, topic: String)
}

View File

@ -0,0 +1,30 @@
package org.bigbluebutton.core.bus
import akka.actor.ActorRef
import akka.event.EventBus
import akka.event.LookupClassification
class IncomingEventBusImp extends EventBus with LookupClassification {
type Event = BigBlueButtonEvent
type Classifier = String
type Subscriber = ActorRef
// is used for extracting the classifier from the incoming events
override protected def classify(event: Event): Classifier = event.topic
// will be invoked for each event for all subscribers which registered themselves
// for the events classifier
override protected def publish(event: Event, subscriber: Subscriber): Unit = {
subscriber ! event.payload
}
// must define a full order over the subscribers, expressed as expected from
// `java.lang.Comparable.compare`
override protected def compareSubscribers(a: Subscriber, b: Subscriber): Int =
a.compareTo(b)
// determines the initial size of the index data structure
// used internally (i.e. the expected number of different classifiers)
override protected def mapSize: Int = 128
}

View File

@ -0,0 +1,11 @@
package org.bigbluebutton.core.domain
case class MeetingInactivityTracker(
maxInactivityTimeoutMinutes: Int,
warningMinutesBeforeMax: Int,
lastActivityTimeInMinutes: Long,
warningSent: Boolean,
warningSentOnTimeInMinutes: Long
)
case class MeetingExpiryTracker(startedOnInMinutes: Long, meetingJoined: Boolean, lastUserLeftOn: Long)

View File

@ -4,71 +4,80 @@ import com.softwaremill.quicklens._
import org.bigbluebutton.core.api.Permissions
case class MeetingProperties(
id: String,
extId: String,
name: String,
recorded: Boolean,
voiceConf: String,
duration: Int,
autoStartRecording: Boolean,
id: String,
extId: String,
name: String,
recorded: Boolean,
voiceConf: String,
duration: Int,
autoStartRecording: Boolean,
allowStartStopRecording: Boolean,
moderatorPass: String,
viewerPass: String,
createTime: Long,
createDate: String,
isBreakout: Boolean)
moderatorPass: String,
viewerPass: String,
createTime: Long,
createDate: String,
isBreakout: Boolean
)
case class MeetingProperties2x(
id: String,
extId: String,
name: String,
voiceConf: String,
duration: Int,
maxUsers: Int,
id: String,
extId: String,
name: String,
voiceConf: String,
duration: Int,
maxUsers: Int,
allowVoiceOnly: Boolean,
isBreakout: Boolean,
extensionProp: MeetingExtensionProp,
recordingProp: MeetingRecordingProp)
isBreakout: Boolean,
extensionProp: MeetingExtensionProp,
recordingProp: MeetingRecordingProp
)
case class MeetingRecordingProp(
recorded: Boolean = false,
autoStartRecording: Boolean = false,
allowStartStopRecording: Boolean = true)
recorded: Boolean = false,
autoStartRecording: Boolean = false,
allowStartStopRecording: Boolean = true
)
case class MeetingExtensionProp(
maxExtensions: Int = 0,
extendByMinutes: Int = 20,
sendNotice: Boolean = true)
maxExtensions: Int = 0,
extendByMinutes: Int = 20,
sendNotice: Boolean = true
)
case class MeetingRecordingStatus(
recording: Boolean = false,
voiceRecordingFilename: String = "")
recording: Boolean = false,
voiceRecordingFilename: String = ""
)
case class MeetingExtensionStatus(
numExtensions: Int = 0,
numExtensions: Int = 0,
sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false,
sent5MinNotice: Boolean = false)
sent5MinNotice: Boolean = false
)
case class Meeting3x(permissions: Permissions,
isRecording: Boolean = false,
muted: Boolean = false,
ended: Boolean = false,
hasLastWebUserLeft: Boolean = false,
lastWebUserLeftOnTimestamp: Long = 0L,
voiceRecordingFilename: String = "",
startedOn: Long = 0L,
pinNumbers: Set[String] = Set.empty,
lastGeneratedPin: Int = 0,
breakoutRoomsStartedOn: Long = 0L,
breakoutRoomsDurationInMinutes: Int = 120,
extensionStatus: MeetingExtensionStatus = new MeetingExtensionStatus,
recordingStatus: MeetingRecordingStatus = new MeetingRecordingStatus)
case class Meeting3x(
permissions: Permissions,
isRecording: Boolean = false,
muted: Boolean = false,
ended: Boolean = false,
hasLastWebUserLeft: Boolean = false,
lastWebUserLeftOnTimestamp: Long = 0L,
voiceRecordingFilename: String = "",
startedOn: Long = 0L,
pinNumbers: Set[String] = Set.empty,
lastGeneratedPin: Int = 0,
breakoutRoomsStartedOn: Long = 0L,
breakoutRoomsDurationInMinutes: Int = 120,
extensionStatus: MeetingExtensionStatus = new MeetingExtensionStatus,
recordingStatus: MeetingRecordingStatus = new MeetingRecordingStatus
)
object Meeting3x {
def isExtensionAllowed(
extension: MeetingExtensionProp,
status: MeetingExtensionStatus): Boolean = status.numExtensions < extension.maxExtensions
status: MeetingExtensionStatus
): Boolean = status.numExtensions < extension.maxExtensions
def incNumExtension(extension: MeetingExtensionProp, status: MeetingExtensionStatus): MeetingExtensionStatus = {
if (status.numExtensions < extension.maxExtensions) {

View File

@ -18,8 +18,10 @@ object Util {
header
}
def buildJson(header: java.util.HashMap[String, Any],
payload: java.util.HashMap[String, Any]): String = {
def buildJson(
header: java.util.HashMap[String, Any],
payload: java.util.HashMap[String, Any]
): String = {
val message = new java.util.HashMap[String, java.util.HashMap[String, Any]]()
message.put(Constants.HEADER, header)

View File

@ -10,7 +10,7 @@ object BreakoutRooms {
def breakoutRoomsdurationInMinutes(status: BreakoutRooms, duration: Int) = status.breakoutRoomsdurationInMinutes = duration
def newBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String], breakoutRooms: BreakoutRooms): Option[BreakoutRoomVO] = {
assignedUsers: Vector[String], breakoutRooms: BreakoutRooms): Option[BreakoutRoomVO] = {
val brvo = new BreakoutRoomVO(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector())
breakoutRooms.add(brvo)
Some(brvo)

View File

@ -1,6 +1,7 @@
package org.bigbluebutton.core.models
import org.bigbluebutton.common2.domain._
import org.bigbluebutton.common2.msgs.AnnotationVO
import org.bigbluebutton.core.apps.WhiteboardKeyUtil
import scala.collection.mutable.ArrayBuffer
@ -45,19 +46,18 @@ object Polls {
}
def handleShowPollResultReqMsg(requesterId: String, pollId: String, lm: LiveMeeting): Option[(SimplePollResultOutVO, AnnotationVO)] = {
def sendWhiteboardAnnotation(annotation: AnnotationVO): Unit = {
def updateWhiteboardAnnotation(annotation: AnnotationVO): AnnotationVO = {
lm.wbModel.updateAnnotation(annotation.wbId, annotation.userId, annotation)
annotation
}
def send(poll: SimplePollResultOutVO, shape: scala.collection.immutable.Map[String, Object]): Option[AnnotationVO] = {
for {
page <- lm.presModel.getCurrentPage()
pageId = if (poll.id.contains("deskshare")) "deskshare" else page.id
annotation = new AnnotationVO(poll.id, WhiteboardKeyUtil.DRAW_END_STATUS, WhiteboardKeyUtil.POLL_RESULT_TYPE, shape, pageId, requesterId, -1)
} yield {
sendWhiteboardAnnotation(annotation)
annotation
val pageId = if (poll.id.contains("deskshare")) "deskshare" else page.id
val updatedShape = shape + ("whiteboardId" -> pageId)
val annotation = new AnnotationVO(poll.id, WhiteboardKeyUtil.DRAW_END_STATUS, WhiteboardKeyUtil.POLL_RESULT_TYPE, updatedShape, pageId, requesterId, -1)
updateWhiteboardAnnotation(annotation)
}
}
@ -101,7 +101,7 @@ object Polls {
}
def handleRespondToPollReqMsg(requesterId: String, pollId: String, questionId: Int, answerId: Int,
lm: LiveMeeting): Option[(String, String, SimplePollResultOutVO)] = {
lm: LiveMeeting): Option[(String, String, SimplePollResultOutVO)] = {
for {
curPres <- Users2x.findPresenter(lm.users2x)
@ -114,7 +114,7 @@ object Polls {
}
def handleStartCustomPollReqMsg(requesterId: String, pollId: String, pollType: String,
answers: Seq[String], lm: LiveMeeting): Option[SimplePollOutVO] = {
answers: Seq[String], lm: LiveMeeting): Option[SimplePollOutVO] = {
def createPoll(pollId: String, numRespondents: Int): Option[Poll] = {
for {
@ -142,7 +142,7 @@ object Polls {
// Helper methods:
//
private def handleRespondToPoll(poll: SimplePollResultOutVO, requesterId: String, pollId: String, questionId: Int,
answerId: Int, lm: LiveMeeting): Option[SimplePollResultOutVO] = {
answerId: Int, lm: LiveMeeting): Option[SimplePollResultOutVO] = {
/*
* Hardcode to zero as we are assuming the poll has only one question.
* Our data model supports multiple question polls but for this

View File

@ -5,8 +5,8 @@ import com.softwaremill.quicklens._
object RegisteredUsers {
def create(userId: String, extId: String, name: String, roles: String,
token: String, avatar: String, guest: Boolean, authenticated: Boolean,
waitingForAcceptance: Boolean, users: RegisteredUsers): RegisteredUser = {
token: String, avatar: String, guest: Boolean, authenticated: Boolean,
waitingForAcceptance: Boolean, users: RegisteredUsers): RegisteredUser = {
val ru = new RegisteredUser(userId, extId, name, roles, token, avatar, guest, authenticated, waitingForAcceptance)
users.save(ru)
ru
@ -48,7 +48,7 @@ object RegisteredUsers {
}
def setWaitingForApproval(users: RegisteredUsers, user: RegisteredUser,
waitingForApproval: Boolean): RegisteredUser = {
waitingForApproval: Boolean): RegisteredUser = {
val u = user.modify(_.waitingForAcceptance).setTo(waitingForApproval)
users.save(u)
u
@ -74,6 +74,6 @@ class RegisteredUsers {
}
case class RegisteredUser(id: String, externId: String, name: String, role: String,
authToken: String, avatarURL: String, guest: Boolean,
authed: Boolean, waitingForAcceptance: Boolean)
authToken: String, avatarURL: String, guest: Boolean,
authed: Boolean, waitingForAcceptance: Boolean)

View File

@ -88,7 +88,7 @@ object Users2x {
def hasPresenter(users: Users2x): Boolean = {
findPresenter(users) match {
case Some(p) => true
case None => false
case None => false
}
}
@ -144,8 +144,8 @@ class Users2x {
}
case class UserState(intId: String, extId: String, name: String, role: String,
guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emoji: String, locked: Boolean,
presenter: Boolean, avatar: String)
guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emoji: String, locked: Boolean,
presenter: Boolean, avatar: String)
case class UserIdAndName(id: String, name: String)

View File

@ -5,17 +5,19 @@ case class Status(isPresenter: Boolean = false, emojiStatus: String = "none")
case class CallerId(num: String = "", name: String = "")
case class Voice(
hasJoined: Boolean = false,
id: String = "",
callerId: CallerId = CallerId(),
muted: Boolean = false,
talking: Boolean = false,
locked: Boolean = false)
hasJoined: Boolean = false,
id: String = "",
callerId: CallerId = CallerId(),
muted: Boolean = false,
talking: Boolean = false,
locked: Boolean = false
)
case class UserV(
id: String,
extId: String,
name: String,
role: String = Roles.VIEWER_ROLE,
id: String,
extId: String,
name: String,
role: String = Roles.VIEWER_ROLE,
status: Status = Status(),
voice: Voice = Voice())
voice: Voice = Voice()
)

View File

@ -118,8 +118,8 @@ class VoiceUsers {
case class VoiceUser2x(intId: String, voiceUserId: String)
case class VoiceUserVO2x(intId: String, voiceUserId: String, callerName: String,
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
talking: Boolean, callingWith: String, listenOnly: Boolean)
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
talking: Boolean, callingWith: String, listenOnly: Boolean)
case class VoiceUserState(intId: String, voiceUserId: String, callingWith: String, callerName: String,
callerNum: String, muted: Boolean, talking: Boolean, listenOnly: Boolean)
callerNum: String, muted: Boolean, talking: Boolean, listenOnly: Boolean)

View File

@ -56,30 +56,6 @@ object MeetingMessageToJsonConverter {
Util.buildJson(header, payload)
}
def voiceRecordingStartedToJson(msg: VoiceRecordingStarted): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.RECORDING_FILE, msg.recordingFile)
payload.put(Constants.VOICE_CONF, msg.confNum)
payload.put(Constants.TIMESTAMP, msg.timestamp)
val header = Util.buildHeader(MessageNames.VOICE_RECORDING_STARTED, None)
Util.buildJson(header, payload)
}
def voiceRecordingStoppedToJson(msg: VoiceRecordingStopped): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.RECORDING_FILE, msg.recordingFile)
payload.put(Constants.VOICE_CONF, msg.confNum)
payload.put(Constants.TIMESTAMP, msg.timestamp)
val header = Util.buildHeader(MessageNames.VOICE_RECORDING_STOPPED, None)
Util.buildJson(header, payload)
}
def recordingStatusChangedToJson(msg: RecordingStatusChanged): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
@ -111,26 +87,6 @@ object MeetingMessageToJsonConverter {
Util.buildJson(header, payload)
}
def startRecordingToJson(msg: StartRecording): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val header = Util.buildHeader(MessageNames.START_RECORDING, None)
Util.buildJson(header, payload)
}
def stopRecordingToJson(msg: StopRecording): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val header = Util.buildHeader(MessageNames.STOP_RECORDING, None)
Util.buildJson(header, payload)
}
def getAllMeetingsReplyToJson(msg: GetAllMeetingsReply): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetings", msg.meetings)
@ -139,80 +95,6 @@ object MeetingMessageToJsonConverter {
Util.buildJson(header, payload)
}
def breakoutRoomsListOutMessageToJson(msg: BreakoutRoomsListOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId)
payload.put("rooms", msg.rooms.toArray)
payload.put("roomsReady", msg.roomsReady)
val header = Util.buildHeader(BreakoutRoomsList.NAME, None)
Util.buildJson(header, payload)
}
def breakoutRoomStartedOutMessageToJson(msg: BreakoutRoomStartedOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.breakout.meetingId)
payload.put("externalMeetingId", msg.breakout.externalMeetingId)
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("sequence", msg.breakout.sequence)
payload.put("name", msg.breakout.name)
val header = Util.buildHeader(BreakoutRoomStarted.NAME, None)
Util.buildJson(header, payload)
}
def breakoutRoomEndedOutMessageToJson(msg: BreakoutRoomEndedOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("meetingId", msg.meetingId)
val header = Util.buildHeader(BreakoutRoomClosed.NAME, None)
Util.buildJson(header, payload)
}
def breakoutRoomJoinURLOutMessageToJson(msg: BreakoutRoomJoinURLOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("breakoutMeetingId", msg.breakoutMeetingId)
payload.put("userId", msg.userId)
payload.put("redirectJoinURL", msg.redirectJoinURL)
payload.put("noRedirectJoinURL", msg.noRedirectJoinURL)
val header = Util.buildHeader(BreakoutRoomJoinURL.NAME, None)
Util.buildJson(header, payload)
}
def updateBreakoutUsersOutMessageToJson(msg: UpdateBreakoutUsersOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("breakoutMeetingId", msg.breakoutMeetingId)
payload.put("recorded", msg.recorded)
payload.put("users", msg.users.toArray)
val header = Util.buildHeader(UpdateBreakoutUsers.NAME, None)
Util.buildJson(header, payload)
}
def meetingTimeRemainingUpdateToJson(msg: MeetingTimeRemainingUpdate): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId)
payload.put("recorded", msg.recorded)
payload.put("timeRemaining", msg.timeRemaining)
val header = Util.buildHeader(TimeRemainingUpdate.NAME, None)
Util.buildJson(header, payload)
}
def breakoutRoomsTimeRemainingUpdateToJson(msg: BreakoutRoomsTimeRemainingUpdateOutMessage): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId)
payload.put("recorded", msg.recorded)
payload.put("timeRemaining", msg.timeRemaining)
val header = Util.buildHeader(BreakoutRoomsTimeRemainingUpdate.NAME, None)
Util.buildJson(header, payload)
}
def inactivityWarningToJson(msg: InactivityWarning): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)

View File

@ -1,275 +0,0 @@
package org.bigbluebutton.core.pubsub.senders
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.messaging.Util
import org.bigbluebutton.core.apps.Page
import scala.collection.JavaConverters
object PesentationMessageToJsonConverter {
/*
private def pageToMap(page: Page): java.util.Map[String, Any] = {
val res = new scala.collection.mutable.Map[String, Any]
res += "id" -> page.id
res += "num" -> page.num
res += "thumb_uri" -> page.thumbUri
res += "swf_uri" -> page.swfUri
res += "txt_uri" -> page.txtUri
res += "svg_uri" -> page.svgUri
res += "current" -> page.current
res += "x_offset" -> page.xOffset
res += "y_offset" -> page.yOffset
res += "width_ratio" -> page.widthRatio
res += "height_ratio" -> page.heightRatio
JavaConverters.mapAsScalaMap(res)
}
*/
def clearPresentationOutMsgToJson(msg: ClearPresentationOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
val header = Util.buildHeader(MessageNames.PRESENTATION_CLEARED, None)
Util.buildJson(header, payload)
}
def removePresentationOutMsgToJson(msg: RemovePresentationOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.PRESENTATION_ID, msg.presentationID)
val header = Util.buildHeader(MessageNames.PRESENTATION_REMOVED, None)
Util.buildJson(header, payload)
}
def getPresentationInfoOutMsgToJson(msg: GetPresentationInfoOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.PRESENTATION_INFO, msg.info)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val info = msg.info
// Create a map for our current presenter
val presenter = new java.util.HashMap[String, String]()
presenter.put(Constants.USER_ID, info.presenter.userId)
presenter.put(Constants.NAME, info.presenter.name)
presenter.put(Constants.ASSIGNED_BY, info.presenter.assignedBy)
payload.put(Constants.PRESENTER, presenter)
// Create an array for our presentations
val presentations = new java.util.ArrayList[java.util.HashMap[String, Object]]
info.presentations.foreach { pres =>
val presentation = new java.util.HashMap[String, Object]()
presentation.put(Constants.ID, pres.id)
presentation.put(Constants.NAME, pres.name)
presentation.put(Constants.CURRENT, pres.current: java.lang.Boolean)
presentation.put(Constants.DOWNLOADABLE, pres.downloadable: java.lang.Boolean)
// Get the pages for a presentation
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
// pres.pages.values foreach { p =>
// pages.add(p)
// }
// store the pages in the presentation
presentation.put(Constants.PAGES, pages)
// add this presentation into our presentations list
presentations.add(presentation);
}
// add the presentation to our map to complete our json
payload.put(Constants.PRESENTATIONS, presentations)
val header = Util.buildHeader(MessageNames.GET_PRESENTATION_INFO_REPLY, Some(msg.replyTo))
Util.buildJson(header, payload)
}
def resizeAndMoveSlideOutMsgToJson(msg: ResizeAndMoveSlideOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_RESIZED, None)
Util.buildJson(header, payload)
}
def gotoSlideOutMsgToJson(msg: GotoSlideOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_CHANGED, None)
Util.buildJson(header, payload)
}
def sharePresentationOutMsgToJson(msg: SharePresentationOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
val presentation = new java.util.HashMap[String, Object]();
presentation.put(Constants.ID, msg.presentation.id)
presentation.put(Constants.NAME, msg.presentation.name)
presentation.put(Constants.CURRENT, msg.presentation.current: java.lang.Boolean)
presentation.put(Constants.DOWNLOADABLE, msg.presentation.downloadable: java.lang.Boolean)
// Get the pages for a presentation
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
// msg.presentation.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
// store the pages in the presentation
presentation.put(Constants.PAGES, pages)
payload.put(Constants.PRESENTATION, presentation);
val header = Util.buildHeader(MessageNames.PRESENTATION_SHARED, None)
Util.buildJson(header, payload)
}
def getSlideInfoOutMsgToJson(msg: GetSlideInfoOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.GET_SLIDE_INFO_REPLY, None)
Util.buildJson(header, payload)
}
def getPreuploadedPresentationsOutMsgToJson(msg: GetPreuploadedPresentationsOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
val header = Util.buildHeader(MessageNames.GET_PREUPLOADED_PRESENTATIONS, None)
Util.buildJson(header, payload)
}
def presentationConversionProgressToJson(msg: PresentationConversionProgress): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.MESSAGE_KEY, msg.messageKey)
payload.put(Constants.CODE, msg.code)
payload.put(Constants.PRESENTATION_ID, msg.presentationId)
payload.put(Constants.PRESENTATION_NAME, msg.presentationName)
val header = Util.buildHeader(MessageNames.PRESENTATION_CONVERSION_PROGRESS, None)
Util.buildJson(header, payload)
}
def presentationConversionErrorToJson(msg: PresentationConversionError): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.MESSAGE_KEY, msg.messageKey)
payload.put(Constants.CODE, msg.code)
payload.put(Constants.PRESENTATION_ID, msg.presentationId)
payload.put(Constants.PRESENTATION_NAME, msg.presentationName)
payload.put(Constants.NUM_PAGES, msg.numberOfPages)
payload.put(Constants.MAX_NUM_PAGES, msg.maxNumberPages)
val header = Util.buildHeader(MessageNames.PRESENTATION_CONVERSION_ERROR, None)
Util.buildJson(header, payload)
}
def presentationPageGenerated(msg: PresentationPageGenerated): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.MESSAGE_KEY, msg.messageKey)
payload.put(Constants.CODE, msg.code)
payload.put(Constants.PRESENTATION_ID, msg.presentationId)
payload.put(Constants.PRESENTATION_NAME, msg.presentationName)
payload.put(Constants.NUM_PAGES, msg.numberOfPages)
payload.put(Constants.PAGES_COMPLETED, msg.pagesCompleted)
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_GENERATED, None)
Util.buildJson(header, payload)
}
def presentationConversionDoneToJson(msg: PresentationConversionDone): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.MESSAGE_KEY, msg.messageKey)
payload.put(Constants.CODE, msg.code)
val presentation = new java.util.HashMap[String, Object]();
presentation.put(Constants.ID, msg.presentation.id)
presentation.put(Constants.NAME, msg.presentation.name)
presentation.put(Constants.CURRENT, msg.presentation.current: java.lang.Boolean)
presentation.put(Constants.DOWNLOADABLE, msg.presentation.downloadable: java.lang.Boolean)
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
// msg.presentation.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
presentation.put(Constants.PAGES, pages)
payload.put(Constants.PRESENTATION, presentation);
val header = Util.buildHeader(MessageNames.PRESENTATION_CONVERSION_DONE, None)
Util.buildJson(header, payload)
}
def presentationChangedToJson(msg: PresentationChanged): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
val presentation = new java.util.HashMap[String, Object]();
presentation.put(Constants.ID, msg.presentation.id)
presentation.put(Constants.NAME, msg.presentation.name)
presentation.put(Constants.CURRENT, msg.presentation.current: java.lang.Boolean)
presentation.put(Constants.DOWNLOADABLE, msg.presentation.downloadable: java.lang.Boolean)
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
// msg.presentation.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
presentation.put(Constants.PAGES, pages)
payload.put(Constants.PRESENTATION, presentation);
val header = Util.buildHeader(MessageNames.PRESENTATION_CHANGED, None)
Util.buildJson(header, payload)
}
def getPresentationStatusReplyToJson(msg: GetPresentationStatusReply): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
val presentation = new java.util.HashMap[String, Object]();
presentation.put(Constants.ID, msg.current.id)
presentation.put(Constants.NAME, msg.current.name)
presentation.put(Constants.CURRENT, msg.current.current: java.lang.Boolean)
presentation.put(Constants.DOWNLOADABLE, msg.current.downloadable: java.lang.Boolean)
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
// msg.current.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
presentation.put(Constants.PAGES, pages)
payload.put(Constants.PRESENTATION, presentation);
val header = Util.buildHeader(MessageNames.GET_PRESENTATION_STATUS_REPLY, Some(msg.replyTo))
Util.buildJson(header, payload)
}
def presentationRemovedToJson(msg: PresentationRemoved): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.PRESENTATION_ID, msg.presentationId)
val header = Util.buildHeader(MessageNames.PRESENTATION_REMOVED, None)
Util.buildJson(header, payload)
}
def pageChangedToJson(msg: PageChanged): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_CHANGED, None)
Util.buildJson(header, payload)
}
}

View File

@ -14,8 +14,9 @@ object ReceivedJsonMsgHandlerActor {
}
class ReceivedJsonMsgHandlerActor(
val eventBus: BbbMsgRouterEventBus,
val incomingJsonMessageBus: IncomingJsonMessageBus)
val eventBus: BbbMsgRouterEventBus,
val incomingJsonMessageBus: IncomingJsonMessageBus
)
extends Actor with ActorLogging
with SystemConfiguration
with ReceivedJsonMsgDeserializer
@ -70,6 +71,9 @@ class ReceivedJsonMsgHandlerActor(
case DestroyMeetingSysCmdMsg.NAME =>
route[DestroyMeetingSysCmdMsg](meetingManagerChannel, envelope, jsonNode)
// Users
case GetUsersMeetingReqMsg.NAME =>
routeGenericMsg[GetUsersMeetingReqMsg](envelope, jsonNode)
// Poll
case StartCustomPollReqMsg.NAME =>
routeGenericMsg[StartCustomPollReqMsg](envelope, jsonNode)

View File

@ -237,22 +237,6 @@ object UsersMessageToJsonConverter {
Util.buildJson(header, payload)
}
def broadcastLayout(msg: BroadcastLayoutEvent): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val users = new java.util.ArrayList[String];
msg.applyTo.foreach(uvo => {
users.add(uvo.id)
})
payload.put(Constants.USERS, users)
val header = Util.buildHeader(MessageNames.GET_USERS_REPLY, None)
Util.buildJson(header, payload)
}
def getUsersReplyToJson(msg: GetUsersReply): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
@ -269,87 +253,6 @@ object UsersMessageToJsonConverter {
Util.buildJson(header, payload)
}
def userJoinedVoice(msg: UserJoinedVoice): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.USER, userToMap(msg.user))
payload.put(Constants.VOICE_CONF, msg.confNum)
val header = Util.buildHeader(MessageNames.USER_JOINED_VOICE, None)
Util.buildJson(header, payload)
}
def userVoiceMuted(msg: UserVoiceMuted): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.USER, userToMap(msg.user))
payload.put(Constants.VOICE_CONF, msg.confNum)
val header = Util.buildHeader(MessageNames.USER_VOICE_MUTED, None)
Util.buildJson(header, payload)
}
def userVoiceTalking(msg: UserVoiceTalking): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.USER, userToMap(msg.user))
payload.put(Constants.VOICE_CONF, msg.confNum)
val header = Util.buildHeader(MessageNames.USER_VOICE_TALKING, None)
Util.buildJson(header, payload)
}
def muteVoiceUserToJson(msg: MuteVoiceUser): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.MUTE, msg.mute)
payload.put(Constants.USER_ID, msg.userId)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.VOICE_CONF_ID, msg.voiceConfId)
payload.put(Constants.VOICE_USER_ID, msg.voiceUserId)
val header = Util.buildHeader(MessageNames.EJECT_VOICE_USER, None)
Util.buildJson(header, payload)
}
def ejectVoiceUserToJson(msg: EjectVoiceUser): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.USER_ID, msg.userId)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.VOICE_CONF_ID, msg.voiceConfId)
payload.put(Constants.VOICE_USER_ID, msg.voiceUserId)
val header = Util.buildHeader(MessageNames.EJECT_VOICE_USER, None)
Util.buildJson(header, payload)
}
def userLeftVoiceToJson(msg: UserLeftVoice): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.USER, userToMap(msg.user))
payload.put(Constants.VOICE_CONF, msg.confNum)
val header = Util.buildHeader(MessageNames.USER_LEFT_VOICE, None)
Util.buildJson(header, payload)
}
def isMeetingMutedReplyToJson(msg: IsMeetingMutedReply): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.MUTED, msg.meetingMuted)
val header = Util.buildHeader(MessageNames.IS_MEETING_MUTED_REPLY, None)
Util.buildJson(header, payload)
}
def recordingStatusChangedToJson(msg: RecordingStatusChanged): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
@ -435,16 +338,6 @@ object UsersMessageToJsonConverter {
Util.buildJson(header, payload)
}
def userListeningOnlyToJson(msg: UserListeningOnly): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.userID)
payload.put(Constants.LISTEN_ONLY, msg.listenOnly)
val header = Util.buildHeader(MessageNames.USER_LISTEN_ONLY, None)
Util.buildJson(header, payload)
}
def getGuestPolicyToJson(msg: GetGuestPolicy): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)

View File

@ -0,0 +1,39 @@
package org.bigbluebutton.core.running
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
//import org.bigbluebutton.core.api.BreakoutRoomCreated
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, IncomingEventBus }
trait AuditHelpers {
def getUsersInVoiceConf(
props: DefaultProps,
outGW: OutMessageGateway
): Unit = {
def buildGetUsersInVoiceConfSysMsg(meetingId: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(GetUsersInVoiceConfSysMsg.NAME, routing)
val body = GetUsersInVoiceConfSysMsgBody(props.voiceProp.voiceConf)
val header = BbbCoreHeaderWithMeetingId(GetUsersInVoiceConfSysMsg.NAME, meetingId)
val event = GetUsersInVoiceConfSysMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val event = buildGetUsersInVoiceConfSysMsg(props.meetingProp.intId)
outGW.send(event)
}
def sendBreakoutRoomCreatedToParent(
props: DefaultProps,
eventBus: IncomingEventBus
): Unit = {
// eventBus.publish(BigBlueButtonEvent(
// props.breakoutProps.parentId,
// BreakoutRoomCreated(props.breakoutProps.parentId, props.meetingProp.intId)
// ))
}
}

View File

@ -8,26 +8,29 @@ import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender, UserJoinedMeetingEvtMsgBuilder }
trait HandlerHelpers {
this: BaseMeetingActor =>
def validateTokenFailed(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String,
valid: Boolean, waitForApproval: Boolean): Unit = {
val event = MsgBuilder.buildValidateAuthTokenRespMsg(meetingId,
userId, authToken, valid, waitForApproval)
valid: Boolean, waitForApproval: Boolean): Unit = {
val event = MsgBuilder.buildValidateAuthTokenRespMsg(
meetingId,
userId, authToken, valid, waitForApproval
)
Sender.send(outGW, event)
// TODO: Should disconnect user here.
}
def sendValidateAuthTokenRespMsg(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String,
valid: Boolean, waitForApproval: Boolean): Unit = {
val event = MsgBuilder.buildValidateAuthTokenRespMsg(meetingId,
userId, authToken, valid, waitForApproval)
valid: Boolean, waitForApproval: Boolean): Unit = {
val event = MsgBuilder.buildValidateAuthTokenRespMsg(
meetingId,
userId, authToken, valid, waitForApproval
)
Sender.send(outGW, event)
}
def userValidatedButNeedToWaitForApproval(outGW: OutMessageGateway, liveMeeting: LiveMeeting,
user: RegisteredUser): Unit = {
user: RegisteredUser): Unit = {
val meetingId = liveMeeting.props.meetingProp.intId
sendValidateAuthTokenRespMsg(outGW, meetingId, user.id, user.authToken, valid = true, waitForApproval = false)
@ -40,8 +43,14 @@ trait HandlerHelpers {
GuestsWaiting.add(guestsWaitingList, guest)
}
def userValidatedAndNoNeedToWaitForApproval(outGW: OutMessageGateway, liveMeeting: LiveMeeting,
user: RegisteredUser): Unit = {
def userValidatedAndNoNeedToWaitForApproval(
outGW: OutMessageGateway,
liveMeeting: LiveMeeting,
user: RegisteredUser
): Unit = {
println("**************** userValidatedAndNoNeedToWaitForApproval")
val meetingId = liveMeeting.props.meetingProp.intId
sendValidateAuthTokenRespMsg(outGW, meetingId,
userId = user.id, authToken = user.authToken, valid = true, waitForApproval = false)
@ -92,8 +101,8 @@ trait HandlerHelpers {
}
def sendAllVoiceUsersInMeeting(outGW: OutMessageGateway, requesterId: String,
voiceUsers: VoiceUsers,
meetingId: String): Unit = {
voiceUsers: VoiceUsers,
meetingId: String): Unit = {
val vu = VoiceUsers.findAll(voiceUsers).map { u =>
VoiceConfUser(intId = u.intId, voiceUserId = u.voiceUserId, callingWith = u.callingWith, callerName = u.callerName,
@ -108,7 +117,8 @@ trait HandlerHelpers {
for {
regUser <- RegisteredUsers.findWithToken(authToken, liveMeeting.registeredUsers)
} yield {
val userState = UserState(intId = regUser.id,
val userState = UserState(
intId = regUser.id,
extId = regUser.externId,
name = regUser.name,
role = regUser.role,
@ -118,7 +128,8 @@ trait HandlerHelpers {
emoji = "none",
presenter = false,
locked = false,
avatar = regUser.avatarURL)
avatar = regUser.avatarURL
)
Users2x.add(liveMeeting.users2x, userState)

View File

@ -9,24 +9,25 @@ import org.bigbluebutton.core.domain.Meeting3x
import org.bigbluebutton.core.models._
import org.bigbluebutton.core2.MeetingStatus2x
class LiveMeeting(val props: DefaultProps,
val status: MeetingStatus2x,
class LiveMeeting(
val props: DefaultProps,
val status: MeetingStatus2x,
val screenshareModel: ScreenshareModel,
val chatModel: ChatModel,
val layoutModel: LayoutModel,
val layouts: Layouts,
val registeredUsers: RegisteredUsers,
val polls: Polls, // 2x
val pollModel: PollModel, // 1.1x
val wbModel: WhiteboardModel,
val presModel: PresentationModel,
val breakoutRooms: BreakoutRooms,
val captionModel: CaptionModel,
val notesModel: SharedNotesModel,
val webcams: Webcams,
val voiceUsers: VoiceUsers,
val users2x: Users2x,
val guestsWaiting: GuestsWaiting) {
val chatModel: ChatModel,
val layoutModel: LayoutModel,
val layouts: Layouts,
val registeredUsers: RegisteredUsers,
val polls: Polls, // 2x
val wbModel: WhiteboardModel,
val presModel: PresentationModel,
val breakoutRooms: BreakoutRooms,
val captionModel: CaptionModel,
val notesModel: SharedNotesModel,
val webcams: Webcams,
val voiceUsers: VoiceUsers,
val users2x: Users2x,
val guestsWaiting: GuestsWaiting
) {
def hasMeetingEnded(): Boolean = {
MeetingStatus2x.hasMeetingEnded(status)

View File

@ -1,6 +1,10 @@
package org.bigbluebutton.core.running
import java.io.{ PrintWriter, StringWriter }
import org.bigbluebutton.core.apps.users.UsersApp
import org.bigbluebutton.core.domain.{ MeetingExpiryTracker, MeetingInactivityTracker }
import org.bigbluebutton.core.util.TimeUtil
//import java.util.concurrent.TimeUnit
import akka.actor._
@ -16,6 +20,7 @@ import org.bigbluebutton.core.apps.presentation.PresentationApp2x
import org.bigbluebutton.core.apps.meeting._
import org.bigbluebutton.core.apps.users.UsersApp2x
import org.bigbluebutton.core.apps.sharednotes.SharedNotesApp2x
import org.bigbluebutton.core.apps.whiteboard.WhiteboardApp2x
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.models._
import org.bigbluebutton.core2.MeetingStatus2x
@ -33,16 +38,21 @@ import org.bigbluebutton.core.apps.layout.LayoutApp2x
import org.bigbluebutton.core.apps.meeting.SyncGetMeetingInfoRespMsgHdlr
object MeetingActor {
def props(props: DefaultProps,
eventBus: IncomingEventBus,
outGW: OutMessageGateway, liveMeeting: LiveMeeting): Props =
def props(
props: DefaultProps,
eventBus: IncomingEventBus,
outGW: OutMessageGateway,
liveMeeting: LiveMeeting
): Props =
Props(classOf[MeetingActor], props, eventBus, outGW, liveMeeting)
}
class MeetingActor(val props: DefaultProps,
val eventBus: IncomingEventBus,
val outGW: OutMessageGateway,
val liveMeeting: LiveMeeting)
class MeetingActor(
val props: DefaultProps,
val eventBus: IncomingEventBus,
val outGW: OutMessageGateway,
val liveMeeting: LiveMeeting
)
extends BaseMeetingActor
with GuestsApp
with LayoutApp2x
@ -50,9 +60,8 @@ class MeetingActor(val props: DefaultProps,
with PollApp2x
with BreakoutApp2x
with UsersApp2x
with WhiteboardApp2x
with PresentationApp
with WhiteboardApp
with PermisssionCheck
with UserBroadcastCamStartMsgHdlr
with UserJoinMeetingReqMsgHdlr
@ -83,19 +92,28 @@ class MeetingActor(val props: DefaultProps,
* Put the internal message injector into another actor so this
* actor is easy to test.
*/
var actorMonitor = context.actorOf(MeetingActorInternal.props(props, eventBus, outGW),
"actorMonitor-" + props.meetingProp.intId)
var actorMonitor = context.actorOf(
MeetingActorAudit.props(props, eventBus, outGW),
"actorMonitor-" + props.meetingProp.intId
)
/** Subscribe to meeting and voice events. **/
eventBus.subscribe(actorMonitor, props.meetingProp.intId)
eventBus.subscribe(actorMonitor, props.voiceProp.voiceConf)
eventBus.subscribe(actorMonitor, props.screenshareProps.screenshareConf)
val presentationApp2x = new PresentationApp2x(liveMeeting, outGW)
val screenshareApp2x = new ScreenshareApp2x(liveMeeting, outGW)
val captionApp2x = new CaptionApp2x(liveMeeting, outGW)
val sharedNotesApp2x = new SharedNotesApp2x(liveMeeting, outGW)
val chatApp2x = new ChatApp2x(liveMeeting, outGW)
val usersApp = new UsersApp(liveMeeting, outGW)
val presentationApp2x = new PresentationApp2x(liveMeeting, outGW = outGW)
val screenshareApp2x = new ScreenshareApp2x(liveMeeting, outGW = outGW)
val captionApp2x = new CaptionApp2x(liveMeeting, outGW = outGW)
val sharedNotesApp2x = new SharedNotesApp2x(liveMeeting, outGW = outGW)
val chatApp2x = new ChatApp2x(liveMeeting, outGW = outGW)
var inactivityTracker = new MeetingInactivityTracker(
liveMeeting.props.durationProps.maxInactivityTimeoutMinutes,
liveMeeting.props.durationProps.warnMinutesBeforeMax,
TimeUtil.millisToMinutes(System.currentTimeMillis()), false, 0L
)
var expiryTracker = new MeetingExpiryTracker(
TimeUtil.millisToMinutes(System.currentTimeMillis()),
false, 0L
)
/*******************************************************************/
//object FakeTestData extends FakeTestData
@ -105,53 +123,55 @@ class MeetingActor(val props: DefaultProps,
def receive = {
//=============================
// 2x messages
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
// Handling RegisterUserReqMsg as it is forwarded from BBBActor and
// its type is not BbbCommonEnvCoreMsg
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: RegisterUserReqMsg => usersApp.handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
// Meeting
case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m)
case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m)
//======================================
//=======================================
// old messages
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
case msg: AllowUserToShareDesktop => handleAllowUserToShareDesktop(msg)
case msg: InitializeMeeting => handleInitializeMeeting(msg)
case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg)
case msg: SendTimeRemainingUpdate => handleSendTimeRemainingUpdate(msg)
case msg: AllowUserToShareDesktop => handleAllowUserToShareDesktop(msg)
case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg)
case msg: SendTimeRemainingUpdate => handleSendTimeRemainingUpdate(msg)
// Screenshare
case msg: DeskShareGetDeskShareInfoRequest => handleDeskShareGetDeskShareInfoRequest(msg)
// Guest
case msg: GetGuestPolicy => handleGetGuestPolicy(msg)
case msg: SetGuestPolicy => handleSetGuestPolicy(msg)
case msg: GetGuestPolicy => handleGetGuestPolicy(msg)
case msg: SetGuestPolicy => handleSetGuestPolicy(msg)
case _ => // do nothing
case _ => // do nothing
}
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
// TODO: Update meeting activity status here
// updateActivityStatus(msg)
msg.core match {
// Users
case m: ValidateAuthTokenReqMsg => handleValidateAuthTokenReqMsg(m)
case m: ValidateAuthTokenReqMsg => usersApp.handleValidateAuthTokenReqMsg(m)
case m: UserJoinMeetingReqMsg => handleUserJoinMeetingReqMsg(m)
case m: UserLeaveReqMsg => handleUserLeaveReqMsg(m)
case m: UserBroadcastCamStartMsg => handleUserBroadcastCamStartMsg(m)
case m: UserBroadcastCamStopMsg => handleUserBroadcastCamStopMsg(m)
case m: UserJoinedVoiceConfEvtMsg => handleUserJoinedVoiceConfEvtMsg(m)
case m: MeetingActivityResponseCmdMsg => handleMeetingActivityResponseCmdMsg(m)
case m: LogoutAndEndMeetingCmdMsg => handleLogoutAndEndMeetingCmdMsg(m)
case m: SetRecordingStatusCmdMsg => handleSetRecordingStatusCmdMsg(m)
case m: GetRecordingStatusReqMsg => handleGetRecordingStatusReqMsg(m)
case m: MeetingActivityResponseCmdMsg => inactivityTracker = usersApp.handleMeetingActivityResponseCmdMsg(m, inactivityTracker)
case m: LogoutAndEndMeetingCmdMsg => usersApp.handleLogoutAndEndMeetingCmdMsg(m)
case m: SetRecordingStatusCmdMsg => usersApp.handleSetRecordingStatusCmdMsg(m)
case m: GetRecordingStatusReqMsg => usersApp.handleGetRecordingStatusReqMsg(m)
case m: ChangeUserEmojiCmdMsg => handleChangeUserEmojiCmdMsg(m)
case m: EjectUserFromMeetingCmdMsg => handleEjectUserFromMeetingCmdMsg(m)
case m: EjectUserFromMeetingCmdMsg => usersApp.handleEjectUserFromMeetingCmdMsg(m)
case m: GetUsersMeetingReqMsg => usersApp.handleGetUsersMeetingReqMsg(m)
// Whiteboard
case m: SendCursorPositionPubMsg => handleSendCursorPositionPubMsg(m)
@ -251,7 +271,7 @@ class MeetingActor(val props: DefaultProps,
handleSyncGetMeetingInfoRespMsg(liveMeeting.props)
// sync all users
handleSyncGetUsersMeetingRespMsg()
usersApp.handleSyncGetUsersMeetingRespMsg()
// sync all presentations
presentationApp2x.handleSyncGetPresentationInfoRespMsg()
@ -266,7 +286,7 @@ class MeetingActor(val props: DefaultProps,
handleStopPollReqMsg(msg.header.userId)
// switch user presenter status for old and new presenter
handleAssignPresenterReqMsg(msg)
usersApp.handleAssignPresenterReqMsg(msg)
// TODO stop current screen sharing session (initiated by the old presenter)
@ -310,6 +330,15 @@ class MeetingActor(val props: DefaultProps,
}
def handleMonitorNumberOfUsers(msg: MonitorNumberOfUsers) {
inactivityTracker = MeetingInactivityTrackerHelper.processMeetingInactivityAudit(
props = liveMeeting.props,
outGW,
eventBus,
inactivityTracker
)
expiryTracker = MeetingExpiryTracker.processMeetingExpiryAudit(liveMeeting.props, expiryTracker, eventBus)
monitorNumberOfWebUsers()
monitorNumberOfUsers()
}
@ -362,8 +391,10 @@ class MeetingActor(val props: DefaultProps,
BbbCommonEnvCoreMsg(envelope, event)
}
val event = buildRecordingStatusChangedEvtMsg(liveMeeting.props.meetingProp.intId,
"system", MeetingStatus2x.isRecording(liveMeeting.status))
val event = buildRecordingStatusChangedEvtMsg(
liveMeeting.props.meetingProp.intId,
"system", MeetingStatus2x.isRecording(liveMeeting.status)
)
outGW.send(event)
}
@ -385,8 +416,10 @@ class MeetingActor(val props: DefaultProps,
BbbCommonEnvCoreMsg(envelope, event)
}
val event = buildRecordingStatusChangedEvtMsg(liveMeeting.props.meetingProp.intId,
"system", MeetingStatus2x.isRecording(liveMeeting.status))
val event = buildRecordingStatusChangedEvtMsg(
liveMeeting.props.meetingProp.intId,
"system", MeetingStatus2x.isRecording(liveMeeting.status)
)
outGW.send(event)
}

View File

@ -0,0 +1,89 @@
package org.bigbluebutton.core.running
import java.io.{ PrintWriter, StringWriter }
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import scala.concurrent.duration._
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, IncomingEventBus }
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.{ Deadline, FiniteDuration }
object MeetingActorAudit {
def props(
props: DefaultProps,
eventBus: IncomingEventBus,
outGW: OutMessageGateway
): Props =
Props(classOf[MeetingActorAudit], props, eventBus, outGW)
}
// This actor is an internal audit actor for each meeting actor that
// periodically sends messages to the meeting actor
class MeetingActorAudit(
val props: DefaultProps,
val eventBus: IncomingEventBus, val outGW: OutMessageGateway
)
extends Actor with ActorLogging with SystemConfiguration with AuditHelpers {
object AuditMonitorInternalMsg
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
val sw: StringWriter = new StringWriter()
sw.write("An exception has been thrown on MeetingActorInternal, exception message [" + e.getMessage() + "] (full stacktrace below)\n")
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString())
Resume
}
}
private val MonitorFrequency = 10 seconds
context.system.scheduler.schedule(5 seconds, MonitorFrequency, self, AuditMonitorInternalMsg)
// Query to get voice conference users
getUsersInVoiceConf(props, outGW)
if (props.meetingProp.isBreakout) {
// This is a breakout room. Inform our parent meeting that we have been successfully created.
/**TODO Need to add a 2.0 notification somehow */
log.error("****** MeetingActorInternal still needs to be fixed with 2.0 breakout messages ******")
/*eventBus.publish(BigBlueButtonEvent(
props.breakoutProps.parentId,
BreakoutRoomCreated(props.breakoutProps.parentId, props.meetingProp.intId)))
*/
}
def receive = {
case AuditMonitorInternalMsg => handleMonitor()
}
def handleMonitor() {
handleMonitorNumberOfWebUsers()
}
def handleMonitorNumberOfWebUsers() {
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, MonitorNumberOfUsers(props.meetingProp.intId)))
// Trigger updating users of time remaining on meeting.
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingUpdate(props.meetingProp.intId)))
if (props.meetingProp.isBreakout) {
/**TODO Need to add a 2.0 notification somehow */
log.error("******* MeetingActorInternal still needs to be fixed with 2.0 breakout messages *******")
// This is a breakout room. Update the main meeting with list of users in this breakout room.
//eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendBreakoutUsersUpdate(props.meetingProp.intId)))
}
}
}

View File

@ -1,314 +0,0 @@
package org.bigbluebutton.core.running
import java.io.{ PrintWriter, StringWriter }
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import scala.concurrent.duration._
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, IncomingEventBus }
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.{ Deadline, FiniteDuration }
object MeetingActorInternal {
def props(props: DefaultProps,
eventBus: IncomingEventBus,
outGW: OutMessageGateway): Props =
Props(classOf[MeetingActorInternal], props, eventBus, outGW)
}
// This actor is an internal audit actor for each meeting actor that
// periodically sends messages to the meeting actor
class MeetingActorInternal(val props: DefaultProps,
val eventBus: IncomingEventBus, val outGW: OutMessageGateway)
extends Actor with ActorLogging with SystemConfiguration {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
val sw: StringWriter = new StringWriter()
sw.write("An exception has been thrown on MeetingActorInternal, exception message [" + e.getMessage() + "] (full stacktrace below)\n")
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString())
Resume
}
}
private def getInactivityDeadline(): Int = {
val time = getMetadata(Metadata.INACTIVITY_DEADLINE, props.metadataProp.metadata) match {
case Some(result) => result.asInstanceOf[Int]
case None => inactivityDeadline
}
log.debug("InactivityDeadline: {} seconds", time)
time
}
private def getInactivityTimeLeft(): Int = {
val time = getMetadata(Metadata.INACTIVITY_TIMELEFT, props.metadataProp.metadata) match {
case Some(result) => result.asInstanceOf[Int]
case None => inactivityTimeLeft
}
log.debug("InactivityTimeLeft: {} seconds", time)
time
}
private def getExpireNeverJoined(): Int = {
val time = expireNeverJoined
log.debug("ExpireNeverJoined: {} seconds", time)
time
}
private def getExpireLastUserLeft(): Int = {
val time = expireLastUserLeft
log.debug("ExpireLastUserLeft: {} seconds", time)
time
}
private val MonitorFrequency = 10 seconds
private val InactivityDeadline = FiniteDuration(getInactivityDeadline(), "seconds")
private val InactivityTimeLeft = FiniteDuration(getInactivityTimeLeft(), "seconds")
private var inactivity = InactivityDeadline.fromNow
private var inactivityWarning: Option[Deadline] = None
private val ExpireMeetingDuration = FiniteDuration(props.durationProps.duration, "minutes")
private val ExpireMeetingNeverJoined = FiniteDuration(getExpireNeverJoined(), "seconds")
private val ExpireMeetingLastUserLeft = FiniteDuration(getExpireLastUserLeft(), "seconds")
private var meetingExpire: Option[Deadline] = Some(ExpireMeetingNeverJoined.fromNow)
// Zero minutes means the meeting has no duration control
private var meetingDuration: Option[Deadline] = if (ExpireMeetingDuration > (0 minutes)) Some(ExpireMeetingDuration.fromNow) else None
context.system.scheduler.schedule(5 seconds, MonitorFrequency, self, "Monitor")
// Query to get voice conference users
def build(meetingId: String): BbbCommonEnvCoreMsg = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(GetUsersInVoiceConfSysMsg.NAME, routing)
val body = GetUsersInVoiceConfSysMsgBody(props.voiceProp.voiceConf)
val header = BbbCoreHeaderWithMeetingId(GetUsersInVoiceConfSysMsg.NAME, meetingId)
val event = GetUsersInVoiceConfSysMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val event = build(props.meetingProp.intId)
outGW.send(event)
if (props.meetingProp.isBreakout) {
// This is a breakout room. Inform our parent meeting that we have been successfully created.
eventBus.publish(BigBlueButtonEvent(
props.breakoutProps.parentId,
BreakoutRoomCreated(props.breakoutProps.parentId, props.meetingProp.intId)))
}
def receive = {
case "Monitor" => handleMonitor()
case msg: UpdateMeetingExpireMonitor => handleUpdateMeetingExpireMonitor(msg)
case msg: Object => handleMessage(msg)
}
def handleMonitor() {
// handleMonitorActivity()
handleMonitorNumberOfWebUsers()
// handleMonitorExpiration()
}
def handleMessage(msg: Object) {
if (isMeetingActivity(msg)) {
notifyActivity()
}
}
def handleMonitorNumberOfWebUsers() {
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, MonitorNumberOfUsers(props.meetingProp.intId)))
// Trigger updating users of time remaining on meeting.
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingUpdate(props.meetingProp.intId)))
if (props.meetingProp.isBreakout) {
// This is a breakout room. Update the main meeting with list of users in this breakout room.
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendBreakoutUsersUpdate(props.meetingProp.intId)))
}
}
private def handleMonitorActivity() {
inactivityWarning match {
case Some(iw) =>
if (inactivity.isOverdue() && iw.isOverdue()) {
log.info("Closing meeting {} due to inactivity for {} seconds", props.meetingProp.intId, InactivityDeadline.toSeconds)
updateInactivityMonitors()
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
// Or else make sure to send only one warning message
}
case None =>
if (inactivity.isOverdue()) {
log.info("Sending inactivity warning to meeting {}", props.meetingProp.intId)
def build(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
val envelope = BbbCoreEnvelope(MeetingInactivityWarningEvtMsg.NAME, routing)
val body = MeetingInactivityWarningEvtMsgBody(timeLeftInSec)
val header = BbbClientMsgHeader(MeetingInactivityWarningEvtMsg.NAME, meetingId, "not-used")
val event = MeetingInactivityWarningEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val event = build(props.meetingProp.intId, InactivityTimeLeft.toSeconds)
outGW.send(event)
// We add 5 seconds so clients will have enough time to process the message
inactivityWarning = Some((InactivityTimeLeft + (5 seconds)).fromNow)
}
}
}
private def handleMonitorExpiration() {
for {
mExpire <- meetingExpire
} yield {
if (mExpire.isOverdue()) {
// User related meeting expiration methods
log.debug("Meeting {} expired. No users", props.meetingProp.intId)
meetingExpire = None
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
}
}
for {
mDuration <- meetingDuration
} yield {
if (mDuration.isOverdue()) {
// Default meeting duration
meetingDuration = None
log.debug("Meeting {} expired. Reached it's fixed duration of {}", props.meetingProp.intId, ExpireMeetingDuration.toString())
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
}
}
}
private def handleUpdateMeetingExpireMonitor(msg: UpdateMeetingExpireMonitor) {
if (msg.hasUser) {
meetingExpire match {
case Some(mExpire) =>
log.debug("Meeting has users. Stopping expiration for meeting {}", props.meetingProp.intId)
meetingExpire = None
case None =>
// User list is empty. Start this meeting expiration method
log.debug("Meeting has no users. Starting {} expiration for meeting {}", ExpireMeetingLastUserLeft.toString(), props.meetingProp.intId)
meetingExpire = Some(ExpireMeetingLastUserLeft.fromNow)
}
}
}
private def updateInactivityMonitors() {
inactivity = InactivityDeadline.fromNow
inactivityWarning = None
}
private def notifyActivity() {
for {
_ <- inactivityWarning
} yield {
val event = buildMeetingIsActiveEvtMsg(props.meetingProp.intId)
outGW.send(event)
}
updateInactivityMonitors()
}
def buildMeetingIsActiveEvtMsg(meetingId: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
val envelope = BbbCoreEnvelope(MeetingIsActiveEvtMsg.NAME, routing)
val body = MeetingIsActiveEvtMsgBody(meetingId)
val header = BbbClientMsgHeader(MeetingIsActiveEvtMsg.NAME, meetingId, "not-used")
val event = MeetingIsActiveEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
private def handleActivityResponse(msg: ActivityResponse) {
log.info("User endorsed that meeting {} is active", props.meetingProp.intId)
updateInactivityMonitors()
val event = buildMeetingIsActiveEvtMsg(props.meetingProp.intId)
outGW.send(event)
}
private def isMeetingActivity(msg: Object): Boolean = {
// We need to avoid all internal system's messages
msg match {
case msg: MonitorNumberOfUsers => false
case msg: SendTimeRemainingUpdate => false
case msg: SendBreakoutUsersUpdate => false
case msg: BreakoutRoomCreated => false
case _ => true
}
}
def getMetadata(key: String, metadata: collection.immutable.Map[String, String]): Option[Object] = {
var value: Option[String] = None
if (metadata.contains(key)) {
value = metadata.get(key)
}
value match {
case Some(v) => {
key match {
case Metadata.INACTIVITY_DEADLINE => {
// Can be defined between 1 minute to 6 hours
metadataIntegerValueOf(v, 60, 21600) match {
case Some(r) => Some(r.asInstanceOf[Object])
case None => None
}
}
case Metadata.INACTIVITY_TIMELEFT => {
// Can be defined between 30 seconds to 30 minutes
metadataIntegerValueOf(v, 30, 1800) match {
case Some(r) => Some(r.asInstanceOf[Object])
case None => None
}
}
case _ => None
}
}
case None => None
}
}
private def metadataIntegerValueOf(value: String, lowerBound: Int, upperBound: Int): Option[Int] = {
stringToInt(value) match {
case Some(r) => {
if (lowerBound <= r && r <= upperBound) {
Some(r)
} else {
None
}
}
case None => None
}
}
private def stringToInt(value: String): Option[Int] = {
var result: Option[Int] = None
try {
result = Some(Integer.parseInt(value))
} catch {
case e: Exception => {
result = None
}
}
result
}
}

View File

@ -0,0 +1,47 @@
package org.bigbluebutton.core.running
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.core.api.EndMeeting
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, IncomingEventBus }
import org.bigbluebutton.core.domain.MeetingExpiryTracker
import org.bigbluebutton.core.util.TimeUtil
object MeetingExpiryTracker {
def hasMeetingExpiredNeverBeenJoined(nowInMinutes: Long, startedOnInMinutes: Long, meetingExpireIfNoUserJoinedInMinutes: Long): Boolean = {
nowInMinutes - startedOnInMinutes > meetingExpireIfNoUserJoinedInMinutes
}
def meetingOverDuration(nowInMinutes: Long, startedOnInMinutes: Long, durationInMinutes: Long): Boolean = {
nowInMinutes > startedOnInMinutes + durationInMinutes
}
def processNeverBeenJoinedExpiry(nowInMinutes: Long, props: DefaultProps, tracker: MeetingExpiryTracker, eventBus: IncomingEventBus): MeetingExpiryTracker = {
if (hasMeetingExpiredNeverBeenJoined(nowInMinutes, tracker.startedOnInMinutes,
props.durationProps.meetingExpireIfNoUserJoinedInMinutes)) {
sendEndMeetingDueToExpiry(props, eventBus)
tracker
} else {
tracker
}
}
def processMeetingExpiryAudit(props: DefaultProps, tracker: MeetingExpiryTracker, eventBus: IncomingEventBus): MeetingExpiryTracker = {
val nowInMinutes = TimeUtil.millisToMinutes(System.currentTimeMillis())
if (!tracker.meetingJoined) {
processNeverBeenJoinedExpiry(nowInMinutes, props, tracker, eventBus)
} else {
if (meetingOverDuration(nowInMinutes, tracker.startedOnInMinutes, props.durationProps.duration)) {
sendEndMeetingDueToExpiry(props, eventBus)
tracker
} else {
tracker
}
}
}
def sendEndMeetingDueToExpiry(props: DefaultProps, eventBus: IncomingEventBus): Unit = {
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
}
}

View File

@ -0,0 +1,112 @@
package org.bigbluebutton.core.running
import org.bigbluebutton.core.domain.MeetingInactivityTracker
import com.softwaremill.quicklens._
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.EndMeeting
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, IncomingEventBus }
import org.bigbluebutton.core.util.TimeUtil
object MeetingInactivityTrackerHelper {
def isMeetingActive(
nowInMinutes: Long,
lastActivityTimeInMinutes: Long,
maxInactivityTimeoutMinutes: Long
): Boolean = {
nowInMinutes - lastActivityTimeInMinutes < maxInactivityTimeoutMinutes
}
def isMeetingInactive(
warningSent: Boolean,
nowInMinutes: Long,
lastActivityTimeInMinutes: Long,
maxInactivityTimeoutMinutes: Long
): Boolean = {
warningSent && (nowInMinutes - lastActivityTimeInMinutes) > maxInactivityTimeoutMinutes
}
def processMeetingInactivityAudit(
props: DefaultProps,
outGW: OutMessageGateway,
eventBus: IncomingEventBus,
tracker: MeetingInactivityTracker
): MeetingInactivityTracker = {
val nowInMinutes = TimeUtil.millisToMinutes(System.currentTimeMillis())
if (isMeetingActive(nowInMinutes, tracker.lastActivityTimeInMinutes, tracker.maxInactivityTimeoutMinutes)) {
tracker
} else {
if (isMeetingInactive(tracker.warningSent, nowInMinutes,
tracker.lastActivityTimeInMinutes,
tracker.maxInactivityTimeoutMinutes)) {
sendEndMeetingDueToInactivity(props, eventBus)
tracker
} else {
if (tracker.warningSent) {
tracker
} else {
warnOfMeetingInactivity(props, outGW, nowInMinutes, tracker)
tracker.modify(_.warningSent).setTo(true).modify(_.warningSentOnTimeInMinutes).setTo(nowInMinutes)
}
}
}
}
def timeLeftInMinutes(nowInMinutes: Long, tracker: MeetingInactivityTracker): Long = {
tracker.lastActivityTimeInMinutes + tracker.maxInactivityTimeoutMinutes - nowInMinutes
}
def warnOfMeetingInactivity(props: DefaultProps, outGW: OutMessageGateway,
nowInMinutes: Long, tracker: MeetingInactivityTracker): MeetingInactivityTracker = {
val timeLeftSeconds = TimeUtil.minutesToSeconds(timeLeftInMinutes(nowInMinutes, tracker))
sendMeetingInactivityWarning(props, outGW, timeLeftSeconds)
tracker
}
def sendEndMeetingDueToInactivity(props: DefaultProps, eventBus: IncomingEventBus): Unit = {
eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, EndMeeting(props.meetingProp.intId)))
}
def sendMeetingInactivityWarning(props: DefaultProps, outGW: OutMessageGateway, timeLeftSeconds: Long): Unit = {
def build(meetingId: String, timeLeftInSec: Long): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
val envelope = BbbCoreEnvelope(MeetingInactivityWarningEvtMsg.NAME, routing)
val body = MeetingInactivityWarningEvtMsgBody(timeLeftInSec)
val header = BbbClientMsgHeader(MeetingInactivityWarningEvtMsg.NAME, meetingId, "not-used")
val event = MeetingInactivityWarningEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val event = build(props.meetingProp.intId, timeLeftSeconds)
outGW.send(event)
}
def processMeetingActivityResponse(
props: DefaultProps,
outGW: OutMessageGateway,
msg: MeetingActivityResponseCmdMsg,
tracker: MeetingInactivityTracker
): MeetingInactivityTracker = {
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)
tracker.modify(_.warningSent).setTo(false)
.modify(_.warningSentOnTimeInMinutes).setTo(0L)
.modify(_.lastActivityTimeInMinutes).setTo(System.currentTimeMillis())
}
}

View File

@ -10,17 +10,16 @@ import org.bigbluebutton.core2.MeetingStatus2x
object RunningMeeting {
def apply(props: DefaultProps, outGW: OutMessageGateway,
eventBus: IncomingEventBus)(implicit context: ActorContext) =
eventBus: IncomingEventBus)(implicit context: ActorContext) =
new RunningMeeting(props, outGW, eventBus)(context)
}
class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
val eventBus: IncomingEventBus)(implicit val context: ActorContext) {
val eventBus: IncomingEventBus)(implicit val context: ActorContext) {
val chatModel = new ChatModel()
val layoutModel = new LayoutModel()
val layouts = new Layouts()
val pollModel = new PollModel()
val wbModel = new WhiteboardModel()
val presModel = new PresentationModel()
val breakoutRooms = new BreakoutRooms()
@ -40,7 +39,7 @@ class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
// We extract the meeting handlers into this class so it is
// easy to test.
val liveMeeting = new LiveMeeting(props, meetingStatux2x, deskshareModel, chatModel, layoutModel, layouts,
registeredUsers, polls2x, pollModel, wbModel, presModel, breakoutRooms, captionModel,
registeredUsers, polls2x, wbModel, presModel, breakoutRooms, captionModel,
notesModel, webcams, voiceUsers, users2x, guestsWaiting)
val actorRef = context.actorOf(MeetingActor.props(props, eventBus, outGW, liveMeeting), props.meetingProp.intId)

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