From b10237ebadd76f82fdd266991d16911f0902828e Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Wed, 5 Oct 2016 17:29:37 +0100 Subject: [PATCH 01/22] Upgrade commons-codec dependency version to 1.10 --- akka-bbb-apps/build.sbt | 2 +- akka-bbb-fsesl/build.sbt | 2 +- bbb-screenshare/app/build.sbt | 2 +- bigbluebutton-web/build.gradle | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/akka-bbb-apps/build.sbt b/akka-bbb-apps/build.sbt index 84bd7c904c..5954a0627f 100755 --- a/akka-bbb-apps/build.sbt +++ b/akka-bbb-apps/build.sbt @@ -55,7 +55,7 @@ libraryDependencies ++= { "org.pegdown" % "pegdown" % "1.4.0", "junit" % "junit" % "4.11", "com.etaty.rediscala" %% "rediscala" % "1.4.0", - "commons-codec" % "commons-codec" % "1.8", + "commons-codec" % "commons-codec" % "1.10", "joda-time" % "joda-time" % "2.3", "com.google.code.gson" % "gson" % "2.5", "redis.clients" % "jedis" % "2.7.2", diff --git a/akka-bbb-fsesl/build.sbt b/akka-bbb-fsesl/build.sbt index 2f751e0e5d..2d99dde598 100755 --- a/akka-bbb-fsesl/build.sbt +++ b/akka-bbb-fsesl/build.sbt @@ -47,7 +47,7 @@ libraryDependencies ++= { "org.pegdown" % "pegdown" % "1.4.0", "junit" % "junit" % "4.11", "com.etaty.rediscala" %% "rediscala" % "1.4.0", - "commons-codec" % "commons-codec" % "1.8", + "commons-codec" % "commons-codec" % "1.10", "joda-time" % "joda-time" % "2.3", "com.google.code.gson" % "gson" % "1.7.1", "redis.clients" % "jedis" % "2.1.0", diff --git a/bbb-screenshare/app/build.sbt b/bbb-screenshare/app/build.sbt index c1a489f772..5e3ad2fc20 100644 --- a/bbb-screenshare/app/build.sbt +++ b/bbb-screenshare/app/build.sbt @@ -44,7 +44,7 @@ libraryDependencies ++= { // "org.pegdown" % "pegdown" % "1.4.0", // "junit" % "junit" % "4.11", // "com.etaty.rediscala" %% "rediscala" % "1.4.0", - "commons-codec" % "commons-codec" % "1.8", + "commons-codec" % "commons-codec" % "1.10", "redis.clients" % "jedis" % "2.7.2", // "org.apache.commons" % "commons-lang3" % "3.2", "org.apache.commons" % "commons-pool2" % "2.3", diff --git a/bigbluebutton-web/build.gradle b/bigbluebutton-web/build.gradle index 67fb9d4142..588866d978 100755 --- a/bigbluebutton-web/build.gradle +++ b/bigbluebutton-web/build.gradle @@ -19,6 +19,7 @@ dependencies { compile 'commons-lang:commons-lang:2.5' compile 'commons-io:commons-io:2.4' + compile 'commons-codec:commons-codec:1.10' compile 'com.google.code.gson:gson:1.7.1' compile 'commons-httpclient:commons-httpclient:3.1' compile 'com.zaxxer:nuprocess:1.1.0' From f7be426305e29e45532a9eae208eef05a03a79dc Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 11 Oct 2016 20:50:51 +0100 Subject: [PATCH 02/22] Breakout rooms refactoring: generated uniques external ID and internal ID. --- .../receivers/MeetingMessageReceiver.java | 55 ++++++------ .../core/BigBlueButtonActor.scala | 42 ++++----- .../core/BigBlueButtonInGW.scala | 1 + .../core/JsonMessageDecoder.scala | 4 +- .../core/JsonMessageSenderActor.scala | 28 +++--- .../org/bigbluebutton/core/MeetingActor.scala | 4 +- .../org/bigbluebutton/core/MeetingModel.scala | 13 +-- .../core/MessageSenderActor.scala | 1 - .../org/bigbluebutton/core/Protocol.scala | 7 +- .../bigbluebutton/core/ProtocolMessages.scala | 2 +- .../bigbluebutton/core/api/Constants.scala | 2 + .../bigbluebutton/core/api/InMessages.scala | 35 ++++---- .../bigbluebutton/core/api/OutMessages.scala | 18 ++-- .../core/apps/BreakoutRoomApp.scala | 59 +++++------- .../core/apps/BreakoutRoomModel.scala | 22 +++-- .../MeetingMessageToJsonConverter.scala | 16 ++-- .../bigbluebutton/core/AppsTestFixtures.scala | 11 ++- .../core/apps/BreakoutRoomsUtilSpec.scala | 7 -- .../messages/CreateMeetingRequest.java | 90 ++++++++++--------- .../payload/BreakoutRoomJoinURLPayload.java | 10 +-- .../messages/payload/BreakoutRoomPayload.java | 6 +- .../payload/BreakoutRoomRequestPayload.java | 21 +++-- .../CreateBreakoutRoomRequestPayload.java | 10 +-- .../payload/ListenInOnBreakoutPayload.java | 18 ++-- .../RequestBreakoutJoinURLPayload.java | 6 +- .../payload/UpdateBreakoutUsersPayload.java | 10 +-- .../CreateBreakoutRoomRequestTest.java | 2 +- .../CreateBreakoutRoomsRequestTest.java | 6 +- .../messages/CreateMeetingRequestTest.java | 13 +-- .../red5/client/UserClientMessageSender.java | 25 +++--- .../main/events/BreakoutRoomEvent.as | 2 +- .../main/model/users/BreakoutRoom.as | 5 +- .../main/model/users/Conference.as | 44 +++++---- .../main/model/users/UserService.as | 8 +- .../modules/users/services/MessageReceiver.as | 23 ++--- .../modules/users/services/MessageSender.as | 6 +- .../users/views/BreakoutRoomSettings.mxml | 11 +-- .../users/views/RoomActionsRenderer.mxml | 4 +- .../modules/users/views/UsersWindow.mxml | 9 +- .../web/controllers/ApiController.groovy | 3 + .../org/bigbluebutton/api/MeetingService.java | 40 ++++++--- .../api/ParamsProcessorUtil.java | 11 ++- .../org/bigbluebutton/api/domain/Meeting.java | 22 +++-- .../api/messaging/MeetingMessageHandler.java | 4 +- .../api/messaging/MessagingService.java | 10 ++- .../api/messaging/RedisMessagingService.java | 49 +++++----- .../messages/CreateBreakoutRoom.java | 10 +-- .../messaging/messages/EndBreakoutRoom.java | 6 +- 48 files changed, 415 insertions(+), 396 deletions(-) diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/MeetingMessageReceiver.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/MeetingMessageReceiver.java index 1c586454e5..cf1100af5b 100755 --- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/MeetingMessageReceiver.java +++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/MeetingMessageReceiver.java @@ -35,7 +35,7 @@ public class MeetingMessageReceiver implements MessageHandler { public void handleMessage(String pattern, String channel, String message) { if (channel.equalsIgnoreCase(MessagingConstants.TO_MEETING_CHANNEL)) { - System.out.println("Meeting message: " + channel + " " + message); + System.out.println("Meeting message: " + channel + " " + message); JsonParser parser = new JsonParser(); JsonObject obj = (JsonObject) parser.parse(message); @@ -45,8 +45,8 @@ public class MeetingMessageReceiver implements MessageHandler { String messageName = header.get("name").getAsString(); if (CreateMeetingRequest.NAME.equals(messageName)) { Gson gson = new Gson(); - CreateMeetingRequest msg = gson.fromJson(message, - CreateMeetingRequest.class); + CreateMeetingRequest msg = gson.fromJson(message, + CreateMeetingRequest.class); bbbGW.handleBigBlueButtonMessage(msg); } } @@ -59,49 +59,50 @@ public class MeetingMessageReceiver implements MessageHandler { EndMeetingMessage emm = (EndMeetingMessage) msg; bbbGW.endMeeting(emm.meetingId); } else if (msg instanceof RegisterUserMessage) { - RegisterUserMessage emm = (RegisterUserMessage) msg; - bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken, emm.avatarURL); + RegisterUserMessage rum = (RegisterUserMessage) msg; + bbbGW.registerUser(rum.meetingID, rum.internalUserId, rum.fullname, rum.role, rum.externUserID, rum.authToken, rum.avatarURL); } else if (msg instanceof DestroyMeetingMessage) { - DestroyMeetingMessage emm = (DestroyMeetingMessage) msg; - bbbGW.destroyMeeting(emm.meetingId); + DestroyMeetingMessage dmm = (DestroyMeetingMessage) msg; + bbbGW.destroyMeeting(dmm.meetingId); } else if (msg instanceof ValidateAuthTokenMessage) { - ValidateAuthTokenMessage emm = (ValidateAuthTokenMessage) msg; + ValidateAuthTokenMessage vam = (ValidateAuthTokenMessage) msg; String sessionId = "tobeimplemented"; - bbbGW.validateAuthToken(emm.meetingId, emm.userId, emm.token, emm.replyTo, sessionId); + bbbGW.validateAuthToken(vam.meetingId, vam.userId, vam.token, vam.replyTo, sessionId); } else if (msg instanceof UserConnectedToGlobalAudio) { - UserConnectedToGlobalAudio emm = (UserConnectedToGlobalAudio) msg; + UserConnectedToGlobalAudio ustga = (UserConnectedToGlobalAudio) msg; Map logData = new HashMap(); - logData.put("voiceConf", emm.voiceConf); - logData.put("userId", emm.userid); - logData.put("username", emm.name); + 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(emm.voiceConf, emm.userid, emm.name); + System.out.println("User connected to global audio: data={}", logStr); + */ + bbbGW.userConnectedToGlobalAudio(ustga.voiceConf, ustga.userid, ustga.name); } else if (msg instanceof UserDisconnectedFromGlobalAudio) { - UserDisconnectedFromGlobalAudio emm = (UserDisconnectedFromGlobalAudio) msg; + UserDisconnectedFromGlobalAudio udfga = (UserDisconnectedFromGlobalAudio) msg; Map logData = new HashMap(); - logData.put("voiceConf", emm.voiceConf); - logData.put("userId", emm.userid); - logData.put("username", emm.name); + 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(emm.voiceConf, emm.userid, emm.name); + System.out.println("User disconnected from global audio: data={}", logStr); + */ + bbbGW.userDisconnectedFromGlobalAudio(udfga.voiceConf, udfga.userid, udfga.name); } else if (msg instanceof GetAllMeetingsRequest) { - GetAllMeetingsRequest emm = (GetAllMeetingsRequest) msg; + GetAllMeetingsRequest gamr = (GetAllMeetingsRequest) msg; bbbGW.getAllMeetings("no_need_of_a_meeting_id"); } else { System.out.println("Unknown message: [" + message + "]"); @@ -126,8 +127,8 @@ public class MeetingMessageReceiver implements MessageHandler { if (msg != null) { if (msg instanceof KeepAliveMessage) { - KeepAliveMessage emm = (KeepAliveMessage) msg; - bbbGW.isAliveAudit(emm.keepAliveId); + KeepAliveMessage kam = (KeepAliveMessage) msg; + bbbGW.isAliveAudit(kam.keepAliveId); } } else { System.out.println("Unknown message: [" + message + "]"); diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala index 9fd760f88e..a2e84486c0 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala @@ -11,13 +11,13 @@ import org.bigbluebutton.SystemConfiguration object BigBlueButtonActor extends SystemConfiguration { def props(system: ActorSystem, - eventBus: IncomingEventBus, - outGW: OutMessageGateway): Props = + eventBus: IncomingEventBus, + outGW: OutMessageGateway): Props = Props(classOf[BigBlueButtonActor], system, eventBus, outGW) } class BigBlueButtonActor(val system: ActorSystem, - eventBus: IncomingEventBus, outGW: OutMessageGateway) extends Actor with ActorLogging { + eventBus: IncomingEventBus, outGW: OutMessageGateway) extends Actor with ActorLogging { implicit def executionContext = system.dispatcher implicit val timeout = Timeout(5 seconds) @@ -25,19 +25,19 @@ class BigBlueButtonActor(val system: ActorSystem, private var meetings = new collection.immutable.HashMap[String, RunningMeeting] def receive = { - case msg: CreateMeeting => handleCreateMeeting(msg) - case msg: DestroyMeeting => handleDestroyMeeting(msg) - case msg: KeepAliveMessage => handleKeepAliveMessage(msg) - case msg: PubSubPing => handlePubSubPingMessage(msg) - case msg: ValidateAuthToken => handleValidateAuthToken(msg) - case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(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: CreateMeeting => handleCreateMeeting(msg) + case msg: DestroyMeeting => handleDestroyMeeting(msg) + case msg: KeepAliveMessage => handleKeepAliveMessage(msg) + case msg: PubSubPing => handlePubSubPingMessage(msg) + case msg: ValidateAuthToken => handleValidateAuthToken(msg) + case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg) + case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg) + case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg) + case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg) + case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg) + case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg) case msg: VoiceConfRecordingStartedMessage => handleVoiceConfRecordingStartedMessage(msg) - case _ => // do nothing + case _ => // do nothing } private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = { @@ -117,9 +117,9 @@ class BigBlueButtonActor(val system: ActorSystem, meetings -= msg.meetingID log.info("Kick everyone out on meetingId={}", msg.meetingID) if (m.mProps.isBreakout) { - log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.externalMeetingID, m.mProps.meetingID) - eventBus.publish(BigBlueButtonEvent(m.mProps.externalMeetingID, - BreakoutRoomEnded(m.mProps.externalMeetingID, m.mProps.meetingID))) + log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.parentMeetingID, m.mProps.meetingID) + eventBus.publish(BigBlueButtonEvent(m.mProps.parentMeetingID, + BreakoutRoomEnded(m.mProps.parentMeetingID, m.mProps.meetingID))) } outGW.send(new EndAndKickAll(msg.meetingID, m.mProps.recorded)) outGW.send(new DisconnectAllUsers(msg.meetingID)) @@ -149,9 +149,9 @@ class BigBlueButtonActor(val system: ActorSystem, eventBus.subscribe(m.actorRef, m.mProps.deskshareBridge) meetings += m.mProps.meetingID -> m - outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.recorded, m.mProps.meetingName, - m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass, - msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate)) + outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.parentMeetingID, + m.mProps.recorded, m.mProps.meetingName, m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass, + msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate, msg.mProps.isBreakout)) m.actorRef ! new InitializeMeeting(m.mProps.meetingID, m.mProps.recorded) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala index 2b83e37d44..5e75cef5dc 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala @@ -57,6 +57,7 @@ class BigBlueButtonInGW( val mProps = new MeetingProperties( msg.payload.id, msg.payload.externalId, + msg.payload.parentId, msg.payload.name, msg.payload.record, msg.payload.voiceConfId, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageDecoder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageDecoder.scala index cc2118cd00..67d50713dd 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageDecoder.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageDecoder.scala @@ -51,7 +51,7 @@ object JsonMessageDecoder { def decode(json: String): Option[InMessage] = { unmarshall(json) match { case Success(validMsg) => Some(validMsg) - case Failure(ex) => None + case Failure(ex) => None } } @@ -75,4 +75,4 @@ object JsonMessageDecoder { case _ => throw MessageProcessException("Cannot parse JSON message: [" + msg + "]") } } -} \ No newline at end of file +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala index 9ec02759c9..56680d48d4 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala @@ -38,27 +38,27 @@ class JsonMessageSenderActor(val service: MessageSender) def receive = { // Breakout - case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg) - case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg) - case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg) + case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg) + case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg) + case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg) case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURL(msg) case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStarted(msg) - case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg) + case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg) case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsers(msg) - case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg) + case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg) - case _ => // do nothing + case _ => // do nothing } // Breakout private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) { - val payload = new BreakoutRoomPayload(msg.meetingId, msg.breakout.breakoutId, msg.breakout.name) + val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.name) val request = new BreakoutRoomStarted(payload) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) } private def handleBreakoutRoomEnded(msg: BreakoutRoomEndedOutMessage) { - val payload = new BreakoutRoomPayload(msg.meetingId, msg.breakoutId, "") + val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "") val request = new BreakoutRoomClosed(payload) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) } @@ -66,7 +66,7 @@ class JsonMessageSenderActor(val service: MessageSender) 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.meetingId, msg.breakoutId, users) + val payload = new UpdateBreakoutUsersPayload(msg.parentMeetingId, msg.breakoutMeetingId, users) val request = new UpdateBreakoutUsers(payload) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson()) } @@ -85,14 +85,14 @@ class JsonMessageSenderActor(val service: MessageSender) private def handleBreakoutRoomsList(msg: BreakoutRoomsListOutMessage) { val rooms = new java.util.ArrayList[BreakoutRoomPayload]() - msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.breakoutId, r.name))) + msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.meetingId, r.name))) 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.breakoutId, msg.room.parentId, msg.room.name, + val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutMeetingId, msg.room.parentId, msg.room.name, 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) @@ -100,14 +100,14 @@ class JsonMessageSenderActor(val service: MessageSender) } private def handleEndBreakoutRoom(msg: EndBreakoutRoom) { - val payload = new EndBreakoutRoomRequestPayload(msg.breakoutId) + 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.meetingId, - msg.breakoutId, msg.userId, msg.joinURL) + val payload = new BreakoutRoomJoinURLPayload(msg.parentMeetingId, + msg.breakoutMeetingId, msg.userId, msg.joinURL) val request = new BreakoutRoomJoinURL(payload) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingActor.scala index c3a67357dd..5c8e3dd18e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingActor.scala @@ -37,8 +37,8 @@ class MeetingActorInternal(val mProps: MeetingProperties, if (mProps.isBreakout) { // This is a breakout room. Inform our parent meeting that we have been successfully created. eventBus.publish(BigBlueButtonEvent( - mProps.externalMeetingID, - BreakoutRoomCreated(mProps.externalMeetingID, mProps.meetingID))) + mProps.parentMeetingID, + BreakoutRoomCreated(mProps.parentMeetingID, mProps.meetingID))) } def receive = { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala index 241bde0f85..427d830a89 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala @@ -4,14 +4,15 @@ import org.bigbluebutton.core.api.Permissions import java.util.concurrent.TimeUnit case object StopMeetingActor -case class MeetingProperties(meetingID: String, externalMeetingID: String, meetingName: String, recorded: Boolean, - voiceBridge: String, deskshareBridge: String, duration: Int, autoStartRecording: Boolean, - allowStartStopRecording: Boolean, moderatorPass: String, viewerPass: String, createTime: Long, - createDate: String, red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean) +case class MeetingProperties(meetingID: String, externalMeetingID: String, parentMeetingID: String, meetingName: String, + recorded: Boolean, voiceBridge: String, deskshareBridge: String, duration: Int, + autoStartRecording: Boolean, allowStartStopRecording: Boolean, moderatorPass: String, + viewerPass: String, createTime: Long, createDate: String, + red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean) 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 diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala index e587c3c240..391f888c22 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala @@ -44,7 +44,6 @@ class MessageSenderActor(val service: MessageSender) extends Actor with ActorLogging { val encoder = new ToJsonEncoder() - def receive = { case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg) case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala index 2f74e5b527..42fd439306 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala @@ -4,7 +4,7 @@ import spray.json.{ DefaultJsonProtocol, JsValue, JsString, DeserializationExcep 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) @@ -20,11 +20,11 @@ object UserMessagesProtocol extends DefaultJsonProtocol { def read(json: JsValue): MessageType.MessageType = json match { case JsString(str) => MessageType.withName(str) - case _ => throw new DeserializationException("Enum string expected") + case _ => throw new DeserializationException("Enum string expected") } } - implicit val breakoutRoomInPayloadFormat = jsonFormat2(BreakoutRoomInPayload) + implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload) implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms) implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage) implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat3(RequestBreakoutJoinURLInMessage) @@ -36,5 +36,4 @@ object UserMessagesProtocol extends DefaultJsonProtocol { implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat10(CreateBreakoutRoomOutMsgPayload) implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload) implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope) - } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala index 35e0601bc9..14afd22a6d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala @@ -7,7 +7,7 @@ trait OutMessage case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload) case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload) -case class CreateBreakoutRoomOutMsgPayload(breakoutId: String, name: String, parentId: String, +case class CreateBreakoutRoomOutMsgPayload(meetingId: String, name: String, parentId: String, voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String, sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/Constants.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/Constants.scala index 6ca5af36db..c55149c0dc 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/Constants.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/Constants.scala @@ -6,6 +6,8 @@ object Constants { val PAYLOAD = "payload" val MEETING_ID = "meeting_id" val EXTERNAL_MEETING_ID = "external_meeting_id" + val PARENT_MEETING_ID = "parent_meeting_id" + val IS_BREAKOUT = "is_breakout"; val TIMESTAMP = "timestamp" val CURRENT_TIME = "current_time" val USER_ID = "userid" diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index 87f553a2ec..0cf1b1edbe 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -42,17 +42,14 @@ case class LockSetting(meetingID: String, locked: Boolean, settings: Map[String, // 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, users: Vector[String]) +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, breakoutId: String, - userId: String) extends InMessage +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, breakoutId: String, - users: Vector[BreakoutUser]) extends InMessage +case class BreakoutRoomUsersUpdate(meetingId: String, breakoutMeetingId: String, users: Vector[BreakoutUser]) 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 @@ -76,9 +73,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: Role, - extUserID: String, authToken: String, avatarURL: String) extends InMessage + extUserID: String, authToken: String, avatarURL: String) 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 @@ -100,9 +97,9 @@ case class GetChatHistoryRequest(meetingID: String, requesterID: String, replyTo case class SendPublicMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage case class SendPrivateMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String, - userid: String, name: String) extends InMessage + userid: String, name: String) extends InMessage case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String, - userid: String, name: String) extends InMessage + userid: String, name: String) extends InMessage /////////////////////////////////////////////////////////////////////////////////////// // Layout @@ -111,7 +108,7 @@ case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just case class GetCurrentLayoutRequest(meetingID: String, requesterID: String) extends InMessage case class SetLayoutRequest(meetingID: String, requesterID: String, layoutID: String) extends InMessage case class LockLayoutRequest(meetingID: String, setById: String, lock: Boolean, viewersOnly: Boolean, - layout: Option[String]) extends InMessage + layout: Option[String]) extends InMessage case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout: String) extends InMessage ////////////////////////////////////////////////////////////////////////////////////// @@ -123,19 +120,19 @@ case class RemovePresentation(meetingID: String, presentationID: String) extends case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage case class SendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) extends InMessage case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, - widthRatio: Double, heightRatio: Double) extends InMessage + widthRatio: Double, heightRatio: Double) extends InMessage case class GotoSlide(meetingID: String, page: String) extends InMessage case class SharePresentation(meetingID: String, presentationID: String, share: Boolean) extends InMessage case class GetSlideInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage case class PreuploadedPresentations(meetingID: String, presentations: Seq[Presentation]) extends InMessage case class PresentationConversionUpdate(meetingID: String, messageKey: String, code: String, - presentationId: String, presName: String) extends InMessage + presentationId: String, presName: String) extends InMessage case class PresentationPageCountError(meetingID: String, messageKey: String, code: String, presentationId: String, - numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage + numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage case class PresentationSlideGenerated(meetingID: String, messageKey: String, code: String, presentationId: String, - numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage + numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage case class PresentationConversionCompleted(meetingID: String, messageKey: String, code: String, - presentation: Presentation) extends InMessage + presentation: Presentation) extends InMessage ///////////////////////////////////////////////////////////////////////////////////// // Polling @@ -164,9 +161,9 @@ case class MuteUserRequest(meetingID: String, requesterID: String, userID: Strin case class LockUserRequest(meetingID: String, requesterID: String, userID: String, lock: Boolean) extends InMessage case class EjectUserFromVoiceRequest(meetingID: String, userId: String, ejectedBy: String) extends InMessage case class VoiceUserJoinedMessage(meetingID: String, user: String, voiceConfId: String, - callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage + callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage case class UserJoinedVoiceConfMessage(voiceConfId: String, voiceUserId: String, userId: String, externUserId: String, - callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage + callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage case class UserLeftVoiceConfMessage(voiceConfId: String, voiceUserId: String) extends InMessage case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala index a356e84547..19d6a828f6 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala @@ -14,8 +14,8 @@ case class VoiceRecordingStarted(meetingID: String, recorded: Boolean, recording 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, recorded: Boolean, name: String, - voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String) 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 case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage @@ -30,17 +30,17 @@ case object IsAliveMessage extends IOutMessage // Breakout Rooms case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomBody], roomsReady: Boolean) extends IOutMessage case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage -case class EndBreakoutRoom(breakoutId: String) extends IOutMessage -case class BreakoutRoomOutPayload(breakoutId: String, name: String, parentId: String, +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(meetingId: String, recorded: Boolean, breakoutId: String, userId: String, joinURL: String) extends IOutMessage -case class BreakoutRoomStartedOutMessage(meetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage -case class BreakoutRoomBody(name: String, breakoutId: String) -case class UpdateBreakoutUsersOutMessage(meetingId: String, recorded: Boolean, breakoutId: String, users: Vector[BreakoutUser]) extends IOutMessage +case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, joinURL: String) extends IOutMessage +case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage +case class BreakoutRoomBody(name: String, meetingId: String) +case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUser]) 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(meetingId: String, breakoutId: String) extends IOutMessage +case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) extends IOutMessage // Permissions case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 90a1d236a4..2af20f383b 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -22,7 +22,9 @@ trait BreakoutRoomApp extends SystemConfiguration { def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) { val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id) } - outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0)); + val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0 + log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length) + outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady )) } def handleCreateBreakoutRooms(msg: CreateBreakoutRooms) { @@ -33,6 +35,8 @@ trait BreakoutRoomApp extends SystemConfiguration { } var i = 0 + // in very rare cases the presentation conversion generates an error, what should we do? + // those cases where default.pdf is deleted from the whiteboard val sourcePresentationId = presModel.getCurrentPresentation().get.id val sourcePresentationSlide = presModel.getCurrentPage().get.num breakoutModel.pendingRoomsNumber = msg.rooms.length; @@ -41,8 +45,8 @@ trait BreakoutRoomApp extends SystemConfiguration { i += 1 val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mProps.meetingID, i) val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(mProps.voiceBridge, i) - val r = breakoutModel.createBreakoutRoom(breakoutMeetingId, room.name, voiceConfId, room.users) - val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, + val r = breakoutModel.createBreakoutRoom(breakoutMeetingId, room.name, mProps.meetingID, room.sequence, voiceConfId, room.users) + val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, r.sequence, r.voiceConfId, msg.durationInMinutes, mProps.moderatorPass, mProps.viewerPass, sourcePresentationId, sourcePresentationSlide, msg.record) outGW.send(new CreateBreakoutRoom(mProps.meetingID, p)) @@ -51,26 +55,26 @@ trait BreakoutRoomApp extends SystemConfiguration { meetingModel.breakoutRoomsStartedOn = timeNowInSeconds; } - def sendJoinURL(userId: String, breakoutId: String) { + def sendJoinURL(userId: String, breakoutMeetingId: String) { for { user <- usersModel.getUser(userId) apiCall = "join" - params = BreakoutRoomsUtil.joinParams(user.name, userId, true, breakoutId, mProps.moderatorPass, true) + params = BreakoutRoomsUtil.joinParams(user.name, userId, true, breakoutMeetingId, mProps.moderatorPass, true) baseString = BreakoutRoomsUtil.createBaseString(params) checksum = BreakoutRoomsUtil.calculateChecksum(apiCall, baseString, bbbWebSharedSecret) joinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, baseString, checksum) - } yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, breakoutId, userId, joinURL)) + } yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, breakoutMeetingId, userId, joinURL)) } def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) { - sendJoinURL(msg.userId, msg.breakoutId) + sendJoinURL(msg.userId, msg.meetingId) } def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) { breakoutModel.pendingRoomsNumber -= 1 val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId) room foreach { room => - sendBreakoutRoomStarted(mProps.meetingID, room.name, room.id, room.voiceConfId) + sendBreakoutRoomStarted(room.parentRoomId, room.name, room.id, room.voiceConfId) } // We avoid sending invitation @@ -88,8 +92,9 @@ trait BreakoutRoomApp extends SystemConfiguration { } } - def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutId: String, voiceConfId: String) { - outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutId))) + def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutMeetingId: String, voiceConfId: String) { + log.info("Sending breakout room started for parent meeting {} and breakout meeting", meetingId, breakoutMeetingId); + outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutMeetingId))) } def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) { @@ -98,16 +103,16 @@ trait BreakoutRoomApp extends SystemConfiguration { } def handleBreakoutRoomUsersUpdate(msg: BreakoutRoomUsersUpdate) { - breakoutModel.updateBreakoutUsers(msg.breakoutId, msg.users) foreach { room => - outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutId, room.users)) + breakoutModel.updateBreakoutUsers(msg.breakoutMeetingId, msg.users) foreach { room => + outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutMeetingId, room.users)) } } def handleSendBreakoutUsersUpdate(msg: SendBreakoutUsersUpdate) { val users = usersModel.getUsers().toVector val breakoutUsers = users map { u => new BreakoutUser(u.externUserID, u.name) } - eventBus.publish(BigBlueButtonEvent(mProps.externalMeetingID, - new BreakoutRoomUsersUpdate(mProps.externalMeetingID, mProps.meetingID, breakoutUsers))) + eventBus.publish(BigBlueButtonEvent(mProps.parentMeetingID, + new BreakoutRoomUsersUpdate(mProps.parentMeetingID, mProps.meetingID, breakoutUsers))) } def handleTransferUserToMeeting(msg: TransferUserToMeetingRequest) { @@ -147,17 +152,13 @@ trait BreakoutRoomApp extends SystemConfiguration { object BreakoutRoomsUtil { def createMeetingId(id: String, index: Int): String = { - id.concat("-").concat(index.toString()) + return DigestUtils.sha1Hex(id.concat("-").concat(index.toString())) + '-' + System.currentTimeMillis(); } def createVoiceConfId(id: String, index: Int): String = { id.concat(index.toString()) } - def fromSWFtoPDF(swfURL: String): String = { - swfURL.replace("swf", "pdf") - } - def createJoinURL(webAPI: String, apiCall: String, baseString: String, checksum: String): String = { var apiURL = if (webAPI.endsWith("/")) webAPI else webAPI.concat("/") apiURL.concat(apiCall).concat("?").concat(baseString).concat("&checksum=").concat(checksum) @@ -174,13 +175,13 @@ object BreakoutRoomsUtil { checksum(apiCall.concat(baseString).concat(sharedSecret)) } - def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutId: String, + def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String, password: String, redirect: Boolean): mutable.Map[String, String] = { val params = new collection.mutable.HashMap[String, String] params += "fullName" -> urlEncode(username) - params += "userID" -> urlEncode(userId + "-" + breakoutId.substring(breakoutId.lastIndexOf("-") + 1)); + params += "userID" -> urlEncode(userId + "-" + breakoutMeetingId.substring(breakoutMeetingId.lastIndexOf("-") + 1)); params += "isBreakout" -> urlEncode(isBreakout.toString()) - params += "meetingID" -> urlEncode(breakoutId) + params += "meetingID" -> urlEncode(breakoutMeetingId) params += "password" -> urlEncode(password) params += "redirect" -> urlEncode(redirect.toString()) @@ -218,18 +219,4 @@ object BreakoutRoomsUtil { def urlEncode(s: String): String = { URLEncoder.encode(s, "UTF-8"); } - - // - //encodeURIComponent() -- Java encoding similiar to JavaScript encodeURIComponent - // - def encodeURIComponent(component: String): String = { - URLEncoder.encode(component, "UTF-8") - .replaceAll("\\%28", "(") - .replaceAll("\\%29", ")") - .replaceAll("\\+", "%20") - .replaceAll("\\%27", "'") - .replaceAll("\\%21", "!") - .replaceAll("\\%7E", "~") - } - } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala index 5ec8a3f6d9..1d90cd685d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala @@ -1,11 +1,10 @@ package org.bigbluebutton.core.apps -import scala.collection.mutable.ArrayBuffer -import scala.collection.immutable.HashMap +import scala.Vector case class BreakoutUser(id: String, name: String) -case class BreakoutRoom(id: String, name: String, voiceConfId: String, - assignedUsers: Vector[String], users: Vector[BreakoutUser]) +case class BreakoutRoom(id: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String, + assignedUsers: Vector[String], users: Vector[BreakoutUser]) class BreakoutRoomModel { private var rooms = new collection.immutable.HashMap[String, BreakoutRoom] @@ -21,9 +20,9 @@ class BreakoutRoomModel { rooms -= id } - def createBreakoutRoom(id: String, name: String, voiceConfId: String, - assignedUsers: Vector[String]): BreakoutRoom = { - val room = new BreakoutRoom(id, name, voiceConfId, assignedUsers, Vector()) + def createBreakoutRoom(id: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String, + assignedUsers: Vector[String]): BreakoutRoom = { + val room = new BreakoutRoom(id, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector()) add(room) } @@ -35,18 +34,17 @@ class BreakoutRoomModel { rooms.values.toArray } - def getAssignedUsers(breakoutId: String): Option[Vector[String]] = { + def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = { for { - room <- rooms.get(breakoutId) + room <- rooms.get(breakoutMeetingId) } yield room.assignedUsers } - def updateBreakoutUsers(breakoutId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = { + def updateBreakoutUsers(breakoutMeetingId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = { for { - room <- rooms.get(breakoutId) + room <- rooms.get(breakoutMeetingId) newroom = room.copy(users = users) room2 = add(newroom) } yield room2 } } - diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala index c8999da668..23a387d819 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala @@ -29,6 +29,8 @@ object MeetingMessageToJsonConverter { val payload = new java.util.HashMap[String, Any]() payload.put(Constants.MEETING_ID, msg.meetingID) payload.put(Constants.EXTERNAL_MEETING_ID, msg.externalMeetingID) + payload.put(Constants.PARENT_MEETING_ID, msg.parentMeetingID) + payload.put(Constants.IS_BREAKOUT, msg.isBreakout) payload.put(Constants.NAME, msg.name) payload.put(Constants.RECORDED, msg.recorded) payload.put(Constants.VOICE_CONF, msg.voiceBridge) @@ -145,8 +147,8 @@ object MeetingMessageToJsonConverter { def breakoutRoomStartedOutMessageToJson(msg: BreakoutRoomStartedOutMessage): String = { val payload = new java.util.HashMap[String, Any]() - payload.put("meetingId", msg.meetingId) - payload.put("breakoutId", msg.breakout.breakoutId) + payload.put("parentMeetingId", msg.parentMeetingId) + payload.put("meetingId", msg.breakout.meetingId) payload.put("name", msg.breakout.name) val header = Util.buildHeader(BreakoutRoomStarted.NAME, None) @@ -155,8 +157,8 @@ object MeetingMessageToJsonConverter { def breakoutRoomEndedOutMessageToJson(msg: BreakoutRoomEndedOutMessage): String = { val payload = new java.util.HashMap[String, Any]() + payload.put("parentMeetingId", msg.parentMeetingId) payload.put("meetingId", msg.meetingId) - payload.put("breakoutId", msg.breakoutId) val header = Util.buildHeader(BreakoutRoomClosed.NAME, None) Util.buildJson(header, payload) @@ -164,8 +166,8 @@ object MeetingMessageToJsonConverter { def breakoutRoomJoinURLOutMessageToJson(msg: BreakoutRoomJoinURLOutMessage): String = { val payload = new java.util.HashMap[String, Any]() - payload.put("meetingId", msg.meetingId) - payload.put("breakoutId", msg.breakoutId) + payload.put("parentMeetingId", msg.parentMeetingId) + payload.put("breakoutMeetingId", msg.breakoutMeetingId) payload.put("userId", msg.userId) payload.put("joinURL", msg.joinURL) @@ -175,8 +177,8 @@ object MeetingMessageToJsonConverter { def updateBreakoutUsersOutMessageToJson(msg: UpdateBreakoutUsersOutMessage): String = { val payload = new java.util.HashMap[String, Any]() - payload.put("meetingId", msg.meetingId) - payload.put("breakoutId", msg.breakoutId) + payload.put("parentMeetingId", msg.parentMeetingId) + payload.put("breakoutMeetingId", msg.breakoutMeetingId) payload.put("recorded", msg.recorded) payload.put("users", msg.users.toArray) diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala index 97bf4c3100..efd6d41254 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala @@ -4,6 +4,7 @@ trait AppsTestFixtures { val meetingId = "testMeetingId" val externalMeetingId = "testExternalMeetingId" + val parentMeetingId = "testParentMeetingId" val meetingName = "test meeting" val record = false val voiceConfId = "85115" @@ -16,13 +17,15 @@ trait AppsTestFixtures { val createTime = System.currentTimeMillis val createDate = "Oct 26, 2015" val isBreakout = false + val red5DeskShareIP = "127.0.0.1" + val red5DeskShareApp = "red5App" - val mProps = new MeetingProperties(meetingId, externalMeetingId, + val mProps = new MeetingProperties(meetingId, externalMeetingId, parentMeetingId, meetingName, record, voiceConfId, deskshareConfId, durationInMinutes, autoStartRecording, allowStartStopRecording, moderatorPassword, viewerPassword, - createTime, createDate, isBreakout) - -} \ No newline at end of file + createTime, createDate, red5DeskShareIP, red5DeskShareApp, + isBreakout) +} diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala index a84000b5e4..423590882f 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala @@ -6,13 +6,6 @@ import org.bigbluebutton.core.UnitSpec class BreakoutRoomsUtilSpec extends UnitSpec { - it should "return a pdfURL" in { - val baseURL = "http://localhost/pre1/page1." - val swfURL = baseURL + "swf" - val pdfURL = BreakoutRoomsUtil.fromSWFtoPDF(swfURL) - assert(pdfURL == baseURL + "pdf") - } - it should "return a meetingId" in { val mainMeetingId = "abc-123" val index = 1 diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java index d2ecfc2881..f408ead825 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java @@ -3,48 +3,52 @@ package org.bigbluebutton.messages; import org.bigbluebutton.common.messages.IBigBlueButtonMessage; public class CreateMeetingRequest implements IBigBlueButtonMessage { - public final static String NAME = "CreateMeetingRequest"; - - public final Header header; - public final CreateMeetingRequestPayload payload; - - public CreateMeetingRequest(CreateMeetingRequestPayload payload) { - this.header = new Header(NAME); - this.payload = payload; - } - - public static class CreateMeetingRequestPayload { - public final String id; - public final String externalId; - public final String name; - public final Boolean record; - public final String voiceConfId; - public final Integer durationInMinutes; - public final Boolean autoStartRecording; - public final Boolean allowStartStopRecording; - public final String moderatorPassword; - public final String viewerPassword; - public final Long createTime; - public final String createDate; - public final Boolean isBreakout; - - public CreateMeetingRequestPayload(String id, String externalId, String name, Boolean record, String voiceConfId, - Integer duration, Boolean autoStartRecording, - Boolean allowStartStopRecording, String moderatorPass, - String viewerPass, Long createTime, String createDate, Boolean isBreakout) { - this.id = id; - this.externalId = externalId; - this.name = name; - this.record = record; - this.voiceConfId = voiceConfId; - this.durationInMinutes = duration; - this.autoStartRecording = autoStartRecording; - this.allowStartStopRecording = allowStartStopRecording; - this.moderatorPassword = moderatorPass; - this.viewerPassword = viewerPass; - this.createTime = createTime; - this.createDate = createDate; - this.isBreakout = isBreakout; + public final static String NAME = "CreateMeetingRequest"; + + public final Header header; + public final CreateMeetingRequestPayload payload; + + public CreateMeetingRequest(CreateMeetingRequestPayload payload) { + this.header = new Header(NAME); + this.payload = payload; + } + + public static class CreateMeetingRequestPayload { + public final String id; + public final String externalId; + public final String parentId; + public final String name; + public final Boolean record; + public final String voiceConfId; + public final Integer durationInMinutes; + public final Boolean autoStartRecording; + public final Boolean allowStartStopRecording; + public final String moderatorPassword; + public final String viewerPassword; + public final Long createTime; + public final String createDate; + public final Boolean isBreakout; + + public CreateMeetingRequestPayload(String id, String externalId, + String parentId, String name, Boolean record, + String voiceConfId, Integer duration, + Boolean autoStartRecording, Boolean allowStartStopRecording, + String moderatorPass, String viewerPass, Long createTime, + String createDate, Boolean isBreakout) { + this.id = id; + this.externalId = externalId; + this.parentId = parentId; + this.name = name; + this.record = record; + this.voiceConfId = voiceConfId; + this.durationInMinutes = duration; + this.autoStartRecording = autoStartRecording; + this.allowStartStopRecording = allowStartStopRecording; + this.moderatorPassword = moderatorPass; + this.viewerPassword = viewerPass; + this.createTime = createTime; + this.createDate = createDate; + this.isBreakout = isBreakout; + } } - } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomJoinURLPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomJoinURLPayload.java index 406a6c1a54..20509fba10 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomJoinURLPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomJoinURLPayload.java @@ -20,14 +20,14 @@ package org.bigbluebutton.messages.payload; public class BreakoutRoomJoinURLPayload { - public final String meetingId; - public final String breakoutId; + public final String parentMeetingId; + public final String breakoutMeetingId; public final String userId; public final String joinURL; - public BreakoutRoomJoinURLPayload(String meetingId, String breakoutId, String userId, String joinURL) { - this.meetingId = meetingId; - this.breakoutId = breakoutId; + public BreakoutRoomJoinURLPayload(String parentMeetingId, String breakoutMeetingId, String userId, String joinURL) { + this.parentMeetingId = parentMeetingId; + this.breakoutMeetingId = breakoutMeetingId; this.userId = userId; this.joinURL = joinURL; } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java index b21d95e836..4e7750549f 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java @@ -2,13 +2,13 @@ package org.bigbluebutton.messages.payload; public class BreakoutRoomPayload { + public final String parentMeetingId; public final String meetingId; - public final String breakoutId; public final String name; - public BreakoutRoomPayload(String meetingId, String breakoutId, String name) { + public BreakoutRoomPayload(String parentMeetingId, String meetingId, String name) { + this.parentMeetingId = parentMeetingId; this.meetingId = meetingId; - this.breakoutId = breakoutId; this.name = name; } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomRequestPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomRequestPayload.java index 87336f3f3d..20cceb76bc 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomRequestPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomRequestPayload.java @@ -3,13 +3,16 @@ package org.bigbluebutton.messages.payload; import java.util.ArrayList; public class BreakoutRoomRequestPayload { - // Name of the breakout room - public final String name; - // List of user ids to assign to the breakout room - public final ArrayList users; - - public BreakoutRoomRequestPayload(String name, ArrayList users) { - this.name = name; - this.users = users; - } + // Name of the breakout room + public final String name; + // Sequence of the breakout room + public final Integer sequence; + // List of user ids to assign to the breakout room + public final ArrayList users; + + public BreakoutRoomRequestPayload(String name, Integer sequence, ArrayList users) { + this.name = name; + this.sequence = sequence; + this.users = users; + } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java index b69987cd9d..8a2f72e9a5 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java @@ -1,8 +1,8 @@ package org.bigbluebutton.messages.payload; public class CreateBreakoutRoomRequestPayload { - public final String breakoutId; - public final String parentId; // The main meeting internal id + public final String breakoutMeetingId; + public final String parentMeetingId; // The main meeting internal id public final String name; // The name of the breakout room public final String voiceConfId; // The voice conference id public final String viewerPassword; @@ -12,13 +12,13 @@ public class CreateBreakoutRoomRequestPayload { public final Integer sourcePresentationSlide; public final Boolean record; - public CreateBreakoutRoomRequestPayload(String breakoutId, String parentId, + public CreateBreakoutRoomRequestPayload(String meetingMeetingId, String parentMeetingId, String name, String voiceConfId, String viewerPassword, String moderatorPassword, Integer duration, String sourcePresentationId, Integer sourcePresentationSlide, Boolean record) { - this.breakoutId = breakoutId; - this.parentId = parentId; + this.breakoutMeetingId = meetingMeetingId; + this.parentMeetingId = parentMeetingId; this.name = name; this.voiceConfId = voiceConfId; this.viewerPassword = viewerPassword; diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/ListenInOnBreakoutPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/ListenInOnBreakoutPayload.java index 1d3d3c51aa..aeed47d518 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/ListenInOnBreakoutPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/ListenInOnBreakoutPayload.java @@ -2,14 +2,14 @@ package org.bigbluebutton.messages.payload; public class ListenInOnBreakoutPayload { - public final String meetingId; - public final String targetMeetingId; - public final String userId; + public final String meetingId; + public final String targetMeetingId; + public final String userId; - public ListenInOnBreakoutPayload(String meetingId, String breakoutId, - String userId) { - this.meetingId = meetingId; - this.targetMeetingId = breakoutId; - this.userId = userId; - } + public ListenInOnBreakoutPayload(String meetingId, String targetMeetingId, + String userId) { + this.meetingId = meetingId; + this.targetMeetingId = targetMeetingId; + this.userId = userId; + } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java index 7c698c6c89..af5d0cb1dd 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java @@ -3,12 +3,12 @@ package org.bigbluebutton.messages.payload; public class RequestBreakoutJoinURLPayload { public final String meetingId; - public final String breakoutId; + public final String breakoutMeetingId; public final String userId; - public RequestBreakoutJoinURLPayload(String meetingId, String breakoutId, String userId) { + public RequestBreakoutJoinURLPayload(String meetingId, String breakoutMeetingId, String userId) { this.meetingId = meetingId; - this.breakoutId = breakoutId; + this.breakoutMeetingId = breakoutMeetingId; this.userId = userId; } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/UpdateBreakoutUsersPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/UpdateBreakoutUsersPayload.java index f96d2ca064..84810e44ca 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/UpdateBreakoutUsersPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/UpdateBreakoutUsersPayload.java @@ -5,12 +5,12 @@ import java.util.ArrayList; public class UpdateBreakoutUsersPayload { public final ArrayList users; - public final String breakoutId; - public final String meetingId; + public final String breakoutMeetingId; + public final String parentMeetingId; - public UpdateBreakoutUsersPayload(String meetingId, String breakoutId, ArrayList users) { - this.meetingId = meetingId; - this.breakoutId = breakoutId; + public UpdateBreakoutUsersPayload(String meetingParentId, String breakoutMeetingId, ArrayList users) { + this.parentMeetingId = meetingParentId; + this.breakoutMeetingId = breakoutMeetingId; this.users = users; } } diff --git a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java index e520494a35..2bba6706f0 100755 --- a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java +++ b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java @@ -31,7 +31,7 @@ public class CreateBreakoutRoomRequestTest { CreateBreakoutRoomRequest rxMsg = gson.fromJson(json, CreateBreakoutRoomRequest.class); Assert.assertEquals(rxMsg.header.name, CreateBreakoutRoomRequest.NAME); - Assert.assertEquals(rxMsg.payload.breakoutId, breakoutId); + Assert.assertEquals(rxMsg.payload.breakoutMeetingId, breakoutId); Assert.assertEquals(rxMsg.payload.name, name); Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId); Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword); diff --git a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java index 48c91e0b9f..a0c780b360 100755 --- a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java +++ b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java @@ -18,15 +18,15 @@ public class CreateBreakoutRoomsRequestTest { ArrayList room1Users = new ArrayList(); room1Users.add("Tidora"); room1Users.add("Nidora"); room1Users.add("Tinidora"); - BreakoutRoomRequestPayload room1 = new BreakoutRoomRequestPayload("room1", room1Users); + BreakoutRoomRequestPayload room1 = new BreakoutRoomRequestPayload("room1", 1, room1Users); ArrayList room2Users = new ArrayList(); room2Users.add("Jose"); room2Users.add("Wally"); room2Users.add("Paolo"); - BreakoutRoomRequestPayload room2= new BreakoutRoomRequestPayload("room2", room2Users); + BreakoutRoomRequestPayload room2= new BreakoutRoomRequestPayload("room2", 2, room2Users); ArrayList room3Users = new ArrayList(); room3Users.add("Alden"); room3Users.add("Yaya Dub"); - BreakoutRoomRequestPayload room3= new BreakoutRoomRequestPayload("room3", room3Users); + BreakoutRoomRequestPayload room3= new BreakoutRoomRequestPayload("room3", 3, room3Users); ArrayList rooms = new ArrayList(); rooms.add(room1); rooms.add(room2); rooms.add(room3); diff --git a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java index 476f8efbe2..133d277f3f 100755 --- a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java +++ b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java @@ -12,6 +12,7 @@ public class CreateMeetingRequestTest { public void testCreateMeetingRequest() { String meetingId = "abc123"; String externalId = "extabc123"; + String parentId = ""; Boolean record = false; Integer durationInMinutes = 20; String name = "Breakout room 1"; @@ -24,11 +25,11 @@ public class CreateMeetingRequestTest { long createTime = System.currentTimeMillis(); String createDate = new Date(createTime).toString(); - CreateMeetingRequestPayload payload = - new CreateMeetingRequestPayload(meetingId, externalId, name, record, voiceConfId, - durationInMinutes, autoStartRecording, - allowStartStopRecording, moderatorPassword, - viewerPassword, createTime, createDate, isBreakout); + CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload( + meetingId, externalId, parentId, name, record, voiceConfId, + durationInMinutes, autoStartRecording, allowStartStopRecording, + moderatorPassword, viewerPassword, createTime, createDate, + isBreakout); CreateMeetingRequest msg = new CreateMeetingRequest(payload); Gson gson = new Gson(); String json = gson.toJson(msg); @@ -38,6 +39,8 @@ public class CreateMeetingRequestTest { Assert.assertEquals(rxMsg.header.name, CreateMeetingRequest.NAME); Assert.assertEquals(rxMsg.payload.id, meetingId); + Assert.assertEquals(rxMsg.payload.externalId, externalId); + Assert.assertEquals(rxMsg.payload.parentId, parentId); Assert.assertEquals(rxMsg.payload.name, name); Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId); Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java index ec68c34394..2f90996207 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java @@ -44,7 +44,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; - public class UserClientMessageSender { private static Logger log = Red5LoggerFactory.getLogger(UserClientMessageSender.class, "bigbluebutton"); @@ -543,8 +542,8 @@ public class UserClientMessageSender { private void processBreakoutRoomJoinURL(BreakoutRoomJoinURL msg) { Map args = new HashMap(); - args.put("meetingId", msg.payload.meetingId); - args.put("breakoutId", msg.payload.breakoutId); + args.put("parentMeetingId", msg.payload.parentMeetingId); + args.put("breakoutMeetingId", msg.payload.breakoutMeetingId); args.put("userId", msg.payload.userId); args.put("joinURL", msg.payload.joinURL); @@ -552,7 +551,7 @@ public class UserClientMessageSender { Gson gson = new Gson(); message.put("msg", gson.toJson(args)); - DirectClientMessage m = new DirectClientMessage(msg.payload.meetingId, msg.payload.userId, "breakoutRoomJoinURL", message); + DirectClientMessage m = new DirectClientMessage(msg.payload.parentMeetingId, msg.payload.userId, "breakoutRoomJoinURL", message); service.sendMessage(m); } @@ -584,42 +583,42 @@ public class UserClientMessageSender { private void processUpdateBreakoutUsers(UpdateBreakoutUsers msg) { Map args = new HashMap(); - args.put("meetingId", msg.payload.meetingId); - args.put("breakoutId", msg.payload.breakoutId); + args.put("parentMeetingId", msg.payload.parentMeetingId); + args.put("breakoutMeetingId", msg.payload.breakoutMeetingId); args.put("users", msg.payload.users); Map message = new HashMap(); Gson gson = new Gson(); message.put("msg", gson.toJson(args)); - BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "updateBreakoutUsers", message); + BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "updateBreakoutUsers", message); service.sendMessage(m); } private void processBreakoutRoomStarted(BreakoutRoomStarted msg) { Map args = new HashMap(); - args.put("breakoutId", msg.payload.breakoutId); - args.put("meetingId", msg.payload.meetingId); + args.put("breakoutMeetingId", msg.payload.meetingId); + args.put("parentMeetingId", msg.payload.parentMeetingId); args.put("name", msg.payload.name); Map message = new HashMap(); Gson gson = new Gson(); message.put("msg", gson.toJson(args)); - BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomStarted", message); + BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomStarted", message); service.sendMessage(m); } private void processBreakoutRoomClosed(BreakoutRoomClosed msg) { Map args = new HashMap(); - args.put("breakoutId", msg.payload.breakoutId); - args.put("meetingId", msg.payload.meetingId); + args.put("breakoutMeetingId", msg.payload.meetingId); + args.put("parentMeetingId", msg.payload.parentMeetingId); Map message = new HashMap(); Gson gson = new Gson(); message.put("msg", gson.toJson(args)); - BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomClosed", message); + BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomClosed", message); service.sendMessage(m); } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as b/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as index c7201daa9d..0bfb85e162 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as @@ -39,7 +39,7 @@ package org.bigbluebutton.main.events { public var meetingId:String; - public var breakoutId:String; + public var breakoutMeetingId:String; public var rooms:Array; diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as index b94a55ee3d..1e3b7e2109 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as @@ -28,7 +28,9 @@ package org.bigbluebutton.main.model.users { public static const OTHER:String = "other"; - public var breakoutId:String; + public var meetingId:String; + + public var sequence:int; public var name:String; @@ -44,6 +46,5 @@ package org.bigbluebutton.main.model.users { public function get numberOfUsers():int { return users.length; } - } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as index c899cfc0d0..5698d7a9a8 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as @@ -534,18 +534,17 @@ package org.bigbluebutton.main.model.users { /* Breakout room feature */ public function addBreakoutRoom(newRoom:BreakoutRoom):void { - if (hasBreakoutRoom(newRoom.breakoutId)) { - removeBreakoutRoom(newRoom.breakoutId); + if (hasBreakoutRoom(newRoom.meetingId)) { + removeBreakoutRoom(newRoom.meetingId); } breakoutRooms.addItem(newRoom); breakoutRooms.refresh(); } - public function updateBreakoutRoomUsers(breakoutId:String, breakoutUsers:Array):void { - var room:Object = getBreakoutRoom(breakoutId); + public function updateBreakoutRoomUsers(breakoutMeetingId:String, breakoutUsers:Array):void { + var room:Object = getBreakoutRoom(breakoutMeetingId); if (room != null) { BreakoutRoom(room).users = new ArrayCollection(breakoutUsers); - var breakoutRoomNumber:String = StringUtils.substringAfterLast(breakoutId, "-"); var updateUsers:Array = []; // Update users breakout rooms var user : BBBUser; @@ -553,15 +552,15 @@ package org.bigbluebutton.main.model.users { var userId:String = StringUtils.substringBeforeLast(breakoutUsers[i].id, "-"); user = getUser(userId); if (user) { - user.addBreakoutRoom(breakoutRoomNumber) + user.addBreakoutRoom(breakoutMeetingId) } updateUsers.push(userId); } // Remove users breakout rooms if the users left the breakout rooms for (var j:int = 0; j < users.length; j++) { user = BBBUser(users.getItemAt(j)); - if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, breakoutRoomNumber)) { - user.removeBreakoutRoom(breakoutRoomNumber); + if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, breakoutMeetingId)) { + user.removeBreakoutRoom(breakoutMeetingId); } } users.refresh(); @@ -569,10 +568,10 @@ package org.bigbluebutton.main.model.users { } /** - * Returns a breakout room by its breakoutId + * Returns a breakout room by its internal meeting ID */ - public function getBreakoutRoom(breakoutId:String):BreakoutRoom { - var r:Object = getBreakoutRoomIndex(breakoutId); + public function getBreakoutRoom(breakoutMeetingId:String):BreakoutRoom { + var r:Object = getBreakoutRoomIndex(breakoutMeetingId); if (r != null) { return r.room as BreakoutRoom; } @@ -580,13 +579,13 @@ package org.bigbluebutton.main.model.users { } /** - * Finds the index of a breakout room by its breakoutId + * Finds the index of a breakout room by its internal meeting ID */ - public function getBreakoutRoomIndex(breakoutId:String):Object { + public function getBreakoutRoomIndex(breakoutMeetingId:String):Object { var aRoom:BreakoutRoom; for (var i:int = 0; i < breakoutRooms.length; i++) { aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom; - if (aRoom.breakoutId == breakoutId) { + if (aRoom.meetingId == breakoutMeetingId) { return {index: i, room: aRoom}; } } @@ -594,8 +593,8 @@ package org.bigbluebutton.main.model.users { return null; } - public function removeBreakoutRoom(breakoutId:String):void { - var p:Object = getBreakoutRoomIndex(breakoutId); + public function removeBreakoutRoom(breakoutMeetingId:String):void { + var p:Object = getBreakoutRoomIndex(breakoutMeetingId); if (p != null) { breakoutRooms.removeItemAt(p.index); breakoutRooms.refresh(); @@ -604,29 +603,28 @@ package org.bigbluebutton.main.model.users { } // Remove breakout room number display from users for (var i:int; i < users.length; i++) { - var breakoutRoomNumber:String = StringUtils.substringAfterLast(breakoutId, "-"); - if (ArrayUtils.contains(users[i].breakoutRooms, breakoutRoomNumber)) { - users[i].removeBreakoutRoom(breakoutRoomNumber); + if (ArrayUtils.contains(users[i].breakoutRooms, breakoutMeetingId)) { + users[i].removeBreakoutRoom(breakoutMeetingId); } } users.refresh(); } } - public function hasBreakoutRoom(breakoutId:String):Boolean { - var p:Object = getBreakoutRoomIndex(breakoutId); + public function hasBreakoutRoom(breakoutMeetingId:String):Boolean { + var p:Object = getBreakoutRoomIndex(breakoutMeetingId); if (p != null) { return true; } return false; } - public function setBreakoutRoomInListen(listen:Boolean, breakoutId:String):void { + public function setBreakoutRoomInListen(listen:Boolean, breakoutMeetingId:String):void { for (var i:int = 0; i < breakoutRooms.length; i++) { var br:BreakoutRoom = BreakoutRoom(breakoutRooms.getItemAt(i)); if (listen == false) { br.listenStatus = BreakoutRoom.NONE; - } else if (listen == true && br.breakoutId == breakoutId) { + } else if (listen == true && br.meetingId == breakoutMeetingId) { br.listenStatus = BreakoutRoom.SELF; } else { br.listenStatus = BreakoutRoom.OTHER; diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as index c7900216e4..82111fe31f 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as @@ -203,16 +203,16 @@ package org.bigbluebutton.main.model.users } public function requestBreakoutJoinUrl(e:BreakoutRoomEvent):void{ - sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutId, e.userId); + sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutMeetingId, e.userId); } public function listenInOnBreakout(e:BreakoutRoomEvent):void { if (e.listen) { - sender.listenInOnBreakout(_conferenceParameters.meetingID, e.breakoutId, _conferenceParameters.userid); + sender.listenInOnBreakout(_conferenceParameters.meetingID, e.breakoutMeetingId, _conferenceParameters.userid); } else { - sender.listenInOnBreakout(e.breakoutId, _conferenceParameters.meetingID, _conferenceParameters.userid); + sender.listenInOnBreakout(e.breakoutMeetingId, _conferenceParameters.meetingID, _conferenceParameters.userid); } - UserManager.getInstance().getConference().setBreakoutRoomInListen(e.listen, e.breakoutId); + UserManager.getInstance().getConference().setBreakoutRoomInListen(e.listen, e.breakoutMeetingId); } public function endAllBreakoutRooms(e:BreakoutRoomEvent):void { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as index 4c40e2923b..0a018df32f 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as @@ -46,16 +46,7 @@ package org.bigbluebutton.modules.users.services import org.bigbluebutton.main.model.users.IMessageListener; import org.bigbluebutton.main.model.users.events.StreamStoppedEvent; import org.bigbluebutton.main.model.users.events.UsersConnectionEvent; - import org.bigbluebutton.modules.users.events.MeetingMutedEvent; - - import org.bigbluebutton.modules.present.events.CursorEvent; - import org.bigbluebutton.modules.present.events.NavigationEvent; - import org.bigbluebutton.modules.present.events.RemovePresentationEvent; - import org.bigbluebutton.modules.present.events.UploadEvent; - import org.bigbluebutton.modules.users.events.MeetingMutedEvent; - import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent; import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent; - import org.bigbluebutton.main.api.JSLog; import org.bigbluebutton.modules.users.events.MeetingMutedEvent; public class MessageReceiver implements IMessageListener @@ -156,8 +147,8 @@ package org.bigbluebutton.modules.users.services handleTimeRemainingUpdate(message); break; case "breakoutRoomsTimeRemainingUpdate": - handleBreakoutRoomsTimeRemainingUpdate(message); - break; + handleBreakoutRoomsTimeRemainingUpdate(message); + break; case "breakoutRoomStarted": handleBreakoutRoomStarted(message); break; @@ -639,7 +630,7 @@ package org.bigbluebutton.modules.users.services for each(var room : Object in map.rooms) { var breakoutRoom : BreakoutRoom = new BreakoutRoom(); - breakoutRoom.breakoutId = room.breakoutId; + breakoutRoom.meetingId = room.meetingId; breakoutRoom.name = room.name; UserManager.getInstance().getConference().addBreakoutRoom(breakoutRoom); } @@ -650,13 +641,13 @@ package org.bigbluebutton.modules.users.services var map:Object = JSON.parse(msg.msg); var event : BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.BREAKOUT_JOIN_URL); event.joinURL = map.joinURL; - event.breakoutId = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); + event.breakoutMeetingId = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); dispatcher.dispatchEvent(event); } private function handleUpdateBreakoutUsers(msg:Object):void{ var map:Object = JSON.parse(msg.msg); - UserManager.getInstance().getConference().updateBreakoutRoomUsers(map.breakoutId, map.users); + UserManager.getInstance().getConference().updateBreakoutRoomUsers(map.breakoutMeetingId, map.users); } private function handleTimeRemainingUpdate(msg:Object):void { @@ -676,14 +667,14 @@ package org.bigbluebutton.modules.users.services private function handleBreakoutRoomStarted(msg:Object):void{ var map:Object = JSON.parse(msg.msg); var breakoutRoom : BreakoutRoom = new BreakoutRoom(); - breakoutRoom.breakoutId = map.breakoutId; + breakoutRoom.meetingId = map.breakoutMeetingId; breakoutRoom.name = map.name; UserManager.getInstance().getConference().addBreakoutRoom(breakoutRoom); } private function handleBreakoutRoomClosed(msg:Object):void{ var map:Object = JSON.parse(msg.msg); - UserManager.getInstance().getConference().removeBreakoutRoom(map.breakoutId); + UserManager.getInstance().getConference().removeBreakoutRoom(map.breakoutMeetingId); } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as index a1ad1da52b..bda7ed2cb5 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as @@ -107,10 +107,10 @@ package org.bigbluebutton.modules.users.services ); } - public function requestBreakoutJoinUrl(meetingId:String, breakoutId:String, userId:String):void { + public function requestBreakoutJoinUrl(parentMeetingId:String, breakoutMeetingId:String, userId:String):void { var message:Object = new Object(); - message["meetingId"] = meetingId; - message["breakoutId"] = breakoutId; + message["meetingId"] = parentMeetingId; + message["breakoutMeetingId"] = breakoutMeetingId; message["userId"] = userId; var jsonMsg:String = JSON.stringify(message); diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml index 13075f7fcd..fa4bb4f33b 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml @@ -65,15 +65,15 @@ with BigBlueButton; if not, see . var event:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.CREATE_BREAKOUT_ROOMS); // event.meetingId is filled in the event handler for BreakoutRoomEvent in UserService class event.rooms = new Array(); + var parentMeetingName:String = UserManager.getInstance().getConference().meetingName; + var roomResource:String = ResourceUtil.getInstance().getString('bbb.users.breakout.room'); for (var i:int = 0; i < (roomsCombo.selectedIndex + 2); i++) { var users:Array = BreakoutList(roomsContainer.getChildAt(i)).users.source; totalUsers += users.length; var room:Object = new Object(); room.users = new Array(); - room.name = - UserManager.getInstance().getConference().meetingName + " (" + - ResourceUtil.getInstance().getString('bbb.users.breakout.room') - + " - " + (i + 1).toString() + ")"; + room.sequence = i + 1; + room.name = parentMeetingName + " (" + roomResource + " - " + room.sequence.toString() + ")"; for (var j:int = 0; j < users.length; j++) { room.users.push(users[j].userID); } @@ -102,10 +102,11 @@ with BigBlueButton; if not, see . for (var u:int = 0; u < list.users.length; u++) { user = list.users.getItemAt(u) as BBBUser; if (user.breakoutRooms.length == 0) { + //@todo: refactor usersInvited ||= true; var event:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.REQUEST_BREAKOUT_JOIN_URL); event.userId = user.userID; - event.breakoutId = UserManager.getInstance().getConference().internalMeetingID + "-" + (i + 1); + event.breakoutMeetingId = UserManager.getInstance().getConference().internalMeetingID + "-" + (i + 1); dispatcher.dispatchEvent(event); } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml index bf5ccf4390..3ab46d4391 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml @@ -37,14 +37,14 @@ protected function listenToBreakoutRoom(event:MouseEvent):void { var e:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.LISTEN_IN); - e.breakoutId = data.breakoutId as String; + e.breakoutMeetingId = data.meetingId as String; e.listen = listenBtn.selected; globalDispatch.dispatchEvent(e); } protected function requestBreakoutJoinUrl(event:MouseEvent):void { var e:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.REQUEST_BREAKOUT_JOIN_URL); - e.breakoutId = data.breakoutId as String; + e.breakoutMeetingId = data.meetingId as String; e.userId = UserManager.getInstance().getConference().getMyUserId(); globalDispatch.dispatchEvent(e); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml index 728d2016de..5bc7880243 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml @@ -343,7 +343,8 @@ // We display only one alert removeJoinAlert(); joinAlert = Alert.show( - ResourceUtil.getInstance().getString('bbb.users.breakout.openJoinURL', [StringUtils.substringAfterLast(event.breakoutId, "-")]), + //@todo: refactor + ResourceUtil.getInstance().getString('bbb.users.breakout.openJoinURL', [StringUtils.substringAfterLast(event.breakoutMeetingId, "-")]), ResourceUtil.getInstance().getString('bbb.users.breakout.confirm'), Alert.YES | Alert.NO, null, @@ -514,7 +515,7 @@ var br:BreakoutRoom = UserManager.getInstance().getConference().getBreakoutRoomInListen(); if (br != null) { var e:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.LISTEN_IN); - e.breakoutId = br.breakoutId; + e.breakoutMeetingId = br.meetingId; e.listen = false; dispatcher.dispatchEvent(e); } @@ -595,7 +596,7 @@ } private function breakoutRoomNameLabelFunction(item:Object, column:DataGridColumn) : String { - return ResourceUtil.getInstance().getString('bbb.users.roomsGrid.room') + " " + StringUtils.substringAfterLast(item.breakoutId, "-"); + return ResourceUtil.getInstance().getString('bbb.users.roomsGrid.room') + " " + item.sequence; } ]]> @@ -633,7 +634,7 @@ - diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index ef9d2b8918..17bebd8ee5 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -869,6 +869,7 @@ class ApiController { meeting { meetingID() { mkp.yield(m.getExternalId()) } internalMeetingID() { mkp.yield(m.getInternalId()) } + parentMeetingID() { mkp.yield(m.getParentMeetingId()) } isBreakout() { mkp.yield(m.isBreakout()) } meetingName() { mkp.yield(m.getName()) } createTime(m.getCreateTime()) @@ -2136,6 +2137,7 @@ class ApiController { isBreakout() { mkp.yield(meeting.isBreakout()) } meetingID() { mkp.yield(meeting.getExternalId()) } internalMeetingID(meeting.getInternalId()) + parentMeetingID() { mkp.yield(meeting.getParentMeetingId()) } createTime(meeting.getCreateTime()) createDate(formatPrettyDate(meeting.getCreateTime())) voiceBridge() { mkp.yield(meeting.getTelVoice()) } @@ -2196,6 +2198,7 @@ class ApiController { returncode(RESP_CODE_SUCCESS) meetingID() { mkp.yield(meeting.getExternalId()) } internalMeetingID() { mkp.yield(meeting.getInternalId()) } + parentMeetingID() { mkp.yield(meeting.getParentMeetingId()) } attendeePW() { mkp.yield(meeting.getViewerPassword()) } moderatorPW() { mkp.yield(meeting.getModeratorPassword()) } createTime(meeting.getCreateTime()) diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java index afbb19b22a..9a2f760223 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java @@ -301,6 +301,10 @@ public class MeetingService implements MessageListener { // TODO: Need a better way to store these values for recordings metadata.put("meetingId", m.getExternalId()); metadata.put("meetingName", m.getName()); + metadata.put("isBreakout", m.isBreakout().toString()); + if (m.isBreakout() != null){ + metadata.put("parentMeetingId", m.getParentMeetingId()); + } messagingService.recordMeetingInfo(m.getInternalId(), metadata); } @@ -308,8 +312,12 @@ public class MeetingService implements MessageListener { Map logData = new HashMap(); logData.put("meetingId", m.getInternalId()); logData.put("externalMeetingId", m.getExternalId()); + if (m.isBreakout() != null){ + logData.put("parentMeetingId", m.getParentMeetingId()); + } logData.put("name", m.getName()); logData.put("duration", m.getDuration()); + logData.put("isBreakout", m.isBreakout()); logData.put("record", m.isRecord()); logData.put("event", "create_meeting"); logData.put("description", "Create meeting."); @@ -320,11 +328,11 @@ public class MeetingService implements MessageListener { log.info("Create meeting: data={}", logStr); messagingService.createMeeting(m.getInternalId(), m.getExternalId(), - m.getName(), m.isRecord(), m.getTelVoice(), m.getDuration(), - m.getAutoStartRecording(), m.getAllowStartStopRecording(), - m.getModeratorPassword(), m.getViewerPassword(), - m.getCreateTime(), formatPrettyDate(m.getCreateTime()), - m.isBreakout()); + m.getParentMeetingId(), m.getName(), m.isRecord(), + m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), + m.getAllowStartStopRecording(), m.getModeratorPassword(), + m.getViewerPassword(), m.getCreateTime(), + formatPrettyDate(m.getCreateTime()), m.isBreakout()); } private String formatPrettyDate(Long timestamp) { @@ -515,20 +523,20 @@ public class MeetingService implements MessageListener { } private void processCreateBreakoutRoom(CreateBreakoutRoom message) { - Meeting parentMeeting = getMeeting(message.parentId); + Meeting parentMeeting = getMeeting(message.parentMeetingId); if (parentMeeting != null) { Map params = new HashMap(); params.put("name", message.name); - params.put("breakoutId", message.breakoutId); - params.put("meetingID", message.parentId); + params.put("meetingID", message.meetingId); + params.put("parentMeetingID", message.parentMeetingId); params.put("isBreakout", "true"); params.put("attendeePW", message.viewerPassword); params.put("moderatorPW", message.moderatorPassword); params.put("voiceBridge", message.voiceConfId); params.put("duration", message.durationInMinutes.toString()); params.put("record", message.record.toString()); - params.put("welcome", getMeeting(message.parentId) + params.put("welcome", getMeeting(message.parentMeetingId) .getWelcomeMessageTemplate()); Map parentMeetingMetadata = parentMeeting @@ -545,17 +553,17 @@ public class MeetingService implements MessageListener { handleCreateMeeting(breakout); - presDownloadService.extractPage(message.parentId, + presDownloadService.extractPage(message.parentMeetingId, message.sourcePresentationId, message.sourcePresentationSlide, breakout.getInternalId()); } else { - log.error("Failed to create breakout room " + message.breakoutId + log.error("Failed to create breakout room " + message.meetingId + ".Reason: Parent meeting not found."); } } private void processEndBreakoutRoom(EndBreakoutRoom message) { - processEndMeeting(new EndMeeting(message.breakoutId)); + processEndMeeting(new EndMeeting(message.breakoutMeetingId)); } private void processEndMeeting(EndMeeting message) { @@ -591,6 +599,9 @@ public class MeetingService implements MessageListener { Map logData = new HashMap(); logData.put("meetingId", m.getInternalId()); logData.put("externalMeetingId", m.getExternalId()); + if (m.isBreakout()) { + logData.put("parentMeetingId", m.getParentMeetingId()); + } logData.put("name", m.getName()); logData.put("duration", m.getDuration()); logData.put("record", m.isRecord()); @@ -601,11 +612,14 @@ public class MeetingService implements MessageListener { Gson gson = new Gson(); String logStr = gson.toJson(logData); - log.info("Meeting restarted: data={}", logStr); + log.info("Meeting started: data={}", logStr); } else { Map logData = new HashMap(); logData.put("meetingId", m.getInternalId()); logData.put("externalMeetingId", m.getExternalId()); + if (m.isBreakout()) { + logData.put("parentMeetingId", m.getParentMeetingId()); + } logData.put("name", m.getName()); logData.put("duration", m.getDuration()); logData.put("record", m.isRecord()); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java index 37517ec569..91296c545b 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -361,11 +361,13 @@ public class ParamsProcessorUtil { internalMeetingId = internalMeetingId + '-' + new Long(createTime).toString(); // If this create meeting request is for a breakout room, we just used - // the passed in breakoutId as the internal meetingId so we can - // correlate - // the breakout meeting with it's parent meeting. + // we need to generate a unique internal and external id and keep + // tracks of the parent meeting id + String parentMeetingId = new String(); if (isBreakout) { - internalMeetingId = params.get("breakoutId"); + externalMeetingId = internalMeetingId; + internalMeetingId = params.get("meetingID"); + parentMeetingId = params.get("parentMeetingID"); } // Create the meeting with all passed in parameters. @@ -382,6 +384,7 @@ public class ParamsProcessorUtil { .withMetadata(meetingInfo) .withWelcomeMessageTemplate(welcomeMessageTemplate) .withWelcomeMessage(welcomeMessage).isBreakout(isBreakout) + .withParentMeetingId(parentMeetingId) .build(); String configXML = getDefaultConfigXML(); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java index 6e2d568fa5..b5aff604b0 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java @@ -21,11 +21,11 @@ package org.bigbluebutton.api.domain; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; + import org.apache.commons.lang.RandomStringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,7 +37,8 @@ public class Meeting { private String name; private String extMeetingId; - private String intMeetingId; + private String intMeetingId; + private String parentMeetingId; private Integer duration = 0; private long createdTime = 0; private long startTime = 0; @@ -72,6 +73,7 @@ public class Meeting { name = builder.name; extMeetingId = builder.externalId; intMeetingId = builder.internalId; + parentMeetingId = builder.parentMeetingId; viewerPass = builder.viewerPass; moderatorPass = builder.moderatorPass; maxUsers = builder.maxUsers; @@ -200,6 +202,10 @@ public class Meeting { public String getInternalId() { return intMeetingId; } + + public String getParentMeetingId() { + return parentMeetingId; + } public String getWebVoice() { return webVoice; @@ -375,7 +381,8 @@ public class Meeting { public static class Builder { private String name; private String externalId; - private String internalId; + private String internalId; + private String parentMeetingId; private int maxUsers; private boolean record; private boolean autoStartRecording; @@ -399,12 +406,17 @@ public class Meeting { this.internalId = internalId; this.createdTime = createTime; } - + + public Builder withParentMeetingId(String parentMeetingId) { + this.parentMeetingId = parentMeetingId; + return this; + } + public Builder withName(String name) { this.name = name; return this; } - + public Builder withDuration(int minutes) { duration = minutes; return this; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java index 4c67e5cee9..593427554a 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java @@ -72,8 +72,8 @@ public class MeetingMessageHandler implements MessageHandler { CreateBreakoutRoomRequest msg = new Gson().fromJson(message, CreateBreakoutRoomRequest.class); for (MessageListener listener : listeners) { listener.handle(new CreateBreakoutRoom( - msg.payload.breakoutId, - msg.payload.parentId, + msg.payload.breakoutMeetingId, + msg.payload.parentMeetingId, msg.payload.name, msg.payload.voiceConfId, msg.payload.viewerPassword, diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java index 19f8ef24db..d445d6d017 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java @@ -29,10 +29,12 @@ import java.util.Set; public interface MessagingService { void recordMeetingInfo(String meetingId, Map info); void destroyMeeting(String meetingID); - void createMeeting(String meetingID, String externalMeetingID, String meetingName, Boolean recorded, - String voiceBridge, Integer duration, Boolean autoStartRecording, - Boolean allowStartStopRecording, String moderatorPass, String viewerPass, - Long createTime, String createDate, Boolean isBreakout); + void createMeeting(String meetingID, String externalMeetingID, + String parentMeetingID, String meetingName, Boolean recorded, + String voiceBridge, Integer duration, Boolean autoStartRecording, + Boolean allowStartStopRecording, String moderatorPass, + String viewerPass, Long createTime, String createDate, + Boolean isBreakout); void endMeeting(String meetingId); void send(String channel, String message); void sendPolls(String meetingId, String title, String question, String questionType, List answers); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java index 206df68b15..e74a530b08 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java @@ -19,28 +19,27 @@ package org.bigbluebutton.api.messaging; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.*; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import javax.imageio.ImageIO; +import java.util.Set; + import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage; import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage; import org.bigbluebutton.api.messaging.converters.messages.RegisterUserMessage; import org.bigbluebutton.common.converters.ToJsonEncoder; +import org.bigbluebutton.common.messages.Constants; import org.bigbluebutton.common.messages.MessagingConstants; +import org.bigbluebutton.common.messages.SendStunTurnInfoReplyMessage; import org.bigbluebutton.messages.CreateMeetingRequest; import org.bigbluebutton.messages.CreateMeetingRequest.CreateMeetingRequestPayload; -import org.bigbluebutton.common.messages.Constants; -import org.bigbluebutton.common.messages.PubSubPingMessage; -import org.bigbluebutton.common.messages.payload.PubSubPingMessagePayload; -import org.bigbluebutton.common.messages.SendStunTurnInfoReplyMessage; import org.bigbluebutton.web.services.turn.StunServer; import org.bigbluebutton.web.services.turn.TurnEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import com.google.gson.Gson; public class RedisMessagingService implements MessagingService { @@ -68,22 +67,24 @@ public class RedisMessagingService implements MessagingService { sender.send(MessagingConstants.TO_MEETING_CHANNEL, json); } - public void createMeeting(String meetingID, String externalMeetingID, String meetingName, Boolean recorded, - String voiceBridge, Integer duration, - Boolean autoStartRecording, Boolean allowStartStopRecording, - String moderatorPass, String viewerPass, Long createTime, - String createDate, Boolean isBreakout) { - CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload(meetingID, externalMeetingID, meetingName, - recorded, voiceBridge, duration, - autoStartRecording, allowStartStopRecording, - moderatorPass, viewerPass, createTime, createDate, isBreakout); - CreateMeetingRequest msg = new CreateMeetingRequest(payload); - - Gson gson = new Gson(); - String json = gson.toJson(msg); - log.info("Sending create meeting message to bbb-apps:[{}]", json); - sender.send(MessagingConstants.TO_MEETING_CHANNEL, json); - } + public void createMeeting(String meetingID, String externalMeetingID, + String parentMeetingID, String meetingName, Boolean recorded, + String voiceBridge, Integer duration, Boolean autoStartRecording, + Boolean allowStartStopRecording, String moderatorPass, + String viewerPass, Long createTime, String createDate, + Boolean isBreakout) { + CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload( + meetingID, externalMeetingID, parentMeetingID, meetingName, + recorded, voiceBridge, duration, autoStartRecording, + allowStartStopRecording, moderatorPass, viewerPass, createTime, + createDate, isBreakout); + CreateMeetingRequest msg = new CreateMeetingRequest(payload); + + Gson gson = new Gson(); + String json = gson.toJson(msg); + log.info("Sending create meeting message to bbb-apps:[{}]", json); + sender.send(MessagingConstants.TO_MEETING_CHANNEL, json); + } public void endMeeting(String meetingId) { EndMeetingMessage msg = new EndMeetingMessage(meetingId); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java index 1ef6057438..8b3eaf4431 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java @@ -2,8 +2,8 @@ package org.bigbluebutton.api.messaging.messages; public class CreateBreakoutRoom implements IMessage { - public final String breakoutId; - public final String parentId; // The main meeting internal id + public final String meetingId; + public final String parentMeetingId; // The main meeting internal id public final String name; // The name of the breakout room public final String voiceConfId; // The voice conference id public final String viewerPassword; @@ -13,13 +13,13 @@ public class CreateBreakoutRoom implements IMessage { public final Integer sourcePresentationSlide; public final Boolean record; - public CreateBreakoutRoom(String breakoutId, String parentId, String name, + public CreateBreakoutRoom(String meetingId, String parentMeetingId, String name, String voiceConfId, String viewerPassword, String moderatorPassword, Integer duration, String sourcePresentationId, Integer sourcePresentationSlide, Boolean record) { - this.breakoutId = breakoutId; - this.parentId = parentId; + this.meetingId = meetingId; + this.parentMeetingId = parentMeetingId; this.name = name; this.voiceConfId = voiceConfId; this.viewerPassword = viewerPassword; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/EndBreakoutRoom.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/EndBreakoutRoom.java index dc5c2b3683..c996f31de9 100644 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/EndBreakoutRoom.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/EndBreakoutRoom.java @@ -1,9 +1,9 @@ package org.bigbluebutton.api.messaging.messages; public class EndBreakoutRoom implements IMessage { - public final String breakoutId; + public final String breakoutMeetingId; - public EndBreakoutRoom(String breakoutId) { - this.breakoutId = breakoutId; + public EndBreakoutRoom(String breakoutMeetingId) { + this.breakoutMeetingId = breakoutMeetingId; } } From c95d208da7f254beb0a4aaac497426e10bdde2c1 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Tue, 11 Oct 2016 22:13:22 +0100 Subject: [PATCH 03/22] Added sequence property breakout room. --- .../core/JsonMessageSenderActor.scala | 6 +++--- .../bigbluebutton/core/api/OutMessages.scala | 2 +- .../core/apps/BreakoutRoomApp.scala | 8 ++++---- .../MeetingMessageToJsonConverter.scala | 1 + .../messages/payload/BreakoutRoomPayload.java | 19 +++++++++++-------- .../red5/client/UserClientMessageSender.java | 1 + .../main/events/BreakoutRoomEvent.as | 2 ++ .../modules/users/services/MessageReceiver.as | 6 +++++- .../modules/users/views/UsersWindow.mxml | 3 +-- 9 files changed, 29 insertions(+), 19 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala index 56680d48d4..4f2a4568ed 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala @@ -52,13 +52,13 @@ class JsonMessageSenderActor(val service: MessageSender) // Breakout private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) { - val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.name) + val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, 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, "") + val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "", 0) val request = new BreakoutRoomClosed(payload) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) } @@ -85,7 +85,7 @@ class JsonMessageSenderActor(val service: MessageSender) 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.name))) + msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.meetingId, 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()) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala index 19d6a828f6..d4c64c53ae 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala @@ -36,7 +36,7 @@ case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, paren sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean) case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, joinURL: String) extends IOutMessage case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage -case class BreakoutRoomBody(name: String, meetingId: String) +case class BreakoutRoomBody(name: String, meetingId: String, sequence: Int) case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends IOutMessage case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 2af20f383b..7b719b9e7e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -21,7 +21,7 @@ trait BreakoutRoomApp extends SystemConfiguration { val eventBus: IncomingEventBus def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) { - val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id) } + val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id, r.sequence) } val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0 log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length) outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady )) @@ -74,7 +74,7 @@ trait BreakoutRoomApp extends SystemConfiguration { breakoutModel.pendingRoomsNumber -= 1 val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId) room foreach { room => - sendBreakoutRoomStarted(room.parentRoomId, room.name, room.id, room.voiceConfId) + sendBreakoutRoomStarted(room.parentRoomId, room.name, room.id, room.sequence, room.voiceConfId) } // We avoid sending invitation @@ -92,9 +92,9 @@ trait BreakoutRoomApp extends SystemConfiguration { } } - def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutMeetingId: String, voiceConfId: String) { + def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutMeetingId: String, sequence: Int,voiceConfId: String) { log.info("Sending breakout room started for parent meeting {} and breakout meeting", meetingId, breakoutMeetingId); - outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutMeetingId))) + outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutMeetingId, sequence))) } def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala index 23a387d819..4bae0e70e0 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala @@ -149,6 +149,7 @@ object MeetingMessageToJsonConverter { val payload = new java.util.HashMap[String, Any]() payload.put("parentMeetingId", msg.parentMeetingId) payload.put("meetingId", msg.breakout.meetingId) + payload.put("sequence", msg.breakout.sequence) payload.put("name", msg.breakout.name) val header = Util.buildHeader(BreakoutRoomStarted.NAME, None) diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java index 4e7750549f..033b727aeb 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java @@ -2,13 +2,16 @@ package org.bigbluebutton.messages.payload; public class BreakoutRoomPayload { - public final String parentMeetingId; - public final String meetingId; - public final String name; + public final String parentMeetingId; + public final String meetingId; + public final String name; + public final Integer sequence; - public BreakoutRoomPayload(String parentMeetingId, String meetingId, String name) { - this.parentMeetingId = parentMeetingId; - this.meetingId = meetingId; - this.name = name; - } + public BreakoutRoomPayload(String parentMeetingId, String meetingId, + String name, Integer sequence) { + this.parentMeetingId = parentMeetingId; + this.meetingId = meetingId; + this.name = name; + this.sequence = sequence; + } } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java index 2f90996207..7e7822e0a3 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java @@ -599,6 +599,7 @@ public class UserClientMessageSender { Map args = new HashMap(); args.put("breakoutMeetingId", msg.payload.meetingId); args.put("parentMeetingId", msg.payload.parentMeetingId); + args.put("sequence", msg.payload.sequence); args.put("name", msg.payload.name); Map message = new HashMap(); diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as b/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as index 0bfb85e162..58ac6998b1 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/events/BreakoutRoomEvent.as @@ -40,6 +40,8 @@ package org.bigbluebutton.main.events { public var meetingId:String; public var breakoutMeetingId:String; + + public var breakoutMeetingSequence:int; public var rooms:Array; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as index 0a018df32f..d12a96d766 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as @@ -632,6 +632,7 @@ package org.bigbluebutton.modules.users.services var breakoutRoom : BreakoutRoom = new BreakoutRoom(); breakoutRoom.meetingId = room.meetingId; breakoutRoom.name = room.name; + breakoutRoom.sequence = room.sequence; UserManager.getInstance().getConference().addBreakoutRoom(breakoutRoom); } UserManager.getInstance().getConference().breakoutRoomsReady = map.roomsReady; @@ -641,7 +642,9 @@ package org.bigbluebutton.modules.users.services var map:Object = JSON.parse(msg.msg); var event : BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.BREAKOUT_JOIN_URL); event.joinURL = map.joinURL; - event.breakoutMeetingId = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); + var meetingId : String = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); + // @todo: extract the sequence number from the models + event.breakoutMeetingSequence = 1; //meetingId; dispatcher.dispatchEvent(event); } @@ -669,6 +672,7 @@ package org.bigbluebutton.modules.users.services var breakoutRoom : BreakoutRoom = new BreakoutRoom(); breakoutRoom.meetingId = map.breakoutMeetingId; breakoutRoom.name = map.name; + breakoutRoom.sequence = map.sequence; UserManager.getInstance().getConference().addBreakoutRoom(breakoutRoom); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml index 5bc7880243..b81229cca6 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml @@ -55,7 +55,6 @@ import mx.events.MenuEvent; import mx.managers.PopUpManager; - import org.as3commons.lang.StringUtils; import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; import org.bigbluebutton.common.IBbbModuleWindow; @@ -344,7 +343,7 @@ removeJoinAlert(); joinAlert = Alert.show( //@todo: refactor - ResourceUtil.getInstance().getString('bbb.users.breakout.openJoinURL', [StringUtils.substringAfterLast(event.breakoutMeetingId, "-")]), + ResourceUtil.getInstance().getString('bbb.users.breakout.openJoinURL', [event.breakoutMeetingSequence]), ResourceUtil.getInstance().getString('bbb.users.breakout.confirm'), Alert.YES | Alert.NO, null, From f8beb9e4e782371c7fa49b670ca4b63f9b175938 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Wed, 12 Oct 2016 12:41:57 +0100 Subject: [PATCH 04/22] Breakout rooms are now sorted by their sequence number. --- .../core/apps/BreakoutRoomApp.scala | 2 +- .../bigbluebutton/main/model/users/BBBUser.as | 13 +++-- .../main/model/users/Conference.as | 47 +++++++++++++------ .../modules/users/services/MessageReceiver.as | 3 +- .../users/views/BreakoutRoomSettings.mxml | 3 +- .../modules/users/views/UsersWindow.mxml | 1 - 6 files changed, 42 insertions(+), 27 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 7b719b9e7e..83087f4dff 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -67,7 +67,7 @@ trait BreakoutRoomApp extends SystemConfiguration { } def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) { - sendJoinURL(msg.userId, msg.meetingId) + sendJoinURL(msg.userId, msg.breakoutMeetingId) } def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) { diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BBBUser.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BBBUser.as index 7d302e8339..4623400cb4 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BBBUser.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BBBUser.as @@ -334,12 +334,11 @@ package org.bigbluebutton.main.model.users private var _breakoutRooms : Array = []; [Bindable("displayNameChange")] - public function get displayName() : String { - if (ArrayUtils.isEmpty(_breakoutRooms)){ + public function get displayName():String { + if (ArrayUtils.isEmpty(_breakoutRooms)) { return name; - } - else { - return "[" + _breakoutRooms.join(",") + "] " +name; + } else { + return "[" + _breakoutRooms.join(",") + "] " + name; } } @@ -352,14 +351,14 @@ package org.bigbluebutton.main.model.users dispatchEvent(new Event("displayNameChange")); } - public function addBreakoutRoom(roomNumber:String):void { + public function addBreakoutRoom(roomNumber:int):void { if (!ArrayUtils.contains(_breakoutRooms, roomNumber)) { _breakoutRooms.push(roomNumber); dispatchEvent(new Event("displayNameChange")); } } - public function removeBreakoutRoom(roomNumber:String):void { + public function removeBreakoutRoom(roomNumber:int):void { _breakoutRooms.splice(_breakoutRooms.indexOf(roomNumber), 1); dispatchEvent(new Event("displayNameChange")); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as index 5698d7a9a8..67d66f39ae 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as @@ -20,6 +20,7 @@ package org.bigbluebutton.main.model.users { import mx.collections.ArrayCollection; import mx.collections.Sort; + import mx.collections.SortField; import org.as3commons.lang.ArrayUtils; import org.as3commons.lang.StringUtils; @@ -538,35 +539,42 @@ package org.bigbluebutton.main.model.users { removeBreakoutRoom(newRoom.meetingId); } breakoutRooms.addItem(newRoom); + sortBreakoutRooms(); + } + + private function sortBreakoutRooms() : void { + var sort:Sort = new Sort(); + sort.fields = [new SortField("sequence", true, false, true)]; + breakoutRooms.sort = sort; breakoutRooms.refresh(); } public function updateBreakoutRoomUsers(breakoutMeetingId:String, breakoutUsers:Array):void { - var room:Object = getBreakoutRoom(breakoutMeetingId); + var room:BreakoutRoom = getBreakoutRoom(breakoutMeetingId); if (room != null) { - BreakoutRoom(room).users = new ArrayCollection(breakoutUsers); + room.users = new ArrayCollection(breakoutUsers); var updateUsers:Array = []; // Update users breakout rooms - var user : BBBUser; + var user:BBBUser; for (var i:int = 0; i < breakoutUsers.length; i++) { var userId:String = StringUtils.substringBeforeLast(breakoutUsers[i].id, "-"); user = getUser(userId); if (user) { - user.addBreakoutRoom(breakoutMeetingId) + user.addBreakoutRoom(room.sequence) } updateUsers.push(userId); } // Remove users breakout rooms if the users left the breakout rooms for (var j:int = 0; j < users.length; j++) { user = BBBUser(users.getItemAt(j)); - if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, breakoutMeetingId)) { - user.removeBreakoutRoom(breakoutMeetingId); + if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, room.sequence)) { + user.removeBreakoutRoom(room.sequence); } } users.refresh(); } } - + /** * Returns a breakout room by its internal meeting ID */ @@ -578,6 +586,17 @@ package org.bigbluebutton.main.model.users { return null; } + public function getBreakoutRoomBySequence(sequence:int):BreakoutRoom { + var aRoom:BreakoutRoom; + for (var i:int = 0; i < breakoutRooms.length; i++) { + aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom; + if (aRoom.sequence == sequence) { + return aRoom; + } + } + return null; + } + /** * Finds the index of a breakout room by its internal meeting ID */ @@ -594,23 +613,23 @@ package org.bigbluebutton.main.model.users { } public function removeBreakoutRoom(breakoutMeetingId:String):void { - var p:Object = getBreakoutRoomIndex(breakoutMeetingId); - if (p != null) { - breakoutRooms.removeItemAt(p.index); - breakoutRooms.refresh(); + var room:Object = getBreakoutRoomIndex(breakoutMeetingId); + if (room != null) { + breakoutRooms.removeItemAt(room.index); + sortBreakoutRooms(); if (breakoutRooms.length == 0) { breakoutRoomsReady = false; } // Remove breakout room number display from users for (var i:int; i < users.length; i++) { - if (ArrayUtils.contains(users[i].breakoutRooms, breakoutMeetingId)) { - users[i].removeBreakoutRoom(breakoutMeetingId); + if (ArrayUtils.contains(users[i].breakoutRooms, room.room.sequence)) { + users[i].removeBreakoutRoom(room.room.sequence); } } users.refresh(); } } - + public function hasBreakoutRoom(breakoutMeetingId:String):Boolean { var p:Object = getBreakoutRoomIndex(breakoutMeetingId); if (p != null) { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as index d12a96d766..fda9dd52dc 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as @@ -643,8 +643,7 @@ package org.bigbluebutton.modules.users.services var event : BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.BREAKOUT_JOIN_URL); event.joinURL = map.joinURL; var meetingId : String = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); - // @todo: extract the sequence number from the models - event.breakoutMeetingSequence = 1; //meetingId; + event.breakoutMeetingSequence = UserManager.getInstance().getConference().getBreakoutRoom(meetingId).sequence; dispatcher.dispatchEvent(event); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml index fa4bb4f33b..769b4233bd 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml @@ -102,11 +102,10 @@ with BigBlueButton; if not, see . for (var u:int = 0; u < list.users.length; u++) { user = list.users.getItemAt(u) as BBBUser; if (user.breakoutRooms.length == 0) { - //@todo: refactor usersInvited ||= true; var event:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.REQUEST_BREAKOUT_JOIN_URL); event.userId = user.userID; - event.breakoutMeetingId = UserManager.getInstance().getConference().internalMeetingID + "-" + (i + 1); + event.breakoutMeetingId = UserManager.getInstance().getConference().getBreakoutRoomBySequence(i + 1).meetingId; dispatcher.dispatchEvent(event); } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml index b81229cca6..81162c71cb 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml @@ -342,7 +342,6 @@ // We display only one alert removeJoinAlert(); joinAlert = Alert.show( - //@todo: refactor ResourceUtil.getInstance().getString('bbb.users.breakout.openJoinURL', [event.breakoutMeetingSequence]), ResourceUtil.getInstance().getString('bbb.users.breakout.confirm'), Alert.YES | Alert.NO, From ff9bc17c15b234c8ae883c3d5785474b6e924d6e Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Wed, 12 Oct 2016 19:55:20 +0100 Subject: [PATCH 05/22] Send sequence number when creating breakout rooms and correctly generate a unique externalMeetingId for breakout rooms. --- .../bigbluebutton/core/JsonMessageSenderActor.scala | 2 +- .../org/bigbluebutton/core/apps/BreakoutRoomApp.scala | 5 ++++- .../payload/CreateBreakoutRoomRequestPayload.java | 4 +++- .../messages/CreateBreakoutRoomRequestTest.java | 9 ++++++--- .../java/org/bigbluebutton/api/MeetingService.java | 1 + .../org/bigbluebutton/api/ParamsProcessorUtil.java | 8 ++++++-- .../api/messaging/MeetingMessageHandler.java | 11 ++++++----- .../api/messaging/messages/CreateBreakoutRoom.java | 8 +++++--- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala index 4f2a4568ed..7a647491d7 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala @@ -93,7 +93,7 @@ class JsonMessageSenderActor(val service: MessageSender) private def handleCreateBreakoutRoom(msg: CreateBreakoutRoom) { val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutMeetingId, msg.room.parentId, msg.room.name, - msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword, + 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()) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 83087f4dff..cff133b7a8 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -152,7 +152,10 @@ trait BreakoutRoomApp extends SystemConfiguration { object BreakoutRoomsUtil { def createMeetingId(id: String, index: Int): String = { - return DigestUtils.sha1Hex(id.concat("-").concat(index.toString())) + '-' + System.currentTimeMillis(); + val timeStamp = System.currentTimeMillis() + val externalHash = DigestUtils.sha1Hex(id.concat("-").concat(timeStamp.toString()).concat("-").concat(index.toString())) + val externalId = externalHash.concat("-").concat(timeStamp.toString()) + DigestUtils.sha1Hex(externalId).concat("-").concat(timeStamp.toString()) } def createVoiceConfId(id: String, index: Int): String = { diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java index 8a2f72e9a5..9c49157c76 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomRequestPayload.java @@ -4,6 +4,7 @@ public class CreateBreakoutRoomRequestPayload { public final String breakoutMeetingId; public final String parentMeetingId; // The main meeting internal id public final String name; // The name of the breakout room + public final Integer sequence; // The sequnce number of the breakout room public final String voiceConfId; // The voice conference id public final String viewerPassword; public final String moderatorPassword; @@ -13,13 +14,14 @@ public class CreateBreakoutRoomRequestPayload { public final Boolean record; public CreateBreakoutRoomRequestPayload(String meetingMeetingId, String parentMeetingId, - String name, String voiceConfId, String viewerPassword, + String name, Integer sequence, String voiceConfId, String viewerPassword, String moderatorPassword, Integer duration, String sourcePresentationId, Integer sourcePresentationSlide, Boolean record) { this.breakoutMeetingId = meetingMeetingId; this.parentMeetingId = parentMeetingId; this.name = name; + this.sequence = sequence; this.voiceConfId = voiceConfId; this.viewerPassword = viewerPassword; this.moderatorPassword = moderatorPassword; diff --git a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java index 2bba6706f0..59f3086d0d 100755 --- a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java +++ b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomRequestTest.java @@ -13,6 +13,7 @@ public class CreateBreakoutRoomRequestTest { String parentId = "abc-123"; Integer durationInMinutes = 20; String name = "Breakout room 1"; + Integer sequence = 3; String voiceConfId = "851153"; String viewerPassword = "vp"; String moderatorPassword = "mp"; @@ -20,9 +21,10 @@ public class CreateBreakoutRoomRequestTest { Integer sourePresentationSlide = 5; Boolean record = false; - CreateBreakoutRoomRequestPayload payload = - new CreateBreakoutRoomRequestPayload(breakoutId, parentId, name, voiceConfId, - viewerPassword, moderatorPassword, durationInMinutes, sourcePresentationId, sourePresentationSlide, record); + CreateBreakoutRoomRequestPayload payload = new CreateBreakoutRoomRequestPayload( + breakoutId, parentId, name, sequence, voiceConfId, + viewerPassword, moderatorPassword, durationInMinutes, + sourcePresentationId, sourePresentationSlide, record); CreateBreakoutRoomRequest msg = new CreateBreakoutRoomRequest(payload); Gson gson = new Gson(); String json = gson.toJson(msg); @@ -33,6 +35,7 @@ public class CreateBreakoutRoomRequestTest { Assert.assertEquals(rxMsg.header.name, CreateBreakoutRoomRequest.NAME); Assert.assertEquals(rxMsg.payload.breakoutMeetingId, breakoutId); Assert.assertEquals(rxMsg.payload.name, name); + Assert.assertEquals(rxMsg.payload.sequence, sequence); Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId); Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword); Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java index 9a2f760223..fb81333b82 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java @@ -531,6 +531,7 @@ public class MeetingService implements MessageListener { params.put("meetingID", message.meetingId); params.put("parentMeetingID", message.parentMeetingId); params.put("isBreakout", "true"); + params.put("sequence", message.sequence.toString()); params.put("attendeePW", message.viewerPassword); params.put("moderatorPW", message.moderatorPassword); params.put("voiceBridge", message.voiceConfId); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java index 91296c545b..f7a08cd894 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -358,16 +358,20 @@ public class ParamsProcessorUtil { // Create a unique internal id by appending the current time. This way, the 3rd-party // app can reuse the external meeting id. long createTime = System.currentTimeMillis(); - internalMeetingId = internalMeetingId + '-' + new Long(createTime).toString(); + internalMeetingId = internalMeetingId.concat("-").concat(new Long(createTime).toString()); // If this create meeting request is for a breakout room, we just used // we need to generate a unique internal and external id and keep // tracks of the parent meeting id String parentMeetingId = new String(); if (isBreakout) { - externalMeetingId = internalMeetingId; internalMeetingId = params.get("meetingID"); parentMeetingId = params.get("parentMeetingID"); + // We rebuild the the external meeting using the has of the parent + // meeting, the shared timestamp and the sequence number + String timeStamp = StringUtils.substringAfter(internalMeetingId, "-"); + String externalHash = DigestUtils.shaHex(parentMeetingId.concat("-").concat(timeStamp.toString()).concat("-").concat(params.get("sequence"))); + externalMeetingId = externalHash.concat("-").concat(timeStamp); } // Create the meeting with all passed in parameters. diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java index 593427554a..31b93ee866 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java @@ -74,11 +74,12 @@ public class MeetingMessageHandler implements MessageHandler { listener.handle(new CreateBreakoutRoom( msg.payload.breakoutMeetingId, msg.payload.parentMeetingId, - msg.payload.name, - msg.payload.voiceConfId, - msg.payload.viewerPassword, - msg.payload.moderatorPassword, - msg.payload.durationInMinutes, + msg.payload.name, + msg.payload.sequence, + msg.payload.voiceConfId, + msg.payload.viewerPassword, + msg.payload.moderatorPassword, + msg.payload.durationInMinutes, msg.payload.sourcePresentationId, msg.payload.sourcePresentationSlide, msg.payload.record diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java index 8b3eaf4431..79aedee164 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/messages/CreateBreakoutRoom.java @@ -5,6 +5,7 @@ public class CreateBreakoutRoom implements IMessage { public final String meetingId; public final String parentMeetingId; // The main meeting internal id public final String name; // The name of the breakout room + public final Integer sequence; // The sequence number of the breakout room public final String voiceConfId; // The voice conference id public final String viewerPassword; public final String moderatorPassword; @@ -13,14 +14,15 @@ public class CreateBreakoutRoom implements IMessage { public final Integer sourcePresentationSlide; public final Boolean record; - public CreateBreakoutRoom(String meetingId, String parentMeetingId, String name, - String voiceConfId, String viewerPassword, - String moderatorPassword, Integer duration, + public CreateBreakoutRoom(String meetingId, String parentMeetingId, + String name, Integer sequence, String voiceConfId, + String viewerPassword, String moderatorPassword, Integer duration, String sourcePresentationId, Integer sourcePresentationSlide, Boolean record) { this.meetingId = meetingId; this.parentMeetingId = parentMeetingId; this.name = name; + this.sequence = sequence; this.voiceConfId = voiceConfId; this.viewerPassword = viewerPassword; this.moderatorPassword = moderatorPassword; From a80b6d9c45ccbaf2f7a5c8bd40fc69fb219f38d8 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Wed, 12 Oct 2016 20:20:37 +0100 Subject: [PATCH 06/22] Replace the deprecated shaHex DigestUtils by sha1Hex. --- .../org/bigbluebutton/api/ParamsProcessorUtil.java | 10 +++++----- .../src/java/org/bigbluebutton/api/Util.java | 2 +- .../presentation/PresentationUrlDownloadService.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java index f7a08cd894..52a0a95e49 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -370,7 +370,7 @@ public class ParamsProcessorUtil { // We rebuild the the external meeting using the has of the parent // meeting, the shared timestamp and the sequence number String timeStamp = StringUtils.substringAfter(internalMeetingId, "-"); - String externalHash = DigestUtils.shaHex(parentMeetingId.concat("-").concat(timeStamp.toString()).concat("-").concat(params.get("sequence"))); + String externalHash = DigestUtils.sha1Hex(parentMeetingId.concat("-").concat(timeStamp.toString()).concat("-").concat(params.get("sequence"))); externalMeetingId = externalHash.concat("-").concat(timeStamp); } @@ -466,7 +466,7 @@ public class ParamsProcessorUtil { } public String convertToInternalMeetingId(String extMeetingId) { - return DigestUtils.shaHex(extMeetingId); + return DigestUtils.sha1Hex(extMeetingId); } public String processPassword(String pass) { @@ -561,7 +561,7 @@ public class ParamsProcessorUtil { return true; } - String cs = DigestUtils.shaHex(meetingID + configXML + securitySalt); + String cs = DigestUtils.sha1Hex(meetingID + configXML + securitySalt); if (cs == null || cs.equals(checksum) == false) { log.info("checksumError: configXML checksum. our: [{}], client: [{}]", cs, checksum); @@ -586,7 +586,7 @@ public class ParamsProcessorUtil { queryString = queryString.replace("checksum=" + checksum, ""); } - String cs = DigestUtils.shaHex(apiCall + queryString + securitySalt); + String cs = DigestUtils.sha1Hex(apiCall + queryString + securitySalt); if (cs == null || cs.equals(checksum) == false) { log.info("query string after checksum removed: [{}]", queryString); @@ -646,7 +646,7 @@ public class ParamsProcessorUtil { csbuf.append(securitySalt); String baseString = csbuf.toString(); - String cs = DigestUtils.shaHex(baseString); + String cs = DigestUtils.sha1Hex(baseString); if (cs == null || cs.equals(checksum) == false) { log.info("POST basestring = [" + baseString + "]"); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java index 3f6548afdf..5f9dc82a29 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java @@ -7,7 +7,7 @@ public final class Util { public static String generatePresentationId(String name) { long timestamp = System.currentTimeMillis(); - return DigestUtils.shaHex(name) + "-" + timestamp; + return DigestUtils.sha1Hex(name) + "-" + timestamp; } public static String createNewFilename(String presId, String fileExt) { diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java index f28a59b316..2b3767542e 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java @@ -105,7 +105,7 @@ public class PresentationUrlDownloadService { public String generatePresentationId(String name) { long timestamp = System.currentTimeMillis(); - return DigestUtils.shaHex(name) + "-" + timestamp; + return DigestUtils.sha1Hex(name) + "-" + timestamp; } public File createPresentationDirectory(String meetingId, From bf5de153a03099895ff89880d9c128976db67c5f Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Wed, 12 Oct 2016 20:24:51 +0100 Subject: [PATCH 07/22] Deleted unused imports from bigbluebutton-apps and bigbluebutton-web --- .../red5/client/DeskShareMessageSender.java | 5 ++--- .../client/WhiteboardClientMessageSender.java | 1 - .../red5/service/DesktopSharingService.java | 3 --- .../api/ClientConfigService.java | 3 --- .../api/messaging/MessageReceiver.java | 1 - .../presentation/imp/Pdf2SwfPageCounter.java | 2 -- .../imp/PdfToSwfSlidesGenerationService.java | 1 - .../presentation/imp/SvgImageCreatorImp.java | 6 +----- .../SwfSlidesGenerationProgressNotifier.java | 3 +-- .../web/services/KeepAliveService.java | 21 ++++++------------- 10 files changed, 10 insertions(+), 36 deletions(-) diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/DeskShareMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/DeskShareMessageSender.java index 57784c825f..b94374355f 100644 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/DeskShareMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/DeskShareMessageSender.java @@ -3,12 +3,11 @@ package org.bigbluebutton.red5.client; import java.util.HashMap; import java.util.Map; -import org.bigbluebutton.common.messages.ChatKeyUtil; -import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage; import org.bigbluebutton.common.messages.DeskShareNotifyASingleViewerEventMessage; +import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage; import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage; -import org.bigbluebutton.red5.client.messaging.DirectClientMessage; import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService; +import org.bigbluebutton.red5.client.messaging.DirectClientMessage; import com.google.gson.JsonObject; import com.google.gson.JsonParser; diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java index 510f88bcea..792ee0645a 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java @@ -1,6 +1,5 @@ package org.bigbluebutton.red5.client; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/DesktopSharingService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/DesktopSharingService.java index f16fdc33c7..fa03834a87 100644 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/DesktopSharingService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/DesktopSharingService.java @@ -18,9 +18,6 @@ */ package org.bigbluebutton.red5.service; -import java.util.HashMap; -import java.util.Map; - import org.bigbluebutton.red5.BigBlueButtonSession; import org.bigbluebutton.red5.Constants; import org.bigbluebutton.red5.pubsub.MessagePublisher; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ClientConfigService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ClientConfigService.java index c06f635980..f4d59fb037 100644 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ClientConfigService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ClientConfigService.java @@ -19,9 +19,6 @@ package org.bigbluebutton.api; -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; import java.util.HashMap; import java.util.Map; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageReceiver.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageReceiver.java index 9be59010d4..5b62209ea9 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageReceiver.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageReceiver.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPubSub; import redis.clients.jedis.exceptions.JedisConnectionException; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/Pdf2SwfPageCounter.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/Pdf2SwfPageCounter.java index 74fc9385c2..2e917caf12 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/Pdf2SwfPageCounter.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/Pdf2SwfPageCounter.java @@ -21,7 +21,6 @@ package org.bigbluebutton.presentation.imp; import java.io.BufferedReader; import java.io.File; -import java.io.IOException; import java.io.InputStreamReader; import java.util.Timer; import java.util.TimerTask; @@ -29,7 +28,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bigbluebutton.presentation.PageCounter; -import org.bigbluebutton.presentation.imp.ExternalProcessExecutor.InterruptTimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java index a4e3369bd0..929dcfb259 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java @@ -30,7 +30,6 @@ import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java index 3b57b9e295..f9ee00f0ab 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SvgImageCreatorImp.java @@ -1,13 +1,9 @@ package org.bigbluebutton.presentation.imp; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import org.bigbluebutton.presentation.SvgImageCreator; import org.bigbluebutton.presentation.SupportedFileTypes; +import org.bigbluebutton.presentation.SvgImageCreator; import org.bigbluebutton.presentation.UploadedPresentation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java index 1fda818a94..c85d669566 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java @@ -21,14 +21,13 @@ package org.bigbluebutton.presentation.imp; import java.util.Map; -import org.apache.commons.lang.StringEscapeUtils; import org.bigbluebutton.api.messaging.MessagingConstants; import org.bigbluebutton.api.messaging.MessagingService; import org.bigbluebutton.presentation.ConversionMessageConstants; import org.bigbluebutton.presentation.ConversionUpdateMessage; +import org.bigbluebutton.presentation.ConversionUpdateMessage.MessageBuilder; import org.bigbluebutton.presentation.GeneratedSlidesInfoHelper; import org.bigbluebutton.presentation.UploadedPresentation; -import org.bigbluebutton.presentation.ConversionUpdateMessage.MessageBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/web/services/KeepAliveService.java b/bigbluebutton-web/src/java/org/bigbluebutton/web/services/KeepAliveService.java index d0ee4734b5..87a07fffac 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/web/services/KeepAliveService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/web/services/KeepAliveService.java @@ -19,20 +19,6 @@ package org.bigbluebutton.web.services; -import org.bigbluebutton.api.messaging.MessageListener; -import org.bigbluebutton.api.messaging.MessagingService; -import org.bigbluebutton.api.messaging.MessagingConstants; -import org.bigbluebutton.api.messaging.RedisMessagingService; -import org.bigbluebutton.api.messaging.messages.IMessage; -import org.bigbluebutton.api.messaging.messages.KeepAliveReply; -import org.bigbluebutton.api.messaging.messages.MeetingDestroyed; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Timer; -import java.util.TimerTask; -import java.util.ArrayList; -import java.util.HashMap; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -40,7 +26,12 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import com.google.gson.Gson; +import org.bigbluebutton.api.messaging.MessageListener; +import org.bigbluebutton.api.messaging.MessagingService; +import org.bigbluebutton.api.messaging.messages.IMessage; +import org.bigbluebutton.api.messaging.messages.KeepAliveReply; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class KeepAliveService implements MessageListener { private static Logger log = LoggerFactory.getLogger(KeepAliveService.class); From 054037c6d66a02ae8ca4a8732181f0aa88243d43 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Wed, 12 Oct 2016 21:53:05 +0100 Subject: [PATCH 08/22] Revert replacing the deprecated shaHex DigestUtils by sha1Hex and updated API controller. --- .../web/controllers/ApiController.groovy | 18 ++++++------------ .../org/bigbluebutton/api/MeetingService.java | 8 +------- .../bigbluebutton/api/ParamsProcessorUtil.java | 10 +++++----- .../src/java/org/bigbluebutton/api/Util.java | 2 +- .../PresentationUrlDownloadService.java | 2 +- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index 17bebd8ee5..fc436f4cb9 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -286,19 +286,9 @@ class ApiController { return } - Boolean isBreakoutRoom = false - if(!StringUtils.isEmpty(params.isBreakout)) { - isBreakoutRoom = new Boolean(StringUtils.strip(params.isBreakout)) - } - // Everything is good so far. Translate the external meeting id to an internal meeting id. If // we can't find the meeting, complain. String internalMeetingId = paramsProcessorUtil.convertToInternalMeetingId(externalMeetingId); - if (isBreakoutRoom) { - // This is a join request for a breakout room. Use the passed meetingId to find the meeting. - internalMeetingId = externalMeetingId - log.info("Join request for breakout room " + internalMeetingId) - } log.info("Retrieving meeting ${internalMeetingId}") Meeting meeting = meetingService.getMeeting(internalMeetingId); @@ -869,7 +859,9 @@ class ApiController { meeting { meetingID() { mkp.yield(m.getExternalId()) } internalMeetingID() { mkp.yield(m.getInternalId()) } - parentMeetingID() { mkp.yield(m.getParentMeetingId()) } + if (m.isBreakout()) { + parentMeetingID() { mkp.yield(m.getParentMeetingId()) } + } isBreakout() { mkp.yield(m.isBreakout()) } meetingName() { mkp.yield(m.getName()) } createTime(m.getCreateTime()) @@ -2137,7 +2129,9 @@ class ApiController { isBreakout() { mkp.yield(meeting.isBreakout()) } meetingID() { mkp.yield(meeting.getExternalId()) } internalMeetingID(meeting.getInternalId()) - parentMeetingID() { mkp.yield(meeting.getParentMeetingId()) } + if (m.isBreakout()) { + parentMeetingID() { mkp.yield(meeting.getParentMeetingId()) } + } createTime(meeting.getCreateTime()) createDate(formatPrettyDate(meeting.getCreateTime())) voiceBridge() { mkp.yield(meeting.getTelVoice()) } diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java index fb81333b82..1ea4552beb 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java @@ -367,15 +367,9 @@ public class MeetingService implements MessageListener { public Meeting getMeeting(String meetingId) { if (meetingId == null) return null; - int dashes = meetingId.split("-", -1).length - 1; for (String key : meetings.keySet()) { - int keyDashes = key.split("-", -1).length - 1; - if (dashes == 2 - && key.equals(meetingId) - || (dashes < 2 && keyDashes < 2 && key - .startsWith(meetingId))) { + if (key.startsWith(meetingId)) return (Meeting) meetings.get(key); - } } return null; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java index 52a0a95e49..f7a08cd894 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -370,7 +370,7 @@ public class ParamsProcessorUtil { // We rebuild the the external meeting using the has of the parent // meeting, the shared timestamp and the sequence number String timeStamp = StringUtils.substringAfter(internalMeetingId, "-"); - String externalHash = DigestUtils.sha1Hex(parentMeetingId.concat("-").concat(timeStamp.toString()).concat("-").concat(params.get("sequence"))); + String externalHash = DigestUtils.shaHex(parentMeetingId.concat("-").concat(timeStamp.toString()).concat("-").concat(params.get("sequence"))); externalMeetingId = externalHash.concat("-").concat(timeStamp); } @@ -466,7 +466,7 @@ public class ParamsProcessorUtil { } public String convertToInternalMeetingId(String extMeetingId) { - return DigestUtils.sha1Hex(extMeetingId); + return DigestUtils.shaHex(extMeetingId); } public String processPassword(String pass) { @@ -561,7 +561,7 @@ public class ParamsProcessorUtil { return true; } - String cs = DigestUtils.sha1Hex(meetingID + configXML + securitySalt); + String cs = DigestUtils.shaHex(meetingID + configXML + securitySalt); if (cs == null || cs.equals(checksum) == false) { log.info("checksumError: configXML checksum. our: [{}], client: [{}]", cs, checksum); @@ -586,7 +586,7 @@ public class ParamsProcessorUtil { queryString = queryString.replace("checksum=" + checksum, ""); } - String cs = DigestUtils.sha1Hex(apiCall + queryString + securitySalt); + String cs = DigestUtils.shaHex(apiCall + queryString + securitySalt); if (cs == null || cs.equals(checksum) == false) { log.info("query string after checksum removed: [{}]", queryString); @@ -646,7 +646,7 @@ public class ParamsProcessorUtil { csbuf.append(securitySalt); String baseString = csbuf.toString(); - String cs = DigestUtils.sha1Hex(baseString); + String cs = DigestUtils.shaHex(baseString); if (cs == null || cs.equals(checksum) == false) { log.info("POST basestring = [" + baseString + "]"); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java index 5f9dc82a29..3f6548afdf 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/Util.java @@ -7,7 +7,7 @@ public final class Util { public static String generatePresentationId(String name) { long timestamp = System.currentTimeMillis(); - return DigestUtils.sha1Hex(name) + "-" + timestamp; + return DigestUtils.shaHex(name) + "-" + timestamp; } public static String createNewFilename(String presId, String fileExt) { diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java index 2b3767542e..f28a59b316 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java @@ -105,7 +105,7 @@ public class PresentationUrlDownloadService { public String generatePresentationId(String name) { long timestamp = System.currentTimeMillis(); - return DigestUtils.sha1Hex(name) + "-" + timestamp; + return DigestUtils.shaHex(name) + "-" + timestamp; } public File createPresentationDirectory(String meetingId, From 5e002d845e0e54188f1530d14e37205b48e05776 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Thu, 13 Oct 2016 12:53:53 +0100 Subject: [PATCH 09/22] Store breakout room sequence in akka-apps and bbb-web. --- .../core/BigBlueButtonInGW.scala | 3 +- .../org/bigbluebutton/core/MeetingModel.scala | 2 +- .../org/bigbluebutton/core/Protocol.scala | 2 +- .../bigbluebutton/core/ProtocolMessages.scala | 9 +- .../core/apps/BreakoutRoomApp.scala | 13 +- .../core/apps/BreakoutRoomModel.scala | 4 + .../bigbluebutton/core/AppsTestFixtures.scala | 3 +- .../messages/CreateMeetingRequest.java | 4 +- .../messages/CreateMeetingRequestTest.java | 4 +- .../web/controllers/ApiController.groovy | 2 + .../org/bigbluebutton/api/MeetingService.java | 13 +- .../api/ParamsProcessorUtil.java | 163 ++++++++++-------- .../org/bigbluebutton/api/domain/Meeting.java | 28 +-- .../api/messaging/MessagingService.java | 2 +- .../api/messaging/RedisMessagingService.java | 4 +- 15 files changed, 152 insertions(+), 104 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala index 5e75cef5dc..7989bf5c84 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala @@ -70,7 +70,8 @@ class BigBlueButtonInGW( msg.payload.createTime, msg.payload.createDate, red5DeskShareIP, red5DeskShareApp, - msg.payload.isBreakout) + msg.payload.isBreakout, + msg.payload.sequence) eventBus.publish(BigBlueButtonEvent("meeting-manager", new CreateMeeting(msg.payload.id, mProps))) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala index 427d830a89..81509b3aa2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MeetingModel.scala @@ -8,7 +8,7 @@ case class MeetingProperties(meetingID: String, externalMeetingID: String, paren recorded: Boolean, voiceBridge: String, deskshareBridge: String, duration: Int, autoStartRecording: Boolean, allowStartStopRecording: Boolean, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, - red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean) + red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean, sequence: Int) case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20, sendNotice: Boolean = true, sent15MinNotice: Boolean = false, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala index 42fd439306..6ad592e11c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala @@ -33,7 +33,7 @@ object UserMessagesProtocol extends DefaultJsonProtocol { implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader) implicit val outMsgHeaderFormat = jsonFormat1(OutMsgHeader) implicit val outMsgEnvelopeHeaderFormat = jsonFormat2(OutMsgEnvelopeHeader) - implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat10(CreateBreakoutRoomOutMsgPayload) + implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat11(CreateBreakoutRoomOutMsgPayload) implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload) implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala index 14afd22a6d..327c8af521 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/ProtocolMessages.scala @@ -7,8 +7,7 @@ trait OutMessage case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload) case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload) -case class CreateBreakoutRoomOutMsgPayload(meetingId: String, name: String, parentId: String, - voiceConfId: String, durationInMinutes: Int, - moderatorPassword: String, viewerPassword: String, - sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean) - +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) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index cff133b7a8..2cafc97de8 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -24,7 +24,7 @@ trait BreakoutRoomApp extends SystemConfiguration { val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id, r.sequence) } val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0 log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length) - outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady )) + outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady)) } def handleCreateBreakoutRooms(msg: CreateBreakoutRooms) { @@ -33,6 +33,10 @@ trait BreakoutRoomApp extends SystemConfiguration { log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}", breakoutModel.pendingRoomsNumber, mProps.meetingID) return } + if (breakoutModel.getNumberOfRooms() > 0) { + log.warning("CreateBreakoutRooms event received while {} breakout rooms running for meeting {}", breakoutModel.getNumberOfRooms(), mProps.meetingID) + return + } var i = 0 // in very rare cases the presentation conversion generates an error, what should we do? @@ -56,6 +60,7 @@ trait BreakoutRoomApp extends SystemConfiguration { } def sendJoinURL(userId: String, breakoutMeetingId: String) { + log.debug("Sending breakout meeting {} Join URL for user: {}", breakoutMeetingId, userId); for { user <- usersModel.getUser(userId) apiCall = "join" @@ -77,13 +82,13 @@ trait BreakoutRoomApp extends SystemConfiguration { sendBreakoutRoomStarted(room.parentRoomId, room.name, room.id, room.sequence, room.voiceConfId) } - // We avoid sending invitation + // We postpone sending invitation until all breakout rooms have been created if (breakoutModel.pendingRoomsNumber == 0) { log.info("All breakout rooms created for meetingId={}", mProps.meetingID) breakoutModel.getRooms().foreach { room => breakoutModel.getAssignedUsers(room.id) foreach { users => users.foreach { u => - log.debug("Sending Join URL for users: {}", u); + log.debug("Sending Join URL for users"); sendJoinURL(u, room.id) } } @@ -92,7 +97,7 @@ trait BreakoutRoomApp extends SystemConfiguration { } } - def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutMeetingId: String, sequence: Int,voiceConfId: String) { + def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutMeetingId: String, sequence: Int, voiceConfId: String) { log.info("Sending breakout room started for parent meeting {} and breakout meeting", meetingId, breakoutMeetingId); outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutMeetingId, sequence))) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala index 1d90cd685d..2ed3ee612b 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala @@ -33,6 +33,10 @@ class BreakoutRoomModel { def getRooms(): Array[BreakoutRoom] = { rooms.values.toArray } + + def getNumberOfRooms(): Int = { + rooms.size + } def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = { for { diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala index efd6d41254..0d2f5850d5 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala @@ -5,6 +5,7 @@ trait AppsTestFixtures { val meetingId = "testMeetingId" val externalMeetingId = "testExternalMeetingId" val parentMeetingId = "testParentMeetingId" + val sequence = 4 val meetingName = "test meeting" val record = false val voiceConfId = "85115" @@ -27,5 +28,5 @@ trait AppsTestFixtures { autoStartRecording, allowStartStopRecording, moderatorPassword, viewerPassword, createTime, createDate, red5DeskShareIP, red5DeskShareApp, - isBreakout) + isBreakout, sequence) } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java index f408ead825..48fbdb5628 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/CreateMeetingRequest.java @@ -28,13 +28,14 @@ public class CreateMeetingRequest implements IBigBlueButtonMessage { public final Long createTime; public final String createDate; public final Boolean isBreakout; + public final Integer sequence; public CreateMeetingRequestPayload(String id, String externalId, String parentId, String name, Boolean record, String voiceConfId, Integer duration, Boolean autoStartRecording, Boolean allowStartStopRecording, String moderatorPass, String viewerPass, Long createTime, - String createDate, Boolean isBreakout) { + String createDate, Boolean isBreakout, Integer sequence) { this.id = id; this.externalId = externalId; this.parentId = parentId; @@ -49,6 +50,7 @@ public class CreateMeetingRequest implements IBigBlueButtonMessage { this.createTime = createTime; this.createDate = createDate; this.isBreakout = isBreakout; + this.sequence = sequence; } } } diff --git a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java index 133d277f3f..e25dfa81c7 100755 --- a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java +++ b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateMeetingRequestTest.java @@ -20,6 +20,7 @@ public class CreateMeetingRequestTest { Boolean autoStartRecording = false; Boolean allowStartStopRecording = false; Boolean isBreakout = true; + Integer sequence = 4; String viewerPassword = "vp"; String moderatorPassword = "mp"; long createTime = System.currentTimeMillis(); @@ -29,7 +30,7 @@ public class CreateMeetingRequestTest { meetingId, externalId, parentId, name, record, voiceConfId, durationInMinutes, autoStartRecording, allowStartStopRecording, moderatorPassword, viewerPassword, createTime, createDate, - isBreakout); + isBreakout, sequence); CreateMeetingRequest msg = new CreateMeetingRequest(payload); Gson gson = new Gson(); String json = gson.toJson(msg); @@ -47,5 +48,6 @@ public class CreateMeetingRequestTest { Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword); Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes); Assert.assertEquals(rxMsg.payload.isBreakout, isBreakout); + Assert.assertEquals(rxMsg.payload.sequence, sequence); } } diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index fc436f4cb9..05fde7f168 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -861,6 +861,7 @@ class ApiController { internalMeetingID() { mkp.yield(m.getInternalId()) } if (m.isBreakout()) { parentMeetingID() { mkp.yield(m.getParentMeetingId()) } + sequence(m.getSequence()) } isBreakout() { mkp.yield(m.isBreakout()) } meetingName() { mkp.yield(m.getName()) } @@ -2131,6 +2132,7 @@ class ApiController { internalMeetingID(meeting.getInternalId()) if (m.isBreakout()) { parentMeetingID() { mkp.yield(meeting.getParentMeetingId()) } + sequence(meeting.getSequence()) } createTime(meeting.getCreateTime()) createDate(formatPrettyDate(meeting.getCreateTime())) diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java index 1ea4552beb..7c8309d2a1 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java @@ -303,7 +303,8 @@ public class MeetingService implements MessageListener { metadata.put("meetingName", m.getName()); metadata.put("isBreakout", m.isBreakout().toString()); if (m.isBreakout() != null){ - metadata.put("parentMeetingId", m.getParentMeetingId()); + metadata.put("sequence", m.getSequence().toString()); + metadata.put("parentMeetingId", m.getParentMeetingId()); } messagingService.recordMeetingInfo(m.getInternalId(), metadata); @@ -313,7 +314,8 @@ public class MeetingService implements MessageListener { logData.put("meetingId", m.getInternalId()); logData.put("externalMeetingId", m.getExternalId()); if (m.isBreakout() != null){ - logData.put("parentMeetingId", m.getParentMeetingId()); + logData.put("sequence", m.getSequence()); + logData.put("parentMeetingId", m.getParentMeetingId()); } logData.put("name", m.getName()); logData.put("duration", m.getDuration()); @@ -332,7 +334,7 @@ public class MeetingService implements MessageListener { m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), m.getAllowStartStopRecording(), m.getModeratorPassword(), m.getViewerPassword(), m.getCreateTime(), - formatPrettyDate(m.getCreateTime()), m.isBreakout()); + formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence()); } private String formatPrettyDate(Long timestamp) { @@ -552,8 +554,9 @@ public class MeetingService implements MessageListener { message.sourcePresentationId, message.sourcePresentationSlide, breakout.getInternalId()); } else { - log.error("Failed to create breakout room " + message.meetingId - + ".Reason: Parent meeting not found."); + log.error( + "Failed to create breakout room {}.Reason: Parent meeting {} not found.", + message.meetingId, message.parentMeetingId); } } diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java index f7a08cd894..be29faa84f 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -288,89 +288,107 @@ public class ParamsProcessorUtil { return metas; } - public Meeting processCreateParams(Map params) { - String meetingName = params.get("name"); - if(meetingName == null){ - meetingName = ""; - } - String externalMeetingId = params.get("meetingID"); - - String viewerPass = processPassword(params.get("attendeePW")); - String modPass = processPassword(params.get("moderatorPW")); - - // Get the digits for voice conference for users joining through the phone. - // If none is provided, generate one. - String telVoice = processTelVoice(params.get("voiceBridge")); - - // Get the voice conference digits/chars for users joing through VOIP on the client. - // If none is provided, make it the same as the telVoice. If one has been provided, - // we expect that the users will be joined in the same voice conference. - String webVoice = params.get("webVoice"); - if (StringUtils.isEmpty(webVoice)) { - webVoice = telVoice; - } - - // Get all the other relevant parameters and generate defaults if none has been provided. - String dialNumber = processDialNumber(params.get("dialNumber")); - String logoutUrl = processLogoutUrl(params.get("logoutURL")); - boolean record = processRecordMeeting(params.get("record")); - int maxUsers = processMaxUser(params.get("maxParticipants")); - int meetingDuration = processMeetingDuration(params.get("duration")); - + public Meeting processCreateParams(Map params) { + String meetingName = params.get("name"); + if (meetingName == null) { + meetingName = ""; + } + String externalMeetingId = params.get("meetingID"); + + String viewerPass = processPassword(params.get("attendeePW")); + String modPass = processPassword(params.get("moderatorPW")); + + // Get the digits for voice conference for users joining through the + // phone. + // If none is provided, generate one. + String telVoice = processTelVoice(params.get("voiceBridge")); + + // Get the voice conference digits/chars for users joing through VOIP on + // the client. + // If none is provided, make it the same as the telVoice. If one has + // been provided, + // we expect that the users will be joined in the same voice conference. + String webVoice = params.get("webVoice"); + if (StringUtils.isEmpty(webVoice)) { + webVoice = telVoice; + } + + // Get all the other relevant parameters and generate defaults if none + // has been provided. + String dialNumber = processDialNumber(params.get("dialNumber")); + String logoutUrl = processLogoutUrl(params.get("logoutURL")); + boolean record = processRecordMeeting(params.get("record")); + int maxUsers = processMaxUser(params.get("maxParticipants")); + int meetingDuration = processMeetingDuration(params.get("duration")); + // set is breakout room property boolean isBreakout = false; if (!StringUtils.isEmpty(params.get("isBreakout"))) { isBreakout = new Boolean(params.get("isBreakout")); } - String welcomeMessageTemplate = processWelcomeMessage(params.get("welcome"), isBreakout); - String welcomeMessage = substituteKeywords(welcomeMessageTemplate, dialNumber, telVoice, meetingName); - - String internalMeetingId = convertToInternalMeetingId(externalMeetingId); - - // Check if this is a test meeting. NOTE: This should not belong here. Extract this out. - if (isTestMeeting(telVoice)) { - internalMeetingId = getIntMeetingIdForTestMeeting(telVoice); - } - - boolean autoStartRec = autoStartRecording; - if (!StringUtils.isEmpty(params.get("autoStartRecording"))) { - try { - autoStartRec = Boolean.parseBoolean(params.get("autoStartRecording")); - } catch(Exception ex){ - log.warn("Invalid param [autoStartRecording] for meeting=[" + internalMeetingId + "]"); - } - } + String welcomeMessageTemplate = processWelcomeMessage( + params.get("welcome"), isBreakout); + String welcomeMessage = substituteKeywords(welcomeMessageTemplate, + dialNumber, telVoice, meetingName); - boolean allowStartStoptRec = allowStartStopRecording; - if (!StringUtils.isEmpty(params.get("allowStartStopRecording"))) { - try { - allowStartStoptRec = Boolean.parseBoolean(params.get("allowStartStopRecording")); - } catch(Exception ex){ - log.warn("Invalid param [allowStartStopRecording] for meeting=[" + internalMeetingId + "]"); - } - } - - // Collect metadata for this meeting that the third-party app wants to store if meeting is recorded. - Map meetingInfo = new HashMap(); - meetingInfo = processMetaParam(params); - - // Create a unique internal id by appending the current time. This way, the 3rd-party - // app can reuse the external meeting id. - long createTime = System.currentTimeMillis(); - internalMeetingId = internalMeetingId.concat("-").concat(new Long(createTime).toString()); + String internalMeetingId = convertToInternalMeetingId(externalMeetingId); + + // Check if this is a test meeting. NOTE: This should not belong here. + // Extract this out. + if (isTestMeeting(telVoice)) { + internalMeetingId = getIntMeetingIdForTestMeeting(telVoice); + } + + boolean autoStartRec = autoStartRecording; + if (!StringUtils.isEmpty(params.get("autoStartRecording"))) { + try { + autoStartRec = Boolean.parseBoolean(params + .get("autoStartRecording")); + } catch (Exception ex) { + log.warn("Invalid param [autoStartRecording] for meeting=[{}]", + internalMeetingId); + } + } + + boolean allowStartStoptRec = allowStartStopRecording; + if (!StringUtils.isEmpty(params.get("allowStartStopRecording"))) { + try { + allowStartStoptRec = Boolean.parseBoolean(params + .get("allowStartStopRecording")); + } catch (Exception ex) { + log.warn( + "Invalid param [allowStartStopRecording] for meeting=[{}]", + internalMeetingId); + } + } + + // Collect metadata for this meeting that the third-party app wants to + // store if meeting is recorded. + Map meetingInfo = new HashMap(); + meetingInfo = processMetaParam(params); + + // Create a unique internal id by appending the current time. This way, + // the 3rd-party + // app can reuse the external meeting id. + long createTime = System.currentTimeMillis(); + internalMeetingId = internalMeetingId.concat("-").concat( + new Long(createTime).toString()); // If this create meeting request is for a breakout room, we just used // we need to generate a unique internal and external id and keep - // tracks of the parent meeting id - String parentMeetingId = new String(); + // tracks of the parent meeting id + String parentMeetingId = new String(); if (isBreakout) { internalMeetingId = params.get("meetingID"); parentMeetingId = params.get("parentMeetingID"); // We rebuild the the external meeting using the has of the parent // meeting, the shared timestamp and the sequence number - String timeStamp = StringUtils.substringAfter(internalMeetingId, "-"); - String externalHash = DigestUtils.shaHex(parentMeetingId.concat("-").concat(timeStamp.toString()).concat("-").concat(params.get("sequence"))); + String timeStamp = StringUtils.substringAfter(internalMeetingId, + "-"); + String externalHash = DigestUtils.shaHex(parentMeetingId + .concat("-").concat(timeStamp.toString()).concat("-") + .concat(params.get("sequence"))); externalMeetingId = externalHash.concat("-").concat(timeStamp); } @@ -388,7 +406,6 @@ public class ParamsProcessorUtil { .withMetadata(meetingInfo) .withWelcomeMessageTemplate(welcomeMessageTemplate) .withWelcomeMessage(welcomeMessage).isBreakout(isBreakout) - .withParentMeetingId(parentMeetingId) .build(); String configXML = getDefaultConfigXML(); @@ -399,8 +416,14 @@ public class ParamsProcessorUtil { meeting.setModeratorOnlyMessage(moderatorOnlyMessage); } + // Add extra parameters for breakout room + if (isBreakout) { + meeting.setSequence(Integer.parseInt(params.get("sequence"))); + meeting.setParentMeetingId(parentMeetingId); + } + return meeting; - } + } public String getApiVersion() { return apiVersion; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java index b5aff604b0..892d69f33f 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/domain/Meeting.java @@ -39,6 +39,7 @@ public class Meeting { private String extMeetingId; private String intMeetingId; private String parentMeetingId; + private Integer sequence = 0; private Integer duration = 0; private long createdTime = 0; private long startTime = 0; @@ -73,7 +74,6 @@ public class Meeting { name = builder.name; extMeetingId = builder.externalId; intMeetingId = builder.internalId; - parentMeetingId = builder.parentMeetingId; viewerPass = builder.viewerPass; moderatorPass = builder.moderatorPass; maxUsers = builder.maxUsers; @@ -154,7 +154,15 @@ public class Meeting { public long getCreateTime() { return createdTime; } - + + public Integer setSequence(Integer s) { + return sequence = s; + } + + public Integer getSequence() { + return sequence; + } + public Integer getDuration() { return duration; } @@ -202,7 +210,11 @@ public class Meeting { public String getInternalId() { return intMeetingId; } - + + public String setParentMeetingId(String p) { + return parentMeetingId = p; + } + public String getParentMeetingId() { return parentMeetingId; } @@ -382,7 +394,6 @@ public class Meeting { private String name; private String externalId; private String internalId; - private String parentMeetingId; private int maxUsers; private boolean record; private boolean autoStartRecording; @@ -400,18 +411,13 @@ public class Meeting { private String defaultAvatarURL; private long createdTime; private boolean isBreakout; - + public Builder(String externalId, String internalId, long createTime) { this.externalId = externalId; this.internalId = internalId; this.createdTime = createTime; } - public Builder withParentMeetingId(String parentMeetingId) { - this.parentMeetingId = parentMeetingId; - return this; - } - public Builder withName(String name) { this.name = name; return this; @@ -486,7 +492,7 @@ public class Meeting { isBreakout = b; return this; } - + public Builder withLogoutUrl(String l) { logoutUrl = l; return this; diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java index d445d6d017..45d5a4b3fc 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java @@ -34,7 +34,7 @@ public interface MessagingService { String voiceBridge, Integer duration, Boolean autoStartRecording, Boolean allowStartStopRecording, String moderatorPass, String viewerPass, Long createTime, String createDate, - Boolean isBreakout); + Boolean isBreakout, Integer sequence); void endMeeting(String meetingId); void send(String channel, String message); void sendPolls(String meetingId, String title, String question, String questionType, List answers); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java index e74a530b08..60ecc1f7ff 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java @@ -72,12 +72,12 @@ public class RedisMessagingService implements MessagingService { String voiceBridge, Integer duration, Boolean autoStartRecording, Boolean allowStartStopRecording, String moderatorPass, String viewerPass, Long createTime, String createDate, - Boolean isBreakout) { + Boolean isBreakout, Integer sequence) { CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload( meetingID, externalMeetingID, parentMeetingID, meetingName, recorded, voiceBridge, duration, autoStartRecording, allowStartStopRecording, moderatorPass, viewerPass, createTime, - createDate, isBreakout); + createDate, isBreakout, sequence); CreateMeetingRequest msg = new CreateMeetingRequest(payload); Gson gson = new Gson(); From b078628ad93fd65bbd67bfc5fa10370e9498a4db Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Thu, 13 Oct 2016 17:17:47 +0100 Subject: [PATCH 10/22] Store breakout room externalMeetingID to be used for generating join URL. --- .../core/JsonMessageSenderActor.scala | 6 ++-- .../bigbluebutton/core/api/OutMessages.scala | 2 +- .../core/apps/BreakoutRoomApp.scala | 30 ++++++++++--------- .../core/apps/BreakoutRoomModel.scala | 8 ++--- .../MeetingMessageToJsonConverter.scala | 3 +- .../core/apps/BreakoutRoomsUtilSpec.scala | 2 +- .../messages/payload/BreakoutRoomPayload.java | 4 ++- .../red5/client/UserClientMessageSender.java | 3 +- .../main/model/users/BreakoutRoom.as | 2 ++ .../main/model/users/Conference.as | 11 +++++++ .../modules/users/services/MessageReceiver.as | 6 ++-- .../users/views/BreakoutRoomSettings.mxml | 2 +- .../users/views/RoomActionsRenderer.mxml | 2 +- 13 files changed, 51 insertions(+), 30 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala index 7a647491d7..17d133ab66 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/JsonMessageSenderActor.scala @@ -52,13 +52,13 @@ class JsonMessageSenderActor(val service: MessageSender) // Breakout private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) { - val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.name, msg.breakout.sequence) + 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 payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "", "", 0) val request = new BreakoutRoomClosed(payload) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) } @@ -85,7 +85,7 @@ class JsonMessageSenderActor(val service: MessageSender) 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.name, r.sequence))) + 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()) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala index d4c64c53ae..5c0753e492 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala @@ -36,7 +36,7 @@ case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, paren sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean) case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, joinURL: String) extends IOutMessage case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage -case class BreakoutRoomBody(name: String, meetingId: String, sequence: Int) +case class BreakoutRoomBody(name: String, externalMeetingId: String, meetingId: String, sequence: Int) case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends IOutMessage case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 2cafc97de8..ac21be1cb2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -21,7 +21,7 @@ trait BreakoutRoomApp extends SystemConfiguration { val eventBus: IncomingEventBus def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) { - val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id, r.sequence) } + val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.externalMeetingId, r.id, r.sequence) } val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0 log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length) outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady)) @@ -47,9 +47,10 @@ trait BreakoutRoomApp extends SystemConfiguration { for (room <- msg.rooms) { i += 1 - val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mProps.meetingID, i) + val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mProps.meetingID, i) val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(mProps.voiceBridge, i) - val r = breakoutModel.createBreakoutRoom(breakoutMeetingId, room.name, mProps.meetingID, room.sequence, voiceConfId, room.users) + val r = breakoutModel.createBreakoutRoom(mProps.meetingID, breakoutMeetingId._1, breakoutMeetingId._2, room.name, + room.sequence, voiceConfId, room.users) val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, r.sequence, r.voiceConfId, msg.durationInMinutes, mProps.moderatorPass, mProps.viewerPass, sourcePresentationId, sourcePresentationSlide, msg.record) @@ -59,16 +60,16 @@ trait BreakoutRoomApp extends SystemConfiguration { meetingModel.breakoutRoomsStartedOn = timeNowInSeconds; } - def sendJoinURL(userId: String, breakoutMeetingId: String) { - log.debug("Sending breakout meeting {} Join URL for user: {}", breakoutMeetingId, userId); + def sendJoinURL(userId: String, externalMeetingId: String) { + log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId); for { user <- usersModel.getUser(userId) apiCall = "join" - params = BreakoutRoomsUtil.joinParams(user.name, userId, true, breakoutMeetingId, mProps.moderatorPass, true) + params = BreakoutRoomsUtil.joinParams(user.name, userId, true, externalMeetingId, mProps.moderatorPass, true) baseString = BreakoutRoomsUtil.createBaseString(params) checksum = BreakoutRoomsUtil.calculateChecksum(apiCall, baseString, bbbWebSharedSecret) joinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, baseString, checksum) - } yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, breakoutMeetingId, userId, joinURL)) + } yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, externalMeetingId, userId, joinURL)) } def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) { @@ -79,7 +80,7 @@ trait BreakoutRoomApp extends SystemConfiguration { breakoutModel.pendingRoomsNumber -= 1 val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId) room foreach { room => - sendBreakoutRoomStarted(room.parentRoomId, room.name, room.id, room.sequence, room.voiceConfId) + sendBreakoutRoomStarted(room.parentRoomId, room.name, room.externalMeetingId, room.id, room.sequence, room.voiceConfId) } // We postpone sending invitation until all breakout rooms have been created @@ -89,7 +90,7 @@ trait BreakoutRoomApp extends SystemConfiguration { breakoutModel.getAssignedUsers(room.id) foreach { users => users.foreach { u => log.debug("Sending Join URL for users"); - sendJoinURL(u, room.id) + sendJoinURL(u, room.externalMeetingId) } } } @@ -97,9 +98,9 @@ trait BreakoutRoomApp extends SystemConfiguration { } } - def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutMeetingId: String, sequence: Int, voiceConfId: String) { - log.info("Sending breakout room started for parent meeting {} and breakout meeting", meetingId, breakoutMeetingId); - outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutMeetingId, sequence))) + def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String, breakoutMeetingId: String, sequence: Int, voiceConfId: String) { + log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId); + outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, externalMeetingId, breakoutMeetingId, sequence))) } def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) { @@ -156,11 +157,12 @@ trait BreakoutRoomApp extends SystemConfiguration { } object BreakoutRoomsUtil { - def createMeetingId(id: String, index: Int): String = { + def createMeetingIds(id: String, index: Int): (String, String) = { val timeStamp = System.currentTimeMillis() val externalHash = DigestUtils.sha1Hex(id.concat("-").concat(timeStamp.toString()).concat("-").concat(index.toString())) val externalId = externalHash.concat("-").concat(timeStamp.toString()) - DigestUtils.sha1Hex(externalId).concat("-").concat(timeStamp.toString()) + val internalId = DigestUtils.sha1Hex(externalId).concat("-").concat(timeStamp.toString()) + (internalId, externalId) } def createVoiceConfId(id: String, index: Int): String = { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala index 2ed3ee612b..e6d54f1a9f 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala @@ -3,7 +3,7 @@ package org.bigbluebutton.core.apps import scala.Vector case class BreakoutUser(id: String, name: String) -case class BreakoutRoom(id: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String, +case class BreakoutRoom(id: String, externalMeetingId: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String, assignedUsers: Vector[String], users: Vector[BreakoutUser]) class BreakoutRoomModel { @@ -20,9 +20,9 @@ class BreakoutRoomModel { rooms -= id } - def createBreakoutRoom(id: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String, + def createBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String, assignedUsers: Vector[String]): BreakoutRoom = { - val room = new BreakoutRoom(id, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector()) + val room = new BreakoutRoom(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector()) add(room) } @@ -33,7 +33,7 @@ class BreakoutRoomModel { def getRooms(): Array[BreakoutRoom] = { rooms.values.toArray } - + def getNumberOfRooms(): Int = { rooms.size } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala index 4bae0e70e0..74f9e05337 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/MeetingMessageToJsonConverter.scala @@ -147,8 +147,9 @@ object MeetingMessageToJsonConverter { def breakoutRoomStartedOutMessageToJson(msg: BreakoutRoomStartedOutMessage): String = { val payload = new java.util.HashMap[String, Any]() - payload.put("parentMeetingId", msg.parentMeetingId) 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) diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala index 423590882f..c980b35d66 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/apps/BreakoutRoomsUtilSpec.scala @@ -10,7 +10,7 @@ class BreakoutRoomsUtilSpec extends UnitSpec { val mainMeetingId = "abc-123" val index = 1 val result = mainMeetingId.concat("-").concat(index.toString()) - val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mainMeetingId, index) + val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mainMeetingId, index) assert(breakoutMeetingId == result) } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java index 033b727aeb..898ab50486 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/BreakoutRoomPayload.java @@ -4,13 +4,15 @@ public class BreakoutRoomPayload { public final String parentMeetingId; public final String meetingId; + public final String externalMeetingId; public final String name; public final Integer sequence; public BreakoutRoomPayload(String parentMeetingId, String meetingId, - String name, Integer sequence) { + String externalMeetingId, String name, Integer sequence) { this.parentMeetingId = parentMeetingId; this.meetingId = meetingId; + this.externalMeetingId = externalMeetingId; this.name = name; this.sequence = sequence; } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java index 7e7822e0a3..7990274ade 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java @@ -598,7 +598,8 @@ public class UserClientMessageSender { private void processBreakoutRoomStarted(BreakoutRoomStarted msg) { Map args = new HashMap(); args.put("breakoutMeetingId", msg.payload.meetingId); - args.put("parentMeetingId", msg.payload.parentMeetingId); + args.put("parentMeetingId", msg.payload.parentMeetingId); + args.put("externalMeetingId", msg.payload.externalMeetingId); args.put("sequence", msg.payload.sequence); args.put("name", msg.payload.name); diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as index 1e3b7e2109..ed653efc13 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/BreakoutRoom.as @@ -28,6 +28,8 @@ package org.bigbluebutton.main.model.users { public static const OTHER:String = "other"; + public var externalMeetingId:String; + public var meetingId:String; public var sequence:int; diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as index 67d66f39ae..61022aa41a 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as @@ -586,6 +586,17 @@ package org.bigbluebutton.main.model.users { return null; } + public function getBreakoutRoomByExternalId(externalId:String):BreakoutRoom { + var aRoom:BreakoutRoom; + for (var i:int = 0; i < breakoutRooms.length; i++) { + aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom; + if (aRoom.externalMeetingId == externalId) { + return aRoom; + } + } + return null; + } + public function getBreakoutRoomBySequence(sequence:int):BreakoutRoom { var aRoom:BreakoutRoom; for (var i:int = 0; i < breakoutRooms.length; i++) { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as index fda9dd52dc..a7d3379ed7 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageReceiver.as @@ -631,6 +631,7 @@ package org.bigbluebutton.modules.users.services { var breakoutRoom : BreakoutRoom = new BreakoutRoom(); breakoutRoom.meetingId = room.meetingId; + breakoutRoom.externalMeetingId = room.externalMeetingId; breakoutRoom.name = room.name; breakoutRoom.sequence = room.sequence; UserManager.getInstance().getConference().addBreakoutRoom(breakoutRoom); @@ -642,8 +643,8 @@ package org.bigbluebutton.modules.users.services var map:Object = JSON.parse(msg.msg); var event : BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.BREAKOUT_JOIN_URL); event.joinURL = map.joinURL; - var meetingId : String = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); - event.breakoutMeetingSequence = UserManager.getInstance().getConference().getBreakoutRoom(meetingId).sequence; + var externalMeetingId : String = StringUtils.substringBetween(event.joinURL, "meetingID=", "&"); + event.breakoutMeetingSequence = UserManager.getInstance().getConference().getBreakoutRoomByExternalId(externalMeetingId).sequence; dispatcher.dispatchEvent(event); } @@ -670,6 +671,7 @@ package org.bigbluebutton.modules.users.services var map:Object = JSON.parse(msg.msg); var breakoutRoom : BreakoutRoom = new BreakoutRoom(); breakoutRoom.meetingId = map.breakoutMeetingId; + breakoutRoom.externalMeetingId = map.externalMeetingId; breakoutRoom.name = map.name; breakoutRoom.sequence = map.sequence; UserManager.getInstance().getConference().addBreakoutRoom(breakoutRoom); diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml index 769b4233bd..f84b9107f1 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml @@ -105,7 +105,7 @@ with BigBlueButton; if not, see . usersInvited ||= true; var event:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.REQUEST_BREAKOUT_JOIN_URL); event.userId = user.userID; - event.breakoutMeetingId = UserManager.getInstance().getConference().getBreakoutRoomBySequence(i + 1).meetingId; + event.breakoutMeetingId = UserManager.getInstance().getConference().getBreakoutRoomBySequence(i + 1).externalMeetingId; dispatcher.dispatchEvent(event); } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml index 3ab46d4391..65f5cfdb93 100644 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/RoomActionsRenderer.mxml @@ -44,7 +44,7 @@ protected function requestBreakoutJoinUrl(event:MouseEvent):void { var e:BreakoutRoomEvent = new BreakoutRoomEvent(BreakoutRoomEvent.REQUEST_BREAKOUT_JOIN_URL); - e.breakoutMeetingId = data.meetingId as String; + e.breakoutMeetingId = data.externalMeetingId as String; e.userId = UserManager.getInstance().getConference().getMyUserId(); globalDispatch.dispatchEvent(e); } From 8e8fee7826a7dcf654f0cd0379dac7ce24258f00 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Thu, 13 Oct 2016 17:43:53 +0100 Subject: [PATCH 11/22] Re-enable recording option for breakout rooms. --- .../modules/users/views/BreakoutRoomSettings.mxml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml index f84b9107f1..8a3b007d52 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/BreakoutRoomSettings.mxml @@ -294,8 +294,8 @@ with BigBlueButton; if not, see . - - + From e187634c2ab6451995dc7a947566924185b33c63 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Fri, 14 Oct 2016 16:33:17 +0100 Subject: [PATCH 12/22] Using blank-presentation.pdf as default breakout room presentation when no current presentation is set to the parent room. --- .../core/apps/BreakoutRoomApp.scala | 4 +- .../slides/blank-presentation.pdf | Bin 0 -> 1868 bytes .../grails-app/conf/bigbluebutton.properties | 441 +++++++++--------- .../grails-app/conf/spring/resources.xml | 1 + .../api/messaging/MeetingMessageHandler.java | 2 +- .../PresentationUrlDownloadService.java | 76 +-- 6 files changed, 268 insertions(+), 256 deletions(-) create mode 100644 bigbluebutton-config/slides/blank-presentation.pdf diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index ac21be1cb2..0d8820440c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -41,8 +41,8 @@ trait BreakoutRoomApp extends SystemConfiguration { var i = 0 // in very rare cases the presentation conversion generates an error, what should we do? // those cases where default.pdf is deleted from the whiteboard - val sourcePresentationId = presModel.getCurrentPresentation().get.id - val sourcePresentationSlide = presModel.getCurrentPage().get.num + val sourcePresentationId = if (!presModel.getCurrentPresentation().isEmpty) presModel.getCurrentPresentation().get.id else "blank" + val sourcePresentationSlide = if (!presModel.getCurrentPage().isEmpty) presModel.getCurrentPage().get.num else 0 breakoutModel.pendingRoomsNumber = msg.rooms.length; for (room <- msg.rooms) { diff --git a/bigbluebutton-config/slides/blank-presentation.pdf b/bigbluebutton-config/slides/blank-presentation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ebf6257403b88d9f0eeeb1dfcb096f0c9fc52a9d GIT binary patch literal 1868 zcmcIlO>f#j5Y2gi#atpKhp@ZGHg*){5NO({r6CZhl~7cz?KN=%UTT(x^wgi;8Dj&* z>4y~60?C?vvpe(NoAu$KcX=XPE-(oKO!UCc&KMu4iC%z%ks;%^&vOmDtE`%u2|GV$ zI!_2l%XPvUQ>HQgK1&ubhBl?c9phcI%q_^BR9b4L(z%63Xm#*VFU+!tu@b83^L6x~ zV~g*=uVw;*a(gU?4+;~Hv;}_?>FXp@7iI-xfiW-iAaEV3q%iZB!X~$P?gCue0Xx25 z&LWV+$Z)4>TCJ=8p!12n2d{=KY@yYReJyDeK&b-a87oWe8Fs^nwhC1dNXfLH)2S(? z4k$7Pj=BK9)hkQgq8wdhvdZgJC}d@;2GLO$w^pMfjPcPjvZaRQMvQ+{GZYj#Wc)Il zT3w)6e7MZlJ@s^K5>2{&$`Wi*GX73ylY3GSrJR~#G*__(NgX0t7nxlQbkQ}lxyebr z08i|z#UscyJG|m5Eb&-z#lpeCk0vJsqBh!fv*j@q;XVB=i}l+=J#W@_J^PMzm}XEbo0+_)EJk{#j*z|-vMoaqIxYhGCi(3ej(W0;(XmIRm-}jx#gE{(f>wAE z!VOlj3j8m=3$*Krz@LPBYv-q&KRrFQGMXg(V^Yf$ljEKFSrs~EIJf~5n+JT)YkQEw zCPr?g2l8#qL(lHTq{MODi?uPU5er_3h0R>Ijr8vA=Xyx+Ud;EJIKP7y+{1N{mi<`Z zHgf}HvVjYlxKK23QiKhhlw|z67F(!ns*Cc2Gs?c>jey&_O#%<8yfZ W7I*7WP=zfmBb^{*hlg*jFWFBbfbT&7 literal 0 HcmV?d00001 diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties index 10e12539b3..1c9d5a130a 100755 --- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties +++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties @@ -1,220 +1,221 @@ -# -# 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 . -# - -# -# These are the default properites for BigBlueButton Web application - -# Default loglevel. -appLogLevel=DEBUG - -#---------------------------------------------------- -# Directory where BigBlueButton stores uploaded slides -presentationDir=/var/bigbluebutton - -#---------------------------------------------------- -# Directory where SWFTOOLS (pdf2swf, jpeg2swf, png2swf) are located -swfToolsDir=/usr/bin - -#---------------------------------------------------- -# Directory where ImageMagick's convert executable is located -imageMagickDir=/usr/bin - -#---------------------------------------------------- -# Use fullpath to ghostscript executable since the exec names are different -# for each platform. -ghostScriptExec=/usr/bin/gs - -#---------------------------------------------------- -# Fonts directory passed into PDF2SWF to support highlighting of texts -# in the SWF slides. -fontsDir=/usr/share/fonts - -#---------------------------------------------------- -# This is a workaround for a problem converting PDF files, referenced at -# http://groups.google.com/group/comp.lang.postscript/browse_thread/thread/c2e264ca76534ce0?pli=1 -noPdfMarkWorkaround=/etc/bigbluebutton/nopdfmark.ps - -#---------------------------------------------------- -# These will be copied in cases where the conversion process -# fails to generate a slide from the uploaded presentation -BLANK_SLIDE=/var/bigbluebutton/blank/blank-slide.swf -BLANK_THUMBNAIL=/var/bigbluebutton/blank/blank-thumb.png - -#---------------------------------------------------- -# Number of minutes the conversion should take. If it takes -# more than this time, cancel the conversion process. -maxConversionTime=5 - -#---------------------------------------------------- -# Maximum number of pages allowed for an uploaded presentation (default 100). -maxNumPages=200 - -#---------------------------------------------------- -# Maximum swf file size for load to the client (default 500000). -MAX_SWF_FILE_SIZE=500000 - -#---------------------------------------------------- -# Maximum allowed number of place object tags in the converted SWF, if exceeded the conversion will fallback to full BMP (default 8000) -placementsThreshold=8000 - -# Maximum allowed number of bitmap images in the converted SWF, if exceeded the conversion will fallback to full BMP (default 8000) -imageTagThreshold=8000 - -# Maximum allowed number of define text tags in the converted SWF, if exceeded the conversion will fallback to full BMP (default 2500) -defineTextThreshold=2500 - -#------------------------------------ -# Number of threads in the pool to do the presentation conversion. -#------------------------------------ -numConversionThreads=2 - -#---------------------------------------------------- -# Additional conversion of the presentation slides to SVG -# to be used in the HTML5 client -svgImagesRequired=false - -# Default number of digits for voice conference users joining through the PSTN. -defaultNumDigitsForTelVoice=5 - -#---------------------------------------------------- -# Default dial access number -defaultDialAccessNumber=613-555-1234 - -#---------------------------------------------------- -# Default welcome message to display when the participant joins the web -# conference. This is only used for the old scheduling which will be -# removed in the future. Use the API to create a conference. -defaultWelcomeMessage=
Welcome to %%CONFNAME%%!

For help on using BigBlueButton see these (short) tutorial videos.

To join the audio bridge click the headset icon (upper-left hand corner). Use a headset to avoid causing background noise for others.
-defaultWelcomeMessageFooter=This server is running BigBlueButton. - -# Default maximum number of users a meeting can have. -# Current default is 0 (meeting doesn't have a user limit). -defaultMaxUsers=0 - -# Default duration of the meeting in minutes. -# Current default is 0 (meeting doesn't end). -defaultMeetingDuration=0 - -# Remove the meeting from memory when the end API is called. -# This allows 3rd-party apps to recycle the meeting right-away -# instead of waiting for the meeting to expire (see below). -removeMeetingWhenEnded=true - -# The number of minutes before the system removes the meeting from memory. -defaultMeetingExpireDuration=1 - -# The number of minutes the system waits when a meeting is created and when -# a user joins. If after this period, a user hasn't joined, the meeting is -# removed from memory. -defaultMeetingCreateJoinDuration=5 - -# Disable recording by default. -# true - don't record even if record param in the api call is set to record -# false - when record param is passed from api, override this default -disableRecordingDefault=false - -# Start recording when first user joins the meeting. -# For backward compatibility with 0.81 where whole meeting -# is recorded. -autoStartRecording=false - -# Allow the user to start/stop recording. -allowStartStopRecording=true - -#---------------------------------------------------- -# This URL is where the BBB client is accessible. When a user sucessfully -# enters a name and password, she is redirected here to load the client. -bigbluebutton.web.serverURL=http://192.168.23.44 - - -#---------------------------------------------------- -# Assign URL where the logged-out participant will be redirected after sign-out. -# If "default", it returns to bigbluebutton.web.serverURL -bigbluebutton.web.logoutURL=default - -# The url of the BigBlueButton client. User's will be redirected here when -# successfully joining the meeting. -defaultClientUrl=${bigbluebutton.web.serverURL}/client/BigBlueButton.html -#defaultClientUrl=http://192.168.0.235/3rd-party.html - -# The default avatar image to display if nothing is passed on the JOIN API (avatarURL) -# call. This avatar is displayed if the user isn't sharing the webcam and -# the option (displayAvatar) is enabled in config.xml -defaultAvatarURL=${bigbluebutton.web.serverURL}/client/avatar.png - -# The URL of the default configuration -defaultConfigURL=${bigbluebutton.web.serverURL}/client/conf/config.xml - -apiVersion=1.0 - -# Salt which is used by 3rd-party apps to authenticate api calls -securitySalt=a820d30da2db356124fce5bd5d8054b4 - -# Directory where we drop the .done file -recordStatusDir=/var/bigbluebutton/recording/status/recorded - -redisHost=127.0.0.1 -redisPort=6379 - -# The directory where the published/unpublised recordings are located. This is for -# the get recording* api calls -publishedDir=/var/bigbluebutton/published -unpublishedDir=/var/bigbluebutton/unpublished - -# The directory where the pre-built configs are stored -configDir=/var/bigbluebutton/configs - -# If the API is enabled. -serviceEnabled = true - -# Test voiceBridge number -testVoiceBridge=99999 -testConferenceMock=conference-mock-default - -#------------------------------------------------------ -# These properties are used to test the conversion process. -# Conference name folder in ${presentationDir} (see above) -beans.presentationService.testConferenceMock=${testConferenceMock} - -# Conference room folder in ${presentationDir}/${testConferenceMock} -beans.presentationService.testRoomMock=conference-mock-default -# Uploaded presentation name -beans.presentationService.testPresentationName=appkonference -# Uploaded presentation file -beans.presentationService.testUploadedPresentation=appkonference.txt -# Default Uploaded presentation file -beans.presentationService.defaultUploadedPresentation=${bigbluebutton.web.serverURL}/default.pdf - -presentationBaseURL=${bigbluebutton.web.serverURL}/bigbluebutton/presentation - -#---------------------------------------------------- -# The URL where the presentations will be loaded from. -#---------------------------------------------------- -beans.presentationService.presentationBaseUrl=${presentationBaseURL} -#---------------------------------------------------- -# Inject values into grails service beans -beans.presentationService.presentationDir=${presentationDir} - -#---------------------------------------------------- -# Specify which IPs can do cross domain requests -accessControlAllowOrigin=${bigbluebutton.web.serverURL} - -#---------------------------------------------------- -# The lapsus of seconds for polling the BBB Server in order to check if it's down. -# After 5 tries if there isn't response, it will be declared down -checkBBBServerEvery=10 +# +# 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 . +# + +# +# These are the default properites for BigBlueButton Web application + +# Default loglevel. +appLogLevel=DEBUG + +#---------------------------------------------------- +# Directory where BigBlueButton stores uploaded slides +presentationDir=/var/bigbluebutton + +#---------------------------------------------------- +# Directory where SWFTOOLS (pdf2swf, jpeg2swf, png2swf) are located +swfToolsDir=/usr/bin + +#---------------------------------------------------- +# Directory where ImageMagick's convert executable is located +imageMagickDir=/usr/bin + +#---------------------------------------------------- +# Use fullpath to ghostscript executable since the exec names are different +# for each platform. +ghostScriptExec=/usr/bin/gs + +#---------------------------------------------------- +# Fonts directory passed into PDF2SWF to support highlighting of texts +# in the SWF slides. +fontsDir=/usr/share/fonts + +#---------------------------------------------------- +# This is a workaround for a problem converting PDF files, referenced at +# http://groups.google.com/group/comp.lang.postscript/browse_thread/thread/c2e264ca76534ce0?pli=1 +noPdfMarkWorkaround=/etc/bigbluebutton/nopdfmark.ps + +#---------------------------------------------------- +# These will be copied in cases where the conversion process +# fails to generate a slide from the uploaded presentation +BLANK_SLIDE=/var/bigbluebutton/blank/blank-slide.swf +BLANK_PRESENTATION=/var/bigbluebutton/blank/blank-presentation.pdf +BLANK_THUMBNAIL=/var/bigbluebutton/blank/blank-thumb.png + +#---------------------------------------------------- +# Number of minutes the conversion should take. If it takes +# more than this time, cancel the conversion process. +maxConversionTime=5 + +#---------------------------------------------------- +# Maximum number of pages allowed for an uploaded presentation (default 100). +maxNumPages=200 + +#---------------------------------------------------- +# Maximum swf file size for load to the client (default 500000). +MAX_SWF_FILE_SIZE=500000 + +#---------------------------------------------------- +# Maximum allowed number of place object tags in the converted SWF, if exceeded the conversion will fallback to full BMP (default 8000) +placementsThreshold=8000 + +# Maximum allowed number of bitmap images in the converted SWF, if exceeded the conversion will fallback to full BMP (default 8000) +imageTagThreshold=8000 + +# Maximum allowed number of define text tags in the converted SWF, if exceeded the conversion will fallback to full BMP (default 2500) +defineTextThreshold=2500 + +#------------------------------------ +# Number of threads in the pool to do the presentation conversion. +#------------------------------------ +numConversionThreads=2 + +#---------------------------------------------------- +# Additional conversion of the presentation slides to SVG +# to be used in the HTML5 client +svgImagesRequired=false + +# Default number of digits for voice conference users joining through the PSTN. +defaultNumDigitsForTelVoice=5 + +#---------------------------------------------------- +# Default dial access number +defaultDialAccessNumber=613-555-1234 + +#---------------------------------------------------- +# Default welcome message to display when the participant joins the web +# conference. This is only used for the old scheduling which will be +# removed in the future. Use the API to create a conference. +defaultWelcomeMessage=
Welcome to %%CONFNAME%%!

For help on using BigBlueButton see these (short) tutorial videos.

To join the audio bridge click the headset icon (upper-left hand corner). Use a headset to avoid causing background noise for others.
+defaultWelcomeMessageFooter=This server is running BigBlueButton. + +# Default maximum number of users a meeting can have. +# Current default is 0 (meeting doesn't have a user limit). +defaultMaxUsers=0 + +# Default duration of the meeting in minutes. +# Current default is 0 (meeting doesn't end). +defaultMeetingDuration=0 + +# Remove the meeting from memory when the end API is called. +# This allows 3rd-party apps to recycle the meeting right-away +# instead of waiting for the meeting to expire (see below). +removeMeetingWhenEnded=true + +# The number of minutes before the system removes the meeting from memory. +defaultMeetingExpireDuration=1 + +# The number of minutes the system waits when a meeting is created and when +# a user joins. If after this period, a user hasn't joined, the meeting is +# removed from memory. +defaultMeetingCreateJoinDuration=5 + +# Disable recording by default. +# true - don't record even if record param in the api call is set to record +# false - when record param is passed from api, override this default +disableRecordingDefault=false + +# Start recording when first user joins the meeting. +# For backward compatibility with 0.81 where whole meeting +# is recorded. +autoStartRecording=false + +# Allow the user to start/stop recording. +allowStartStopRecording=true + +#---------------------------------------------------- +# This URL is where the BBB client is accessible. When a user sucessfully +# enters a name and password, she is redirected here to load the client. +bigbluebutton.web.serverURL=http://192.168.23.44 + + +#---------------------------------------------------- +# Assign URL where the logged-out participant will be redirected after sign-out. +# If "default", it returns to bigbluebutton.web.serverURL +bigbluebutton.web.logoutURL=default + +# The url of the BigBlueButton client. User's will be redirected here when +# successfully joining the meeting. +defaultClientUrl=${bigbluebutton.web.serverURL}/client/BigBlueButton.html +#defaultClientUrl=http://192.168.0.235/3rd-party.html + +# The default avatar image to display if nothing is passed on the JOIN API (avatarURL) +# call. This avatar is displayed if the user isn't sharing the webcam and +# the option (displayAvatar) is enabled in config.xml +defaultAvatarURL=${bigbluebutton.web.serverURL}/client/avatar.png + +# The URL of the default configuration +defaultConfigURL=${bigbluebutton.web.serverURL}/client/conf/config.xml + +apiVersion=1.0 + +# Salt which is used by 3rd-party apps to authenticate api calls +securitySalt=a820d30da2db356124fce5bd5d8054b4 + +# Directory where we drop the .done file +recordStatusDir=/var/bigbluebutton/recording/status/recorded + +redisHost=127.0.0.1 +redisPort=6379 + +# The directory where the published/unpublised recordings are located. This is for +# the get recording* api calls +publishedDir=/var/bigbluebutton/published +unpublishedDir=/var/bigbluebutton/unpublished + +# The directory where the pre-built configs are stored +configDir=/var/bigbluebutton/configs + +# If the API is enabled. +serviceEnabled = true + +# Test voiceBridge number +testVoiceBridge=99999 +testConferenceMock=conference-mock-default + +#------------------------------------------------------ +# These properties are used to test the conversion process. +# Conference name folder in ${presentationDir} (see above) +beans.presentationService.testConferenceMock=${testConferenceMock} + +# Conference room folder in ${presentationDir}/${testConferenceMock} +beans.presentationService.testRoomMock=conference-mock-default +# Uploaded presentation name +beans.presentationService.testPresentationName=appkonference +# Uploaded presentation file +beans.presentationService.testUploadedPresentation=appkonference.txt +# Default Uploaded presentation file +beans.presentationService.defaultUploadedPresentation=${bigbluebutton.web.serverURL}/default.pdf + +presentationBaseURL=${bigbluebutton.web.serverURL}/bigbluebutton/presentation + +#---------------------------------------------------- +# The URL where the presentations will be loaded from. +#---------------------------------------------------- +beans.presentationService.presentationBaseUrl=${presentationBaseURL} +#---------------------------------------------------- +# Inject values into grails service beans +beans.presentationService.presentationDir=${presentationDir} + +#---------------------------------------------------- +# Specify which IPs can do cross domain requests +accessControlAllowOrigin=${bigbluebutton.web.serverURL} + +#---------------------------------------------------- +# The lapsus of seconds for polling the BBB Server in order to check if it's down. +# After 5 tries if there isn't response, it will be declared down +checkBBBServerEvery=10 diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml index 48cc70b20a..4c8319a9cd 100755 --- a/bigbluebutton-web/grails-app/conf/spring/resources.xml +++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml @@ -61,6 +61,7 @@ with BigBlueButton; if not, see . + diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java index 31b93ee866..9bfd168087 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java @@ -89,7 +89,7 @@ public class MeetingMessageHandler implements MessageHandler { } else if (EndBreakoutRoomRequest.NAME.equals(messageName)) { EndBreakoutRoomRequest msg = new Gson().fromJson(message, EndBreakoutRoomRequest.class); - log.info("Received an end breakout room request message for breakout meeting id=[{}]", msg.payload.meetingId); + log.info("Received end breakout room request message for breakout meeting id=[{}]", msg.payload.meetingId); for (MessageListener listener : listeners) { listener.handle(new EndBreakoutRoom(msg.payload.meetingId)); } diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java index f28a59b316..63836e91e4 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java @@ -27,6 +27,7 @@ public class PresentationUrlDownloadService { private DocumentConversionService documentConversionService; private String presentationBaseURL; private String presentationDir; + private String BLANK_PRESENTATION; public void processUploadedPresentation(UploadedPresentation uploadedPres) { documentConversionService.processDocument(uploadedPres); @@ -43,11 +44,12 @@ public class PresentationUrlDownloadService { public void extractPage(String sourceMeetingId, String presentationId, Integer presentationSlide, String destinationMeetingId) { - // Construct the source meeting path + // Build the source meeting path File sourceMeetingPath = new File(presentationDir + File.separator + sourceMeetingId + File.separator + sourceMeetingId + File.separator + presentationId); + // Find the source meeting presentation file final String presentationFilter = presentationId; FilenameFilter pdfFilter = new FilenameFilter() { public boolean accept(File dir, String name) { @@ -57,7 +59,7 @@ public class PresentationUrlDownloadService { }; File[] matches = sourceMeetingPath.listFiles(pdfFilter); - if (matches.length != 1) { + if (matches != null && matches.length != 1) { // No PDF presentation was found, we look for an image presentation FilenameFilter imgFlter = new FilenameFilter() { public boolean accept(File dir, String name) { @@ -67,40 +69,44 @@ public class PresentationUrlDownloadService { matches = sourceMeetingPath.listFiles(imgFlter); } - if (matches.length != 1) { - log.info("Not matching PDF file with prefix {} found at {}", + File sourcePresentationFile; + if (matches == null || matches.length != 1) { + log.warn( + "Not matching PDF file with prefix {} found at {}. Using the default blank PDF", sourceMeetingId, sourceMeetingPath); + sourcePresentationFile = new File(BLANK_PRESENTATION); } else { - File sourcePresentationFile = matches[0]; - String filenameExt = FilenameUtils - .getExtension(sourcePresentationFile.getName()); - String presId = generatePresentationId(presentationId); - String newFilename = Util.createNewFilename(presId, filenameExt); - - File uploadDir = createPresentationDirectory(destinationMeetingId, - presentationDir, presId); - String newFilePath = uploadDir.getAbsolutePath() - + File.separatorChar + newFilename; - File newPresentation = new File(newFilePath); - - if (sourcePresentationFile.getName().toLowerCase().endsWith("pdf")) { - pageExtractor.extractPage(sourcePresentationFile, new File( - newFilePath), presentationSlide); - } else { - try { - FileUtils.copyFile(sourcePresentationFile, newPresentation); - } catch (IOException e) { - log.error("Could not copy presentation {} to {}", - sourcePresentationFile.getAbsolutePath(), - newPresentation.getAbsolutePath()); - e.printStackTrace(); - } - } - - processUploadedFile(destinationMeetingId, presId, "default-" - + presentationSlide.toString() + "." + filenameExt, - newPresentation); + sourcePresentationFile = matches[0]; } + // Build the target meeting path + String filenameExt = FilenameUtils.getExtension(sourcePresentationFile + .getName()); + String presId = generatePresentationId(presentationId); + String newFilename = Util.createNewFilename(presId, filenameExt); + + File uploadDir = createPresentationDirectory(destinationMeetingId, + presentationDir, presId); + String newFilePath = uploadDir.getAbsolutePath() + File.separatorChar + + newFilename; + File newPresentation = new File(newFilePath); + + if (sourcePresentationFile.getName().toLowerCase().endsWith("pdf")) { + pageExtractor.extractPage(sourcePresentationFile, new File( + newFilePath), presentationSlide); + } else { + try { + FileUtils.copyFile(sourcePresentationFile, newPresentation); + } catch (IOException e) { + log.error("Could not copy presentation {} to {}", + sourcePresentationFile.getAbsolutePath(), + newPresentation.getAbsolutePath()); + e.printStackTrace(); + } + } + + processUploadedFile(destinationMeetingId, presId, "default-" + + presentationSlide.toString() + "." + filenameExt, + newPresentation); } public String generatePresentationId(String name) { @@ -220,4 +226,8 @@ public class PresentationUrlDownloadService { this.documentConversionService = documentConversionService; } + public void setBlankPresentation(String blankPresentation) { + this.BLANK_PRESENTATION = blankPresentation; + } + } From 638b6d0433ae3e4b27241d0640eac2b22d561dff Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Fri, 14 Oct 2016 16:59:22 +0100 Subject: [PATCH 13/22] Store breakout meeting info in redis under "meeting:breakout" key instead of "meeting:info" --- .../org/bigbluebutton/api/MeetingService.java | 8 ++-- .../api/messaging/MessagingService.java | 2 +- .../api/messaging/RedisMessagingService.java | 4 +- .../api/messaging/RedisStorageService.java | 38 +++++++++++-------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java index 7c8309d2a1..1f3249cd3e 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingService.java @@ -302,12 +302,14 @@ public class MeetingService implements MessageListener { metadata.put("meetingId", m.getExternalId()); metadata.put("meetingName", m.getName()); metadata.put("isBreakout", m.isBreakout().toString()); + + Map breakoutMetadata = new TreeMap(); if (m.isBreakout() != null){ - metadata.put("sequence", m.getSequence().toString()); - metadata.put("parentMeetingId", m.getParentMeetingId()); + breakoutMetadata.put("sequence", m.getSequence().toString()); + breakoutMetadata.put("parentMeetingId", m.getParentMeetingId()); } - messagingService.recordMeetingInfo(m.getInternalId(), metadata); + messagingService.recordMeetingInfo(m.getInternalId(), metadata, breakoutMetadata); } Map logData = new HashMap(); diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java index 45d5a4b3fc..b665c9b398 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.Set; public interface MessagingService { - void recordMeetingInfo(String meetingId, Map info); + void recordMeetingInfo(String meetingId, Map info, Map breakoutInfo); void destroyMeeting(String meetingID); void createMeeting(String meetingID, String externalMeetingID, String parentMeetingID, String meetingName, Boolean recorded, diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java index 60ecc1f7ff..4d4d4e75d6 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java @@ -49,8 +49,8 @@ public class RedisMessagingService implements MessagingService { private MessageSender sender; private ToJsonEncoder encoder = new ToJsonEncoder(); - public void recordMeetingInfo(String meetingId, Map info) { - storeService.recordMeetingInfo(meetingId, info); + public void recordMeetingInfo(String meetingId, Map info, Map breakoutInfo) { + storeService.recordMeetingInfo(meetingId, info, breakoutInfo); } public void destroyMeeting(String meetingID) { diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisStorageService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisStorageService.java index 1797a97ff2..f27a34d9b9 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisStorageService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisStorageService.java @@ -28,24 +28,32 @@ public class RedisStorageService { // CLIENT LIST on redis-cli redisPool = new JedisPool(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub"); - } - public void recordMeetingInfo(String meetingId, Map info) { - Jedis jedis = redisPool.getResource(); - try { - for (String key: info.keySet()) { - log.debug("Storing metadata {} = {}", key, info.get(key)); - } + public void recordMeetingInfo(String meetingId, Map info, + Map breakoutInfo) { + Jedis jedis = redisPool.getResource(); + try { + for (String key : info.keySet()) { + log.debug("Storing metadata {} = {}", key, info.get(key)); + } - log.debug("Saving metadata in {}", meetingId); - jedis.hmset("meeting:info:" + meetingId, info); - } catch (Exception e){ - log.warn("Cannot record the info meeting:"+meetingId,e); - } finally { - jedis.close(); - } - } + log.debug("Saving metadata in {}", meetingId); + jedis.hmset("meeting:info:" + meetingId, info); + + for (String breakoutKey : breakoutInfo.keySet()) { + log.debug("Storing breakout metadata {} = {}", breakoutKey, + breakoutInfo.get(breakoutKey)); + } + + log.debug("Saving breakout metadata in {}", meetingId); + jedis.hmset("meeting:breakout:" + meetingId, breakoutInfo); + } catch (Exception e) { + log.warn("Cannot record the info meeting:" + meetingId, e); + } finally { + jedis.close(); + } + } public void removeMeeting(String meetingId){ Jedis jedis = redisPool.getResource(); From f055771abd85f3ecfea3a589fe1d5622ef42451e Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan Date: Fri, 14 Oct 2016 16:18:54 +0000 Subject: [PATCH 14/22] Fix handler for 'get_whiteboard_shapes_reply' not calling the cb --- .../imports/api/shapes/server/modifiers/eventHandlers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bigbluebutton-html5/imports/api/shapes/server/modifiers/eventHandlers.js b/bigbluebutton-html5/imports/api/shapes/server/modifiers/eventHandlers.js index 1f101904df..2d55951487 100755 --- a/bigbluebutton-html5/imports/api/shapes/server/modifiers/eventHandlers.js +++ b/bigbluebutton-html5/imports/api/shapes/server/modifiers/eventHandlers.js @@ -14,9 +14,9 @@ eventEmitter.on('get_whiteboard_shapes_reply', function (arg) { let whiteboardId = shape.wb_id; addShapeToCollection(meetingId, whiteboardId, shape); } - - return arg.callback(); } + + return arg.callback(); }); eventEmitter.on('send_whiteboard_shape_message', function (arg) { From c694f632eade1583e6db80afa95e8118bcac1a66 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Fri, 14 Oct 2016 20:46:34 +0100 Subject: [PATCH 15/22] Added redirect property to RequestBreakoutJoinURL. --- .../org/bigbluebutton/core/Protocol.scala | 2 +- .../bigbluebutton/core/api/InMessages.scala | 2 +- .../core/apps/BreakoutRoomApp.scala | 9 ++++---- .../RequestBreakoutJoinURLPayload.java | 21 +++++++++++-------- .../main/model/users/UserService.as | 2 +- .../modules/users/services/MessageSender.as | 13 +++++------- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala index 6ad592e11c..e0c9e689d8 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala @@ -27,7 +27,7 @@ object UserMessagesProtocol extends DefaultJsonProtocol { implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload) implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms) implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage) - implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat3(RequestBreakoutJoinURLInMessage) + implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat4(RequestBreakoutJoinURLInMessage) implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest) implicit val endBreakoutRoomsFormat = jsonFormat1(EndAllBreakoutRooms) implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index 0cf1b1edbe..0c1a37f108 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -45,7 +45,7 @@ case class BreakoutRoomsListMessage(meetingId: String) extends InMessage 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 +case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutMeetingId: String, userId: String, redirect: Boolean) 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. diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 0d8820440c..8b7822bbac 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -60,12 +60,12 @@ trait BreakoutRoomApp extends SystemConfiguration { meetingModel.breakoutRoomsStartedOn = timeNowInSeconds; } - def sendJoinURL(userId: String, externalMeetingId: String) { + def sendJoinURL(userId: String, externalMeetingId: String, redirect: Boolean) { log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId); for { user <- usersModel.getUser(userId) apiCall = "join" - params = BreakoutRoomsUtil.joinParams(user.name, userId, true, externalMeetingId, mProps.moderatorPass, true) + params = BreakoutRoomsUtil.joinParams(user.name, userId, true, externalMeetingId, mProps.moderatorPass, redirect) baseString = BreakoutRoomsUtil.createBaseString(params) checksum = BreakoutRoomsUtil.calculateChecksum(apiCall, baseString, bbbWebSharedSecret) joinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, baseString, checksum) @@ -73,7 +73,7 @@ trait BreakoutRoomApp extends SystemConfiguration { } def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) { - sendJoinURL(msg.userId, msg.breakoutMeetingId) + sendJoinURL(msg.userId, msg.breakoutMeetingId, msg.redirect) } def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) { @@ -90,7 +90,8 @@ trait BreakoutRoomApp extends SystemConfiguration { breakoutModel.getAssignedUsers(room.id) foreach { users => users.foreach { u => log.debug("Sending Join URL for users"); - sendJoinURL(u, room.externalMeetingId) + // @fixme: to refactor with CreateBreakoutRooms + sendJoinURL(u, room.externalMeetingId, true) } } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java index af5d0cb1dd..00f2aabaee 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/RequestBreakoutJoinURLPayload.java @@ -2,13 +2,16 @@ package org.bigbluebutton.messages.payload; public class RequestBreakoutJoinURLPayload { - public final String meetingId; - public final String breakoutMeetingId; - public final String userId; - - public RequestBreakoutJoinURLPayload(String meetingId, String breakoutMeetingId, String userId) { - this.meetingId = meetingId; - this.breakoutMeetingId = breakoutMeetingId; - this.userId = userId; - } + public final String meetingId; + public final String breakoutMeetingId; + public final String userId; + public final Boolean redirect; + + public RequestBreakoutJoinURLPayload(String meetingId, + String breakoutMeetingId, String userId, Boolean redirect) { + this.meetingId = meetingId; + this.breakoutMeetingId = breakoutMeetingId; + this.userId = userId; + this.redirect = redirect; + } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as index 82111fe31f..66b8262275 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as @@ -203,7 +203,7 @@ package org.bigbluebutton.main.model.users } public function requestBreakoutJoinUrl(e:BreakoutRoomEvent):void{ - sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutMeetingId, e.userId); + sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutMeetingId, e.userId, true); } public function listenInOnBreakout(e:BreakoutRoomEvent):void { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as index bda7ed2cb5..8f2622f9fa 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as @@ -107,24 +107,21 @@ package org.bigbluebutton.modules.users.services ); } - public function requestBreakoutJoinUrl(parentMeetingId:String, breakoutMeetingId:String, userId:String):void { + public function requestBreakoutJoinUrl(parentMeetingId:String, breakoutMeetingId:String, userId:String, redirect:Boolean):void { var message:Object = new Object(); message["meetingId"] = parentMeetingId; message["breakoutMeetingId"] = breakoutMeetingId; message["userId"] = userId; + message["redirect"] = redirect; var jsonMsg:String = JSON.stringify(message); var _nc:ConnectionManager = BBB.initConnectionManager(); - _nc.sendMessage("breakoutroom.requestBreakoutJoinUrl", function(result:String):void - { + _nc.sendMessage("breakoutroom.requestBreakoutJoinUrl", function(result:String):void { // On successful result - }, function(status:String):void - { // status - On error occurred + }, function(status:String):void { // status - On error occurred LOGGER.error(status); - }, - jsonMsg - ); + }, jsonMsg); } public function listenInOnBreakout(meetingId:String, targetMeetingId:String, userId:String):void { From 415e34fb28e1919f1fa0faeb38900e4c425c82cd Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Fri, 14 Oct 2016 21:28:44 +0100 Subject: [PATCH 16/22] Added new property redirectOnJoin to CreateBreakoutRoomsRequest. --- .../org/bigbluebutton/core/Protocol.scala | 2 +- .../bigbluebutton/core/api/InMessages.scala | 2 +- .../core/apps/BreakoutRoomApp.scala | 4 +-- .../core/apps/BreakoutRoomModel.scala | 1 + .../CreateBreakoutRoomsRequestPayload.java | 35 ++++++++++--------- .../CreateBreakoutRoomsRequestTest.java | 3 +- .../main/model/users/UserService.as | 2 +- .../modules/users/services/MessageSender.as | 3 +- 8 files changed, 29 insertions(+), 23 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala index e0c9e689d8..7138d1eb81 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/Protocol.scala @@ -25,7 +25,7 @@ object UserMessagesProtocol extends DefaultJsonProtocol { } implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload) - implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms) + implicit val createBreakoutRoomsFormat = jsonFormat5(CreateBreakoutRooms) implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage) implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat4(RequestBreakoutJoinURLInMessage) implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index 0c1a37f108..805e890ac5 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -42,7 +42,7 @@ case class LockSetting(meetingID: String, locked: Boolean, settings: Map[String, // 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 CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean, redirectOnJoin: 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, redirect: Boolean) extends InMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala index 8b7822bbac..2d858d45b9 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomApp.scala @@ -44,6 +44,7 @@ trait BreakoutRoomApp extends SystemConfiguration { val sourcePresentationId = if (!presModel.getCurrentPresentation().isEmpty) presModel.getCurrentPresentation().get.id else "blank" val sourcePresentationSlide = if (!presModel.getCurrentPage().isEmpty) presModel.getCurrentPage().get.num else 0 breakoutModel.pendingRoomsNumber = msg.rooms.length; + breakoutModel.redirectOnJoin = msg.redirectOnJoin; for (room <- msg.rooms) { i += 1 @@ -90,8 +91,7 @@ trait BreakoutRoomApp extends SystemConfiguration { breakoutModel.getAssignedUsers(room.id) foreach { users => users.foreach { u => log.debug("Sending Join URL for users"); - // @fixme: to refactor with CreateBreakoutRooms - sendJoinURL(u, room.externalMeetingId, true) + sendJoinURL(u, room.externalMeetingId, breakoutModel.redirectOnJoin) } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala index e6d54f1a9f..dbc653480e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutRoomModel.scala @@ -10,6 +10,7 @@ class BreakoutRoomModel { private var rooms = new collection.immutable.HashMap[String, BreakoutRoom] var pendingRoomsNumber: Integer = 0 + var redirectOnJoin: Boolean = false def add(room: BreakoutRoom): BreakoutRoom = { rooms += room.id -> room diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomsRequestPayload.java b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomsRequestPayload.java index 33e020df19..35038b6e0c 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomsRequestPayload.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/messages/payload/CreateBreakoutRoomsRequestPayload.java @@ -3,21 +3,24 @@ package org.bigbluebutton.messages.payload; import java.util.ArrayList; public class CreateBreakoutRoomsRequestPayload { - // The main meeting internal id - public final String meetingId; - // The list of breakout rooms - public final ArrayList rooms; - // The duration of the breakout room - public final Integer durationInMinutes; - // Breakout rooms recording option - public final Boolean record; + // The main meeting internal id + public final String meetingId; + // The list of breakout rooms + public final ArrayList rooms; + // The duration of the breakout room + public final Integer durationInMinutes; + // Breakout rooms recording option + public final Boolean record; + // Creates join URL with redirect value true or false + public final Boolean redirectOnJoin; - public CreateBreakoutRoomsRequestPayload(String meetingId, - ArrayList breakoutRooms, - Integer duration, Boolean record) { - this.meetingId = meetingId; - this.rooms = breakoutRooms; - this.durationInMinutes = duration; - this.record = record; - } + public CreateBreakoutRoomsRequestPayload(String meetingId, + ArrayList breakoutRooms, + Integer duration, Boolean record, Boolean redirectOnJoin) { + this.meetingId = meetingId; + this.rooms = breakoutRooms; + this.durationInMinutes = duration; + this.record = record; + this.redirectOnJoin = redirectOnJoin; + } } diff --git a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java index a0c780b360..c7ee9eb253 100755 --- a/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java +++ b/bbb-common-message/src/test/java/org/bigbluebutton/messages/CreateBreakoutRoomsRequestTest.java @@ -15,6 +15,7 @@ public class CreateBreakoutRoomsRequestTest { String meetingId = "abc123"; Integer durationInMinutes = 20; Boolean record = true; + Boolean redirectOnJoin = false; ArrayList room1Users = new ArrayList(); room1Users.add("Tidora"); room1Users.add("Nidora"); room1Users.add("Tinidora"); @@ -31,7 +32,7 @@ public class CreateBreakoutRoomsRequestTest { ArrayList rooms = new ArrayList(); rooms.add(room1); rooms.add(room2); rooms.add(room3); - CreateBreakoutRoomsRequestPayload payload = new CreateBreakoutRoomsRequestPayload(meetingId, rooms, durationInMinutes, record); + CreateBreakoutRoomsRequestPayload payload = new CreateBreakoutRoomsRequestPayload(meetingId, rooms, durationInMinutes, record, redirectOnJoin); CreateBreakoutRoomsRequest msg = new CreateBreakoutRoomsRequest(payload); Gson gson = new Gson(); String json = gson.toJson(msg); diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as index 66b8262275..67196559c6 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/UserService.as @@ -199,7 +199,7 @@ package org.bigbluebutton.main.model.users } public function createBreakoutRooms(e:BreakoutRoomEvent):void{ - sender.createBreakoutRooms(_conferenceParameters.meetingID, e.rooms, e.durationInMinutes, e.record); + sender.createBreakoutRooms(_conferenceParameters.meetingID, e.rooms, e.durationInMinutes, e.record, true); } public function requestBreakoutJoinUrl(e:BreakoutRoomEvent):void{ diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as index 8f2622f9fa..9881a0fe0f 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/services/MessageSender.as @@ -87,12 +87,13 @@ package org.bigbluebutton.modules.users.services ); } - public function createBreakoutRooms(meetingId:String, rooms:Array, durationInMinutes:int, record:Boolean):void { + public function createBreakoutRooms(meetingId:String, rooms:Array, durationInMinutes:int, record:Boolean, redirectOnJoin:Boolean):void { var message:Object = new Object(); message["meetingId"] = meetingId; message["rooms"] = rooms; message["durationInMinutes"] = durationInMinutes; message["record"] = record; + message["redirectOnJoin"] = redirectOnJoin; var jsonMsg:String = JSON.stringify(message); var _nc:ConnectionManager = BBB.initConnectionManager(); From 265216a33cb35d01f416e3383c0024c19c520089 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Mon, 17 Oct 2016 09:08:29 +0100 Subject: [PATCH 17/22] Updated bbb-record rules to detect recording directories. --- bigbluebutton-config/bin/bbb-record | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bigbluebutton-config/bin/bbb-record b/bigbluebutton-config/bin/bbb-record index 6adbe52166..608707dbfe 100755 --- a/bigbluebutton-config/bin/bbb-record +++ b/bigbluebutton-config/bin/bbb-record @@ -33,7 +33,7 @@ # 2013-04-05 GUG Description is optional in bbb-record --watch # 2013-04-05 GUG Map internal meeting id with external meeting id # 2016-07-02 FFD Updates for 1.1 -# 2016-09-27 GTR Stricter recording directories names detection to cover breakout rooms recordings +# 2016-10-17 GTR Stricter rule for detection of recording directories names #set -e #set -x @@ -408,7 +408,7 @@ if [ $DELETEALL ]; then rm -f /var/bigbluebutton/screenshare/*.flv rm -f /var/freeswitch/meetings/*.wav - for meeting in $(ls /var/bigbluebutton | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}-\?[[:digit:]]\{1\}\?$"); do + for meeting in $(ls /var/bigbluebutton | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}$"); do echo "deleting: $meeting" rm -rf /var/bigbluebutton/$meeting done @@ -448,10 +448,10 @@ if [ -z $HEAD ]; then fi tmp_file=$(mktemp) -ls -t /var/bigbluebutton | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}-\?[[:digit:]]\{1\}\?$" | head -n $HEAD > $tmp_file -ls -t /var/bigbluebutton/recording/raw | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}-\?[[:digit:]]\{1\}\?$" | head -n $HEAD >> $tmp_file +ls -t /var/bigbluebutton | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}$" | head -n $HEAD > $tmp_file +ls -t /var/bigbluebutton/recording/raw | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}$" | head -n $HEAD >> $tmp_file -#for meeting in $(ls -t /var/bigbluebutton | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}-\?[[:digit:]]\{1\}\?$" | head -n $HEAD); do +#for meeting in $(ls -t /var/bigbluebutton | grep "^[0-9a-f]\{40\}-[[:digit:]]\{13\}$" | head -n $HEAD); do for meeting in $(cat $tmp_file | sort -t - -k 2 -r| uniq); do echo -n "$meeting" timestamp=$(echo $meeting | sed s/.*-//g) From 2b7c7d84e4c7c388f19644e292bfffbc435237a2 Mon Sep 17 00:00:00 2001 From: Ghazi Triki Date: Mon, 17 Oct 2016 10:15:02 +0100 Subject: [PATCH 18/22] Monitoring for number of user is not triggered for breakout rooms. --- .../org/bigbluebutton/core/LiveMeeting.scala | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/LiveMeeting.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/LiveMeeting.scala index 9514ab2203..63c9f46a6c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/LiveMeeting.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/LiveMeeting.scala @@ -12,17 +12,17 @@ import org.bigbluebutton.core.apps.CaptionApp import org.bigbluebutton.core.apps.CaptionModel class LiveMeeting(val mProps: MeetingProperties, - val eventBus: IncomingEventBus, - val outGW: OutMessageGateway, - val chatModel: ChatModel, - val layoutModel: LayoutModel, - val meetingModel: MeetingModel, - val usersModel: UsersModel, - val pollModel: PollModel, - val wbModel: WhiteboardModel, - val presModel: PresentationModel, - val breakoutModel: BreakoutRoomModel, - val captionModel: CaptionModel)(implicit val context: ActorContext) + val eventBus: IncomingEventBus, + val outGW: OutMessageGateway, + val chatModel: ChatModel, + val layoutModel: LayoutModel, + val meetingModel: MeetingModel, + val usersModel: UsersModel, + val pollModel: PollModel, + val wbModel: WhiteboardModel, + val presModel: PresentationModel, + val breakoutModel: BreakoutRoomModel, + val captionModel: CaptionModel)(implicit val context: ActorContext) extends UsersApp with PresentationApp with LayoutApp with ChatApp with WhiteboardApp with PollApp with BreakoutRoomApp with CaptionApp { @@ -56,7 +56,7 @@ class LiveMeeting(val mProps: MeetingProperties, } def startCheckingIfWeNeedToEndVoiceConf() { - if (usersModel.numWebUsers == 0) { + if (usersModel.numWebUsers == 0 && !mProps.isBreakout) { meetingModel.lastWebUserLeft() log.debug("MonitorNumberOfWebUsers started for meeting [" + mProps.meetingID + "]") } From 373dd9535b002ae6e888b2f51efb8d0447cb3332 Mon Sep 17 00:00:00 2001 From: Lajellu Date: Mon, 17 Oct 2016 14:14:12 -0700 Subject: [PATCH 19/22] HTML5 - fixes fullscreen toggle to un-fullscreen --- .../nav-bar/settings-dropdown/component.jsx | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx index 92f7dc830c..3832c6bd43 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx @@ -51,22 +51,32 @@ const toggleFullScreen = () => { if (document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled) { - if (element.requestFullscreen) { - element.requestFullscreen(); - } else if (element.mozRequestFullScreen) { - element.mozRequestFullScreen(); - } else if (element.webkitRequestFullscreen) { - element.webkitRequestFullscreen(); - } else if (element.msRequestFullscreen) { - element.msRequestFullscreen(); - } - } else { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen(); + + // If the page is already fullscreen, exit fullscreen + if (document.fullscreenElement + || document.webkitFullscreenElement + || document.mozFullScreenElement + || document.msFullscreenElement) { + + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } + + // If the page is not currently fullscreen, make fullscreen + } else { + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } } } }; From 6d1823f2c76af06e2db0a751251a1b7bac7f4dbf Mon Sep 17 00:00:00 2001 From: JaeeunCho Date: Mon, 17 Oct 2016 14:29:00 -0700 Subject: [PATCH 20/22] HTML5 - fixed linebreak with lint --- .../actions-dropdown/component.jsx | 194 +++++++++--------- 1 file changed, 96 insertions(+), 98 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx index 406e3e71a1..db6f116546 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx @@ -1,98 +1,96 @@ -import React, { Component, PropTypes } from 'react'; -import { defineMessages, injectIntl } from 'react-intl'; - -import Button from '/imports/ui/components/button/component'; -import Dropdown from '/imports/ui/components/dropdown/component'; -import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component'; -import DropdownContent from '/imports/ui/components/dropdown/content/component'; -import DropdownList from '/imports/ui/components/dropdown/list/component'; -import DropdownListItem from '/imports/ui/components/dropdown/list/item/component'; - -const intlMessages = defineMessages({ - actionsLabel: { - id: 'app.actionsBar.actionsDropdown.actionsLabel', - - //defaultMessage: 'Actions', - }, - presentationLabel: { - id: 'app.actionsBar.actionsDropdown.presentationLabel', - defaultMessage: 'Upload a presentation', - }, - initPollLabel: { - id: 'app.actionsBar.actionsDropdown.initPollLabel', - defaultMessage: 'Initiate a poll', - }, - desktopShareLabel: { - id: 'app.actionsBar.actionsDropdown.desktopShareLabel', - defaultMessage: 'Share your screen', - }, - presentationDesc: { - id: 'app.actionsBar.actionsDropdown.presentationDesc', - defaultMessage: 'Upload your presentation', - }, - initPollDesc: { - id: 'app.actionsBar.actionsDropdown.initPollDesc', - defaultMessage: 'Initiate a poll', - }, - desktopShareDesc: { - id: 'app.actionsBar.actionsDropdown.desktopShareDesc', - defaultMessage: 'Share your screen with others', - }, -}); - -const presentation = () => {console.log('Should show the uploader component');}; - -const polling = () => {console.log('Should initiate a polling');}; - -const shareScreen = () => {console.log('Should start screen sharing');}; - -class ActionsDropdown extends Component { - constructor(props) { - super(props); - } - - render() { - const { intl } = this.props; - return ( - - -