From 9e6a40280e659671cb5d8bbba982909de40e30d0 Mon Sep 17 00:00:00 2001 From: Richard Alam <ritzalam@gmail.com> Date: Sat, 5 Sep 2020 08:43:12 -0700 Subject: [PATCH] - set html5 as default client - add meetingEndedURL and endWhenNoModerator create param - meetingEndedURL is complete - endWhenNoModerator is partially implemented. Will be continued in another PR. --- .../java/org/bigbluebutton/api/ApiParams.java | 10 ++++++ .../org/bigbluebutton/api/MeetingService.java | 36 ++++++++++++------- .../api/ParamsProcessorUtil.java | 21 +++++++++++ .../org/bigbluebutton/api/domain/Meeting.java | 22 +++++++++++- .../grails-app/conf/bigbluebutton.properties | 9 +++-- .../grails-app/conf/spring/resources.xml | 1 + 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java index 5c2d04245b..5bfa44ec76 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java @@ -70,6 +70,16 @@ public class ApiParams { public static final String LOCK_SETTINGS_LOCK_ON_JOIN = "lockSettingsLockOnJoin"; public static final String LOCK_SETTINGS_LOCK_ON_JOIN_CONFIGURABLE = "lockSettingsLockOnJoinConfigurable"; + // New param passed on create call to callback when meeting ends. + // This is a duplicate of the endCallbackUrl meta param as we want this + // param to stay on the server and not propagated to client and recordings. + public static final String MEETING_ENDED_CALLBACK_URL = "meetingEndedURL"; + + // Param to end the meeting when there are no moderators after a certain period of time. + // Needed for classes where teacher gets disconnected and can't get back in. Prevents + // students from running amok. + public static final String END_WHEN_NO_MODERATOR = "endWhenNoModerator"; + private ApiParams() { throw new IllegalStateException("ApiParams is a utility class. Instanciation is forbidden."); } 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 7860a12ece..25a2665ec9 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 @@ -40,6 +40,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; +import org.apache.commons.lang3.StringUtils; import org.apache.http.client.utils.URIBuilder; import org.bigbluebutton.api.domain.GuestPolicy; import org.bigbluebutton.api.domain.Meeting; @@ -716,27 +717,38 @@ public class MeetingService implements MessageListener { String endCallbackUrl = "endCallbackUrl".toLowerCase(); Map<String, String> metadata = m.getMetadata(); - if (!m.isBreakout() && metadata.containsKey(endCallbackUrl)) { - String callbackUrl = metadata.get(endCallbackUrl); - try { + if (!m.isBreakout()) { + if (metadata.containsKey(endCallbackUrl)) { + String callbackUrl = metadata.get(endCallbackUrl); + try { callbackUrl = new URIBuilder(new URI(callbackUrl)) - .addParameter("recordingmarks", m.haveRecordingMarks() ? "true" : "false") - .addParameter("meetingID", m.getExternalId()).build().toURL().toString(); - callbackUrlService.handleMessage(new MeetingEndedEvent(m.getInternalId(), m.getExternalId(), m.getName(), callbackUrl)); - } catch (MalformedURLException e) { - log.error("Malformed URL in callback url=[{}]", callbackUrl, e); - } catch (URISyntaxException e) { - log.error("URI Syntax error in callback url=[{}]", callbackUrl, e); - } catch (Exception e) { - log.error("Error in callback url=[{}]", callbackUrl, e); + .addParameter("recordingmarks", m.haveRecordingMarks() ? "true" : "false") + .addParameter("meetingID", m.getExternalId()).build().toURL().toString(); + MeetingEndedEvent event = new MeetingEndedEvent(m.getInternalId(), m.getExternalId(), m.getName(), callbackUrl); + processMeetingEndedCallback(event); + } catch (Exception e) { + log.error("Error in callback url=[{}]", callbackUrl, e); + } } + if (! StringUtils.isEmpty(m.getMeetingEndedCallbackURL())) { + String meetingEndedCallbackURL = m.getMeetingEndedCallbackURL(); + callbackUrlService.handleMessage(new MeetingEndedEvent(m.getInternalId(), m.getExternalId(), m.getName(), meetingEndedCallbackURL)); + } } processRemoveEndedMeeting(message); } } + private void processMeetingEndedCallback(MeetingEndedEvent event) { + try { + callbackUrlService.handleMessage(event); + } catch (Exception e) { + log.error("Error in callback url=[{}]", event.getCallbackUrl(), e); + } + } + private void userJoined(UserJoined message) { Meeting m = getMeeting(message.meetingId); if (m != null) { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java index 89930a94b7..c171e5e17c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -116,6 +116,7 @@ public class ParamsProcessorUtil { private Integer userInactivityThresholdInMinutes = 30; private Integer userActivitySignResponseDelayInMinutes = 5; private Boolean defaultAllowDuplicateExtUserid = true; + private Boolean defaultEndWhenNoModerator = false; private String formatConfNum(String s) { if (s.length() > 5) { @@ -422,6 +423,15 @@ public class ParamsProcessorUtil { } } + boolean endWhenNoModerator = defaultEndWhenNoModerator; + if (!StringUtils.isEmpty(params.get(ApiParams.END_WHEN_NO_MODERATOR))) { + try { + endWhenNoModerator = Boolean.parseBoolean(params.get(ApiParams.END_WHEN_NO_MODERATOR)); + } catch (Exception ex) { + log.warn("Invalid param [endWhenNoModerator] for meeting=[{}]", internalMeetingId); + } + } + String guestPolicy = defaultGuestPolicy; if (!StringUtils.isEmpty(params.get(ApiParams.GUEST_POLICY))) { guestPolicy = params.get(ApiParams.GUEST_POLICY); @@ -489,6 +499,11 @@ public class ParamsProcessorUtil { meeting.setModeratorOnlyMessage(moderatorOnlyMessage); } + if (!StringUtils.isEmpty(params.get(ApiParams.MEETING_ENDED_CALLBACK_URL))) { + String meetingEndedCallbackURL = params.get(ApiParams.MEETING_ENDED_CALLBACK_URL); + meeting.setMeetingEndedCallbackURL(meetingEndedCallbackURL); + } + meeting.setMaxInactivityTimeoutMinutes(maxInactivityTimeoutMinutes); meeting.setWarnMinutesBeforeMax(warnMinutesBeforeMax); meeting.setMeetingExpireIfNoUserJoinedInMinutes(meetingExpireIfNoUserJoinedInMinutes); @@ -1135,4 +1150,10 @@ public class ParamsProcessorUtil { public void setAllowDuplicateExtUserid(Boolean allow) { this.defaultAllowDuplicateExtUserid = allow; } + + public void setEndWhenNoModerator(Boolean val) { + this.defaultEndWhenNoModerator = val; + } + + } 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 624e85cf49..4ee757a942 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 @@ -94,6 +94,11 @@ public class Meeting { public final Boolean allowDuplicateExtUserid; + private String meetingEndedCallbackURL = ""; + + public final Boolean endWhenNoModerator; + + public Meeting(Meeting.Builder builder) { name = builder.name; extMeetingId = builder.externalId; @@ -122,7 +127,8 @@ public class Meeting { guestPolicy = builder.guestPolicy; breakoutRoomsParams = builder.breakoutRoomsParams; lockSettingsParams = builder.lockSettingsParams; - allowDuplicateExtUserid = builder.allowDuplicateExtUserid; + allowDuplicateExtUserid = builder.allowDuplicateExtUserid; + endWhenNoModerator = builder.endWhenNoModerator; userCustomData = new HashMap<>(); @@ -574,6 +580,14 @@ public class Meeting { this.userActivitySignResponseDelayInMinutes = userActivitySignResponseDelayInMinutes; } + public String getMeetingEndedCallbackURL() { + return meetingEndedCallbackURL; + } + + public void setMeetingEndedCallbackURL(String meetingEndedCallbackURL) { + this.meetingEndedCallbackURL = meetingEndedCallbackURL; + } + public Map<String, Object> getUserCustomData(String userID){ return (Map<String, Object>) userCustomData.get(userID); } @@ -623,6 +637,7 @@ public class Meeting { private BreakoutRoomsParams breakoutRoomsParams; private LockSettingsParams lockSettingsParams; private Boolean allowDuplicateExtUserid; + private Boolean endWhenNoModerator; public Builder(String externalId, String internalId, long createTime) { this.externalId = externalId; @@ -754,6 +769,11 @@ public class Meeting { this.allowDuplicateExtUserid = allowDuplicateExtUserid; return this; } + + public Builder withEndWhenNoModerator(Boolean endWhenNoModerator) { + this.endWhenNoModerator = endWhenNoModerator; + return this; + } public Meeting build() { return new Meeting(this); diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties index 26d818d40b..cb809d0910 100755 --- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties +++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties @@ -235,10 +235,10 @@ defaultClientUrl=${bigbluebutton.web.serverURL}/client/BigBlueButton.html allowRequestsWithoutSession=false # Force all attendees to join the meeting using the HTML5 client -attendeesJoinViaHTML5Client=false +attendeesJoinViaHTML5Client=true # Force all moderators to join the meeting using the HTML5 client -moderatorsJoinViaHTML5Client=false +moderatorsJoinViaHTML5Client=true # The url of the BigBlueButton HTML5 client. Users will be redirected here when # successfully joining the meeting. @@ -347,3 +347,8 @@ lockSettingsLockOnJoinConfigurable=false allowDuplicateExtUserid=true defaultTextTrackUrl=${bigbluebutton.web.serverURL}/bigbluebutton + +# Param to end the meeting when there are no moderators after a certain period of time. +# Needed for classes where teacher gets disconnected and can't get back in. Prevents +# students from running amok. +endWhenNoModerator=false diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml index df4684abf7..79b90ec521 100755 --- a/bigbluebutton-web/grails-app/conf/spring/resources.xml +++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml @@ -158,6 +158,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <property name="lockSettingsLockOnJoin" value="${lockSettingsLockOnJoin}"/> <property name="lockSettingsLockOnJoinConfigurable" value="${lockSettingsLockOnJoinConfigurable}"/> <property name="allowDuplicateExtUserid" value="${allowDuplicateExtUserid}"/> + <property name="endWhenNoModerator" value="${endWhenNoModerator}"/> </bean> <import resource="doc-conversion.xml"/> -- GitLab