diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java index 4f880fcb27dd6d99b330ba99776e9248d38f98d6..b37abf05f512764a26f85dd7aedbcba90bade446 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java @@ -18,6 +18,9 @@ package org.bigbluebutton.api; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; @@ -29,11 +32,20 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.TreeMap; import java.util.Set; -import java.util.concurrent.*; - -import org.bigbluebutton.api.domain.*; +import java.util.TreeMap; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +import org.apache.http.client.utils.URIBuilder; +import org.bigbluebutton.api.domain.Meeting; +import org.bigbluebutton.api.domain.Recording; +import org.bigbluebutton.api.domain.User; +import org.bigbluebutton.api.domain.UserSession; import org.bigbluebutton.api.messaging.MessageListener; import org.bigbluebutton.api.messaging.RedisStorageService; import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage; @@ -47,6 +59,8 @@ import org.bigbluebutton.api.messaging.messages.MeetingDestroyed; import org.bigbluebutton.api.messaging.messages.MeetingEnded; import org.bigbluebutton.api.messaging.messages.MeetingStarted; import org.bigbluebutton.api.messaging.messages.RegisterUser; +import org.bigbluebutton.api.messaging.messages.StunTurnInfoRequested; +import org.bigbluebutton.api.messaging.messages.UpdateRecordingStatus; import org.bigbluebutton.api.messaging.messages.UserJoined; import org.bigbluebutton.api.messaging.messages.UserJoinedVoice; import org.bigbluebutton.api.messaging.messages.UserLeft; @@ -60,7 +74,6 @@ import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.bigbluebutton.common.messages.Constants; import org.bigbluebutton.common.messages.SendStunTurnInfoReplyMessage; import org.bigbluebutton.presentation.PresentationUrlDownloadService; -import org.bigbluebutton.api.messaging.messages.StunTurnInfoRequested; import org.bigbluebutton.web.services.RegisteredUserCleanupTimerTask; import org.bigbluebutton.web.services.callback.CallbackUrlService; import org.bigbluebutton.web.services.callback.MeetingEndedEvent; @@ -447,6 +460,14 @@ public class MeetingService implements MessageListener { message.meetingId, message.parentMeetingId); } } + + private void processUpdateRecordingStatus(UpdateRecordingStatus message) { + Meeting m = getMeeting(message.meetingId); + // Set only once + if (m != null && message.recording && !m.haveRecordingMarks()) { + m.setHaveRecordingMarks(message.recording); + } + } private void processEndBreakoutRoom(EndBreakoutRoom message) { processEndMeeting(new EndMeeting(message.breakoutMeetingId)); @@ -570,12 +591,18 @@ public class MeetingService implements MessageListener { Map<String, String> metadata = m.getMetadata(); if (metadata.containsKey(END_CALLBACK_URL)) { String callbackUrl = metadata.get(END_CALLBACK_URL); + try { + callbackUrl = new URIBuilder(new URI(callbackUrl)).addParameter("recordingmarks", m.haveRecordingMarks() ? "true" : "false").build().toURL().toString(); + } catch (MalformedURLException e) { + log.error("Malformed URL in callback url=[{}]", callbackUrl); + } catch (URISyntaxException e) { + log.error("URI Syntax error in callback url=[{}]", callbackUrl); + e.printStackTrace(); + } callbackUrlService.handleMessage(new MeetingEndedEvent(callbackUrl)); } processRemoveEndedMeeting(message); - - return; } } @@ -861,6 +888,8 @@ public class MeetingService implements MessageListener { processStunTurnInfoRequested((StunTurnInfoRequested) message); } else if (message instanceof CreateBreakoutRoom) { processCreateBreakoutRoom((CreateBreakoutRoom) message); + } else if (message instanceof UpdateRecordingStatus) { + processUpdateRecordingStatus((UpdateRecordingStatus) message); } } }; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java index 99ec4c9ed56522ed1fe982a65f304ac495c1e4d5..e3e1f66894877f6cc649b22b59d58375ffc81564 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java @@ -51,6 +51,7 @@ public class Meeting { private boolean record; private boolean autoStartRecording = false; private boolean allowStartStopRecording = false; + private boolean haveRecordingMarks = false; private boolean webcamsOnlyForModerator = false; private String dialNumber; private String defaultAvatarURL; @@ -212,7 +213,16 @@ public class Meeting { public Boolean isBreakout() { return isBreakout; } + + + public void setHaveRecordingMarks(boolean marks) { + haveRecordingMarks = marks; + } + public boolean haveRecordingMarks() { + return haveRecordingMarks; + } + public String getName() { return name; } @@ -495,7 +505,7 @@ public class Meeting { this.allowStartStopRecording = allow; return this; } - + public Builder withWebcamsOnlyForModerator(boolean only) { this.webcamsOnlyForModerator = only; return this; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UpdateRecordingStatus.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UpdateRecordingStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..ba77958dccd430ab4f8f3677c7a7888b6460fec3 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UpdateRecordingStatus.java @@ -0,0 +1,11 @@ +package org.bigbluebutton.api.messaging.messages; + +public class UpdateRecordingStatus implements IMessage { + public final String meetingId; + public final Boolean recording; + + public UpdateRecordingStatus(String meetingId, Boolean recording) { + this.meetingId = meetingId; + this.recording = recording; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java index 8044f00e88ba466363fc7d527e9e5a091c74f60a..c06145228676ab423b86508f068988d5d05b9865 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/callback/CallbackUrlService.java @@ -1,24 +1,22 @@ package org.bigbluebutton.web.services.callback; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; + import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; -import org.apache.http.entity.ContentType; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; -import org.apache.http.nio.client.methods.HttpAsyncMethods; -import org.apache.http.nio.client.methods.ZeroCopyConsumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.concurrent.*; - public class CallbackUrlService { private static Logger log = LoggerFactory.getLogger(CallbackUrlService.class); @@ -119,10 +117,10 @@ public class CallbackUrlService { } private boolean fetchCallbackUrl(final String callbackUrl) { - log.info("Calling callback url {}", callbackUrl); - String finalUrl = followRedirect(callbackUrl, 0, callbackUrl); + log.info("Calling callback url {}", finalUrl); + if (finalUrl == null) return false; boolean success = false; diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala index fdac5722337d9ed07af247fa19b1fd21e6003420..700e83a626b9e1451b22ef6d9110459e4b9796f7 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala @@ -87,6 +87,8 @@ class ReceivedJsonMsgHdlrActor(val msgFromAkkaAppsEventBus: MsgFromAkkaAppsEvent route[UserRoleChangedEvtMsg](envelope, jsonNode) case CreateBreakoutRoomSysCmdMsg.NAME => route[CreateBreakoutRoomSysCmdMsg](envelope, jsonNode) + case RecordingStatusChangedEvtMsg.NAME => + route[RecordingStatusChangedEvtMsg](envelope, jsonNode) case _ => //log.debug("************ Cannot route envelope name " + envelope.name) diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala index dfc45af7d8c4ded5365c7fae5563bfded515b78a..b034d89b228bdc14f15d2c88dac5a2f0c6ad8694 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala @@ -36,6 +36,7 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) case m: UserBroadcastCamStartedEvtMsg => handleUserBroadcastCamStartedEvtMsg(m) case m: UserBroadcastCamStoppedEvtMsg => handleUserBroadcastCamStoppedEvtMsg(m) case m: CreateBreakoutRoomSysCmdMsg => handleCreateBreakoutRoomSysCmdMsg(m) + case m: RecordingStatusChangedEvtMsg => handleRecordingStatusChangedEvtMsg(m) case _ => log.error("***** Cannot handle " + msg.envelope.name) } } @@ -69,6 +70,10 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) )) } + + def handleRecordingStatusChangedEvtMsg(msg: RecordingStatusChangedEvtMsg): Unit = { + olgMsgGW.handle(new UpdateRecordingStatus(msg.header.meetingId, msg.body.recording)); + } def handleCheckAlivePongSysMsg(msg: CheckAlivePongSysMsg): Unit = { olgMsgGW.handle(new org.bigbluebutton.api.messaging.messages.KeepAliveReply(msg.body.system, msg.body.timestamp))